diff mbox series

[i386] : Rewrite float_truncate patterns

Message ID CAFULd4bCn9cQHQ4YLTpEJQPQ3MK1aXjFJ1op561vNgQ-wBh4xA@mail.gmail.com
State New
Headers show
Series [i386] : Rewrite float_truncate patterns | expand

Commit Message

Uros Bizjak Sept. 5, 2018, 6:09 p.m. UTC
Hello!

IRA is able to generate temporary output memory location by itself, so
there is no need to manually provide one in the pattern. Based on this
functionality, attached patch rewrites float_truncate patterns in a
much simpler and elegant way. It also introduces "enabled" attribute
that handles TARGET_MIX_SSE_I387 and flag_unsafe_math_optimizations
flags in insn patterns.

2018-09-05  Uros Bizjak  <ubizjak@gmail.com>

    * config/i386/i386.md (truncdfsf2): Remove expander.
    (truncdfsf2_with_temp): Ditto.
    (truncxf<mode>2): Ditto.
    (*truncdfsf_fast_mixed): Remove insn pattern.
    (*truncdfsf_fast_i387): Ditto.
    (*truncdfsf_mixed): Ditto.
    (*truncdfsf_i387): Ditto.
    (*truncdfsf2_i387_1): Ditto.
    (*truncxfsf2_mixed): Ditto.
    (*truncxfdf2_mixed): Ditto.
    (*truncxf<mode>2_i387_noop): Ditto. Update callers
    to call gen_truncxf<mode>2 instead.
    (*truncxf<mode>2_i387): Remove.
    (reg->reg splitters): Remove splitter pattern.
    (reg->mem splitters): Ditto.

    (truncdfsf2): New insn pattern.
    (truncxf<mode>2): Ditto.

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

Committed to mainline SVN.

Uros.
diff mbox series

Patch

diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 62dab1662a38..aa904c24cd40 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -4615,23 +4615,43 @@ 
 
 ;; Conversion from DFmode to SFmode.
 
-(define_expand "truncdfsf2"
-  [(set (match_operand:SF 0 "nonimmediate_operand")
+(define_insn "truncdfsf2"
+  [(set (match_operand:SF 0 "nonimm_ssenomem_operand" "=m,f,v")
 	(float_truncate:SF
-	  (match_operand:DF 1 "nonimmediate_operand")))]
+	  (match_operand:DF 1 "register_ssemem_operand" "f,f,vm")))]
   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
 {
-  if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
-    ;
-  else if (flag_unsafe_math_optimizations)
-    ;
-  else
+  switch (which_alternative)
     {
-      rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
-      emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
-      DONE;
+    case 0:
+    case 1:
+      return output_387_reg_move (insn, operands);
+
+    case 2:
+      return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
+
+    default:
+      gcc_unreachable ();
     }
-})
+}
+  [(set_attr "type" "fmov,fmov,ssecvt")
+   (set_attr "mode" "SF")
+   (set (attr "enabled")
+     (if_then_else
+       (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
+       (cond [(eq_attr "alternative" "0")
+		(symbol_ref "TARGET_MIX_SSE_I387")
+	      (eq_attr "alternative" "1")
+		(symbol_ref "TARGET_MIX_SSE_I387
+			     && flag_unsafe_math_optimizations")
+	   ]
+	   (symbol_ref "true"))
+       (cond [(eq_attr "alternative" "0")
+		(symbol_ref "true")
+	      (eq_attr "alternative" "1")
+		(symbol_ref "flag_unsafe_math_optimizations")
+	   ]
+	   (symbol_ref "false"))))])
 
 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
    cvtsd2ss:
@@ -4642,7 +4662,7 @@ 
    anyway.  */
 (define_split
   [(set (match_operand:SF 0 "sse_reg_operand")
-        (float_truncate:SF
+	(float_truncate:SF
 	  (match_operand:DF 1 "nonimmediate_operand")))]
   "TARGET_USE_VECTOR_FP_CONVERTS
    && optimize_insn_for_speed_p ()
@@ -4679,7 +4699,7 @@ 
 				   CONST0_RTX (DFmode)));
 })
 
-;; It's more profitable to split and then extend in the same register.
+;; It's more profitable to split and then truncate in the same register.
 (define_peephole2
   [(set (match_operand:SF 0 "sse_reg_operand")
 	(float_truncate:SF
@@ -4690,197 +4710,21 @@ 
    (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
   "operands[2] = lowpart_subreg (DFmode, operands[0], SFmode);")
 
-(define_expand "truncdfsf2_with_temp"
-  [(parallel [(set (match_operand:SF 0)
-		   (float_truncate:SF (match_operand:DF 1)))
-	      (clobber (match_operand:SF 2))])])
-
-;; SSE alternative doesn't depend on flag_unsafe_math_optimizations,
-;; because nothing we do there is unsafe.
-(define_insn "*truncdfsf_fast_mixed"
-  [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,v")
-        (float_truncate:SF
-          (match_operand:DF 1 "nonimmediate_operand" "f  ,vm")))]
-  "TARGET_SSE2 && TARGET_SSE_MATH"
-{
-  switch (which_alternative)
-    {
-    case 0:
-      return output_387_reg_move (insn, operands);
-    case 1:
-      return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
-    default:
-      gcc_unreachable ();
-    }
-}
-  [(set_attr "type" "fmov,ssecvt")
-   (set_attr "prefix" "orig,maybe_vex")
-   (set_attr "mode" "SF")
-   (set (attr "enabled")
-     (cond [(eq_attr "alternative" "0")
-              (symbol_ref "TARGET_MIX_SSE_I387
-			   && flag_unsafe_math_optimizations")
-	   ]
-           (symbol_ref "true")))])
-
-(define_insn "*truncdfsf_fast_i387"
-  [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
-        (float_truncate:SF
-          (match_operand:DF 1 "nonimmediate_operand" "f")))]
-  "TARGET_80387 && flag_unsafe_math_optimizations"
-  "* return output_387_reg_move (insn, operands);"
-  [(set_attr "type" "fmov")
-   (set_attr "mode" "SF")])
-
-(define_insn "*truncdfsf_mixed"
-  [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,v ,?f,?v,?*r")
-	(float_truncate:SF
-	  (match_operand:DF 1 "nonimmediate_operand" "f ,vm,f ,f ,f")))
-   (clobber (match_operand:SF 2 "memory_operand"     "=X,X ,m ,m ,m"))]
-  "TARGET_MIX_SSE_I387"
-{
-  switch (which_alternative)
-    {
-    case 0:
-      return output_387_reg_move (insn, operands);
-    case 1:
-      return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
-
-    default:
-      return "#";
-    }
-}
-  [(set_attr "isa" "*,sse2,*,*,*")
-   (set_attr "type" "fmov,ssecvt,multi,multi,multi")
-   (set_attr "unit" "*,*,i387,i387,i387")
-   (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
-   (set_attr "mode" "SF")])
-
-(define_insn "*truncdfsf_i387"
-  [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?v,?*r")
-	(float_truncate:SF
-	  (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
-   (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
-  "TARGET_80387"
-{
-  switch (which_alternative)
-    {
-    case 0:
-      return output_387_reg_move (insn, operands);
-
-    default:
-      return "#";
-    }
-}
-  [(set_attr "type" "fmov,multi,multi,multi")
-   (set_attr "unit" "*,i387,i387,i387")
-   (set_attr "mode" "SF")])
-
-(define_insn "*truncdfsf2_i387_1"
-  [(set (match_operand:SF 0 "memory_operand" "=m")
-	(float_truncate:SF
-	  (match_operand:DF 1 "register_operand" "f")))]
-  "TARGET_80387
-   && !(TARGET_SSE2 && TARGET_SSE_MATH)
-   && !TARGET_MIX_SSE_I387"
-  "* return output_387_reg_move (insn, operands);"
-  [(set_attr "type" "fmov")
-   (set_attr "mode" "SF")])
-
-(define_split
-  [(set (match_operand:SF 0 "register_operand")
-	(float_truncate:SF
-	 (match_operand:DF 1 "fp_register_operand")))
-   (clobber (match_operand 2))]
-  "reload_completed"
-  [(set (match_dup 2) (match_dup 1))
-   (set (match_dup 0) (match_dup 2))]
-  "operands[1] = gen_rtx_REG (SFmode, REGNO (operands[1]));")
-
 ;; Conversion from XFmode to {SF,DF}mode
 
-(define_expand "truncxf<mode>2"
-  [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
-		   (float_truncate:MODEF
-		     (match_operand:XF 1 "register_operand")))
-	      (clobber (match_dup 2))])]
-  "TARGET_80387"
-{
-  if (flag_unsafe_math_optimizations)
-    {
-      rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
-      emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
-      if (reg != operands[0])
-	emit_move_insn (operands[0], reg);
-      DONE;
-    }
-  else
-    operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
-})
-
-(define_insn "*truncxfsf2_mixed"
-  [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?v,?*r")
-	(float_truncate:SF
-	  (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
-   (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
-  "TARGET_80387"
-{
-  gcc_assert (!which_alternative);
-  return output_387_reg_move (insn, operands);
-}
-  [(set_attr "type" "fmov,multi,multi,multi")
-   (set_attr "unit" "*,i387,i387,i387")
-   (set_attr "mode" "SF")])
-
-(define_insn "*truncxfdf2_mixed"
-  [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?v,?*r")
-	(float_truncate:DF
-	  (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
-   (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
-  "TARGET_80387"
-{
-  gcc_assert (!which_alternative);
-  return output_387_reg_move (insn, operands);
-}
-  [(set_attr "isa" "*,*,sse2,*")
-   (set_attr "type" "fmov,multi,multi,multi")
-   (set_attr "unit" "*,i387,i387,i387")
-   (set_attr "mode" "DF")])
-
-(define_insn "truncxf<mode>2_i387_noop"
-  [(set (match_operand:MODEF 0 "register_operand" "=f")
-	(float_truncate:MODEF
-	  (match_operand:XF 1 "register_operand" "f")))]
-  "TARGET_80387 && flag_unsafe_math_optimizations"
-  "* return output_387_reg_move (insn, operands);"
-  [(set_attr "type" "fmov")
-   (set_attr "mode" "<MODE>")])
-
-(define_insn "*truncxf<mode>2_i387"
-  [(set (match_operand:MODEF 0 "memory_operand" "=m")
+(define_insn "truncxf<mode>2"
+  [(set (match_operand:MODEF 0 "nonimmediate_operand" "=m,f")
 	(float_truncate:MODEF
-	  (match_operand:XF 1 "register_operand" "f")))]
+	  (match_operand:XF 1 "register_operand" "f,f")))]
   "TARGET_80387"
   "* return output_387_reg_move (insn, operands);"
   [(set_attr "type" "fmov")
-   (set_attr "mode" "<MODE>")])
-
-(define_split
-  [(set (match_operand:MODEF 0 "register_operand")
-	(float_truncate:MODEF
-	  (match_operand:XF 1 "register_operand")))
-   (clobber (match_operand:MODEF 2 "memory_operand"))]
-  "TARGET_80387 && reload_completed"
-  [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
-   (set (match_dup 0) (match_dup 2))])
-
-(define_split
-  [(set (match_operand:MODEF 0 "memory_operand")
-	(float_truncate:MODEF
-	  (match_operand:XF 1 "register_operand")))
-   (clobber (match_operand:MODEF 2 "memory_operand"))]
-  "TARGET_80387"
-  [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
+   (set_attr "mode" "<MODE>")
+   (set (attr "enabled")
+     (cond [(eq_attr "alternative" "1")
+	      (symbol_ref "flag_unsafe_math_optimizations")
+	   ]
+	   (symbol_ref "true")))])
 
 ;; Signed conversion to DImode.
 
@@ -15810,8 +15654,8 @@ 
   rtx op1 = gen_reg_rtx (XFmode);
 
   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
-  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
-  emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
+  emit_insn (gen_truncxf<mode>2 (operands[0], op0));
+  emit_insn (gen_truncxf<mode>2 (operands[1], op1));
   DONE;
 })
 
@@ -15874,7 +15718,7 @@ 
 
   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
 					     operands[1], op2));
-  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
+  emit_insn (gen_truncxf<mode>2 (operands[0], op0));
   DONE;
 })
 
@@ -15929,7 +15773,7 @@ 
   rtx op0 = gen_reg_rtx (XFmode);
 
   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
-  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
+  emit_insn (gen_truncxf<mode>2 (operands[0], op0));
   DONE;
 })
 
@@ -15960,7 +15804,7 @@ 
   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
 
   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
-  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
+  emit_insn (gen_truncxf<mode>2 (operands[0], op0));
   DONE;
 })
 
@@ -15998,7 +15842,7 @@ 
 
   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
   emit_insn (gen_asinxf2 (op0, op1));
-  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
+  emit_insn (gen_truncxf<mode>2 (operands[0], op0));
   DONE;
 })
 
@@ -16036,7 +15880,7 @@ 
 
   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
   emit_insn (gen_acosxf2 (op0, op1));
-  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
+  emit_insn (gen_truncxf<mode>2 (operands[0], op0));
   DONE;
 })
 
@@ -16095,7 +15939,7 @@ 
   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
 
   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
-  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
+  emit_insn (gen_truncxf<mode>2 (operands[0], op0));
   DONE;
 })
 
@@ -16125,7 +15969,7 @@ 
   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
 
   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
-  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
+  emit_insn (gen_truncxf<mode>2 (operands[0], op0));
   DONE;
 })
 
@@ -16155,7 +15999,7 @@ 
   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
 
   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
-  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
+  emit_insn (gen_truncxf<mode>2 (operands[0], op0));
   DONE;
 })
 
@@ -16213,7 +16057,7 @@ 
   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
 
   ix86_emit_i387_log1p (op0, operands[1]);
-  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
+  emit_insn (gen_truncxf<mode>2 (operands[0], op0));
   DONE;
 })
 
@@ -16268,7 +16112,7 @@ 
   rtx op1 = gen_reg_rtx (XFmode);
 
   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
-  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
+  emit_insn (gen_truncxf<mode>2 (operands[0], op1));
   DONE;
 })
 
@@ -16392,7 +16236,7 @@ 
 
   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
   emit_insn (gen_expxf2 (op0, op1));
-  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
+  emit_insn (gen_truncxf<mode>2 (operands[0], op0));
   DONE;
 })
 
@@ -16426,7 +16270,7 @@ 
 
   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
   emit_insn (gen_exp10xf2 (op0, op1));
-  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
+  emit_insn (gen_truncxf<mode>2 (operands[0], op0));
   DONE;
 })
 
@@ -16460,7 +16304,7 @@ 
 
   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
   emit_insn (gen_exp2xf2 (op0, op1));
-  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
+  emit_insn (gen_truncxf<mode>2 (operands[0], op0));
   DONE;
 })
 
@@ -16516,7 +16360,7 @@ 
 
   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
   emit_insn (gen_expm1xf2 (op0, op1));
-  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
+  emit_insn (gen_truncxf<mode>2 (operands[0], op0));
   DONE;
 })
 
@@ -16554,7 +16398,7 @@ 
 
   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
-  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
+  emit_insn (gen_truncxf<mode>2 (operands[0], op0));
   DONE;
 })
 
@@ -16590,7 +16434,7 @@ 
   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
   emit_insn (gen_scalbxf3 (op0, op1, op2));
-  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
+  emit_insn (gen_truncxf<mode>2 (operands[0], op0));
   DONE;
 })
 
@@ -16616,7 +16460,7 @@ 
   rtx op1 = gen_reg_rtx (XFmode);
 
   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
-  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
+  emit_insn (gen_truncxf<mode>2 (operands[0], op0));
   DONE;
 })
 
@@ -17053,7 +16897,7 @@ 
   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
 
-  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
+  emit_insn (gen_truncxf<mode>2 (operands[0], op0));
   DONE;
 })