re PR target/70322 (STV doesn't optimize andn)
authorJakub Jelinek <jakub@redhat.com>
Fri, 2 Dec 2016 16:28:41 +0000 (17:28 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Fri, 2 Dec 2016 16:28:41 +0000 (17:28 +0100)
PR target/70322
* config/i386/i386.c (dimode_scalar_to_vector_candidate_p): Handle
NOT.
(dimode_scalar_chain::compute_convert_gain): Likewise.
(dimode_scalar_chain::convert_insn): Likewise.
* config/i386/i386.md (*one_cmpldi2_doubleword): New
define_insn_and_split.
(one_cmpl<mode>2): Use SWIM1248x iterator instead of SWIM.

* gcc.target/i386/pr70322-1.c: New test.
* gcc.target/i386/pr70322-2.c: New test.
* gcc.target/i386/pr70322-3.c: New test.

From-SVN: r243195

gcc/ChangeLog
gcc/config/i386/i386.c
gcc/config/i386/i386.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/pr70322-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr70322-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr70322-3.c [new file with mode: 0644]

index 68d3588715b91c8ec0e26d9344cbd19c1ca8892b..33fd2ebee06a5d7410650d4879e7178d93a93c7e 100644 (file)
@@ -1,5 +1,14 @@
 2016-12-02  Jakub Jelinek  <jakub@redhat.com>
 
+       PR target/70322
+       * config/i386/i386.c (dimode_scalar_to_vector_candidate_p): Handle
+       NOT.
+       (dimode_scalar_chain::compute_convert_gain): Likewise.
+       (dimode_scalar_chain::convert_insn): Likewise.
+       * config/i386/i386.md (*one_cmpldi2_doubleword): New
+       define_insn_and_split.
+       (one_cmpl<mode>2): Use SWIM1248x iterator instead of SWIM.
+
        PR target/78614
        * rtl.c (copy_rtx): Don't clear used flag here.
        (shallow_copy_rtx_stat): Clear used flag here unless code the rtx
index 5678fa2ba857ae810d97b97a6bdf22b0e7273e9d..0bee09b2c60d5bb8042dfe268345a7771343551d 100644 (file)
@@ -2826,6 +2826,9 @@ dimode_scalar_to_vector_candidate_p (rtx_insn *insn)
        return false;
       break;
 
+    case NOT:
+      break;
+
     case REG:
       return true;
 
@@ -2848,7 +2851,8 @@ dimode_scalar_to_vector_candidate_p (rtx_insn *insn)
 
   if ((GET_MODE (XEXP (src, 0)) != DImode
        && !CONST_INT_P (XEXP (src, 0)))
-      || (GET_MODE (XEXP (src, 1)) != DImode
+      || (GET_CODE (src) != NOT
+         && GET_MODE (XEXP (src, 1)) != DImode
          && !CONST_INT_P (XEXP (src, 1))))
     return false;
 
@@ -3415,6 +3419,8 @@ dimode_scalar_chain::compute_convert_gain ()
          if (CONST_INT_P (XEXP (src, 1)))
            gain -= vector_const_cost (XEXP (src, 1));
        }
+      else if (GET_CODE (src) == NOT)
+       gain += ix86_cost->add - COSTS_N_INSNS (1);
       else if (GET_CODE (src) == COMPARE)
        {
          /* Assume comparison cost is the same.  */
@@ -3770,6 +3776,14 @@ dimode_scalar_chain::convert_insn (rtx_insn *insn)
       PUT_MODE (src, V2DImode);
       break;
 
+    case NOT:
+      src = XEXP (src, 0);
+      convert_op (&src, insn);
+      subreg = gen_reg_rtx (V2DImode);
+      emit_insn_before (gen_move_insn (subreg, CONSTM1_RTX (V2DImode)), insn);
+      src = gen_rtx_XOR (V2DImode, src, subreg);
+      break;
+
     case MEM:
       if (!REG_P (dst))
        convert_op (&src, insn);
index 583d2bb6ea50e2866c679e7b740f015a894548ca..da7cb07a0ef6349842df2c4ae99dc9179667d714 100644 (file)
 \f
 ;; One complement instructions
 
+(define_insn_and_split "*one_cmpldi2_doubleword"
+  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
+       (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
+  "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
+   && ix86_unary_operator_ok (NOT, DImode, operands)"
+  "#"
+  "&& reload_completed"
+  [(set (match_dup 0)
+       (not:SI (match_dup 1)))
+   (set (match_dup 2)
+       (not:SI (match_dup 3)))]
+  "split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);")
+
 (define_expand "one_cmpl<mode>2"
-  [(set (match_operand:SWIM 0 "nonimmediate_operand")
-       (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
+  [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
+       (not:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")))]
   ""
   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
 
index 7cb66d99693bea49787f5bcd67467274b6a42ba3..3a478b9abed15c62f757a4ef5f2b2f197783c3ea 100644 (file)
@@ -1,3 +1,10 @@
+2016-12-02  Jakub Jelinek  <jakub@redhat.com>
+
+       PR target/70322
+       * gcc.target/i386/pr70322-1.c: New test.
+       * gcc.target/i386/pr70322-2.c: New test.
+       * gcc.target/i386/pr70322-3.c: New test.
+
 2016-12-02  Andre Vieira  <andre.simoesdiasvieira@arm.com>
            Thomas Preud'homme  <thomas.preudhomme@arm.com>
 
diff --git a/gcc/testsuite/gcc.target/i386/pr70322-1.c b/gcc/testsuite/gcc.target/i386/pr70322-1.c
new file mode 100644 (file)
index 0000000..bc10675
--- /dev/null
@@ -0,0 +1,12 @@
+/* PR target/70322 */
+/* { dg-do compile { target ia32 } } */
+/* { dg-options "-O2 -msse2 -mstv -mbmi" } */
+/* { dg-final { scan-assembler "pandn" } } */
+
+extern long long z;
+
+void
+foo (long long x, long long y)
+{
+  z = ~x & y;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr70322-2.c b/gcc/testsuite/gcc.target/i386/pr70322-2.c
new file mode 100644 (file)
index 0000000..7c5d0be
--- /dev/null
@@ -0,0 +1,12 @@
+/* PR target/70322 */
+/* { dg-do compile { target ia32 } } */
+/* { dg-options "-O2 -msse2 -mstv -mno-bmi" } */
+/* { dg-final { scan-assembler "pandn" { xfail *-*-* } } } */
+
+extern long long z;
+
+void
+foo (long long x, long long y)
+{
+  z = ~x & y;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr70322-3.c b/gcc/testsuite/gcc.target/i386/pr70322-3.c
new file mode 100644 (file)
index 0000000..89a8da3
--- /dev/null
@@ -0,0 +1,13 @@
+/* PR target/70322 */
+/* { dg-do compile { target ia32 } } */
+/* { dg-options "-O2 -msse2 -mstv" } */
+/* { dg-final { scan-assembler "pxor" } } */
+/* { dg-final { scan-assembler "por" } } */
+
+extern long long z;
+
+void
+foo (long long x, long long y)
+{
+  z = ~x | y;
+}