[i386] : Use gen_{add2,sub3,extend}_insn some more

Message ID CAFULd4ZXu-Bf3-BbBh9MUsAfEpPbYf-061Mw_o4929b8mC4mTQ@mail.gmail.com
State New
Headers show
Series
  • [i386] : Use gen_{add2,sub3,extend}_insn some more
Related show

Commit Message

Uros Bizjak June 13, 2019, 9:36 p.m.
Attached patch converts a bunch of indirect function calls to use
generic gen_{add2,sub3,extend}_insn functions. The patch corrects
and<mode>3 expander, which generated invalid RTX (non-existent
QI/HImode->DImode extend instructions for 32bit STV targets), so fake
insn-and-split patterns were necessary. The new approach is to leave
DImode and instructions up to STV pass, and split them just before
register allocation to zero-extends.

2019-06-13  UroŇ° Bizjak  <ubizjak@gmail.com>

    * config/i386/i386.md (SWIM1248s): Rename from SWIM1248x.
    Update all uses.
    (and<mode>3): Use gen_extend_insn instead of indirect functions.
    Do not generate DImode extends for 32bit targets.
    (and->zext post-reload splitter): Use gen_extend_insn
    instead of indirect functions.
    (anddi->zext pre-reload splitter): New.
    (*zext<mode>_doubleword_and): Remove.
    (*zext<mode>_doubleword): Ditto.
    (*zextsi_doubleword): Dittto.

2019-06-13  UroŇ° Bizjak  <ubizjak@gmail.com>

    * config/i386/i386-expand.c (ix86_expand_int_sse_cmp):
    Use gen_sub3_insn instead of indirect function.
    (ix86_expand_ashl_const): Use gen_add2_insn instead of
    indirect function.
    (ix86_adjust_counter): Ditto.

Patch was bootstrapped and regression tested on x86_64-linux-gnu {,-m32}.

Committed to mainline SVN.

Uros.

Patch

diff --git a/gcc/config/i386/i386-expand.c b/gcc/config/i386/i386-expand.c
index 0585c7d08bd0..770106162fb0 100644
--- a/gcc/config/i386/i386-expand.c
+++ b/gcc/config/i386/i386-expand.c
@@ -4303,27 +4303,15 @@  ix86_expand_int_sse_cmp (rtx dest, enum rtx_code code, rtx cop0, rtx cop1,
 	    case E_V2DImode:
 		{
 		  rtx t1, t2, mask;
-		  rtx (*gen_sub3) (rtx, rtx, rtx);
 
-		  switch (mode)
-		    {
-		    case E_V16SImode: gen_sub3 = gen_subv16si3; break;
-		    case E_V8DImode: gen_sub3 = gen_subv8di3; break;
-		    case E_V8SImode: gen_sub3 = gen_subv8si3; break;
-		    case E_V4DImode: gen_sub3 = gen_subv4di3; break;
-		    case E_V4SImode: gen_sub3 = gen_subv4si3; break;
-		    case E_V2DImode: gen_sub3 = gen_subv2di3; break;
-		    default:
-		      gcc_unreachable ();
-		    }
 		  /* Subtract (-(INT MAX) - 1) from both operands to make
 		     them signed.  */
 		  mask = ix86_build_signbit_mask (mode, true, false);
 		  t1 = gen_reg_rtx (mode);
-		  emit_insn (gen_sub3 (t1, cop0, mask));
+		  emit_insn (gen_sub3_insn (t1, cop0, mask));
 
 		  t2 = gen_reg_rtx (mode);
-		  emit_insn (gen_sub3 (t2, cop1, mask));
+		  emit_insn (gen_sub3_insn (t2, cop1, mask));
 
 		  cop0 = t1;
 		  cop1 = t2;
@@ -4339,9 +4327,8 @@  ix86_expand_int_sse_cmp (rtx dest, enum rtx_code code, rtx cop0, rtx cop1,
 	    case E_V8HImode:
 	      /* Perform a parallel unsigned saturating subtraction.  */
 	      x = gen_reg_rtx (mode);
-	      emit_insn (gen_rtx_SET (x, gen_rtx_US_MINUS (mode, cop0,
-							   cop1)));
-
+	      emit_insn (gen_rtx_SET
+			 (x, gen_rtx_US_MINUS (mode, cop0, cop1)));
 	      cop0 = x;
 	      cop1 = CONST0_RTX (mode);
 	      code = EQ;
@@ -5562,18 +5549,17 @@  ix86_split_long_move (rtx operands[])
 static void
 ix86_expand_ashl_const (rtx operand, int count, machine_mode mode)
 {
-  rtx (*insn)(rtx, rtx, rtx);
-
   if (count == 1
       || (count * ix86_cost->add <= ix86_cost->shift_const
 	  && !optimize_insn_for_size_p ()))
     {
-      insn = mode == DImode ? gen_addsi3 : gen_adddi3;
       while (count-- > 0)
-	emit_insn (insn (operand, operand, operand));
+	emit_insn (gen_add2_insn (operand, operand));
     }
   else
     {
+      rtx (*insn)(rtx, rtx, rtx);
+
       insn = mode == DImode ? gen_ashlsi3 : gen_ashldi3;
       emit_insn (insn (operand, operand, GEN_INT (count)));
     }
@@ -6506,10 +6492,7 @@  expand_setmem_epilogue (rtx destmem, rtx destptr, rtx value, rtx vec_value,
 static void
 ix86_adjust_counter (rtx countreg, HOST_WIDE_INT value)
 {
-  rtx (*gen_add)(rtx, rtx, rtx)
-    = GET_MODE (countreg) == DImode ? gen_adddi3 : gen_addsi3;
-
-  emit_insn (gen_add (countreg, countreg, GEN_INT (-value)));
+  emit_insn (gen_add2_insn (countreg, GEN_INT (-value)));
 }
 
 /* Depending on ISSETMEM, copy enough from SRCMEM to DESTMEM or set enough to
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 01338e294ab4..b484caebc453 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -1018,10 +1018,11 @@ 
 			       (HI "TARGET_HIMODE_MATH")
 			       SI])
 
-;; Math-dependant integer modes with DImode.
-(define_mode_iterator SWIM1248x [(QI "TARGET_QIMODE_MATH")
-				 (HI "TARGET_HIMODE_MATH")
-				 SI (DI "(TARGET_STV && TARGET_SSE2) || TARGET_64BIT")])
+;; Math-dependant integer modes with DImode (enabled for 32bit with STV).
+(define_mode_iterator SWIM1248s
+	[(QI "TARGET_QIMODE_MATH")
+	 (HI "TARGET_HIMODE_MATH")
+	 SI (DI "TARGET_64BIT || (TARGET_STV && TARGET_SSE2)")])
 
 ;; Math-dependant single word integer modes without QImode.
 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
@@ -4076,45 +4077,6 @@ 
   [(set_attr "isa" "*,avx512dq,avx512dq")
    (set_attr "type" "imovx,mskmov,mskmov")
    (set_attr "mode" "SI,QI,QI")])
-
-(define_insn_and_split "*zext<mode>_doubleword_and"
-  [(set (match_operand:DI 0 "register_operand" "=&<r>")
-	(zero_extend:DI (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
-  "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
-   && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
-  "#"
-  "&& reload_completed && GENERAL_REG_P (operands[0])"
-  [(set (match_dup 2) (const_int 0))]
-{
-  split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);
-
-  emit_move_insn (operands[0], const0_rtx);
-
-  gcc_assert (!TARGET_PARTIAL_REG_STALL);
-  emit_insn (gen_movstrict<mode>
-	     (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
-})
-
-(define_insn_and_split "*zext<mode>_doubleword"
-  [(set (match_operand:DI 0 "register_operand" "=r")
-	(zero_extend:DI (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
-  "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
-   && !(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
-  "#"
-  "&& reload_completed && GENERAL_REG_P (operands[0])"
-  [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
-   (set (match_dup 2) (const_int 0))]
-  "split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);")
-
-(define_insn_and_split "*zextsi_doubleword"
-  [(set (match_operand:DI 0 "register_operand" "=r")
-	(zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
-  "!TARGET_64BIT && TARGET_STV && TARGET_SSE2"
-  "#"
-  "&& reload_completed && GENERAL_REG_P (operands[0])"
-  [(set (match_dup 0) (match_dup 1))
-   (set (match_dup 2) (const_int 0))]
-  "split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);")
 
 ;; Sign extension instructions
 
@@ -8394,48 +8356,34 @@ 
 ;; it should be done with splitters.
 
 (define_expand "and<mode>3"
-  [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
-	(and:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")
-		      (match_operand:SWIM1248x 2 "<general_szext_operand>")))]
+  [(set (match_operand:SWIM1248s 0 "nonimmediate_operand")
+	(and:SWIM1248s (match_operand:SWIM1248s 1 "nonimmediate_operand")
+		       (match_operand:SWIM1248s 2 "<general_szext_operand>")))]
   ""
 {
   machine_mode mode = <MODE>mode;
-  rtx (*insn) (rtx, rtx);
 
-  if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
+  if (<MODE>mode == DImode && !TARGET_64BIT)
+    ;
+  else if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
     {
-      HOST_WIDE_INT ival = INTVAL (operands[2]);
+      unsigned HOST_WIDE_INT ival = UINTVAL (operands[2]);
 
-      if (ival == (HOST_WIDE_INT) 0xffffffff)
+      if (ival == GET_MODE_MASK (SImode))
 	mode = SImode;
-      else if (ival == 0xffff)
+      else if (ival == GET_MODE_MASK (HImode))
 	mode = HImode;
-      else if (ival == 0xff)
+      else if (ival == GET_MODE_MASK (QImode))
 	mode = QImode;
-      }
-
-  if (mode == <MODE>mode)
-    {
-      ix86_expand_binary_operator (AND, <MODE>mode, operands);
-      DONE;
     }
 
-  if (<MODE>mode == DImode)
-    insn = (mode == SImode)
-	   ? gen_zero_extendsidi2
-	   : (mode == HImode)
-	   ? gen_zero_extendhidi2
-	   : gen_zero_extendqidi2;
-  else if (<MODE>mode == SImode)
-    insn = (mode == HImode)
-	   ? gen_zero_extendhisi2
-	   : gen_zero_extendqisi2;
-  else if (<MODE>mode == HImode)
-    insn = gen_zero_extendqihi2;
+  if (mode != <MODE>mode)
+    emit_insn (gen_extend_insn
+	       (operands[0], gen_lowpart (mode, operands[1]),
+		<MODE>mode, mode, 1));
   else
-    gcc_unreachable ();
+    ix86_expand_binary_operator (AND, <MODE>mode, operands);
 
-  emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
   DONE;
 })
 
@@ -8471,6 +8419,40 @@ 
   DONE;
 })
 
+(define_split
+  [(set (match_operand:DI 0 "register_operand")
+	(and:DI
+	 (match_operand:DI 1 "nonimmediate_operand")
+	 (match_operand:DI 2 "const_int_operand")))
+   (clobber (reg:CC FLAGS_REG))]
+  "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
+   && can_create_pseudo_p ()"
+  [(const_int 0)]
+{
+  unsigned HOST_WIDE_INT ival = UINTVAL (operands[2]);
+  machine_mode mode;
+
+  if (ival == GET_MODE_MASK (SImode))
+    mode = SImode;
+  else if (ival == GET_MODE_MASK (HImode))
+    mode = HImode;
+  else if (ival == GET_MODE_MASK (QImode))
+    mode = QImode;
+  else
+    FAIL;
+
+  split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
+
+  if (mode == SImode)
+    emit_move_insn (operands[0], operands[1]);
+  else
+    emit_insn (gen_extend_insn
+	       (operands[0], gen_lowpart (mode, operands[1]),
+		SImode, mode, 1));
+  emit_move_insn (operands[3], const0_rtx);
+  DONE;
+})
+
 (define_insn "*anddi_1"
   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
 	(and:DI
@@ -8617,37 +8599,25 @@ 
        || REGNO (operands[0]) != REGNO (operands[1]))"
   [(const_int 0)]
 {
-  HOST_WIDE_INT ival = INTVAL (operands[2]);
+  unsigned HOST_WIDE_INT ival = UINTVAL (operands[2]);
   machine_mode mode;
-  rtx (*insn) (rtx, rtx);
 
-  if (ival == (HOST_WIDE_INT) 0xffffffff)
+  if (ival == GET_MODE_MASK (SImode))
     mode = SImode;
-  else if (ival == 0xffff)
+  else if (ival == GET_MODE_MASK (HImode))
     mode = HImode;
+  else if (ival == GET_MODE_MASK (QImode))
+    mode = QImode;
   else
-    {
-      gcc_assert (ival == 0xff);
-      mode = QImode;
-    }
+    gcc_unreachable ();
 
-  if (<MODE>mode == DImode)
-    insn = (mode == SImode)
-	   ? gen_zero_extendsidi2
-	   : (mode == HImode)
-	   ? gen_zero_extendhidi2
-	   : gen_zero_extendqidi2;
-  else
-    {
-      if (<MODE>mode != SImode)
-	/* Zero extend to SImode to avoid partial register stalls.  */
-	operands[0] = gen_lowpart (SImode, operands[0]);
+  /* Zero extend to SImode to avoid partial register stalls.  */
+  if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
+    operands[0] = gen_lowpart (SImode, operands[0]);
 
-      insn = (mode == HImode)
-	     ? gen_zero_extendhisi2
-	     : gen_zero_extendqisi2;
-    }
-  emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
+  emit_insn (gen_extend_insn
+	     (operands[0], gen_lowpart (mode, operands[1]),
+	      GET_MODE (operands[0]), mode, 1));
   DONE;
 })
 
@@ -9003,9 +8973,9 @@ 
 ;; If this is considered useful, it should be done with splitters.
 
 (define_expand "<code><mode>3"
-  [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
-	(any_or:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")
-			     (match_operand:SWIM1248x 2 "<general_operand>")))]
+  [(set (match_operand:SWIM1248s 0 "nonimmediate_operand")
+	(any_or:SWIM1248s (match_operand:SWIM1248s 1 "nonimmediate_operand")
+			  (match_operand:SWIM1248s 2 "<general_operand>")))]
   ""
   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
 
@@ -9697,8 +9667,8 @@ 
 ;; One complement instructions
 
 (define_expand "one_cmpl<mode>2"
-  [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
-	(not:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")))]
+  [(set (match_operand:SWIM1248s 0 "nonimmediate_operand")
+	(not:SWIM1248s (match_operand:SWIM1248s 1 "nonimmediate_operand")))]
   ""
   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")