https://gcc.gnu.org/g:c01ad7a27af18f430639b6ec9597199eb655cc76
commit r16-7003-gc01ad7a27af18f430639b6ec9597199eb655cc76 Author: Andrew Pinski <[email protected]> Date: Fri Jan 16 20:50:53 2026 -0800 slsr: Fix replace_rhs_if_not_dup and others for overflow [PR106883] 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. 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]> Diff: --- 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(-) diff --git a/gcc/gimple-ssa-strength-reduction.cc b/gcc/gimple-ssa-strength-reduction.cc index 990943c767cd..d493dc87d3a5 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 000000000000..4198deb955d9 --- /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 479f40f93de7..b6d76b39646e 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" } } */
