In theory, const_wide_int can also be handle with extra check for each components of the HOST_WIDE_INT array, and the check is need for both shift and bit_and operands. I assume the optimization opportnunity is rare, so the patch just add extra check to make sure GET_MODE_INNER (mode) can fix into a HOST_WIDE_INT.
gcc/ChangeLog: PR target/115384 * simplify-rtx.cc (simplify_context::simplify_binary_operation_1): Only do the simplification of (AND (ASHIFTRT A imm) mask) to (LSHIFTRT A imm) when inner mode fits HOST_WIDE_INT. gcc/testsuite/ChangeLog: * gcc.target/i386/pr115384.c: New test. --- gcc/simplify-rtx.cc | 4 +++- gcc/testsuite/gcc.target/i386/pr115384.c | 12 ++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr115384.c diff --git a/gcc/simplify-rtx.cc b/gcc/simplify-rtx.cc index 9bc3ef9ad9f..4992bee7506 100644 --- a/gcc/simplify-rtx.cc +++ b/gcc/simplify-rtx.cc @@ -4074,7 +4074,9 @@ simplify_context::simplify_binary_operation_1 (rtx_code code, || (GET_CODE (XEXP (op0, 1)) == CONST_VECTOR && CONST_VECTOR_DUPLICATE_P (XEXP (op0, 1)))) && GET_CODE (op1) == CONST_VECTOR - && CONST_VECTOR_DUPLICATE_P (op1)) + && CONST_VECTOR_DUPLICATE_P (op1) + && (GET_MODE_PRECISION (GET_MODE_INNER (mode)) + <= HOST_BITS_PER_WIDE_INT)) { unsigned HOST_WIDE_INT shift_count = (CONST_INT_P (XEXP (op0, 1)) diff --git a/gcc/testsuite/gcc.target/i386/pr115384.c b/gcc/testsuite/gcc.target/i386/pr115384.c new file mode 100644 index 00000000000..3ba7a0b8115 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr115384.c @@ -0,0 +1,12 @@ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-options "-O" } */ + +typedef __attribute__((__vector_size__(sizeof(__int128)))) __int128 W; + +W w; + +void +foo() +{ + w = w >> 4 & 18446744073709551600llu; +} -- 2.31.1