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