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
>

Reply via email to