The ((X + C1) | (C2 - X)) < 0 fold from r17-4207 and its variants drop the
C2 - X or -X operand, which traps on overflow under -ftrapv: for
X = INT_MIN, ((X + 3) | -X) < 0 traps at -O0 but not at -O2.  Do not
match when overflow traps.  The ABS_EXPR form from r17-4207 already
requires TYPE_OVERFLOW_UNDEFINED.

Bootstrapped and regression tested on x86_64-pc-linux-gnu.

Assisted-by: Claude Opus 5 (Anthropic)

gcc/ChangeLog:

        * match.pd (ior_range_test, ior_range_test_1, ior_range_test_0):
        Do not match if overflow traps.

gcc/testsuite/ChangeLog:

        * gcc.dg/tree-ssa/ior-range-test-4.c: New test.

Signed-off-by: Dominic P <[email protected]>
---
OK for trunk?

 gcc/match.pd                                     |  6 +++++-
 gcc/testsuite/gcc.dg/tree-ssa/ior-range-test-4.c | 14 ++++++++++++++
 2 files changed, 19 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/ior-range-test-4.c

diff --git a/gcc/match.pd b/gcc/match.pd
index 688357f0ecd..862da998e62 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -5164,22 +5164,26 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
  (bit_ior:c@3 (plus@0 @4 INTEGER_CST@1) (minus INTEGER_CST@2 @4))
  (if (single_use (@3)
       && !TYPE_OVERFLOW_SANITIZED (TREE_TYPE (@0))
+      && !TYPE_OVERFLOW_TRAPS (TREE_TYPE (@0))
       && wi::ge_p (wi::to_wide (@1) + wi::to_wide (@2), 0, SIGNED))))
 (match (ior_range_test_1 @0 @1)
  (bit_ior:c@2 @0 (minus INTEGER_CST@1 @0))
  (if (single_use (@2)
       && !TYPE_OVERFLOW_SANITIZED (TREE_TYPE (@0))
+      && !TYPE_OVERFLOW_TRAPS (TREE_TYPE (@0))
       && wi::ge_p (wi::to_wide (@1), 0, SIGNED))))
 (match (ior_range_test_1 @0 @1)
  (bit_ior:c@2 (plus@0 @3 INTEGER_CST@1) (negate @3))
  (if (single_use (@2)
       && !TYPE_OVERFLOW_SANITIZED (TREE_TYPE (@0))
+      && !TYPE_OVERFLOW_TRAPS (TREE_TYPE (@0))
       && wi::ge_p (wi::to_wide (@1), 0, SIGNED))))
 (match (ior_range_test_0 @0)
  (bit_ior:c@1 @0 (negate @0))
  (if (INTEGRAL_TYPE_P (TREE_TYPE (@0))
       && single_use (@1)
-      && !TYPE_OVERFLOW_SANITIZED (TREE_TYPE (@0)))))
+      && !TYPE_OVERFLOW_SANITIZED (TREE_TYPE (@0))
+      && !TYPE_OVERFLOW_TRAPS (TREE_TYPE (@0)))))
 (for cmp (lt ge)
      out (gt le)
  (simplify
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ior-range-test-4.c 
b/gcc/testsuite/gcc.dg/tree-ssa/ior-range-test-4.c
new file mode 100644
index 00000000000..f9f0a1179b4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ior-range-test-4.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftrapv -fdump-tree-optimized" } */
+/* { dg-require-effective-target int32 } */
+
+/* The subtraction and the negation can trap.  */
+
+int f1 (int x) { return ((x + 1) | (1 - x)) < 0; }
+int f2 (int x) { return (((x + 1) | (1 - x)) >> 31) & 1; }
+int f3 (int x) { return (x | (6 - x)) < 0; }
+int f4 (int x) { return ((x + 6) | -x) < 0; }
+int f5 (int x) { return (x | -x) < 0; }
+int f6 (int x) { return (unsigned) (x | -x) >> 31; }
+
+/* { dg-final { scan-tree-dump-times " \\| " 6 "optimized" } } */
-- 
2.55.0

Reply via email to