]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
i386.c (ix86_expand_branch): Don't split DI mode xor instruction to SI mode.
authorIlya Enkovich <enkovich.gnu@gmail.com>
Fri, 15 Jan 2016 11:04:25 +0000 (11:04 +0000)
committerIlya Enkovich <ienkovich@gcc.gnu.org>
Fri, 15 Jan 2016 11:04:25 +0000 (11:04 +0000)
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
gcc/config/i386/i386.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/pr65105-5.c [new file with mode: 0644]

index ac14805ae7625efeffb87961e624893982beca49..bd052951e86b2b06923a1ccf8ded0401fd742451 100644 (file)
@@ -1,3 +1,8 @@
+2016-01-15  Ilya Enkovich  <enkovich.gnu@gmail.com>
+
+       * config/i386/i386.c (ix86_expand_branch): Don't split
+       DI mode xor instruction to SI mode.
+
 2016-01-15  Jan Hubicka  <hubicka@ucw.cz>
 
        PR ipa/68148
index 996913b17d71295485400a80e40a85562d01a2af..92f3a4130f09b99f077a84659bbbc3c6fb3ba48b 100644 (file)
@@ -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.  */
       {
index d949b8350344bd5baa282bd5079cbd1875a9fe38..456edf205c711cec0a5195c289f7d74398772618 100644 (file)
@@ -1,3 +1,7 @@
+2016-01-15  Ilya Enkovich  <enkovich.gnu@gmail.com>
+
+       * gcc.target/i386/pr65105-5.c: New test.
+
 2016-01-15  Jan Hubicka <hubicka@ucw.cz>
 
        * 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 (file)
index 0000000..5818c1c
--- /dev/null
@@ -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);
+}