aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorBin Cheng <bin.cheng@arm.com>2016-08-16 13:09:40 +0000
committerBin Cheng <amker@gcc.gnu.org>2016-08-16 13:09:40 +0000
commit3c556bc4e9eb31561f246e8e2944b05a95cc1a4a (patch)
tree3f3f8f1a9f4e26388ee99a4cec27390b5ef38284 /gcc
parentedd1a1cb736d0b32396633f2ff45de46a33efb74 (diff)
downloadgcc-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/ChangeLog8
-rw-r--r--gcc/config/aarch64/aarch64-simd.md40
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.target/aarch64/simd/vcond-ne-bit.c32
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\]" } } */