]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
middle-end/110495 - avoid associating constants with (VL) vectors
authorRichard Biener <rguenther@suse.de>
Mon, 3 Jul 2023 08:28:10 +0000 (10:28 +0200)
committerRichard Biener <rguenther@suse.de>
Tue, 4 Jul 2023 07:04:51 +0000 (09:04 +0200)
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).

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
gcc/testsuite/gcc.dg/tree-ssa/addadd-2.c
gcc/testsuite/gcc.dg/tree-ssa/forwprop-27.c
gcc/tree.h

index f09583bbcac491cdb0e193f7465914fa4f843cda..861b7dfcdddb0838531f2d191ebe1dbf4aa2db2f 100644 (file)
@@ -3025,19 +3025,21 @@ 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))
-         (inner_op @0 { cst; } )
-         /* X+INT_MAX+1 is X-INT_MIN.  */
-         (if (INTEGRAL_TYPE_P (type) && cst
-              && wi::to_wide (cst) == wi::min_value (type))
-          (neg_inner_op @0 { wide_int_to_tree (type, wi::to_wide (cst)); })
-          /* Last resort, use some unsigned type.  */
-          (with { tree utype = unsigned_type_for (type); }
-           (if (utype)
-            (view_convert (inner_op
-                           (view_convert:utype @0)
-                           (view_convert:utype
-                            { drop_tree_overflow (cst); }))))))))))))))
+        (if (cst)
+         (if (INTEGRAL_TYPE_P (type) && !TREE_OVERFLOW (cst))
+          (inner_op @0 { cst; } )
+          /* X+INT_MAX+1 is X-INT_MIN.  */
+          (if (INTEGRAL_TYPE_P (type)
+               && wi::to_wide (cst) == wi::min_value (type))
+           (neg_inner_op @0 { wide_int_to_tree (type, wi::to_wide (cst)); })
+           /* Last resort, use some unsigned type.  */
+           (with { tree utype = unsigned_type_for (type); }
+            (if (utype)
+             (view_convert (inner_op
+                            (view_convert:utype @0)
+                            (view_convert:utype
+                             { TREE_OVERFLOW (cst)
+                               ? drop_tree_overflow (cst) : cst; })))))))))))))))
 
   /* (CST1 - A) +- CST2 -> CST3 - A  */
   (for outer_op (plus minus)
index 39aa032c9b186bea18d72df217642e67c0ecebe9..8c05911f4733a29d82d2b59b827d3b19516f16f8 100644 (file)
@@ -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" } } */
index 9775a4c636748effaabd46d74e311cdf3c687bb8..6c71a4fc81cba0ed1378017db883e658184a572c 100644 (file)
@@ -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"} } */
 
index 213a097ab5594c82c0a8f3264134ec9bb10b0e91..fa02e2907a1f2b642bd3971ed399a85882188890 100644 (file)
@@ -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)