diff mbox

Handle andn and ~ in 32-bit stv pass (PR target/70322)

Message ID 20161202163055.GA3541@tucnak.redhat.com
State New
Headers show

Commit Message

Jakub Jelinek Dec. 2, 2016, 4:30 p.m. UTC
On Fri, Dec 02, 2016 at 05:12:20PM +0100, Uros Bizjak wrote:
> >> This patch:
> >> 1) adds one_cmpldi2 pattern for stv purposes (which splits into two
> >>    one_cmplsi2 after reload)
> >> 2) teaches the 32-bit stv pass to handle NOT (as xor all-ones)
> >> 3) renames the old *andndi3_doubleword to *andndi3_doubleword_bmi, as it
> >>    is for -mbmi only, and adds another *andndi3_doubleword pattern that is
> >>    meant to live just from combine till the stv pass, or worse case till
> >>    following split1 pass when it is split back into not followed by and;
> >>    this change makes it possible to use pandn in stv pass, even without
> >>    -mbmi
> >
> > Please use attached (lightly tested) patch to implement point 3)
> > above. The patch splits insn after reload, as is the case with all STV
> > patterns.
> 
> Now attached for real.

Ok, I've checked in following patch (compared to your notes just added
xfail to the pr70322-2.c test scan-assembler), feel free to test your patch
and remove the xfail again.

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.

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



	Jakub
diff mbox

Patch

--- gcc/config/i386/i386.c.jj	2016-12-02 11:17:40.702995111 +0100
+++ gcc/config/i386/i386.c	2016-12-02 12:01:31.656469089 +0100
@@ -2826,6 +2826,9 @@  dimode_scalar_to_vector_candidate_p (rtx
 	return false;
       break;
 
+    case NOT:
+      break;
+
     case REG:
       return true;
 
@@ -2848,7 +2851,8 @@  dimode_scalar_to_vector_candidate_p (rtx
 
   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_gai
 	  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_i
       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);
--- gcc/config/i386/i386.md.jj	2016-12-01 23:24:51.663157486 +0100
+++ gcc/config/i386/i386.md	2016-12-02 12:50:27.616829191 +0100
@@ -9312,9 +9312,22 @@ 
 
 ;; 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;")
 
--- gcc/testsuite/gcc.target/i386/pr70322-1.c.jj	2016-12-02 12:52:47.193051745 +0100
+++ gcc/testsuite/gcc.target/i386/pr70322-1.c	2016-12-02 12:52:24.708338078 +0100
@@ -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;
+}
--- gcc/testsuite/gcc.target/i386/pr70322-2.c.jj	2016-12-02 12:52:50.165013898 +0100
+++ gcc/testsuite/gcc.target/i386/pr70322-2.c	2016-12-02 12:52:39.302152232 +0100
@@ -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;
+}
--- gcc/testsuite/gcc.target/i386/pr70322-3.c.jj	2016-12-02 13:07:27.658796578 +0100
+++ gcc/testsuite/gcc.target/i386/pr70322-3.c	2016-12-02 13:08:11.899229225 +0100
@@ -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;
+}