diff options
author | Jakub Jelinek <jakub@redhat.com> | 2015-03-10 22:03:21 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2015-03-10 22:03:21 +0100 |
commit | 2d977ff983f86b3f7b7c9f1cb5a479af75cd589e (patch) | |
tree | c87f415ef71f1c48e9b1ccc38f4e78d1b89918ac /gcc | |
parent | 48188959fd8a9bb1d7da833466f314210693bc11 (diff) | |
download | gcc-2d977ff983f86b3f7b7c9f1cb5a479af75cd589e.zip gcc-2d977ff983f86b3f7b7c9f1cb5a479af75cd589e.tar.gz gcc-2d977ff983f86b3f7b7c9f1cb5a479af75cd589e.tar.bz2 |
re PR target/65368 (_bzhi_u32 intrinsic generates incorrect code when -O1 or above is specified and index is an immediate)
PR target/65368
* config/i386/i386.md (bmi2_bzhi_<mode>3): Removed define_insn,
new define_expand.
(*bmi2_bzhi_<mode>3, *bmi2_bzhi_<mode>3_1): New define_insns.
* gcc.target/i386/bmi2-bzhi-2.c: New test.
From-SVN: r221335
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/config/i386/i386.md | 44 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/bmi2-bzhi-2.c | 67 |
4 files changed, 118 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6802d20..b77fb5e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2015-03-10 Jakub Jelinek <jakub@redhat.com> + + PR target/65368 + * config/i386/i386.md (bmi2_bzhi_<mode>3): Removed define_insn, + new define_expand. + (*bmi2_bzhi_<mode>3, *bmi2_bzhi_<mode>3_1): New define_insns. + 2015-03-10 Jan Hubicka <hubicka@ucw.cz> * ipa-icf.c (sem_function::equals_wpa): Move here some checks diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 8a80415..1129b93 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -12678,18 +12678,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/ChangeLog b/gcc/testsuite/ChangeLog index 5acef58..2a201e1 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2015-03-10 Jakub Jelinek <jakub@redhat.com> + + PR target/65368 + * gcc.target/i386/bmi2-bzhi-2.c: New test. + 2015-03-10 Paul Thomas <pault@gcc.gnu.org> PR fortran/65024 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 0000000..34579d5 --- /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 +} |