https://gcc.gnu.org/g:2653d6c63d491dd8f61efff553ad4d7bcc33d53c
commit r17-5320-g2653d6c63d491dd8f61efff553ad4d7bcc33d53c Author: Jakub Jelinek <[email protected]> Date: Mon Oct 19 09:55:20 2026 +0200 bitintlower: Remove unused large/huge _BitInt PHIs [PR127904] tree-outof-ssa.cc before performing coalescing does eliminate_useless_phis (), which removes removes PHIs and dead PHIs. The following testcase is miscompiled because the coalescing performed for the large/huge _BitInt SSA_NAME subset is apparently confused by such dead PHIs and puts the result of such an PHI into the same partition as one of the PHI args which is unfortunately used later on in the function as well, so by reusing the partition we clobber the value of the argument and then use the incorrect value later on. From this, I think the remove dead PHIs part of eliminate_useless_phis is not just an optimization but I think the coalescing somehow relies on it. So, this patch performs such removal (again, for large/huge _BitInt PHIs only) before doing the coalescing as well. 2026-10-19 Jakub Jelinek <[email protected]> PR tree-optimization/127904 * tree-outof-ssa.h (remove_gimple_phi_args): Declare. * tree-outof-ssa.cc (remove_gimple_phi_args): No longer static. * gimple-lower-bitint.cc: Include tree-outof-ssa.h. (gimple_lower_bitint): Remove zero uses large/huge _BitInt PHI results. * gcc.dg/torture/bitint-111.c: New test. Reviewed-by: Richard Biener <[email protected]> Diff: --- gcc/gimple-lower-bitint.cc | 12 ++++++++++++ gcc/testsuite/gcc.dg/torture/bitint-111.c | 29 +++++++++++++++++++++++++++++ gcc/tree-outof-ssa.cc | 2 +- gcc/tree-outof-ssa.h | 1 + 4 files changed, 43 insertions(+), 1 deletion(-) diff --git a/gcc/gimple-lower-bitint.cc b/gcc/gimple-lower-bitint.cc index 0883335f1089..9b52dab2f9ca 100644 --- a/gcc/gimple-lower-bitint.cc +++ b/gcc/gimple-lower-bitint.cc @@ -58,6 +58,7 @@ along with GCC; see the file COPYING3. If not see #include "gimple-lower-bitint.h" #include "attribs.h" #include "asan.h" +#include "tree-outof-ssa.h" /* Split BITINT_TYPE precisions in 4 categories. Small _BitInt, where target hook says it is a single limb, middle _BitInt which per ABI @@ -7635,6 +7636,17 @@ gimple_lower_bitint (void) default: break; } + else if (gphi *phi = dyn_cast <gphi *> (stmt)) + { + /* Remove PHIs with no uses, coalescing apparently + relies on this. */ + if (has_zero_uses (s)) + { + remove_gimple_phi_args (phi); + gsi = gsi_for_stmt (stmt); + remove_phi_node (&gsi, true); + } + } } /* We need to also rewrite stores of large/huge _BitInt INTEGER_CSTs into memory. Such functions could have no large/huge SSA_NAMEs. */ diff --git a/gcc/testsuite/gcc.dg/torture/bitint-111.c b/gcc/testsuite/gcc.dg/torture/bitint-111.c new file mode 100644 index 000000000000..d89ab05ea704 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/bitint-111.c @@ -0,0 +1,29 @@ +/* PR tree-optimization/127904 */ +/* { dg-do run { target bitint575 } } */ + +typedef unsigned _BitInt(575) B; + +[[gnu::noipa]] B +foo (B a, B b, int c, unsigned n) +{ + B r = 0; + for (unsigned i = 0; i < n; i++) + { + B x; + if (c) + x = a; + else + x = b; + for (unsigned j = 0; j < n; j++) + x = (B) j; + r += x; + } + return r + a + b; +} + +int +main () +{ + if (foo (5, 7, 0, 2) != 14 || foo (5, 7, 1, 3) != 18) + __builtin_abort (); +} diff --git a/gcc/tree-outof-ssa.cc b/gcc/tree-outof-ssa.cc index ece86e2ab6fa..f113709e50d2 100644 --- a/gcc/tree-outof-ssa.cc +++ b/gcc/tree-outof-ssa.cc @@ -793,7 +793,7 @@ eliminate_phi (edge e, elim_graph *g) /* Remove each argument from PHI. If an arg was the last use of an SSA_NAME, check to see if this allows another PHI node to be removed. */ -static void +void remove_gimple_phi_args (gphi *phi) { use_operand_p arg_p; diff --git a/gcc/tree-outof-ssa.h b/gcc/tree-outof-ssa.h index 3d05c6237081..49fc1469eb44 100644 --- a/gcc/tree-outof-ssa.h +++ b/gcc/tree-outof-ssa.h @@ -81,6 +81,7 @@ get_gimple_for_ssa_name (tree exp) extern bool ssa_is_replaceable_p (gimple *stmt); extern void finish_out_of_ssa (struct ssaexpand *sa); extern unsigned int rewrite_out_of_ssa (struct ssaexpand *sa); +extern void remove_gimple_phi_args (gphi *phi); extern void expand_phi_nodes (struct ssaexpand *sa); #endif /* GCC_TREE_OUTOF_SSA_H */
