From: ienkovich Date: Fri, 15 Jan 2016 11:04:25 +0000 (+0000) Subject: gcc/ X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=6271bd93bf201cf83b48ad349f06919e87da54fd;p=thirdparty%2Fgcc.git 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@232413 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ac14805ae762..bd052951e86b 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 996913b17d71..92f3a4130f09 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 d949b8350344..456edf205c71 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 000000000000..5818c1c0bac8 --- /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); +}