[PATCH, i386]: Fix too broad (mem,reg)->(const,reg) splitters

Uros Bizjak ubizjak@gmail.com
Thu May 5 22:52:00 GMT 2016


Hello!

This patch fixes a bunch of too broad (mem,reg)->(const,reg)
splitters, that block other similar splitters. The solution is to
check, if the splitter will transform the insn in the splitter
condition, instead of using FAIL in the splitter preparation
statements.

2016-05-06  Uros Bizjak  <ubizjak@gmail.com>

    PR target/70873
    * config/i386/i386-protos.h (ix86_standard_x87sse_constant_load_p):
    New prototype.
    * config/i386/i386.c (ix86_standard_x87sse_constant_load_p): New.
    * config/i386/i386.md (push mem splitter): Use find_constant_src in
    the splitter condition.
    (FP load splitter): Use ix86_standard_x87sse_constant_load_p in
    the splitter condition.
    (FP float_extend load splitter): Ditto.

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

Committed to mainline SVN.

Uros.
-------------- next part --------------
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index 4145ed5..447f67e 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -52,6 +52,7 @@ extern const char *standard_80387_constant_opcode (rtx);
 extern rtx standard_80387_constant_rtx (int);
 extern int standard_sse_constant_p (rtx, machine_mode);
 extern const char *standard_sse_constant_opcode (rtx_insn *, rtx);
+extern bool ix86_standard_x87sse_constant_load_p (const rtx_insn *, rtx);
 extern bool symbolic_reference_mentioned_p (rtx);
 extern bool extended_reg_mentioned_p (rtx);
 extern bool x86_extended_QIreg_mentioned_p (rtx_insn *);
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 9680aaf..05476f3 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -11219,6 +11219,26 @@ standard_sse_constant_opcode (rtx_insn *insn, rtx x)
   gcc_unreachable ();
 }
 
+/* Returns true if INSN can be transformed from a memory load
+   to a supported FP constant load.  */
+
+bool
+ix86_standard_x87sse_constant_load_p (const rtx_insn *insn, rtx dst)
+{
+  rtx src = find_constant_src (insn);
+
+  gcc_assert (REG_P (dst));
+
+  if (src == NULL
+      || (SSE_REGNO_P (REGNO (dst))
+	  && standard_sse_constant_p (src, GET_MODE (dst)) != 1)
+      || (STACK_REGNO_P (REGNO (dst))
+	   && standard_80387_constant_p (src) < 1))
+    return false;
+
+  return true;
+}
+
 /* Returns true if OP contains a symbol reference */
 
 bool
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index dd56b05..0bf01ab 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -3072,14 +3072,10 @@
 (define_split
   [(set (match_operand:SF 0 "push_operand")
 	(match_operand:SF 1 "memory_operand"))]
-  "reload_completed"
+  "reload_completed
+   && find_constant_src (insn)"
   [(set (match_dup 0) (match_dup 2))]
-{
-  operands[2] = find_constant_src (curr_insn);
-
-  if (operands[2] == NULL_RTX)
-    FAIL;
-})
+  "operands[2] = find_constant_src (curr_insn);")
 
 (define_split
   [(set (match_operand 0 "push_operand")
@@ -3601,19 +3597,10 @@
    && (GET_MODE (operands[0]) == TFmode
        || GET_MODE (operands[0]) == XFmode
        || GET_MODE (operands[0]) == DFmode
-       || GET_MODE (operands[0]) == SFmode)"
+       || GET_MODE (operands[0]) == SFmode)
+   && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
   [(set (match_dup 0) (match_dup 2))]
-{
-  operands[2] = find_constant_src (curr_insn);
-
-  if (operands[2] == NULL_RTX
-      || (SSE_REGNO_P (REGNO (operands[0]))
-	  && standard_sse_constant_p (operands[2],
-				      GET_MODE (operands[0])) != 1)
-      || (STACK_REGNO_P (REGNO (operands[0]))
-	   && standard_80387_constant_p (operands[2]) < 1))
-    FAIL;
-})
+  "operands[2] = find_constant_src (curr_insn);")
 
 (define_split
   [(set (match_operand 0 "any_fp_register_operand")
@@ -3621,19 +3608,10 @@
   "reload_completed
    && (GET_MODE (operands[0]) == TFmode
        || GET_MODE (operands[0]) == XFmode
-       || GET_MODE (operands[0]) == DFmode)"
+       || GET_MODE (operands[0]) == DFmode)
+   && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
   [(set (match_dup 0) (match_dup 2))]
-{
-  operands[2] = find_constant_src (curr_insn);
-
-  if (operands[2] == NULL_RTX
-      || (SSE_REGNO_P (REGNO (operands[0]))
-	  && standard_sse_constant_p (operands[2],
-				      GET_MODE (operands[0])) != 1)
-      || (STACK_REGNO_P (REGNO (operands[0]))
-	   && standard_80387_constant_p (operands[2]) < 1))
-    FAIL;
-})
+  "operands[2] = find_constant_src (curr_insn);")
 
 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
 (define_split


More information about the Gcc-patches mailing list