Commit 3c556bc4 by Bin Cheng Committed by Bin Cheng

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
parent edd1a1cb
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> 2016-08-16 Eric Botcazou <ebotcazou@adacore.com>
* doc/install.texi (*-*-solaris2*): Adjust latest change. * doc/install.texi (*-*-solaris2*): Adjust latest change.
......
...@@ -2573,7 +2573,17 @@ ...@@ -2573,7 +2573,17 @@
"TARGET_SIMD" "TARGET_SIMD"
{ {
rtx mask = gen_reg_rtx (<V_cmp_result>mode); 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], emit_insn (gen_vec_cmp<mode><v_cmp_result> (mask, operands[3],
operands[4], operands[5])); operands[4], operands[5]));
emit_insn (gen_vcond_mask_<mode><v_cmp_result> (operands[0], operands[1], emit_insn (gen_vcond_mask_<mode><v_cmp_result> (operands[0], operands[1],
...@@ -2593,7 +2603,17 @@ ...@@ -2593,7 +2603,17 @@
"TARGET_SIMD" "TARGET_SIMD"
{ {
rtx mask = gen_reg_rtx (<V_cmp_result>mode); 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], emit_insn (gen_vec_cmp<mode><v_cmp_result> (mask, operands[3],
operands[4], operands[5])); operands[4], operands[5]));
emit_insn (gen_vcond_mask_<v_cmp_mixed><v_cmp_result> ( emit_insn (gen_vcond_mask_<v_cmp_mixed><v_cmp_result> (
...@@ -2614,7 +2634,17 @@ ...@@ -2614,7 +2634,17 @@
"TARGET_SIMD" "TARGET_SIMD"
{ {
rtx mask = gen_reg_rtx (<MODE>mode); 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], emit_insn (gen_vec_cmp<mode><mode> (mask, operands[3],
operands[4], operands[5])); operands[4], operands[5]));
emit_insn (gen_vcond_mask_<mode><v_cmp_result> (operands[0], operands[1], emit_insn (gen_vcond_mask_<mode><v_cmp_result> (operands[0], operands[1],
...@@ -2633,7 +2663,17 @@ ...@@ -2633,7 +2663,17 @@
"TARGET_SIMD" "TARGET_SIMD"
{ {
rtx mask = gen_reg_rtx (<V_cmp_result>mode); 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> ( emit_insn (gen_vec_cmp<v_cmp_mixed><v_cmp_mixed> (
mask, operands[3], mask, operands[3],
operands[4], operands[5])); operands[4], operands[5]));
......
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> 2016-08-16 Martin Liska <mliska@suse.cz>
* gcc.dg/tree-prof/val-prof-7.c (int main): Change size * gcc.dg/tree-prof/val-prof-7.c (int main): Change size
......
/* { 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\]" } } */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment