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) >
