https://gcc.gnu.org/g:256d683ac8ed30459b81b1498390252057e314a9
commit r17-1559-g256d683ac8ed30459b81b1498390252057e314a9 Author: Andrew Pinski <[email protected]> Date: Sun Jun 14 13:19:47 2026 -0700 match: Fix up `(~x) >> (type)x` pattern for truncation [PR125790] 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]> Diff: --- 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(-) diff --git a/gcc/match.pd b/gcc/match.pd index d52ea89af2b6..d0d37116ddf1 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 000000000000..49749b330cfa --- /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 7c1de1249c40..e5de9f2c8e15 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 000000000000..00a5288c207f --- /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; +}
