From 94f373957092bf7c3ed8a83d00e5c4f21e7ffd35 Mon Sep 17 00:00:00 2001 From: Ilya Enkovich Date: Fri, 15 Jan 2016 11:04:25 +0000 Subject: [PATCH] i386.c (ix86_expand_branch): Don't split DI mode xor instruction to SI mode. gcc/ * config/i386/i386.c (ix86_expand_branch): Don't split DI mode xor instruction to SI mode. gcc/testsuite/ * gcc.target/i386/pr65105-5.c: New test. From-SVN: r232413 --- gcc/ChangeLog | 5 +++++ gcc/config/i386/i386.c | 13 +++++++++++++ gcc/testsuite/ChangeLog | 4 ++++ gcc/testsuite/gcc.target/i386/pr65105-5.c | 22 ++++++++++++++++++++++ 4 files changed, 44 insertions(+) create mode 100644 gcc/testsuite/gcc.target/i386/pr65105-5.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ac14805ae76..bd052951e86 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2016-01-15 Ilya Enkovich + + * config/i386/i386.c (ix86_expand_branch): Don't split + DI mode xor instruction to SI mode. + 2016-01-15 Jan Hubicka PR ipa/68148 diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 996913b17d7..92f3a4130f0 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -21699,6 +21699,19 @@ ix86_expand_branch (enum rtx_code code, rtx op0, rtx op1, rtx label) case DImode: if (TARGET_64BIT) goto simple; + /* For 32-bit target DI comparison may be performed on + SSE registers. To allow this we should avoid split + to SI mode which is achieved by doing xor in DI mode + and then comparing with zero (which is recognized by + STV pass). We don't compare using xor when optimizing + for size. */ + if (!optimize_insn_for_size_p () + && TARGET_STV + && (code == EQ || code == NE)) + { + op0 = force_reg (mode, gen_rtx_XOR (mode, op0, op1)); + op1 = const0_rtx; + } case TImode: /* Expand DImode branch into multiple compare+branch. */ { diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d949b835034..456edf205c7 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2016-01-15 Ilya Enkovich + + * gcc.target/i386/pr65105-5.c: New test. + 2016-01-15 Jan Hubicka * gcc.c-torture/execute/alias-4.c: New testcase. diff --git a/gcc/testsuite/gcc.target/i386/pr65105-5.c b/gcc/testsuite/gcc.target/i386/pr65105-5.c new file mode 100644 index 00000000000..5818c1c0bac --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr65105-5.c @@ -0,0 +1,22 @@ +/* PR target/pr65105 */ +/* { dg-do compile { target { ia32 } } } */ +/* { dg-options "-O2 -march=core-avx2" } */ +/* { dg-final { scan-assembler "pand" } } */ +/* { dg-final { scan-assembler "pxor" } } */ +/* { dg-final { scan-assembler "ptest" } } */ + +struct S1 +{ + unsigned long long a; + unsigned long long b; +}; + +void +test (int p1, unsigned long long p2, int p3, struct S1 *p4) +{ + int i; + + for (i = 0; i < p1; i++) + if ((p4[i].a & p2) != p2) + p4[i].a ^= (1ULL << p3); +}