I missed this during the review and when I suggest adding support
for the cast. But a truncation of the shifter operand the value
could be defined.
Since the front-end adds a cast to unsigned int, we need to split
pr125707.c into two and xfail the long case and change it to
`long long` so it would xfail for ilp32 [and llp64il32] targets.
PR tree-optimization/125790
gcc/ChangeLog:
* match.pd (`(~x)>>x`): Reject truncation of shifter.
gcc/testsuite/ChangeLog:
* gcc.dg/pr125707.c: Move the long over to pr125707-1.c.
* gcc.dg/pr125707-1.c: New test; xfailed.
* gcc.dg/pr125790-1.c: New test.
Signed-off-by: Andrew Pinski <[email protected]>
---
gcc/match.pd | 8 +++++---
gcc/testsuite/gcc.dg/pr125707-1.c | 11 +++++++++++
gcc/testsuite/gcc.dg/pr125707.c | 8 +-------
gcc/testsuite/gcc.dg/pr125790-1.c | 18 ++++++++++++++++++
4 files changed, 35 insertions(+), 10 deletions(-)
create mode 100644 gcc/testsuite/gcc.dg/pr125707-1.c
create mode 100644 gcc/testsuite/gcc.dg/pr125790-1.c
diff --git a/gcc/match.pd b/gcc/match.pd
index d52ea89af2b..d0d37116ddf 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -1832,11 +1832,13 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
SIGNED))
(minus (plus @1 { build_minus_one_cst (type); }) @0))))
-/* (~X) >> X -> -1 for signed X. */
+/* (~X) >> (type1)X -> -1 for signed X.
+ The cast needs not to be truncating cast. */
(simplify
- (rshift (bit_not @0) (convert? @0))
+ (rshift (bit_not @0) (convert?@1 @0))
(if (INTEGRAL_TYPE_P (type)
- && !TYPE_UNSIGNED (type))
+ && !TYPE_UNSIGNED (type)
+ && TYPE_PRECISION (type) <= TYPE_PRECISION (TREE_TYPE (@1)))
{ build_minus_one_cst (type); }))
#endif
diff --git a/gcc/testsuite/gcc.dg/pr125707-1.c
b/gcc/testsuite/gcc.dg/pr125707-1.c
new file mode 100644
index 00000000000..49749b330cf
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr125707-1.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+long long
+rshift_bit_not_long_x_x (long long x)
+{
+ return (~x) >> x;
+}
+
+/* xfailed because gimplifier introduces a truncation. */
+/* { dg-final { scan-tree-dump-times "return -1;" 1 "optimized" { xfail *-*-*
} } } */
diff --git a/gcc/testsuite/gcc.dg/pr125707.c b/gcc/testsuite/gcc.dg/pr125707.c
index 7c1de1249c4..e5de9f2c8e1 100644
--- a/gcc/testsuite/gcc.dg/pr125707.c
+++ b/gcc/testsuite/gcc.dg/pr125707.c
@@ -7,10 +7,4 @@ rshift_bit_not_int_x_x (int x)
return (~x) >> x;
}
-long
-rshift_bit_not_long_x_x (long x)
-{
- return (~x) >> x;
-}
-
-/* { dg-final { scan-tree-dump-times "return -1;" 2 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "return -1;" 1 "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/pr125790-1.c
b/gcc/testsuite/gcc.dg/pr125790-1.c
new file mode 100644
index 00000000000..00a5288c207
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr125790-1.c
@@ -0,0 +1,18 @@
+/* { dg-do run { target int32 } } */
+/* { dg-options "-O1" } */
+
+
+__attribute__((noipa))
+long long
+rshift (long long x)
+{
+ return (~x) >> (unsigned char)x;
+}
+
+int
+main(void)
+{
+ if (rshift(0xffffffff0000003fLL) != 0)
+ __builtin_abort();
+ return 0;
+}
--
2.43.0