https://gcc.gnu.org/g:610f1166538ad2e637c913be78b074100270cc5c

commit r17-3234-g610f1166538ad2e637c913be78b074100270cc5c
Author: Andrea Pinski <[email protected]>
Date:   Mon Jul 27 20:11:33 2026 -0700

    match: Fix recent pattern for signed integer overflow dealing with - 
[PR126418]
    
    A recent match patterns were added that introduce signed integer overflow 
where
    there was none before.  `cmp + (-cmp ^ x)` has no signed integer overflow 
when
    x is INT_MIN when cmp is 0. This gets translated into cmp ? -x : x.
    But this has now introduced an signed integer overflow for INT_MIN.
    The fix is to use unsigned type for the negative.
    
    Bootstrapped and tested on x86_64-linux-gnu.
    
    Changes since v1:
    * v2: Remove the abs patterns since a signed integer overflow would have 
happened anyways.
    
            PR tree-optimization/126418
    
    gcc/ChangeLog:
    
            * match.pd (`(A ^ -cmp) + cmp`): Cast to unsigned type
            before taking the negative.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.dg/tree-ssa/pr126418-1.c: New test.
    
    Signed-off-by: Andrea Pinski <[email protected]>

Diff:
---
 gcc/match.pd                               |  8 +++++++-
 gcc/testsuite/gcc.dg/tree-ssa/pr126418-1.c | 11 +++++++++++
 2 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/gcc/match.pd b/gcc/match.pd
index eee44365ea37..3f476cc4baad 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -4987,7 +4987,13 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
  (if (INTEGRAL_TYPE_P (type)
       && !TYPE_SATURATING (type)
       && (GIMPLE || !TREE_SIDE_EFFECTS (@0)))
-  (cond (convert:boolean_type_node @1) (negate @0) @0)))
+  /* Do the negate in unsigned type always; otherwise
+     we would be introducing an overflow.  */
+  (with { tree utype = unsigned_type_for (type); }
+   (cond
+    (convert:boolean_type_node @1)
+    (convert:type (negate (convert:utype @0)))
+    @0))))
 
 /* Transform A & (B*cmp) into (A&B)*cmp.  */
 (simplify
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr126418-1.c 
b/gcc/testsuite/gcc.dg/tree-ssa/pr126418-1.c
new file mode 100644
index 000000000000..3714069b43f8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr126418-1.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-forwprop1" } */
+
+int f_cmp_gt_commuted(int x, int y)
+{
+  int cmp = x > y;
+  return cmp + (-cmp ^ x);
+}
+
+/* { dg-final { scan-tree-dump-times "\\(unsigned int\\) " 1 "forwprop1" } } */
+/* { dg-final { scan-tree-dump-times "\\(int\\) " 1 "forwprop1" } } */

Reply via email to