diff options
-rw-r--r-- | gcc/combine.c | 7 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/pr97386-1.c | 16 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/pr97386-2.c | 20 |
3 files changed, 41 insertions, 2 deletions
diff --git a/gcc/combine.c b/gcc/combine.c index c88382e..4782e1d 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -11003,8 +11003,11 @@ simplify_shift_const_1 (enum rtx_code code, machine_mode result_mode, break; /* For ((int) (cstLL >> count)) >> cst2 just give up. Queuing up outer sign extension (often left and right shift) is - hardly more efficient than the original. See PR70429. */ - if (code == ASHIFTRT && int_mode != int_result_mode) + hardly more efficient than the original. See PR70429. + Similarly punt for rotates with different modes. + See PR97386. */ + if ((code == ASHIFTRT || code == ROTATE) + && int_mode != int_result_mode) break; rtx count_rtx = gen_int_shift_amount (int_result_mode, count); diff --git a/gcc/testsuite/gcc.c-torture/execute/pr97386-1.c b/gcc/testsuite/gcc.c-torture/execute/pr97386-1.c new file mode 100644 index 0000000..c50e038 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr97386-1.c @@ -0,0 +1,16 @@ +/* PR rtl-optimization/97386 */ + +__attribute__((noipa)) unsigned char +foo (unsigned int c) +{ + return __builtin_bswap16 ((unsigned long long) (0xccccLLU << c | 0xccccLLU >> ((-c) & 63))); +} + +int +main () +{ + unsigned char x = foo (0); + if (__CHAR_BIT__ == 8 && __SIZEOF_SHORT__ == 2 && x != 0xcc) + __builtin_abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.c-torture/execute/pr97386-2.c b/gcc/testsuite/gcc.c-torture/execute/pr97386-2.c new file mode 100644 index 0000000..e61829d --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr97386-2.c @@ -0,0 +1,20 @@ +/* PR rtl-optimization/97386 */ + +__attribute__((noipa)) unsigned +foo (int x) +{ + unsigned long long a = (0x800000000000ccccULL << x) | (0x800000000000ccccULL >> (64 - x)); + unsigned int b = a; + return (b << 24) | (b >> 8); +} + +int +main () +{ + if (__CHAR_BIT__ == 8 + && __SIZEOF_INT__ == 4 + && __SIZEOF_LONG_LONG__ == 8 + && foo (1) != 0x99000199U) + __builtin_abort (); + return 0; +} |