On Mon, Sep 7, 2026 at 7:52 AM <[email protected]> wrote:
>
> From: Kyrylo Tkachov <[email protected]>
>
> match_arith_overflow can build a commutative overflow internal function
> with noncanonical operands.  For a complement test, it puts the complemented
> operand first.  This can disagree with the canonical order of a related
> addition.
>
> The widening_mul dump before the change contains:
>
>   _7 = .ADD_OVERFLOW (b_4(D), a_3(D));
>   sum_5 = a_3(D) + b_4(D);
>
> Select the internal function before building the call.  Use
> first_commutative_argument and tree_swap_operands_p to order its operands.
> The dump then contains:
>
>   _7 = .ADD_OVERFLOW (a_3(D), b_4(D));
>   sum_5 = a_3(D) + b_4(D);
>
> This also canonicalizes MUL_OVERFLOW operands.  SUB_OVERFLOW keeps its
> original order because it is not commutative.
>
> Bootstrapped and tested on aarch64-none-linux-gnu.
> Ok for trunk?
> Thanks,
> Kyrill
>
> gcc/ChangeLog:
>
>         * tree-ssa-math-opts.cc (match_arith_overflow): Canonicalize the
>         operands of commutative overflow internal functions.
>
> gcc/testsuite/ChangeLog:
>
>         * gcc.target/aarch64/add-overflow-canonical-1.c: New test.
>
> Signed-off-by: Kyrylo Tkachov <[email protected]>
> ---
>  .../gcc.target/aarch64/add-overflow-canonical-1.c  | 11 +++++++++++
>  gcc/tree-ssa-math-opts.cc                          | 14 +++++++++-----
>  2 files changed, 20 insertions(+), 5 deletions(-)
>  create mode 100644 
> gcc/testsuite/gcc.target/aarch64/add-overflow-canonical-1.c
>
> diff --git a/gcc/testsuite/gcc.target/aarch64/add-overflow-canonical-1.c 
> b/gcc/testsuite/gcc.target/aarch64/add-overflow-canonical-1.c
> new file mode 100644
> index 00000000000..5e11c51f3cf
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/add-overflow-canonical-1.c
> @@ -0,0 +1,11 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fdump-tree-widening_mul" } */
> +
> +unsigned
> +f (unsigned a, unsigned b)
> +{
> +  unsigned sum = a + b;
> +  return a <= ~b ? sum : ~0u;
> +}
> +
> +/* { dg-final { scan-tree-dump {ADD_OVERFLOW \(a_[^,]*, b_} "widening_mul" } 
> } */
> diff --git a/gcc/tree-ssa-math-opts.cc b/gcc/tree-ssa-math-opts.cc
> index b371b5b7cff..e5d4575eed2 100644
> --- a/gcc/tree-ssa-math-opts.cc
> +++ b/gcc/tree-ssa-math-opts.cc
> @@ -4932,12 +4932,16 @@ match_arith_overflow (gimple_stmt_iterator *gsi, 
> gimple *stmt,
>             }
>         }
>      }
> +  internal_fn ifn = (code == MULT_EXPR
> +                    ? IFN_MUL_OVERFLOW
> +                    : code != MINUS_EXPR
> +                    ? IFN_ADD_OVERFLOW : IFN_SUB_OVERFLOW);
> +  if (first_commutative_argument (ifn) == 0

Just `code != MINUS_EXPR` is needed here.  Since MULT and ADD are both
commutative.
Otherwise ok.

> +      && tree_swap_operands_p (rhs1, rhs2))
> +    std::swap (rhs1, rhs2);
> +
>    tree ctype = build_complex_type (type);
> -  gcall *g = gimple_build_call_internal (code == MULT_EXPR
> -                                        ? IFN_MUL_OVERFLOW
> -                                        : code != MINUS_EXPR
> -                                        ? IFN_ADD_OVERFLOW : 
> IFN_SUB_OVERFLOW,
> -                                        2, rhs1, rhs2);
> +  gcall *g = gimple_build_call_internal (ifn, 2, rhs1, rhs2);
>    tree ctmp = make_ssa_name (ctype);
>    gimple_call_set_lhs (g, ctmp);
>    gsi_insert_before (gsi, g, GSI_SAME_STMT);
> --
> 2.50.1 (Apple Git-155)
>

Reply via email to