aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEaswaran Raman <eraman@google.com>2015-04-17 22:30:30 +0000
committerEaswaran Raman <eraman@google.com>2015-04-17 22:30:30 +0000
commit3e28154fda36a3052e44dd035e7b90e0895e7354 (patch)
tree8ba01ee2b8a0cd51ca476ea5c50616b6485b2cd6
parent3627ab09ddde8095bc28465a5d47efa2d3b36b7d (diff)
Backport r221335 from trunk to google/gcc-4_9 branch and rollback r222160.
Google ref b/20266256. git-svn-id: https://gcc.gnu.org/svn/gcc/branches/google/gcc-4_9@222206 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--contrib/testsuite-management/x86_64-grtev4-linux-gnu.xfail4
-rw-r--r--gcc/config/i386/i386.md44
-rw-r--r--gcc/testsuite/gcc.target/i386/bmi2-bzhi-2.c67
3 files changed, 106 insertions, 9 deletions
diff --git a/contrib/testsuite-management/x86_64-grtev4-linux-gnu.xfail b/contrib/testsuite-management/x86_64-grtev4-linux-gnu.xfail
index 60ae8635733..b4fa6933791 100644
--- a/contrib/testsuite-management/x86_64-grtev4-linux-gnu.xfail
+++ b/contrib/testsuite-management/x86_64-grtev4-linux-gnu.xfail
@@ -21,10 +21,6 @@ FAIL: gcc.dg/wself-assign-1.c (test for warnings, line 22)
# http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60037
FAIL: ext/random/hypergeometric_distribution/operators/values.cc execution test
-# Google b/20266256 (flaky due to hardware dependency)
-flaky | FAIL: gcc.target/i386/bmi2-bzhi32-1.c execution test
-flaky | FAIL: gcc.target/i386/bmi2-bzhi64-1.c execution test
-
# Google b/20184248
FAIL: 17_intro/headers/c++1998/complex.cc (test for excess errors)
FAIL: 26_numerics/complex/c99.cc (test for excess errors)
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index de56b9e1dce..2369e4b4098 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -12159,18 +12159,52 @@
(set_attr "mode" "<MODE>")])
;; BMI2 instructions.
-(define_insn "bmi2_bzhi_<mode>3"
+(define_expand "bmi2_bzhi_<mode>3"
+ [(parallel
+ [(set (match_operand:SWI48 0 "register_operand")
+ (zero_extract:SWI48
+ (match_operand:SWI48 1 "nonimmediate_operand")
+ (umin:SWI48
+ (and:SWI48 (match_operand:SWI48 2 "register_operand")
+ (const_int 255))
+ (match_dup 3))
+ (const_int 0)))
+ (clobber (reg:CC FLAGS_REG))])]
+ "TARGET_BMI2"
+ "operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);")
+
+(define_insn "*bmi2_bzhi_<mode>3"
[(set (match_operand:SWI48 0 "register_operand" "=r")
- (and:SWI48 (lshiftrt:SWI48 (const_int -1)
- (match_operand:SWI48 2 "register_operand" "r"))
- (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
+ (zero_extract:SWI48
+ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
+ (umin:SWI48
+ (and:SWI48 (match_operand:SWI48 2 "register_operand" "r")
+ (const_int 255))
+ (match_operand:SWI48 3 "const_int_operand" "n"))
+ (const_int 0)))
(clobber (reg:CC FLAGS_REG))]
- "TARGET_BMI2"
+ "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
"bzhi\t{%2, %1, %0|%0, %1, %2}"
[(set_attr "type" "bitmanip")
(set_attr "prefix" "vex")
(set_attr "mode" "<MODE>")])
+(define_mode_attr k [(SI "k") (DI "q")])
+(define_insn "*bmi2_bzhi_<mode>3_1"
+ [(set (match_operand:SWI48 0 "register_operand" "=r")
+ (zero_extract:SWI48
+ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
+ (umin:SWI48
+ (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
+ (match_operand:SWI48 3 "const_int_operand" "n"))
+ (const_int 0)))
+ (clobber (reg:CC FLAGS_REG))]
+ "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
+ "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
+ [(set_attr "type" "bitmanip")
+ (set_attr "prefix" "vex")
+ (set_attr "mode" "<MODE>")])
+
(define_insn "bmi2_pdep_<mode>3"
[(set (match_operand:SWI48 0 "register_operand" "=r")
(unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
diff --git a/gcc/testsuite/gcc.target/i386/bmi2-bzhi-2.c b/gcc/testsuite/gcc.target/i386/bmi2-bzhi-2.c
new file mode 100644
index 00000000000..34579d52695
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/bmi2-bzhi-2.c
@@ -0,0 +1,67 @@
+/* PR target/65368 */
+/* { dg-do assemble { target bmi2 } } */
+/* { dg-options "-O2 -mbmi2" } */
+
+#include <x86intrin.h>
+#include "bmi2-check.h"
+
+unsigned int a;
+unsigned long long b;
+
+#define A __attribute__((noinline, noclone))
+
+A unsigned int f1 (void) { return _bzhi_u32 (a, 0); }
+A unsigned int f2 (unsigned int x) { return _bzhi_u32 (x, 0); }
+A unsigned int f3 (void) { return _bzhi_u32 (a, 5); }
+A unsigned int f4 (unsigned int x) { return _bzhi_u32 (x, 5); }
+A unsigned int f5 (void) { return _bzhi_u32 (a, 31); }
+A unsigned int f6 (unsigned int x) { return _bzhi_u32 (x, 31); }
+A unsigned int f7 (void) { return _bzhi_u32 (a, 32); }
+A unsigned int f8 (unsigned int x) { return _bzhi_u32 (x, 32); }
+A unsigned int f9 (void) { return _bzhi_u32 (a, 37); }
+A unsigned int f10 (unsigned int x) { return _bzhi_u32 (x, 37); }
+A unsigned int f11 (void) { return _bzhi_u32 (a, 257); }
+A unsigned int f12 (unsigned int x) { return _bzhi_u32 (x, 257); }
+A unsigned int f13 (void) { return _bzhi_u32 (a, 289); }
+A unsigned int f14 (unsigned int x) { return _bzhi_u32 (x, 289); }
+#ifdef __x86_64__
+A unsigned long long f21 (void) { return _bzhi_u64 (b, 0); }
+A unsigned long long f22 (unsigned long long x) { return _bzhi_u64 (x, 0); }
+A unsigned long long f23 (void) { return _bzhi_u64 (b, 5); }
+A unsigned long long f24 (unsigned long long x) { return _bzhi_u64 (x, 5); }
+A unsigned long long f25 (void) { return _bzhi_u64 (b, 63); }
+A unsigned long long f26 (unsigned long long x) { return _bzhi_u64 (x, 63); }
+A unsigned long long f27 (void) { return _bzhi_u64 (b, 64); }
+A unsigned long long f28 (unsigned long long x) { return _bzhi_u64 (x, 64); }
+A unsigned long long f29 (void) { return _bzhi_u64 (b, 69); }
+A unsigned long long f30 (unsigned long long x) { return _bzhi_u64 (x, 69); }
+A unsigned long long f31 (void) { return _bzhi_u64 (b, 257); }
+A unsigned long long f32 (unsigned long long x) { return _bzhi_u64 (x, 257); }
+A unsigned long long f33 (void) { return _bzhi_u64 (b, 321); }
+A unsigned long long f34 (unsigned long long x) { return _bzhi_u64 (x, 321); }
+#endif
+
+static void
+bmi2_test ()
+{
+ a = -1U;
+ b = -1ULL;
+ if (f1 () != 0 || f2 (-1U) != 0
+ || f3 () != 0x1f || f4 (-1U) != 0x1f
+ || f5 () != 0x7fffffffU || f6 (-1U) != 0x7fffffffU
+ || f7 () != -1U || f8 (-1U) != -1U
+ || f9 () != -1U || f10 (-1U) != -1U
+ || f11 () != 1 || f12 (-1U) != 1
+ || f13 () != -1U || f14 (-1U) != -1U)
+ abort ();
+#ifdef __x86_64__
+ if (f21 () != 0 || f22 (-1ULL) != 0
+ || f23 () != 0x1f || f24 (-1ULL) != 0x1f
+ || f25 () != 0x7fffffffffffffffULL || f26 (-1ULL) != 0x7fffffffffffffffULL
+ || f27 () != -1ULL || f28 (-1ULL) != -1ULL
+ || f29 () != -1ULL || f30 (-1ULL) != -1ULL
+ || f31 () != 1 || f32 (-1ULL) != 1
+ || f33 () != -1ULL || f34 (-1ULL) != -1ULL)
+ abort ();
+#endif
+}