https://gcc.gnu.org/g:7b8104e346cf3949b0ca6eab93106ac860fb3306
commit r17-3988-g7b8104e346cf3949b0ca6eab93106ac860fb3306 Author: Kyrylo Tkachov <[email protected]> Date: Sat Sep 5 12:54:56 2026 +0200 tree-ssa: Canonicalize arithmetic overflow IFN operands 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 tree_swap_operands_p to order the operands of addition and multiplication. 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 regression tested on aarch64-unknown-linux-gnu. 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]> Diff: --- .../gcc.target/aarch64/add-overflow-canonical-1.c | 11 +++++++++++ gcc/tree-ssa-math-opts.cc | 14 +++++++++----- 2 files changed, 20 insertions(+), 5 deletions(-) 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 000000000000..5e11c51f3cf0 --- /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 b371b5b7cff9..70ac17c9e2fa 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 (code != MINUS_EXPR + && 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);
