On Thu, Jan 22, 2026 at 6:46 AM Andrew Pinski <[email protected]> wrote: > > Like the previous patch this up slsr in the other locations for the > added overflow issues that were being introduced. This was slightly > harder than insert_initializers as we need to allow for type > mismatches in more cases. > But with this all fixed, the testcases in PR 120258 (and its duplicates) > are all working correctly. > > Bootstrapped and tested on x86-linux-gnu.
This series is OK. Thanks for dealing with this. Richard. > PR tree-optimization/120258 > PR tree-optimization/106883 > > gcc/ChangeLog: > > * gimple-ssa-strength-reduction.cc (replace_mult_candidate): Allow for > basis_name and bump_tree not to be the same type as the lhs. > Rewrite added multiply for undefined overflow. > (create_add_on_incoming_edge): Allow for init > to be a different type from the wanted type. > Rewrite added add for undefined overflow. > (replace_rhs_if_not_dup): Rewrite replaced stmts > for undefined overflow. > (replace_one_candidate): Allow for basis_name and > rhs2 to be a different type from lhs. > > gcc/testsuite/ChangeLog: > > * gcc.dg/tree-ssa/slsr-8.c: Update the number of `*`. > * gcc.dg/torture/pr120258-1.c: New test. > > Signed-off-by: Andrew Pinski <[email protected]> > --- > gcc/gimple-ssa-strength-reduction.cc | 40 +++++++++++++++++++++-- > gcc/testsuite/gcc.dg/torture/pr120258-1.c | 12 +++++++ > gcc/testsuite/gcc.dg/tree-ssa/slsr-8.c | 6 ++-- > 3 files changed, 53 insertions(+), 5 deletions(-) > create mode 100644 gcc/testsuite/gcc.dg/torture/pr120258-1.c > > diff --git a/gcc/gimple-ssa-strength-reduction.cc > b/gcc/gimple-ssa-strength-reduction.cc > index 990943c767c..d493dc87d3a 100644 > --- a/gcc/gimple-ssa-strength-reduction.cc > +++ b/gcc/gimple-ssa-strength-reduction.cc > @@ -2220,6 +2220,13 @@ replace_mult_candidate (slsr_cand_t c, tree > basis_name, offset_int bump, > { > gimple_stmt_iterator gsi = gsi_for_stmt (c->cand_stmt); > slsr_cand_t cc = lookup_cand (c->first_interp); > + tree lhs = gimple_assign_lhs (c->cand_stmt); > + basis_name = gimple_convert (&gsi, true, GSI_SAME_STMT, > + UNKNOWN_LOCATION, > + TREE_TYPE (lhs), basis_name); > + bump_tree = gimple_convert (&gsi, true, GSI_SAME_STMT, > + UNKNOWN_LOCATION, > + TREE_TYPE (lhs), bump_tree); > gimple_assign_set_rhs_with_ops (&gsi, code, basis_name, bump_tree); > update_stmt (gsi_stmt (gsi)); > while (cc) > @@ -2227,6 +2234,9 @@ replace_mult_candidate (slsr_cand_t c, tree basis_name, > offset_int bump, > cc->cand_stmt = gsi_stmt (gsi); > cc = lookup_cand (cc->next_interp); > } > + if (gimple_needing_rewrite_undefined (gsi_stmt (gsi))) > + rewrite_to_defined_unconditional (&gsi); > + > if (dump_file && (dump_flags & TDF_DETAILS)) > stmt_to_print = gsi_stmt (gsi); > } > @@ -2330,9 +2340,19 @@ create_add_on_incoming_edge (slsr_cand_t c, tree > basis_name, > > if (incr_vec[i].initializer) > { > + tree init = incr_vec[i].initializer; > + tree wanted_type = POINTER_TYPE_P (basis_type) ? c->stride_type : > basis_type; > + > + if (!types_compatible_p (TREE_TYPE (c->stride), wanted_type)) > + { > + tree cast_stride = make_temp_ssa_name (wanted_type, NULL, > + "slsr"); > + cast_stmt = gimple_build_assign (cast_stride, NOP_EXPR, > + init); > + init = cast_stride; > + } > enum tree_code code = negate_incr ? MINUS_EXPR : plus_code; > - new_stmt = gimple_build_assign (lhs, code, basis_name, > - incr_vec[i].initializer); > + new_stmt = gimple_build_assign (lhs, code, basis_name, init); > } > else { > tree stride; > @@ -3689,7 +3709,14 @@ replace_rhs_if_not_dup (enum tree_code new_code, tree > new_rhs1, tree new_rhs2, > && (!operand_equal_p (new_rhs1, old_rhs2, 0) > || !operand_equal_p (new_rhs2, old_rhs1, 0)))) > { > + tree lhs = gimple_assign_lhs (c->cand_stmt); > gimple_stmt_iterator gsi = gsi_for_stmt (c->cand_stmt); > + new_rhs1 = gimple_convert (&gsi, true, GSI_SAME_STMT, > + UNKNOWN_LOCATION, > + TREE_TYPE (lhs), new_rhs1); > + new_rhs2 = gimple_convert (&gsi, true, GSI_SAME_STMT, > + UNKNOWN_LOCATION, > + TREE_TYPE (lhs), new_rhs2); > slsr_cand_t cc = lookup_cand (c->first_interp); > gimple_assign_set_rhs_with_ops (&gsi, new_code, new_rhs1, new_rhs2); > update_stmt (gsi_stmt (gsi)); > @@ -3699,6 +3726,8 @@ replace_rhs_if_not_dup (enum tree_code new_code, tree > new_rhs1, tree new_rhs2, > cc = lookup_cand (cc->next_interp); > } > > + if (gimple_needing_rewrite_undefined (gsi_stmt (gsi))) > + rewrite_to_defined_unconditional (&gsi); > if (dump_file && (dump_flags & TDF_DETAILS)) > return gsi_stmt (gsi); > } > @@ -3813,7 +3842,14 @@ replace_one_candidate (slsr_cand_t c, unsigned i, tree > basis_name, > || !operand_equal_p (rhs2, orig_rhs2, 0)) > { > gimple_stmt_iterator gsi = gsi_for_stmt (c->cand_stmt); > + tree lhs = gimple_assign_lhs (c->cand_stmt); > slsr_cand_t cc = lookup_cand (c->first_interp); > + basis_name = gimple_convert (&gsi, true, GSI_SAME_STMT, > + UNKNOWN_LOCATION, > + TREE_TYPE (lhs), basis_name); > + rhs2 = gimple_convert (&gsi, true, GSI_SAME_STMT, > + UNKNOWN_LOCATION, > + TREE_TYPE (lhs), rhs2); > gimple_assign_set_rhs_with_ops (&gsi, MINUS_EXPR, basis_name, rhs2); > update_stmt (gsi_stmt (gsi)); > while (cc) > diff --git a/gcc/testsuite/gcc.dg/torture/pr120258-1.c > b/gcc/testsuite/gcc.dg/torture/pr120258-1.c > new file mode 100644 > index 00000000000..4198deb955d > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/torture/pr120258-1.c > @@ -0,0 +1,12 @@ > +/* { dg-do run } */ > +/* PR tree-optimization/120258 */ > +/* SLSR would introduce an addition and multiplication > + that would have undefined behavior with respect to overflow > + and that would cause the following to be incorrect. */ > + > +int a = 1, b, c; > +int main() { > + c = -__INT_MAX__* b - __INT_MAX__* a; > + if (b - __INT_MAX__ * a >= 0) > + __builtin_abort(); > +} > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/slsr-8.c > b/gcc/testsuite/gcc.dg/tree-ssa/slsr-8.c > index 479f40f93de..b6d76b39646 100644 > --- a/gcc/testsuite/gcc.dg/tree-ssa/slsr-8.c > +++ b/gcc/testsuite/gcc.dg/tree-ssa/slsr-8.c > @@ -23,7 +23,7 @@ f (int s, int *c, int *d) > However, this proves to be a useful test for introducing an > initializer with a cast, so we'll keep it as is. */ > > -/* There are 5 ' * ' instances in the decls (since "int * iftmp.0;" is > - added), 2 parms, 3 in the code, and the return value. The second one > +/* There are 2 ' * ' instances in the decls (holding x1 and a temp), > + 2 parms, 3 in the code, and the return type. The second one > in the code may be a widening multiply (for example, on AArch64). */ > -/* { dg-final { scan-tree-dump-times " w?\\* " 10 "optimized" } } */ > +/* { dg-final { scan-tree-dump-times " w?\\* " 8 "optimized" } } */ > -- > 2.43.0 >
