3 recent match patterns were added that introduce signed integer overflow where
there was none before. These 3 were in the form of `cmp + (-cmp ^ x)` and
`((dec_exp + -cmp) ^ -cmp)` In the first 2, ABSU is needed to be used
and in the other one we need to cast first to the unsigned type before
taking the 2comps negative value and then cast back.
Bootstrapped and tested on x86_64-linux-gnu.
PR tree-optimization/126418
gcc/ChangeLog:
* match.pd (`((x - (x<0)) ^ -(x<0)`): Use ABSU.
(`(X ^ -(X < 0)) + (X < 0)`): Likewise.
(`(A ^ -cmp) + cmp`): Cast to unsigned type
before taking the negative.
gcc/testsuite/ChangeLog:
* gcc.dg/tree-ssa/pr113894.c: Update testcase for ABSU.
* gcc.dg/tree-ssa/pr123514.c: Likewise.
* gcc.dg/tree-ssa/pr126418-1.c: New test.
Signed-off-by: Andrea Pinski <[email protected]>
---
gcc/match.pd | 18 +++++++++++++-----
gcc/testsuite/gcc.dg/tree-ssa/pr113894.c | 2 +-
gcc/testsuite/gcc.dg/tree-ssa/pr123514.c | 2 +-
gcc/testsuite/gcc.dg/tree-ssa/pr126418-1.c | 11 +++++++++++
4 files changed, 26 insertions(+), 7 deletions(-)
create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr126418-1.c
diff --git a/gcc/match.pd b/gcc/match.pd
index 50e73177022..751f5571183 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -228,22 +228,24 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(abs @0)))
#endif
-/* (X - (X < 0)) ^ -(X < 0) -> abs (X) */
+/* (X - (X < 0)) ^ -(X < 0) -> absu (X) */
(simplify
(bit_xor:c (minus @0 (convert@1 (lt @0 integer_zerop)))
(negate @1))
(if (INTEGRAL_TYPE_P (TREE_TYPE (@0))
&& !TYPE_UNSIGNED (TREE_TYPE (@0)))
- (abs @0)))
+ (with { tree utype = unsigned_type_for (type); }
+ (convert (absu:utype @0)))))
-/* (X ^ -(X < 0)) + (X < 0) -> abs (X) */
+/* (X ^ -(X < 0)) + (X < 0) -> absu (X) */
(simplify
(plus:c (bit_xor:c @0 (negate (convert@1 (lt @0 integer_zerop)))) @1)
(if (INTEGRAL_TYPE_P (TREE_TYPE (@0))
&& !TYPE_UNSIGNED (TREE_TYPE (@0))
&& !TYPE_SATURATING (TREE_TYPE (@0))
&& (GIMPLE || !TREE_SIDE_EFFECTS (@0)))
- (abs @0)))
+ (with { tree utype = unsigned_type_for (type); }
+ (convert (absu:utype @0)))))
/* Following match patterns are used by the match_spaceship function to detect
all possible spaceship combinations. */
@@ -4960,7 +4962,13 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(if (INTEGRAL_TYPE_P (type)
&& !TYPE_SATURATING (type)
&& (GIMPLE || !TREE_SIDE_EFFECTS (@0)))
- (cond (convert:boolean_type_node @1) (negate @0) @0)))
+ /* Do the negate in unsigned type always; otherwise
+ we would be introducing an overflow. */
+ (with { tree utype = unsigned_type_for (type); }
+ (cond
+ (convert:boolean_type_node @1)
+ (convert:type (negate (convert:utype @0)))
+ @0))))
/* Transform A & (B*cmp) into (A&B)*cmp. */
(simplify
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr113894.c
b/gcc/testsuite/gcc.dg/tree-ssa/pr113894.c
index dc7a450d3e8..829a214632d 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr113894.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr113894.c
@@ -58,6 +58,6 @@ unsigned f_unsigned_not_zero_one(unsigned x, unsigned cmp)
not known to be 0 or 1. */
/* { dg-final { scan-tree-dump-times " \\^ " 2 "forwprop1" } } */
/* Sign tests should expose absolute value. */
-/* { dg-final { scan-tree-dump-times " = ABS_EXPR" 2 "forwprop1" } } */
+/* { dg-final { scan-tree-dump-times " = ABSU_EXPR" 2 "forwprop1" } } */
/* Other zero-one predicates should expose conditional negation. */
/* { dg-final { scan-tree-dump-times " \\? " 5 "forwprop1" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr123514.c
b/gcc/testsuite/gcc.dg/tree-ssa/pr123514.c
index 4a09d859031..ef2dde1804b 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr123514.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr123514.c
@@ -8,4 +8,4 @@ bit_trick (int x)
return ((x + mask) ^ mask);
}
-/* { dg-final { scan-tree-dump "ABS_EXPR" "optimized" } } */
+/* { dg-final { scan-tree-dump "ABSU_EXPR " "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr126418-1.c
b/gcc/testsuite/gcc.dg/tree-ssa/pr126418-1.c
new file mode 100644
index 00000000000..3714069b43f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr126418-1.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-forwprop1" } */
+
+int f_cmp_gt_commuted(int x, int y)
+{
+ int cmp = x > y;
+ return cmp + (-cmp ^ x);
+}
+
+/* { dg-final { scan-tree-dump-times "\\(unsigned int\\) " 1 "forwprop1" } } */
+/* { dg-final { scan-tree-dump-times "\\(int\\) " 1 "forwprop1" } } */
--
2.43.0