aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/config/i386/ia32intrin.h12
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/ubsan/pr82498.c159
4 files changed, 179 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index bff2a6f..58923e8 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2017-10-13 Jakub Jelinek <jakub@redhat.com>
+
+ 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 <rguenther@suse.de>
PR tree-optimization/82451
diff --git a/gcc/config/i386/ia32intrin.h b/gcc/config/i386/ia32intrin.h
index 5f954fc..1f4e484 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 a830453..0a8246f 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2017-10-13 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/82498
+ * gcc.dg/ubsan/pr82498.c: New test.
+
2017-10-13 Richard Biener <rguenther@suse.de>
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 0000000..1d093a0
--- /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 <x86intrin.h>
+
+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;
+}