+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.
+
2016-05-05 Uros Bizjak <ubizjak@gmail.com>
* config/i386/i386.md (peehole2 patterns): Change true_regnum
- to REGNUM in all peephole2 patterns.
- (post-reload splitters): Change true_regnum to REGNUM in
+ to REGNO in all peephole2 patterns.
+ (post-reload splitters): Change true_regnum to REGNO in
post-reload splitters.
(zero_extend splitters): Use general_reg_operand and
nonimmediate_gr_operand predicates.
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 *);
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
(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")
&& (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")
"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