diff options
author | Bin Cheng <bin.cheng@arm.com> | 2016-08-16 13:09:40 +0000 |
---|---|---|
committer | Bin Cheng <amker@gcc.gnu.org> | 2016-08-16 13:09:40 +0000 |
commit | 3c556bc4e9eb31561f246e8e2944b05a95cc1a4a (patch) | |
tree | 3f3f8f1a9f4e26388ee99a4cec27390b5ef38284 /gcc | |
parent | edd1a1cb736d0b32396633f2ff45de46a33efb74 (diff) | |
download | gcc-3c556bc4e9eb31561f246e8e2944b05a95cc1a4a.zip gcc-3c556bc4e9eb31561f246e8e2944b05a95cc1a4a.tar.gz gcc-3c556bc4e9eb31561f246e8e2944b05a95cc1a4a.tar.bz2 |
re PR tree-optimization/69848 (poor vectorization of a loop from SPEC2006 464.h264ref)
PR tree-optimization/69848
* config/aarch64/aarch64-simd.md (vcond<mode><mode>): Invert NE
and swtich operands to avoid additional NOT instruction.
(vcond<v_cmp_mixed><mode>): Ditto.
(vcondu<mode><mode>, vcondu<mode><v_cmp_mixed>): Ditto.
gcc/testsuite
* gcc.target/aarch64/simd/vcond-ne-bit.c: New test.
From-SVN: r239502
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/config/aarch64/aarch64-simd.md | 40 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/aarch64/simd/vcond-ne-bit.c | 32 |
4 files changed, 85 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 93a12f3..e2d39a8 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2016-08-16 Bin Cheng <bin.cheng@arm.com> + + PR tree-optimization/69848 + * config/aarch64/aarch64-simd.md (vcond<mode><mode>): Invert NE + and swtich operands to avoid additional NOT instruction. + (vcond<v_cmp_mixed><mode>): Ditto. + (vcondu<mode><mode>, vcondu<mode><v_cmp_mixed>): Ditto. + 2016-08-16 Eric Botcazou <ebotcazou@adacore.com> * doc/install.texi (*-*-solaris2*): Adjust latest change. diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md index feb5e96..70140744 100644 --- a/gcc/config/aarch64/aarch64-simd.md +++ b/gcc/config/aarch64/aarch64-simd.md @@ -2573,7 +2573,17 @@ "TARGET_SIMD" { rtx mask = gen_reg_rtx (<V_cmp_result>mode); + enum rtx_code code = GET_CODE (operands[3]); + /* NE is handled as !EQ in vec_cmp patterns, we can explicitly invert + it as well as switch operands 1/2 in order to avoid the additional + NOT instruction. */ + if (code == NE) + { + operands[3] = gen_rtx_fmt_ee (EQ, GET_MODE (operands[3]), + operands[4], operands[5]); + std::swap (operands[1], operands[2]); + } emit_insn (gen_vec_cmp<mode><v_cmp_result> (mask, operands[3], operands[4], operands[5])); emit_insn (gen_vcond_mask_<mode><v_cmp_result> (operands[0], operands[1], @@ -2593,7 +2603,17 @@ "TARGET_SIMD" { rtx mask = gen_reg_rtx (<V_cmp_result>mode); + enum rtx_code code = GET_CODE (operands[3]); + /* NE is handled as !EQ in vec_cmp patterns, we can explicitly invert + it as well as switch operands 1/2 in order to avoid the additional + NOT instruction. */ + if (code == NE) + { + operands[3] = gen_rtx_fmt_ee (EQ, GET_MODE (operands[3]), + operands[4], operands[5]); + std::swap (operands[1], operands[2]); + } emit_insn (gen_vec_cmp<mode><v_cmp_result> (mask, operands[3], operands[4], operands[5])); emit_insn (gen_vcond_mask_<v_cmp_mixed><v_cmp_result> ( @@ -2614,7 +2634,17 @@ "TARGET_SIMD" { rtx mask = gen_reg_rtx (<MODE>mode); + enum rtx_code code = GET_CODE (operands[3]); + /* NE is handled as !EQ in vec_cmp patterns, we can explicitly invert + it as well as switch operands 1/2 in order to avoid the additional + NOT instruction. */ + if (code == NE) + { + operands[3] = gen_rtx_fmt_ee (EQ, GET_MODE (operands[3]), + operands[4], operands[5]); + std::swap (operands[1], operands[2]); + } emit_insn (gen_vec_cmp<mode><mode> (mask, operands[3], operands[4], operands[5])); emit_insn (gen_vcond_mask_<mode><v_cmp_result> (operands[0], operands[1], @@ -2633,7 +2663,17 @@ "TARGET_SIMD" { rtx mask = gen_reg_rtx (<V_cmp_result>mode); + enum rtx_code code = GET_CODE (operands[3]); + /* NE is handled as !EQ in vec_cmp patterns, we can explicitly invert + it as well as switch operands 1/2 in order to avoid the additional + NOT instruction. */ + if (code == NE) + { + operands[3] = gen_rtx_fmt_ee (EQ, GET_MODE (operands[3]), + operands[4], operands[5]); + std::swap (operands[1], operands[2]); + } emit_insn (gen_vec_cmp<v_cmp_mixed><v_cmp_mixed> ( mask, operands[3], operands[4], operands[5])); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index bd2a2d9..764ff69 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-08-16 Bin Cheng <bin.cheng@arm.com> + + PR tree-optimization/69848 + * gcc.target/aarch64/simd/vcond-ne-bit.c: New test. + 2016-08-16 Martin Liska <mliska@suse.cz> * gcc.dg/tree-prof/val-prof-7.c (int main): Change size diff --git a/gcc/testsuite/gcc.target/aarch64/simd/vcond-ne-bit.c b/gcc/testsuite/gcc.target/aarch64/simd/vcond-ne-bit.c new file mode 100644 index 0000000..25170c2 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/simd/vcond-ne-bit.c @@ -0,0 +1,32 @@ +/* { dg-do run } */ +/* { dg-options "-save-temps" } */ +/* { dg-require-effective-target vect_int } */ +/* { dg-require-effective-target vect_condition } */ +#include <stdlib.h> + +int fn1 (int) __attribute__ ((noinline)); + +int a[128]; +int fn1(int d) { + int b, c = 1; + for (b = 0; b < 128; b++) + if (a[b]) + c = 0; + return c; +} + +int +main (void) +{ + int i; + for (i = 0; i < 128; i++) + a[i] = 0; + if (fn1(10) != 1) + abort (); + a[3] = 2; + a[24] = 1; + if (fn1(10) != 0) + abort (); + return 0; +} +/* { dg-final { scan-assembler-not "\[ \t\]not\[ \t\]" } } */ |