https://gcc.gnu.org/g:d8164f4da406c5061075472961b3c448604eb686

commit r17-4852-gd8164f4da406c5061075472961b3c448604eb686
Author: Andrea Pinski <[email protected]>
Date:   Fri Oct 2 05:36:15 2026 -0700

    match: Fix `(convert)abs((convert)a)` pattern for integer overflow 
[PR127689]
    
    There are 2 patterns that are similar in match.pd for changing into
    a smaller abs. One handles `abs((ext)a)` and one for `(trunc)abs((ext)a)`.
    The one with the truncate afterwards does not use absu for integer types
    which can introduce undefined behavior in some cases.
    So let's restrict the second one to non integral types as the first one
    will handle those always; the check for casting from unsigned is another
    difference but the casting from unsigned is handled by a different abs
    pattern for non-negative values.
    
    Bootstrapped and tested on x86_64-linux-gnu.
    
            PR tree-optimization/127689
    
    gcc/ChangeLog:
    
            * match.pd (`(trunc)abs((ext)a)`): Move right
            after `abs((ext)a)` pattern.  Restrict to
            non integral types.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.dg/torture/pr127689-1.c: New test.
    
    Signed-off-by: Andrea Pinski <[email protected]>

Diff:
---
 gcc/match.pd                              | 22 +++++++++++-----------
 gcc/testsuite/gcc.dg/torture/pr127689-1.c | 28 ++++++++++++++++++++++++++++
 2 files changed, 39 insertions(+), 11 deletions(-)

diff --git a/gcc/match.pd b/gcc/match.pd
index 2d1161b860b2..648bda9bf11f 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -214,6 +214,17 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
   (with { tree utype = unsigned_type_for (TREE_TYPE (@0)); }
    (convert (absu:utype @0)))))
 
+/* (trunc)abs (extend x) --> abs (x) for non-integral types.  */
+(simplify
+ (convert (abs (convert@1 @0)))
+  (if (!ANY_INTEGRAL_TYPE_P (TREE_TYPE (@0))
+       && !HONOR_SNANS (@1)
+       && types_match (type, TREE_TYPE (@0))
+       && element_precision (type) < element_precision (TREE_TYPE (@1))
+       && (!VECTOR_TYPE_P (type)
+          || target_supports_op_p (type, ABS_EXPR, optab_default)))
+   (abs @0)))
+
 #if GIMPLE
 /* Optimize (X + (X >> (prec - 1))) ^ (X >> (prec - 1)) into abs (X).  */
 (simplify
@@ -10340,17 +10351,6 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
      (IFN_COPYSIGN @0 { build_minus_one_cst (type); })
      (IFN_COPYSIGN @0 { build_one_cst (type); })))))
 
-/* (trunc)abs (extend x) --> abs (x)  */
-(simplify
- (convert (abs (convert@1 @0)))
-  (if (optimize
-      && !HONOR_SNANS (@1)
-      && types_match (type, TREE_TYPE (@0))
-      && element_precision (type) < element_precision (TREE_TYPE (@1))
-      && (!VECTOR_TYPE_P (type)
-         || target_supports_op_p (type, ABS_EXPR, optab_default)))
-   (abs @0)))
-
 (for froms (BUILT_IN_FMAF BUILT_IN_FMA BUILT_IN_FMAL)
      tos (IFN_FMA IFN_FMA IFN_FMA)
  (simplify
diff --git a/gcc/testsuite/gcc.dg/torture/pr127689-1.c 
b/gcc/testsuite/gcc.dg/torture/pr127689-1.c
new file mode 100644
index 000000000000..28c92d516712
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr127689-1.c
@@ -0,0 +1,28 @@
+/* { dg-do run } */
+/* { dg-additional-options "-fno-tree-forwprop" } */
+/* PR tree-optimization/127689 */
+
+
+__attribute__((noipa))void check(int v)
+{
+    if (v != -4)
+      __builtin_exit(1);
+}
+int p;
+signed char s, v;
+signed char t = 0x80;
+__attribute__((noipa))
+void y(signed char w) {
+  int t1 = w;
+  t1 = __builtin_abs(t1); //256, 0x80
+  p = t1;
+  s = p;
+  signed char t2 = t1; // -256, 0x80
+  t = t2 % 3; // -2
+  v = 2 * t; // -4
+    check(v);
+}
+int main()
+{
+    y(0x80);
+}

Reply via email to