diff options
author | Richard Biener <rguenther@suse.de> | 2023-07-03 10:28:10 +0200 |
---|---|---|
committer | Richard Biener <rguenther@suse.de> | 2023-07-04 09:04:51 +0200 |
commit | f703d2fd3f03890a180e8cc04df087c208999e81 (patch) | |
tree | 29d94f79261e9b5025f0a5aaf3b2e4814ad6ef34 | |
parent | 0682a32c026f1e246eb07bb8066abca4636f01d8 (diff) | |
download | gcc-f703d2fd3f03890a180e8cc04df087c208999e81.zip gcc-f703d2fd3f03890a180e8cc04df087c208999e81.tar.gz gcc-f703d2fd3f03890a180e8cc04df087c208999e81.tar.bz2 |
middle-end/110495 - avoid associating constants with (VL) vectors
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.
-rw-r--r-- | gcc/match.pd | 28 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/addadd-2.c | 1 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/forwprop-27.c | 4 | ||||
-rw-r--r-- | gcc/tree.h | 2 |
4 files changed, 20 insertions, 15 deletions
diff --git a/gcc/match.pd b/gcc/match.pd index f09583b..861b7df 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -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) diff --git a/gcc/testsuite/gcc.dg/tree-ssa/addadd-2.c b/gcc/testsuite/gcc.dg/tree-ssa/addadd-2.c index 39aa032..8c05911 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 9775a4c..6c71a4f 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"} } */ @@ -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) |