When trying to associate (v + INT_MAX) + INT_MAX we are using
the TREE_OVERFLOW bit to check for correctness.  That isn't
working for VECTOR_CSTs and it can't in general when one considers
VL vectors.  It looks like it should work for COMPLEX_CSTs but
I didn't try to single out _Complex int in this change.

The following makes sure that for vectors we use the fallback of
using unsigned arithmetic when associating the above to
v + (INT_MAX + INT_MAX).

Bootstrapped and tested on x86_64-unknown-linux-gnu, OK?

Thanks,
Richard.

        PR middle-end/110495
        * tree.h (TREE_OVERFLOW): Do not mention VECTOR_CSTs
        since we do not set TREE_OVERFLOW on those since the
        introduction of VL vectors.
        * match.pd (x +- CST +- CST): For VECTOR_CST do not look
        at TREE_OVERFLOW to determine validity of association.

        * gcc.dg/tree-ssa/addadd-2.c: Amend.
        * gcc.dg/tree-ssa/forwprop-27.c: Adjust.
---
 gcc/match.pd                                | 9 +++++----
 gcc/testsuite/gcc.dg/tree-ssa/addadd-2.c    | 1 +
 gcc/testsuite/gcc.dg/tree-ssa/forwprop-27.c | 4 +++-
 gcc/tree.h                                  | 2 +-
 4 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/gcc/match.pd b/gcc/match.pd
index f09583bbcac..d193a572005 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -3025,7 +3025,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
        (with { tree cst = const_binop (outer_op == inner_op
                                        ? PLUS_EXPR : MINUS_EXPR,
                                        type, @1, @2); }
-        (if (cst && !TREE_OVERFLOW (cst))
+        (if (INTEGRAL_TYPE_P (type) && cst && !TREE_OVERFLOW (cst))
          (inner_op @0 { cst; } )
          /* X+INT_MAX+1 is X-INT_MIN.  */
          (if (INTEGRAL_TYPE_P (type) && cst
@@ -3037,7 +3037,8 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
             (view_convert (inner_op
                            (view_convert:utype @0)
                            (view_convert:utype
-                            { drop_tree_overflow (cst); }))))))))))))))
+                            { TREE_OVERFLOW (cst)
+                              ? drop_tree_overflow (cst) : cst; }))))))))))))))
 
   /* (CST1 - A) +- CST2 -> CST3 - A  */
   (for outer_op (plus minus)
@@ -3049,7 +3050,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
        forever if something doesn't simplify into a constant.  */
      (if (!CONSTANT_CLASS_P (@0))
       (minus (outer_op! (view_convert @1) @2) (view_convert @0)))
-     (if (!ANY_INTEGRAL_TYPE_P (TREE_TYPE (@0))
+     (if (!INTEGRAL_TYPE_P (TREE_TYPE (@0))
          || TYPE_OVERFLOW_WRAPS (TREE_TYPE (@0)))
       (view_convert (minus (outer_op! @1 (view_convert @2)) @0))
       (if (types_match (type, @0) && !TYPE_OVERFLOW_SANITIZED (type))
@@ -3068,7 +3069,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
       forever if something doesn't simplify into a constant.  */
     (if (!CONSTANT_CLASS_P (@0))
      (plus (view_convert @0) (minus! @1 (view_convert @2))))
-    (if (!ANY_INTEGRAL_TYPE_P (TREE_TYPE (@0))
+    (if (!INTEGRAL_TYPE_P (TREE_TYPE (@0))
         || TYPE_OVERFLOW_WRAPS (TREE_TYPE (@0)))
      (view_convert (plus @0 (minus! (view_convert @1) @2)))
      (if (types_match (type, @0) && !TYPE_OVERFLOW_SANITIZED (type))
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/addadd-2.c 
b/gcc/testsuite/gcc.dg/tree-ssa/addadd-2.c
index 39aa032c9b1..8c05911f473 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/addadd-2.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/addadd-2.c
@@ -12,4 +12,5 @@ void k(S*x){
   *x = (S)(y + __INT_MAX__);
 }
 
+/* { dg-final { scan-tree-dump "4294967294" "optimized" { target int32plus } } 
} */
 /* { dg-final { scan-tree-dump-not "2147483647" "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-27.c 
b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-27.c
index 9775a4c6367..6c71a4fc81c 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-27.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-27.c
@@ -33,7 +33,9 @@ void i (V *v1, V *v2){
   *v2 = (c1-*v2)+c2;
 }
 
-/* { dg-final { scan-tree-dump-not "\\\+" "forwprop1"} } */
+/* { dg-final { scan-tree-dump-times "\\\+" 1 "forwprop1"} } */
 /* { dg-final { scan-tree-dump "{ 0, 4 }" "forwprop1"} } */
 /* { dg-final { scan-tree-dump "{ 37, -5 }" "forwprop1"} } */
+/* { dg-final { scan-tree-dump "{ 27, 23 }" "forwprop1"} } */
+/* { dg-final { scan-tree-dump "{ 37, 3 }" "forwprop1"} } */
 
diff --git a/gcc/tree.h b/gcc/tree.h
index f11c758afb9..bedbbb0bcc0 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -824,7 +824,7 @@ extern void omp_clause_range_check_failed (const_tree, 
const char *, int,
 #define TYPE_REF_CAN_ALIAS_ALL(NODE) \
   (PTR_OR_REF_CHECK (NODE)->base.static_flag)
 
-/* In an INTEGER_CST, REAL_CST, COMPLEX_CST, or VECTOR_CST, this means
+/* In an INTEGER_CST, REAL_CST, or COMPLEX_CST, this means
    there was an overflow in folding.  */
 
 #define TREE_OVERFLOW(NODE) (CST_CHECK (NODE)->base.public_flag)
-- 
2.35.3

Reply via email to