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
+      && 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