Successfully identified regression in *gcc* in CI configuration tcwg_bmk_gnu_tk1/gnu-release-arm-spec2k6-O3_LTO. So far, this commit has regressed CI configurations:
- tcwg_bmk_gnu_tk1/gnu-release-arm-spec2k6-O3_LTO
Culprit:
<cut>
commit c7207339a7dbce5b68f872064e624dcf1639ba46
Author: Wilco Dijkstra <wdijkstr(a)arm.com>
Date: Mon Oct 14 12:21:14 2019 +0000
[ARM] Switch to default sched pressure algorithm
Currently the Arm backend selects the alternative sched pressure algorithm.
The issue is that this doesn't take register pressure into account, and so
it causes significant additional spilling on Arm where there are only 14
allocatable registers. Building SPEC2006 showed significant codesize gains
with the default pressure algorithm, so switch back to that. PR77308 shows
~800 fewer instructions.
SPECINT2006 is ~0.6% faster on Cortex-A57 together with the other DImode
patches. Overall SPEC codesize is 1.1% smaller.
gcc/
* config/arm/arm.c (arm_option_override): Don't override sched
pressure algorithm.
From-SVN: r276960
</cut>
Results regressed to (for first_bad == c7207339a7dbce5b68f872064e624dcf1639ba46)
# reset_artifacts:
-10
# build_abe binutils:
-9
# build_abe stage1 -- --set gcc_override_configure=--with-mode=arm --set gcc_override_configure=--disable-libsanitizer:
-8
# build_abe linux:
-7
# build_abe glibc:
-6
# build_abe stage2 -- --set gcc_override_configure=--with-mode=arm --set gcc_override_configure=--disable-libsanitizer:
-5
# true:
0
# benchmark -O3_LTO_marm -- artifacts/build-c7207339a7dbce5b68f872064e624dcf1639ba46/results_id:
1
# 435.gromacs,gromacs_base.default regressed by 106
# 459.GemsFDTD,GemsFDTD_base.default regressed by 103
# 436.cactusADM,cactusADM_base.default regressed by 115
# 444.namd,namd_base.default regressed by 103
# 482.sphinx3,sphinx_livepretend_base.default regressed by 103
# 410.bwaves,bwaves_base.default regressed by 107
# 454.calculix,calculix_base.default regressed by 105
from (for last_good == 7bd8bec53f0e43c7a7852c54650746e65324514b)
# reset_artifacts:
-10
# build_abe binutils:
-9
# build_abe stage1 -- --set gcc_override_configure=--with-mode=arm --set gcc_override_configure=--disable-libsanitizer:
-8
# build_abe linux:
-7
# build_abe glibc:
-6
# build_abe stage2 -- --set gcc_override_configure=--with-mode=arm --set gcc_override_configure=--disable-libsanitizer:
-5
# true:
0
# benchmark -O3_LTO_marm -- artifacts/build-7bd8bec53f0e43c7a7852c54650746e65324514b/results_id:
1
Artifacts of last_good build: https://ci.linaro.org/job/tcwg_bmk_ci_gnu-bisect-tcwg_bmk_tk1-gnu-release-a…
Results ID of last_good: tk1_32/tcwg_bmk_gnu_tk1/bisect-gnu-release-arm-spec2k6-O3_LTO/1638
Artifacts of first_bad build: https://ci.linaro.org/job/tcwg_bmk_ci_gnu-bisect-tcwg_bmk_tk1-gnu-release-a…
Results ID of first_bad: tk1_32/tcwg_bmk_gnu_tk1/bisect-gnu-release-arm-spec2k6-O3_LTO/1643
Build top page/logs: https://ci.linaro.org/job/tcwg_bmk_ci_gnu-bisect-tcwg_bmk_tk1-gnu-release-a…
Configuration details:
Reproduce builds:
<cut>
mkdir investigate-gcc-c7207339a7dbce5b68f872064e624dcf1639ba46
cd investigate-gcc-c7207339a7dbce5b68f872064e624dcf1639ba46
git clone https://git.linaro.org/toolchain/jenkins-scripts
mkdir -p artifacts/manifests
curl -o artifacts/manifests/build-baseline.sh https://ci.linaro.org/job/tcwg_bmk_ci_gnu-bisect-tcwg_bmk_tk1-gnu-release-a… --fail
curl -o artifacts/manifests/build-parameters.sh https://ci.linaro.org/job/tcwg_bmk_ci_gnu-bisect-tcwg_bmk_tk1-gnu-release-a… --fail
curl -o artifacts/test.sh https://ci.linaro.org/job/tcwg_bmk_ci_gnu-bisect-tcwg_bmk_tk1-gnu-release-a… --fail
chmod +x artifacts/test.sh
# Reproduce the baseline build (build all pre-requisites)
./jenkins-scripts/tcwg_bmk-build.sh @@ artifacts/manifests/build-baseline.sh
# Save baseline build state (which is then restored in artifacts/test.sh)
rsync -a --del --delete-excluded --exclude bisect/ --exclude artifacts/ --exclude gcc/ ./ ./bisect/baseline/
cd gcc
# Reproduce first_bad build
git checkout --detach c7207339a7dbce5b68f872064e624dcf1639ba46
../artifacts/test.sh
# Reproduce last_good build
git checkout --detach 7bd8bec53f0e43c7a7852c54650746e65324514b
../artifacts/test.sh
cd ..
</cut>
History of pending regressions and results: https://git.linaro.org/toolchain/ci/base-artifacts.git/log/?h=linaro-local/…
Artifacts: https://ci.linaro.org/job/tcwg_bmk_ci_gnu-bisect-tcwg_bmk_tk1-gnu-release-a…
Build log: https://ci.linaro.org/job/tcwg_bmk_ci_gnu-bisect-tcwg_bmk_tk1-gnu-release-a…
Full commit (up to 1000 lines):
<cut>
commit c7207339a7dbce5b68f872064e624dcf1639ba46
Author: Wilco Dijkstra <wdijkstr(a)arm.com>
Date: Mon Oct 14 12:21:14 2019 +0000
[ARM] Switch to default sched pressure algorithm
Currently the Arm backend selects the alternative sched pressure algorithm.
The issue is that this doesn't take register pressure into account, and so
it causes significant additional spilling on Arm where there are only 14
allocatable registers. Building SPEC2006 showed significant codesize gains
with the default pressure algorithm, so switch back to that. PR77308 shows
~800 fewer instructions.
SPECINT2006 is ~0.6% faster on Cortex-A57 together with the other DImode
patches. Overall SPEC codesize is 1.1% smaller.
gcc/
* config/arm/arm.c (arm_option_override): Don't override sched
pressure algorithm.
From-SVN: r276960
---
gcc/ChangeLog | 5 +++++
gcc/config/arm/arm.c | 5 -----
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index c2cbd4274ca..f07a0e61e6b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+2019-10-14 Wilco Dijkstra <wdijkstr(a)arm.com>
+
+ * config/arm/arm.c (arm_option_override): Don't override sched
+ pressure algorithm.
+
2019-10-14 Richard Biener <rguenther(a)suse.de>
PR tree-optimization/92069
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 39e1a1ef9a2..394b1dd1902 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -3555,11 +3555,6 @@ arm_option_override (void)
global_options.x_param_values,
global_options_set.x_param_values);
- /* Use the alternative scheduling-pressure algorithm by default. */
- maybe_set_param_value (PARAM_SCHED_PRESSURE_ALGORITHM, SCHED_PRESSURE_MODEL,
- global_options.x_param_values,
- global_options_set.x_param_values);
-
/* Look through ready list and all of queue for instructions
relevant for L2 auto-prefetcher. */
int param_sched_autopref_queue_depth;
</cut>
Successfully identified regression in *gcc* in CI configuration tcwg_bmk_gnu_tx1/gnu-master-aarch64-spec2k6-O3_LTO. So far, this commit has regressed CI configurations:
- tcwg_bmk_gnu_tx1/gnu-master-aarch64-spec2k6-O3_LTO
Culprit:
<cut>
commit fedcf3c476aff7533741a1c61071200f0a38cf83
Author: Richard Biener <rguenther(a)suse.de>
Date: Thu Jul 8 09:52:49 2021 +0200
tree-optimization/101373 - avoid PRE across externally throwing call
PRE already tries to avoid hoisting possibly trapping expressions
across calls that might not return normally but fails to consider
const calls that throw externally. The following fixes that and
also plugs the hole of trapping references not pruned in case
they are not catched by the actuall call clobbering it.
At -Os we hit the same issue in RTL PRE and postreload-gcse has
even more incomplete checks so the patch adjusts both of those
as well.
2021-07-08 Richard Biener <rguenther(a)suse.de>
PR tree-optimization/101373
* tree-ssa-pre.c (prune_clobbered_mems): Also prune trapping
references when the BB may not return.
(compute_avail): Pass in the function we're working on and
replace cfun references with it. Externally throwing
const calls also possibly terminate the function.
(pass_pre::execute): Pass down the function we're working on.
* gcse.c (compute_hash_table_work): Externally throwing
const/pure calls also need record_last_mem_set_info.
* postreload-gcse.c (record_opr_changes): Looping or externally
throwing const/pure calls also need record_last_mem_set_info.
* g++.dg/torture/pr101373.C: New testcase, XFAILed.
* gnat.dg/opt95.adb: Likewise.
</cut>
Results regressed to (for first_bad == fedcf3c476aff7533741a1c61071200f0a38cf83)
# reset_artifacts:
-10
# build_abe binutils:
-9
# build_abe stage1 -- --set gcc_override_configure=--disable-libsanitizer:
-8
# build_abe linux:
-7
# build_abe glibc:
-6
# build_abe stage2 -- --set gcc_override_configure=--disable-libsanitizer:
-5
# true:
0
# benchmark -O3_LTO -- artifacts/build-fedcf3c476aff7533741a1c61071200f0a38cf83/results_id:
1
# 429.mcf,mcf_base.default regressed by 106
from (for last_good == fe610051a803131822bd02a8842a67b573b8e46a)
# reset_artifacts:
-10
# build_abe binutils:
-9
# build_abe stage1 -- --set gcc_override_configure=--disable-libsanitizer:
-8
# build_abe linux:
-7
# build_abe glibc:
-6
# build_abe stage2 -- --set gcc_override_configure=--disable-libsanitizer:
-5
# true:
0
# benchmark -O3_LTO -- artifacts/build-fe610051a803131822bd02a8842a67b573b8e46a/results_id:
1
Artifacts of last_good build: https://ci.linaro.org/job/tcwg_bmk_ci_gnu-bisect-tcwg_bmk_tx1-gnu-master-aa…
Results ID of last_good: tx1_64/tcwg_bmk_gnu_tx1/bisect-gnu-master-aarch64-spec2k6-O3_LTO/1618
Artifacts of first_bad build: https://ci.linaro.org/job/tcwg_bmk_ci_gnu-bisect-tcwg_bmk_tx1-gnu-master-aa…
Results ID of first_bad: tx1_64/tcwg_bmk_gnu_tx1/bisect-gnu-master-aarch64-spec2k6-O3_LTO/1613
Build top page/logs: https://ci.linaro.org/job/tcwg_bmk_ci_gnu-bisect-tcwg_bmk_tx1-gnu-master-aa…
Configuration details:
Reproduce builds:
<cut>
mkdir investigate-gcc-fedcf3c476aff7533741a1c61071200f0a38cf83
cd investigate-gcc-fedcf3c476aff7533741a1c61071200f0a38cf83
git clone https://git.linaro.org/toolchain/jenkins-scripts
mkdir -p artifacts/manifests
curl -o artifacts/manifests/build-baseline.sh https://ci.linaro.org/job/tcwg_bmk_ci_gnu-bisect-tcwg_bmk_tx1-gnu-master-aa… --fail
curl -o artifacts/manifests/build-parameters.sh https://ci.linaro.org/job/tcwg_bmk_ci_gnu-bisect-tcwg_bmk_tx1-gnu-master-aa… --fail
curl -o artifacts/test.sh https://ci.linaro.org/job/tcwg_bmk_ci_gnu-bisect-tcwg_bmk_tx1-gnu-master-aa… --fail
chmod +x artifacts/test.sh
# Reproduce the baseline build (build all pre-requisites)
./jenkins-scripts/tcwg_bmk-build.sh @@ artifacts/manifests/build-baseline.sh
# Save baseline build state (which is then restored in artifacts/test.sh)
rsync -a --del --delete-excluded --exclude bisect/ --exclude artifacts/ --exclude gcc/ ./ ./bisect/baseline/
cd gcc
# Reproduce first_bad build
git checkout --detach fedcf3c476aff7533741a1c61071200f0a38cf83
../artifacts/test.sh
# Reproduce last_good build
git checkout --detach fe610051a803131822bd02a8842a67b573b8e46a
../artifacts/test.sh
cd ..
</cut>
History of pending regressions and results: https://git.linaro.org/toolchain/ci/base-artifacts.git/log/?h=linaro-local/…
Artifacts: https://ci.linaro.org/job/tcwg_bmk_ci_gnu-bisect-tcwg_bmk_tx1-gnu-master-aa…
Build log: https://ci.linaro.org/job/tcwg_bmk_ci_gnu-bisect-tcwg_bmk_tx1-gnu-master-aa…
Full commit (up to 1000 lines):
<cut>
commit fedcf3c476aff7533741a1c61071200f0a38cf83
Author: Richard Biener <rguenther(a)suse.de>
Date: Thu Jul 8 09:52:49 2021 +0200
tree-optimization/101373 - avoid PRE across externally throwing call
PRE already tries to avoid hoisting possibly trapping expressions
across calls that might not return normally but fails to consider
const calls that throw externally. The following fixes that and
also plugs the hole of trapping references not pruned in case
they are not catched by the actuall call clobbering it.
At -Os we hit the same issue in RTL PRE and postreload-gcse has
even more incomplete checks so the patch adjusts both of those
as well.
2021-07-08 Richard Biener <rguenther(a)suse.de>
PR tree-optimization/101373
* tree-ssa-pre.c (prune_clobbered_mems): Also prune trapping
references when the BB may not return.
(compute_avail): Pass in the function we're working on and
replace cfun references with it. Externally throwing
const calls also possibly terminate the function.
(pass_pre::execute): Pass down the function we're working on.
* gcse.c (compute_hash_table_work): Externally throwing
const/pure calls also need record_last_mem_set_info.
* postreload-gcse.c (record_opr_changes): Looping or externally
throwing const/pure calls also need record_last_mem_set_info.
* g++.dg/torture/pr101373.C: New testcase, XFAILed.
* gnat.dg/opt95.adb: Likewise.
---
gcc/gcse.c | 3 ++-
gcc/postreload-gcse.c | 4 +++-
gcc/testsuite/g++.dg/torture/pr101373.C | 33 +++++++++++++++++++++++++++
gcc/testsuite/gnat.dg/opt95.adb | 40 +++++++++++++++++++++++++++++++++
gcc/tree-ssa-pre.c | 34 +++++++++++++++++-----------
5 files changed, 99 insertions(+), 15 deletions(-)
diff --git a/gcc/gcse.c b/gcc/gcse.c
index ecf7e51aac5..ccd33664af5 100644
--- a/gcc/gcse.c
+++ b/gcc/gcse.c
@@ -1537,7 +1537,8 @@ compute_hash_table_work (struct gcse_hash_table_d *table)
record_last_reg_set_info (insn, regno);
if (! RTL_CONST_OR_PURE_CALL_P (insn)
- || RTL_LOOPING_CONST_OR_PURE_CALL_P (insn))
+ || RTL_LOOPING_CONST_OR_PURE_CALL_P (insn)
+ || can_throw_external (insn))
record_last_mem_set_info (insn);
}
diff --git a/gcc/postreload-gcse.c b/gcc/postreload-gcse.c
index 0b28247e299..6c95d09a1e5 100644
--- a/gcc/postreload-gcse.c
+++ b/gcc/postreload-gcse.c
@@ -779,7 +779,9 @@ record_opr_changes (rtx_insn *insn)
EXECUTE_IF_SET_IN_HARD_REG_SET (callee_clobbers, 0, regno, hrsi)
record_last_reg_set_info_regno (insn, regno);
- if (! RTL_CONST_OR_PURE_CALL_P (insn))
+ if (! RTL_CONST_OR_PURE_CALL_P (insn)
+ || RTL_LOOPING_CONST_OR_PURE_CALL_P (insn)
+ || can_throw_external (insn))
record_last_mem_set_info (insn);
}
}
diff --git a/gcc/testsuite/g++.dg/torture/pr101373.C b/gcc/testsuite/g++.dg/torture/pr101373.C
new file mode 100644
index 00000000000..f8c809739e2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr101373.C
@@ -0,0 +1,33 @@
+// { dg-do run }
+// { dg-xfail-run-if "PR100409" { *-*-* } }
+
+int __attribute__((const,noipa)) foo (int j)
+{
+ if (j != 0)
+ throw 1;
+ return 0;
+}
+
+int __attribute__((noipa)) bar (int *p, int n)
+{
+ int ret = 0;
+ if (n)
+ {
+ foo (n);
+ ret = *p;
+ }
+ ret += *p;
+ return ret;
+}
+
+int main()
+{
+ try
+ {
+ return bar (nullptr, 1);
+ }
+ catch (...)
+ {
+ return 0;
+ }
+}
diff --git a/gcc/testsuite/gnat.dg/opt95.adb b/gcc/testsuite/gnat.dg/opt95.adb
new file mode 100644
index 00000000000..2c72582b3f1
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/opt95.adb
@@ -0,0 +1,40 @@
+-- { dg-do run }
+-- { dg-options "-O2 -gnatp" }
+
+procedure Opt95 is
+
+ function Foo (J : Integer) return Integer;
+ pragma Pure_Function (Foo);
+ pragma Machine_Attribute (Foo, "noipa");
+
+ function Foo (J : Integer) return Integer is
+ begin
+ if J /= 0 then
+ raise Constraint_Error;
+ end if;
+ return 0;
+ end;
+
+ function Bar (A : access Integer; N : Integer) return Integer;
+ pragma Machine_Attribute (Bar, "noipa");
+
+ function Bar (A : access Integer; N : Integer) return Integer is
+ Ret : Integer := 0;
+ Ret2 : Integer := 0;
+ begin
+ if N /= 0 then
+ Ret2 := Foo (N);
+ Ret := A.all;
+ end if;
+ Ret := Ret + A.all;
+ return Ret + Ret2;
+ end;
+
+ V : Integer;
+ pragma Volatile (V);
+
+begin
+ V := Bar (null, 1);
+exception
+ when Constraint_Error => null;
+end;
diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c
index 69141c2f0c9..aa5244e678c 100644
--- a/gcc/tree-ssa-pre.c
+++ b/gcc/tree-ssa-pre.c
@@ -2071,6 +2071,13 @@ prune_clobbered_mems (bitmap_set_t set, basic_block block)
&& value_dies_in_block_x (expr, block))))
to_remove = i;
}
+ /* If the REFERENCE may trap make sure the block does not contain
+ a possible exit point.
+ ??? This is overly conservative if we translate AVAIL_OUT
+ as the available expression might be after the exit point. */
+ if (BB_MAY_NOTRETURN (block)
+ && vn_reference_may_trap (ref))
+ to_remove = i;
}
else if (expr->kind == NARY)
{
@@ -3860,7 +3867,7 @@ insert (void)
AVAIL_OUT[BLOCK] = AVAIL_IN[BLOCK] U PHI_GEN[BLOCK] U TMP_GEN[BLOCK]. */
static void
-compute_avail (void)
+compute_avail (function *fun)
{
basic_block block, son;
@@ -3871,7 +3878,7 @@ compute_avail (void)
/* We pretend that default definitions are defined in the entry block.
This includes function arguments and the static chain decl. */
- FOR_EACH_SSA_NAME (i, name, cfun)
+ FOR_EACH_SSA_NAME (i, name, fun)
{
pre_expr e;
if (!SSA_NAME_IS_DEFAULT_DEF (name)
@@ -3881,31 +3888,31 @@ compute_avail (void)
e = get_or_alloc_expr_for_name (name);
add_to_value (get_expr_value_id (e), e);
- bitmap_insert_into_set (TMP_GEN (ENTRY_BLOCK_PTR_FOR_FN (cfun)), e);
- bitmap_value_insert_into_set (AVAIL_OUT (ENTRY_BLOCK_PTR_FOR_FN (cfun)),
+ bitmap_insert_into_set (TMP_GEN (ENTRY_BLOCK_PTR_FOR_FN (fun)), e);
+ bitmap_value_insert_into_set (AVAIL_OUT (ENTRY_BLOCK_PTR_FOR_FN (fun)),
e);
}
if (dump_file && (dump_flags & TDF_DETAILS))
{
- print_bitmap_set (dump_file, TMP_GEN (ENTRY_BLOCK_PTR_FOR_FN (cfun)),
+ print_bitmap_set (dump_file, TMP_GEN (ENTRY_BLOCK_PTR_FOR_FN (fun)),
"tmp_gen", ENTRY_BLOCK);
- print_bitmap_set (dump_file, AVAIL_OUT (ENTRY_BLOCK_PTR_FOR_FN (cfun)),
+ print_bitmap_set (dump_file, AVAIL_OUT (ENTRY_BLOCK_PTR_FOR_FN (fun)),
"avail_out", ENTRY_BLOCK);
}
/* Allocate the worklist. */
- worklist = XNEWVEC (basic_block, n_basic_blocks_for_fn (cfun));
+ worklist = XNEWVEC (basic_block, n_basic_blocks_for_fn (fun));
/* Seed the algorithm by putting the dominator children of the entry
block on the worklist. */
- for (son = first_dom_son (CDI_DOMINATORS, ENTRY_BLOCK_PTR_FOR_FN (cfun));
+ for (son = first_dom_son (CDI_DOMINATORS, ENTRY_BLOCK_PTR_FOR_FN (fun));
son;
son = next_dom_son (CDI_DOMINATORS, son))
worklist[sp++] = son;
- BB_LIVE_VOP_ON_EXIT (ENTRY_BLOCK_PTR_FOR_FN (cfun))
- = ssa_default_def (cfun, gimple_vop (cfun));
+ BB_LIVE_VOP_ON_EXIT (ENTRY_BLOCK_PTR_FOR_FN (fun))
+ = ssa_default_def (fun, gimple_vop (fun));
/* Loop until the worklist is empty. */
while (sp)
@@ -3970,7 +3977,8 @@ compute_avail (void)
before it. */
int flags = gimple_call_flags (stmt);
if (!(flags & ECF_CONST)
- || (flags & ECF_LOOPING_CONST_OR_PURE))
+ || (flags & ECF_LOOPING_CONST_OR_PURE)
+ || stmt_can_throw_external (fun, stmt))
BB_MAY_NOTRETURN (block) = 1;
}
@@ -3987,7 +3995,7 @@ compute_avail (void)
BB_LIVE_VOP_ON_EXIT (block) = gimple_vdef (stmt);
if (gimple_has_side_effects (stmt)
- || stmt_could_throw_p (cfun, stmt)
+ || stmt_could_throw_p (fun, stmt)
|| is_gimple_debug (stmt))
continue;
@@ -4384,7 +4392,7 @@ pass_pre::execute (function *fun)
we require AVAIL. */
if (n_basic_blocks_for_fn (fun) < 4000)
{
- compute_avail ();
+ compute_avail (fun);
compute_antic ();
insert ();
}
</cut>
Successfully identified regression in *gcc* in CI configuration tcwg_bmk_gnu_tx1/gnu-release-aarch64-spec2k6-O2. So far, this commit has regressed CI configurations:
- tcwg_bmk_gnu_tx1/gnu-release-aarch64-spec2k6-O2
Culprit:
<cut>
commit a4dfaad2e5594d871fe00a1116005e28f95d644e
Author: Richard Sandiford <richard.sandiford(a)arm.com>
Date: Mon Sep 30 16:20:44 2019 +0000
Remove global call sets: gcse.c
This is another case in which we can conservatively treat partial
kills as full kills. Again this is in principle a bug fix for
TARGET_HARD_REGNO_CALL_PART_CLOBBERED targets, but in practice
it probably doesn't make a difference.
2019-09-30 Richard Sandiford <richard.sandiford(a)arm.com>
gcc/
* gcse.c: Include function-abi.h.
(compute_hash_table_work): Use insn_callee_abi to get the ABI of
the call insn target. Invalidate partially call-clobbered
registers as well as fully call-clobbered ones.
From-SVN: r276323
</cut>
Results regressed to (for first_bad == a4dfaad2e5594d871fe00a1116005e28f95d644e)
# reset_artifacts:
-10
# build_abe binutils:
-9
# build_abe stage1 -- --set gcc_override_configure=--disable-libsanitizer:
-8
# build_abe linux:
-7
# build_abe glibc:
-6
# build_abe stage2 -- --set gcc_override_configure=--disable-libsanitizer:
-5
# true:
0
# benchmark -O2 -- artifacts/build-a4dfaad2e5594d871fe00a1116005e28f95d644e/results_id:
1
# 447.dealII,[.] _ZNK12SparseMatrixIdE5vmultI6VectorIdES3_EEvRT regressed by 112
from (for last_good == c1b582720a39c3cb944aaff0298f721cdd034e3f)
# reset_artifacts:
-10
# build_abe binutils:
-9
# build_abe stage1 -- --set gcc_override_configure=--disable-libsanitizer:
-8
# build_abe linux:
-7
# build_abe glibc:
-6
# build_abe stage2 -- --set gcc_override_configure=--disable-libsanitizer:
-5
# true:
0
# benchmark -O2 -- artifacts/build-c1b582720a39c3cb944aaff0298f721cdd034e3f/results_id:
1
Artifacts of last_good build: https://ci.linaro.org/job/tcwg_bmk_ci_gnu-bisect-tcwg_bmk_tx1-gnu-release-a…
Results ID of last_good: tx1_64/tcwg_bmk_gnu_tx1/bisect-gnu-release-aarch64-spec2k6-O2/1425
Artifacts of first_bad build: https://ci.linaro.org/job/tcwg_bmk_ci_gnu-bisect-tcwg_bmk_tx1-gnu-release-a…
Results ID of first_bad: tx1_64/tcwg_bmk_gnu_tx1/bisect-gnu-release-aarch64-spec2k6-O2/1421
Build top page/logs: https://ci.linaro.org/job/tcwg_bmk_ci_gnu-bisect-tcwg_bmk_tx1-gnu-release-a…
Configuration details:
Reproduce builds:
<cut>
mkdir investigate-gcc-a4dfaad2e5594d871fe00a1116005e28f95d644e
cd investigate-gcc-a4dfaad2e5594d871fe00a1116005e28f95d644e
git clone https://git.linaro.org/toolchain/jenkins-scripts
mkdir -p artifacts/manifests
curl -o artifacts/manifests/build-baseline.sh https://ci.linaro.org/job/tcwg_bmk_ci_gnu-bisect-tcwg_bmk_tx1-gnu-release-a… --fail
curl -o artifacts/manifests/build-parameters.sh https://ci.linaro.org/job/tcwg_bmk_ci_gnu-bisect-tcwg_bmk_tx1-gnu-release-a… --fail
curl -o artifacts/test.sh https://ci.linaro.org/job/tcwg_bmk_ci_gnu-bisect-tcwg_bmk_tx1-gnu-release-a… --fail
chmod +x artifacts/test.sh
# Reproduce the baseline build (build all pre-requisites)
./jenkins-scripts/tcwg_bmk-build.sh @@ artifacts/manifests/build-baseline.sh
cd gcc
# Reproduce first_bad build
git checkout --detach a4dfaad2e5594d871fe00a1116005e28f95d644e
../artifacts/test.sh
# Reproduce last_good build
git checkout --detach c1b582720a39c3cb944aaff0298f721cdd034e3f
../artifacts/test.sh
cd ..
</cut>
History of pending regressions and results: https://git.linaro.org/toolchain/ci/base-artifacts.git/log/?h=linaro-local/…
Artifacts: https://ci.linaro.org/job/tcwg_bmk_ci_gnu-bisect-tcwg_bmk_tx1-gnu-release-a…
Build log: https://ci.linaro.org/job/tcwg_bmk_ci_gnu-bisect-tcwg_bmk_tx1-gnu-release-a…
Full commit (up to 1000 lines):
<cut>
commit a4dfaad2e5594d871fe00a1116005e28f95d644e
Author: Richard Sandiford <richard.sandiford(a)arm.com>
Date: Mon Sep 30 16:20:44 2019 +0000
Remove global call sets: gcse.c
This is another case in which we can conservatively treat partial
kills as full kills. Again this is in principle a bug fix for
TARGET_HARD_REGNO_CALL_PART_CLOBBERED targets, but in practice
it probably doesn't make a difference.
2019-09-30 Richard Sandiford <richard.sandiford(a)arm.com>
gcc/
* gcse.c: Include function-abi.h.
(compute_hash_table_work): Use insn_callee_abi to get the ABI of
the call insn target. Invalidate partially call-clobbered
registers as well as fully call-clobbered ones.
From-SVN: r276323
---
gcc/ChangeLog | 7 +++++++
gcc/gcse.c | 10 ++++++++--
2 files changed, 15 insertions(+), 2 deletions(-)
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 9d8b083d539..1b1c31cf009 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2019-09-30 Richard Sandiford <richard.sandiford(a)arm.com>
+
+ * gcse.c: Include function-abi.h.
+ (compute_hash_table_work): Use insn_callee_abi to get the ABI of
+ the call insn target. Invalidate partially call-clobbered
+ registers as well as fully call-clobbered ones.
+
2019-09-30 Richard Sandiford <richard.sandiford(a)arm.com>
* function.c (aggregate_value_p): Work out which ABI the
diff --git a/gcc/gcse.c b/gcc/gcse.c
index 9bde8619b7b..aeb59c645e1 100644
--- a/gcc/gcse.c
+++ b/gcc/gcse.c
@@ -160,6 +160,7 @@ along with GCC; see the file COPYING3. If not see
#include "dbgcnt.h"
#include "gcse.h"
#include "gcse-common.h"
+#include "function-abi.h"
/* We support GCSE via Partial Redundancy Elimination. PRE optimizations
are a superset of those done by classic GCSE.
@@ -1528,8 +1529,13 @@ compute_hash_table_work (struct gcse_hash_table_d *table)
if (CALL_P (insn))
{
hard_reg_set_iterator hrsi;
- EXECUTE_IF_SET_IN_HARD_REG_SET (regs_invalidated_by_call,
- 0, regno, hrsi)
+
+ /* We don't track modes of hard registers, so we need
+ to be conservative and assume that partial kills
+ are full kills. */
+ HARD_REG_SET callee_clobbers
+ = insn_callee_abi (insn).full_and_partial_reg_clobbers ();
+ EXECUTE_IF_SET_IN_HARD_REG_SET (callee_clobbers, 0, regno, hrsi)
record_last_reg_set_info (insn, regno);
if (! RTL_CONST_OR_PURE_CALL_P (insn)
</cut>
Successfully identified regression in *glibc* in CI configuration tcwg_cross/gnu-master-aarch64-build_cross. So far, this commit has regressed CI configurations:
- tcwg_cross/gnu-master-aarch64-build_cross
Culprit:
<cut>
commit 6ec6c77867af4ddfec7323e0ac6ede89effca852
Author: liuhongt <hongtao.liu(a)intel.com>
Date: Wed Jul 7 10:07:59 2021 +0800
soft-fp: Add __extendhfsf2/__extendhfdf2, __truncsfhf2/__truncdfhf2, __eqhf2/__nehf2
1. Add __extendhfdf2/__extendhfsf2 to return an IEEE half converted to IEEE double/single.
2. Add __truncdfhf2/__extendsfhf2 to truncate IEEE double/single into IEEE half.
3. Add __eqhf2/__nehf2 to return 0 if a == b and a,b are not NAN, otherwise return 1.
These are needed by x86 _Float16:
https://software.intel.com/content/www/us/en/develop/download/intel-avx512-…
support in GCC.
</cut>
Results regressed to (for first_bad == 6ec6c77867af4ddfec7323e0ac6ede89effca852)
# reset_artifacts:
-10
# true:
0
# build_abe binutils:
1
# build_abe stage1:
2
# build_abe linux:
3
# First few build errors in logs:
# 00:00:14 make[2]: *** [/home/tcwg-buildslave/workspace/tcwg_gnu_0/abe/builds/x86_64-pc-linux-gnu/aarch64-linux-gnu/glibc-glibc.git~master/sysd-rules:483: /home/tcwg-buildslave/workspace/tcwg_gnu_0/abe/builds/x86_64-pc-linux-gnu/aarch64-linux-gnu/glibc-glibc.git~master/csu/start.o] Error 1
# 00:00:14 make[2]: *** [/home/tcwg-buildslave/workspace/tcwg_gnu_0/abe/builds/x86_64-pc-linux-gnu/aarch64-linux-gnu/glibc-glibc.git~master/sysd-rules:499: /home/tcwg-buildslave/workspace/tcwg_gnu_0/abe/builds/x86_64-pc-linux-gnu/aarch64-linux-gnu/glibc-glibc.git~master/csu/start.os] Error 1
# 00:00:14 make[2]: *** [/home/tcwg-buildslave/workspace/tcwg_gnu_0/abe/builds/x86_64-pc-linux-gnu/aarch64-linux-gnu/glibc-glibc.git~master/sysd-rules:483: /home/tcwg-buildslave/workspace/tcwg_gnu_0/abe/builds/x86_64-pc-linux-gnu/aarch64-linux-gnu/glibc-glibc.git~master/csu/crtn.o] Error 1
# 00:00:14 make[2]: *** [/home/tcwg-buildslave/workspace/tcwg_gnu_0/abe/builds/x86_64-pc-linux-gnu/aarch64-linux-gnu/glibc-glibc.git~master/sysd-rules:483: /home/tcwg-buildslave/workspace/tcwg_gnu_0/abe/builds/x86_64-pc-linux-gnu/aarch64-linux-gnu/glibc-glibc.git~master/csu/crti.o] Error 1
# 00:00:14 make[2]: *** [../o-iterator.mk:9: /home/tcwg-buildslave/workspace/tcwg_gnu_0/abe/builds/x86_64-pc-linux-gnu/aarch64-linux-gnu/glibc-glibc.git~master/csu/check_fds.o] Error 1
# 00:00:14 make[2]: *** [../o-iterator.mk:9: /home/tcwg-buildslave/workspace/tcwg_gnu_0/abe/builds/x86_64-pc-linux-gnu/aarch64-linux-gnu/glibc-glibc.git~master/csu/check_fds.os] Error 1
# 00:00:14 ../sysdeps/aarch64/nptl/tls.h:91:19: error: ‘__builtin_thread_pointer’ is not supported on this target
# 00:00:14 make[2]: *** [/home/tcwg-buildslave/workspace/tcwg_gnu_0/abe/builds/x86_64-pc-linux-gnu/aarch64-linux-gnu/glibc-glibc.git~master/sysd-rules:485: /home/tcwg-buildslave/workspace/tcwg_gnu_0/abe/builds/x86_64-pc-linux-gnu/aarch64-linux-gnu/glibc-glibc.git~master/csu/libc-tls.o] Error 1
# 00:00:14 ../sysdeps/unix/sysv/linux/aarch64/sysdep.h:190:17: error: invalid register name for ‘_x0’
# 00:00:14 ../sysdeps/unix/sysv/linux/aarch64/sysdep.h:174:22: error: invalid register name for ‘_x8’
from (for last_good == b46cfcef3f7dab8e90729c6616ac1420f2642245)
# reset_artifacts:
-10
# true:
0
# build_abe binutils:
1
# build_abe stage1:
2
# build_abe linux:
3
# build_abe glibc:
4
# build_abe stage2:
5
# build_abe qemu:
6
Artifacts of last_good build: https://ci.linaro.org/job/tcwg_cross-bisect-gnu-master-aarch64-build_cross/…
Artifacts of first_bad build: https://ci.linaro.org/job/tcwg_cross-bisect-gnu-master-aarch64-build_cross/…
Build top page/logs: https://ci.linaro.org/job/tcwg_cross-bisect-gnu-master-aarch64-build_cross/…
Configuration details:
Reproduce builds:
<cut>
mkdir investigate-glibc-6ec6c77867af4ddfec7323e0ac6ede89effca852
cd investigate-glibc-6ec6c77867af4ddfec7323e0ac6ede89effca852
git clone https://git.linaro.org/toolchain/jenkins-scripts
mkdir -p artifacts/manifests
curl -o artifacts/manifests/build-baseline.sh https://ci.linaro.org/job/tcwg_cross-bisect-gnu-master-aarch64-build_cross/… --fail
curl -o artifacts/manifests/build-parameters.sh https://ci.linaro.org/job/tcwg_cross-bisect-gnu-master-aarch64-build_cross/… --fail
curl -o artifacts/test.sh https://ci.linaro.org/job/tcwg_cross-bisect-gnu-master-aarch64-build_cross/… --fail
chmod +x artifacts/test.sh
# Reproduce the baseline build (build all pre-requisites)
./jenkins-scripts/tcwg_gnu-build.sh @@ artifacts/manifests/build-baseline.sh
cd glibc
# Reproduce first_bad build
git checkout --detach 6ec6c77867af4ddfec7323e0ac6ede89effca852
../artifacts/test.sh
# Reproduce last_good build
git checkout --detach b46cfcef3f7dab8e90729c6616ac1420f2642245
../artifacts/test.sh
cd ..
</cut>
History of pending regressions and results: https://git.linaro.org/toolchain/ci/base-artifacts.git/log/?h=linaro-local/…
Artifacts: https://ci.linaro.org/job/tcwg_cross-bisect-gnu-master-aarch64-build_cross/…
Build log: https://ci.linaro.org/job/tcwg_cross-bisect-gnu-master-aarch64-build_cross/…
Full commit (up to 1000 lines):
<cut>
commit 6ec6c77867af4ddfec7323e0ac6ede89effca852
Author: liuhongt <hongtao.liu(a)intel.com>
Date: Wed Jul 7 10:07:59 2021 +0800
soft-fp: Add __extendhfsf2/__extendhfdf2, __truncsfhf2/__truncdfhf2, __eqhf2/__nehf2
1. Add __extendhfdf2/__extendhfsf2 to return an IEEE half converted to IEEE double/single.
2. Add __truncdfhf2/__extendsfhf2 to truncate IEEE double/single into IEEE half.
3. Add __eqhf2/__nehf2 to return 0 if a == b and a,b are not NAN, otherwise return 1.
These are needed by x86 _Float16:
https://software.intel.com/content/www/us/en/develop/download/intel-avx512-…
support in GCC.
---
soft-fp/eqhf2.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++
soft-fp/extendhfdf2.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++
soft-fp/extendhfsf2.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++
soft-fp/half.h | 2 ++
soft-fp/truncdfhf2.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++
soft-fp/truncsfhf2.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 253 insertions(+)
diff --git a/soft-fp/eqhf2.c b/soft-fp/eqhf2.c
new file mode 100644
index 0000000000..6d6634e5c5
--- /dev/null
+++ b/soft-fp/eqhf2.c
@@ -0,0 +1,49 @@
+/* Software floating-point emulation.
+ Return 0 iff a == b, 1 otherwise
+ Copyright (C) 2021 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include "soft-fp.h"
+#include "half.h"
+
+CMPtype
+__eqhf2 (HFtype a, HFtype b)
+{
+ FP_DECL_EX;
+ FP_DECL_H (A);
+ FP_DECL_H (B);
+ CMPtype r;
+
+ FP_INIT_EXCEPTIONS;
+ FP_UNPACK_RAW_H (A, a);
+ FP_UNPACK_RAW_H (B, b);
+ FP_CMP_EQ_H (r, A, B, 1);
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
+
+strong_alias (__eqhf2, __nehf2);
diff --git a/soft-fp/extendhfdf2.c b/soft-fp/extendhfdf2.c
new file mode 100644
index 0000000000..337ba791d4
--- /dev/null
+++ b/soft-fp/extendhfdf2.c
@@ -0,0 +1,53 @@
+/* Software floating-point emulation.
+ Return an IEEE half converted to IEEE double
+ Copyright (C) 2021 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#define FP_NO_EXACT_UNDERFLOW
+#include "soft-fp.h"
+#include "half.h"
+#include "double.h"
+
+DFtype
+__extendhfdf2 (HFtype a)
+{
+ FP_DECL_EX;
+ FP_DECL_H (A);
+ FP_DECL_D (R);
+ DFtype r;
+
+ FP_INIT_EXCEPTIONS;
+ FP_UNPACK_RAW_H (A, a);
+#if _FP_W_TYPE_SIZE < _FP_FRACBITS_D
+ FP_EXTEND (D, H, 2, 1, R, A);
+#else
+ FP_EXTEND (D, H, 1, 1, R, A);
+#endif
+ FP_PACK_RAW_D (r, R);
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
diff --git a/soft-fp/extendhfsf2.c b/soft-fp/extendhfsf2.c
new file mode 100644
index 0000000000..a02f46d9a9
--- /dev/null
+++ b/soft-fp/extendhfsf2.c
@@ -0,0 +1,49 @@
+/* Software floating-point emulation.
+ Return an IEEE half converted to IEEE single
+ Copyright (C) 2021 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#define FP_NO_EXACT_UNDERFLOW
+#include "soft-fp.h"
+#include "half.h"
+#include "single.h"
+
+SFtype
+__extendhfsf2 (HFtype a)
+{
+ FP_DECL_EX;
+ FP_DECL_H (A);
+ FP_DECL_S (R);
+ SFtype r;
+
+ FP_INIT_EXCEPTIONS;
+ FP_UNPACK_RAW_H (A, a);
+ FP_EXTEND (S, H, 1, 1, R, A);
+ FP_PACK_RAW_S (r, R);
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
diff --git a/soft-fp/half.h b/soft-fp/half.h
index ca2c1fad03..70af2712fc 100644
--- a/soft-fp/half.h
+++ b/soft-fp/half.h
@@ -167,4 +167,6 @@ union _FP_UNION_H
#define _FP_FRAC_HIGH_RAW_H(X) _FP_FRAC_HIGH_1 (X)
#define _FP_FRAC_HIGH_DW_H(X) _FP_FRAC_HIGH_1 (X)
+#define FP_CMP_EQ_H(r, X, Y, ex) _FP_CMP_EQ (H, 1, (r), X, Y, (ex))
+
#endif /* !SOFT_FP_HALF_H */
diff --git a/soft-fp/truncdfhf2.c b/soft-fp/truncdfhf2.c
new file mode 100644
index 0000000000..8bcb278769
--- /dev/null
+++ b/soft-fp/truncdfhf2.c
@@ -0,0 +1,52 @@
+/* Software floating-point emulation.
+ Truncate IEEE double into IEEE half.
+ Copyright (C) 2021 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include "soft-fp.h"
+#include "half.h"
+#include "double.h"
+
+HFtype
+__truncdfhf2 (DFtype a)
+{
+ FP_DECL_EX;
+ FP_DECL_D (A);
+ FP_DECL_H (R);
+ HFtype r;
+
+ FP_INIT_ROUNDMODE;
+ FP_UNPACK_SEMIRAW_D (A, a);
+#if _FP_W_TYPE_SIZE < _FP_FRACBITS_D
+ FP_TRUNC (H, D, 1, 2, R, A);
+#else
+ FP_TRUNC (H, D, 1, 1, R, A);
+#endif
+ FP_PACK_SEMIRAW_H (r, R);
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
diff --git a/soft-fp/truncsfhf2.c b/soft-fp/truncsfhf2.c
new file mode 100644
index 0000000000..25bee29f7f
--- /dev/null
+++ b/soft-fp/truncsfhf2.c
@@ -0,0 +1,48 @@
+/* Software floating-point emulation.
+ Truncate IEEE single into IEEE half.
+ Copyright (C) 2021 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Lesser General Public License restrictions do apply in
+ other respects; for example, they cover modification of the file,
+ and distribution when not linked into a combine executable.)
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include "soft-fp.h"
+#include "half.h"
+#include "single.h"
+
+HFtype
+__truncsfhf2 (SFtype a)
+{
+ FP_DECL_EX;
+ FP_DECL_S (A);
+ FP_DECL_H (R);
+ HFtype r;
+
+ FP_INIT_ROUNDMODE;
+ FP_UNPACK_SEMIRAW_S (A, a);
+ FP_TRUNC (H, S, 1, 1, R, A);
+ FP_PACK_SEMIRAW_H (r, R);
+ FP_HANDLE_EXCEPTIONS;
+
+ return r;
+}
</cut>