[i386] : Some further movstrict cleanups

Message ID CAFULd4b0ZR3Ev7525PBJKT8_3eW5Q0X__ru3pFUmFz7cO1n6Ww@mail.gmail.com
State New
Headers show
Series
  • [i386] : Some further movstrict cleanups
Related show

Commit Message

Uros Bizjak July 29, 2019, 11 p.m.
Attached patch allows only SUBREGs as output operands to movstrict
expander and further allows only register operand outputs in various
corresponding splitters. This enforces the restriction, as documented
for STRICT_LOW_PART RTX:

     This expression code is used in only one context: as the
     destination operand of a 'set' expression.  In addition, the
     operand of this expression must be a non-paradoxical 'subreg'
     expression.

Additionally, the patch removes post-reload calls to movstrict
expander and consequently constructs RTXes involving STRICT_LOW_PART
with hard registers "by hand".

2019-07-30  UroŇ° Bizjak  <ubizjak@gmail.com>

    * config/i386/i386.md (movstrict<mode>): Use register_operand
    predicate for operand 0.  Add expander condition.  Assert that
    operand 0 is a SUBREG RTX.
    (*movstrict<mode>_1): Use register_operand predicate for operand 0.
    Update operand constraints and insn condition.
    (zero_extend<mode>si2_and): Do not call gen_movstrict<mode>.
    (zero_extendqihi2_and): Do not call gen_movstrictqi.
    (*setcc_qi_slp): Use register_operand predicate for operand 0.
    Update operand 0 constraints.
    (setcc_qi_slp splitters): Use register_operand predicate for operand 0.

Bootstrapped and regression tested on x86_64-linux-gnu {,-m32}.

Committed to mainline SVN.

Uros.

Patch

Index: config/i386/i386.md
===================================================================
--- config/i386/i386.md	(revision 273873)
+++ config/i386/i386.md	(working copy)
@@ -2786,26 +2786,20 @@ 
    (set_attr "bdver1_decode" "double")])
 
 (define_expand "movstrict<mode>"
-  [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
+  [(set (strict_low_part (match_operand:SWI12 0 "register_operand"))
 	(match_operand:SWI12 1 "general_operand"))]
-  ""
+  "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
 {
-  if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
+  gcc_assert (SUBREG_P (operands[0]));
+  if (GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
     FAIL;
-  if (SUBREG_P (operands[0])
-      && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
-    FAIL;
-  /* Don't generate memory->memory moves, go through a register */
-  if (MEM_P (operands[0]) && MEM_P (operands[1]))
-    operands[1] = force_reg (<MODE>mode, operands[1]);
 })
 
 (define_insn "*movstrict<mode>_1"
   [(set (strict_low_part
-	  (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
-	(match_operand:SWI12 1 "general_operand" "<r>n,m"))]
-  "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
-   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
+	  (match_operand:SWI12 0 "register_operand" "+<r>"))
+	(match_operand:SWI12 1 "general_operand" "<r>mn"))]
+  "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
   "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
   [(set_attr "type" "imov")
    (set_attr "mode" "<MODE>")])
@@ -4011,8 +4005,10 @@ 
       ix86_expand_clear (operands[0]);
 
       gcc_assert (!TARGET_PARTIAL_REG_STALL);
-      emit_insn (gen_movstrict<mode>
-		  (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
+      emit_insn (gen_rtx_SET
+      		 (gen_rtx_STRICT_LOW_PART
+		  (VOIDmode, gen_lowpart (<MODE>mode, operands[0])),
+		  operands[1]));
       DONE;
     }
 
@@ -4063,8 +4059,10 @@ 
       ix86_expand_clear (operands[0]);
 
       gcc_assert (!TARGET_PARTIAL_REG_STALL);
-      emit_insn (gen_movstrictqi
-		  (gen_lowpart (QImode, operands[0]), operands[1]));
+      emit_insn (gen_rtx_SET
+		 (gen_rtx_STRICT_LOW_PART
+		  (VOIDmode, gen_lowpart (QImode, operands[0])),
+		  operands[1]));
       DONE;
     }
 
@@ -11835,7 +11833,7 @@ 
    (set_attr "mode" "QI")])
 
 (define_insn "*setcc_qi_slp"
-  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
+  [(set (strict_low_part (match_operand:QI 0 "register_operand" "+q"))
 	(match_operator:QI 1 "ix86_comparison_operator"
 	  [(reg FLAGS_REG) (const_int 0)]))]
   ""
@@ -11864,7 +11862,7 @@ 
 })
 
 (define_split
-  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
+  [(set (strict_low_part (match_operand:QI 0 "register_operand"))
 	(ne:QI (match_operator 1 "ix86_comparison_operator"
 	         [(reg FLAGS_REG) (const_int 0)])
 	    (const_int 0)))]
@@ -11896,7 +11894,7 @@ 
 })
 
 (define_split
-  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
+  [(set (strict_low_part (match_operand:QI 0 "register_operand"))
 	(eq:QI (match_operator 1 "ix86_comparison_operator"
 	         [(reg FLAGS_REG) (const_int 0)])
 	    (const_int 0)))]