In this simplification rule added in r17-4511-g885ad73e630ca2, we assume
that C1 and C3 are of the same type and call wi::leu_p () with those
constants converted to wide_int. This leads to a triggered assert on
wide-int.h:1049 whenever C1 and C3 have different precision, which causes
an ICE reported in PR127552. Fix this by converting to widest_int
instead.
To test the change, amend the original match-bit-extract-shift.c file to
use constants of various types in the existing testcases.
Bootstrapped and regtested on aarch64-linux-gnu and x86_64-linux-gnu.
PR tree-optimization/127552
gcc/ChangeLog:
* match.pd: Fix constant comparison in ((X >> C1) & C2) << C3.
gcc/testsuite/ChangeLog:
* gcc.dg/tree-ssa/match-bit-extract-shift.c: Adjust testcases.
---
gcc/match.pd | 2 +-
.../gcc.dg/tree-ssa/match-bit-extract-shift.c | 14 +++++++-------
2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/gcc/match.pd b/gcc/match.pd
index b6a9d4e79be..688357f0ecd 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -1545,7 +1545,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
tree mask_shifted = fold_build2 (LSHIFT_EXPR, TREE_TYPE (@0),
mask, @3);
}
- (if (wi::leu_p (wi::to_wide (@1), wi::to_wide (@3)))
+ (if (wi::to_widest (@1) <= wi::to_widest (@3))
(bit_and (lshift @0 (minus @3 @1)) { mask_shifted; })
(bit_and (rshift @0 (minus @1 @3)) { mask_shifted; })))))))
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/match-bit-extract-shift.c
b/gcc/testsuite/gcc.dg/tree-ssa/match-bit-extract-shift.c
index 292ce5a41c9..56d386d4305 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/match-bit-extract-shift.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/match-bit-extract-shift.c
@@ -6,33 +6,33 @@
uint32_t f (uint64_t x)
{
- return (((x >> 32) & 0x1) << 16)
- | (((x >> 24) & 0xff) << 8);
+ return (((x >> 32) & 0x1) << 16L)
+ | (((x >> 24UL) & 0xff) << 8);
}
uint32_t f2 (uint64_t x)
{
- return (((x >> 3) & 0x3) << 16);
+ return (((x >> 3) & 0x3) << 16LL);
}
uint32_t f3 (uint64_t x)
{
- return (((x >> 61) & 0xE) << 16);
+ return (((x >> 61ULL) & 0xE) << 16);
}
uint32_t f4 (uint64_t x)
{
- return (((x >> 62) & 0xE) << 16);
+ return (((x >> 62U) & 0xE) << 16UL);
}
uint32_t f5 (uint64_t x)
{
- return (((x >> 63) & 0xF) << 17);
+ return (((x >> 63L) & 0xF) << 17U);
}
uint64_t f6 (uint64_t x)
{
- return (((x >> 32) & 0xFFFFFF) << 47);
+ return (((x >> 32U) & 0xFFFFFF) << 47ULL);
}
/* { dg-final { scan-tree-dump-not "<< 16" forwprop1 } } */
--
2.43.0