diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index c19dc6cd895..b6192e55521 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -12060,10 +12060,11 @@ aarch64_mask_and_shift_for_ubfiz_p (scalar_int_mode mode, rtx mask, rtx shft_amnt) { return CONST_INT_P (mask) && CONST_INT_P (shft_amnt) - && INTVAL (shft_amnt) < GET_MODE_BITSIZE (mode) - && exact_log2 ((INTVAL (mask) >> INTVAL (shft_amnt)) + 1) >= 0 - && (INTVAL (mask) - & ((HOST_WIDE_INT_1U << INTVAL (shft_amnt)) - 1)) == 0; + && INTVAL (mask) > 0 + && UINTVAL (shft_amnt) < GET_MODE_BITSIZE (mode) + && exact_log2 ((UINTVAL (mask) >> UINTVAL (shft_amnt)) + 1) >= 0 + && (UINTVAL (mask) + & ((HOST_WIDE_INT_1U << UINTVAL (shft_amnt)) - 1)) == 0; } /* Return true if the masks and a shift amount from an RTX of the form diff --git a/gcc/testsuite/gcc.c-torture/execute/pr98681.c b/gcc/testsuite/gcc.c-torture/execute/pr98681.c new file mode 100644 index 00000000000..a256881342f --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr98681.c @@ -0,0 +1,18 @@ +/* PR target/98681 */ + +__attribute__((noipa)) int +foo (int x) +{ + if (x > 32) + return (x << -64) & 255; + else + return x; +} + +int +main () +{ + if (foo (32) != 32 || foo (-150) != -150) + __builtin_abort (); + return 0; +}