From: Jakub Jelinek Date: Fri, 13 Oct 2017 07:17:06 +0000 (+0200) Subject: re PR target/82498 (Missed optimization for x86 rotate instruction) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=ef8c92e8e76b51040e0c3a37ff7dd0a3463a727d;p=gcc.git re PR target/82498 (Missed optimization for x86 rotate instruction) PR target/82498 * config/i386/ia32intrin.h (__rold, __rord, __rolq, __rorq): Allow any values of __C while still being pattern recognizable as a simple rotate instruction. * gcc.dg/ubsan/pr82498.c: New test. From-SVN: r253708 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index bff2a6fe00d..58923e8835a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2017-10-13 Jakub Jelinek + + PR target/82498 + * config/i386/ia32intrin.h (__rold, __rord, __rolq, __rorq): Allow + any values of __C while still being pattern recognizable as a simple + rotate instruction. + 2017-10-13 Richard Biener PR tree-optimization/82451 diff --git a/gcc/config/i386/ia32intrin.h b/gcc/config/i386/ia32intrin.h index 5f954fce85e..1f4e484d55b 100644 --- a/gcc/config/i386/ia32intrin.h +++ b/gcc/config/i386/ia32intrin.h @@ -147,7 +147,8 @@ extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__)) __rold (unsigned int __X, int __C) { - return (__X << __C) | (__X >> (32 - __C)); + __C &= 31; + return (__X << __C) | (__X >> (-__C & 31)); } /* 8bit ror */ @@ -171,7 +172,8 @@ extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__)) __rord (unsigned int __X, int __C) { - return (__X >> __C) | (__X << (32 - __C)); + __C &= 31; + return (__X >> __C) | (__X << (-__C & 31)); } /* Pause */ @@ -239,7 +241,8 @@ extern __inline unsigned long long __attribute__((__gnu_inline__, __always_inline__, __artificial__)) __rolq (unsigned long long __X, int __C) { - return (__X << __C) | (__X >> (64 - __C)); + __C &= 63; + return (__X << __C) | (__X >> (-__C & 63)); } /* 64bit ror */ @@ -247,7 +250,8 @@ extern __inline unsigned long long __attribute__((__gnu_inline__, __always_inline__, __artificial__)) __rorq (unsigned long long __X, int __C) { - return (__X >> __C) | (__X << (64 - __C)); + __C &= 63; + return (__X >> __C) | (__X << (-__C & 63)); } /* Read flags register */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a830453eabd..0a8246fd980 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2017-10-13 Jakub Jelinek + + PR target/82498 + * gcc.dg/ubsan/pr82498.c: New test. + 2017-10-13 Richard Biener PR tree-optimization/82451 diff --git a/gcc/testsuite/gcc.dg/ubsan/pr82498.c b/gcc/testsuite/gcc.dg/ubsan/pr82498.c new file mode 100644 index 00000000000..1d093a058e1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/ubsan/pr82498.c @@ -0,0 +1,159 @@ +/* PR target/82498 */ +/* { dg-do run { target i?86-*-* x86_64-*-* } } */ +/* { dg-options "-fsanitize=undefined -fno-sanitize-recover=undefined" } */ + +#include + +volatile unsigned int a; +volatile unsigned long long b; +volatile int c; + +int +main () +{ + a = 0x12345678U; + a = __rold (a, 0); + if (a != 0x12345678U) + __builtin_abort (); + a = __rold (a, 32); + if (a != 0x12345678U) + __builtin_abort (); + a = __rold (a, -32); + if (a != 0x12345678U) + __builtin_abort (); + a = __rold (a, 37); + if (a != 0x468acf02U) + __builtin_abort (); + a = __rold (a, -5); + if (a != 0x12345678U) + __builtin_abort (); + a = __rord (a, 0); + if (a != 0x12345678U) + __builtin_abort (); + a = __rord (a, 32); + if (a != 0x12345678U) + __builtin_abort (); + a = __rord (a, -32); + if (a != 0x12345678U) + __builtin_abort (); + a = __rord (a, -37); + if (a != 0x468acf02U) + __builtin_abort (); + a = __rord (a, 5); + if (a != 0x12345678U) + __builtin_abort (); + c = 0; + a = __rold (a, c); + if (a != 0x12345678U) + __builtin_abort (); + c = 32; + a = __rold (a, c); + if (a != 0x12345678U) + __builtin_abort (); + c = -32; + a = __rold (a, c); + if (a != 0x12345678U) + __builtin_abort (); + c = 37; + a = __rold (a, c); + if (a != 0x468acf02U) + __builtin_abort (); + c = -5; + a = __rold (a, c); + if (a != 0x12345678U) + __builtin_abort (); + c = 0; + a = __rord (a, c); + if (a != 0x12345678U) + __builtin_abort (); + c = 32; + a = __rord (a, c); + if (a != 0x12345678U) + __builtin_abort (); + c = -32; + a = __rord (a, c); + if (a != 0x12345678U) + __builtin_abort (); + c = -37; + a = __rord (a, c); + if (a != 0x468acf02U) + __builtin_abort (); + c = 5; + a = __rord (a, c); + if (a != 0x12345678U) + __builtin_abort (); +#ifdef __x86_64__ + b = 0x123456789abcdef1ULL; + b = __rolq (b, 0); + if (b != 0x123456789abcdef1ULL) + __builtin_abort (); + b = __rolq (b, 64); + if (b != 0x123456789abcdef1ULL) + __builtin_abort (); + b = __rolq (b, -64); + if (b != 0x123456789abcdef1ULL) + __builtin_abort (); + b = __rolq (b, 69); + if (b != 0x468acf13579bde22ULL) + __builtin_abort (); + b = __rolq (b, -5); + if (b != 0x123456789abcdef1ULL) + __builtin_abort (); + b = __rorq (b, 0); + if (b != 0x123456789abcdef1ULL) + __builtin_abort (); + b = __rorq (b, 64); + if (b != 0x123456789abcdef1ULL) + __builtin_abort (); + b = __rorq (b, -64); + if (b != 0x123456789abcdef1ULL) + __builtin_abort (); + b = __rorq (b, -69); + if (b != 0x468acf13579bde22ULL) + __builtin_abort (); + b = __rorq (b, 5); + if (b != 0x123456789abcdef1ULL) + __builtin_abort (); + c = 0; + b = __rolq (b, c); + if (b != 0x123456789abcdef1ULL) + __builtin_abort (); + c = 64; + b = __rolq (b, c); + if (b != 0x123456789abcdef1ULL) + __builtin_abort (); + c = -64; + b = __rolq (b, c); + if (b != 0x123456789abcdef1ULL) + __builtin_abort (); + c = 69; + b = __rolq (b, c); + if (b != 0x468acf13579bde22ULL) + __builtin_abort (); + c = -5; + b = __rolq (b, c); + if (b != 0x123456789abcdef1ULL) + __builtin_abort (); + c = 0; + b = __rorq (b, c); + if (b != 0x123456789abcdef1ULL) + __builtin_abort (); + c = 64; + b = __rorq (b, c); + if (b != 0x123456789abcdef1ULL) + __builtin_abort (); + c = -64; + b = __rorq (b, c); + if (b != 0x123456789abcdef1ULL) + __builtin_abort (); + c = -69; + b = __rorq (b, c); + if (b != 0x468acf13579bde22ULL) + __builtin_abort (); + c = 5; + b = __rorq (b, c); + if (b != 0x123456789abcdef1ULL) + __builtin_abort (); +#endif + return 0; +}