summaryrefslogtreecommitdiff
path: root/gcc/config/i386/i386.md
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/i386/i386.md')
-rw-r--r--gcc/config/i386/i386.md114
1 files changed, 107 insertions, 7 deletions
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 3846065066b..95a52cdd1a7 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -16093,6 +16093,28 @@
[(set_attr "type" "icmov")
(set_attr "mode" "<MODE>")])
+;; Don't do conditional moves with memory inputs. This splitter helps
+;; register starved x86_32 by forcing inputs into registers before reload.
+(define_split
+ [(set (match_operand:SWI248 0 "register_operand")
+ (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
+ [(reg FLAGS_REG) (const_int 0)])
+ (match_operand:SWI248 2 "nonimmediate_operand")
+ (match_operand:SWI248 3 "nonimmediate_operand")))]
+ "!TARGET_64BIT && TARGET_CMOVE
+ && TARGET_AVOID_MEM_OPND_FOR_CMOVE
+ && (MEM_P (operands[2]) || MEM_P (operands[3]))
+ && can_create_pseudo_p ()
+ && optimize_insn_for_speed_p ()"
+ [(set (match_dup 0)
+ (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
+{
+ if (MEM_P (operands[2]))
+ operands[2] = force_reg (<MODE>mode, operands[2]);
+ if (MEM_P (operands[3]))
+ operands[3] = force_reg (<MODE>mode, operands[3]);
+})
+
(define_insn "*movqicc_noc"
[(set (match_operand:QI 0 "register_operand" "=r,r")
(if_then_else:QI (match_operator 1 "ix86_comparison_operator"
@@ -16105,14 +16127,12 @@
(set_attr "mode" "QI")])
(define_split
- [(set (match_operand 0 "register_operand")
- (if_then_else (match_operator 1 "ix86_comparison_operator"
- [(reg FLAGS_REG) (const_int 0)])
- (match_operand 2 "register_operand")
- (match_operand 3 "register_operand")))]
+ [(set (match_operand:SWI12 0 "register_operand")
+ (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
+ [(reg FLAGS_REG) (const_int 0)])
+ (match_operand:SWI12 2 "register_operand")
+ (match_operand:SWI12 3 "register_operand")))]
"TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
- && (GET_MODE (operands[0]) == QImode
- || GET_MODE (operands[0]) == HImode)
&& reload_completed"
[(set (match_dup 0)
(if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
@@ -16122,6 +16142,33 @@
operands[3] = gen_lowpart (SImode, operands[3]);
})
+;; Don't do conditional moves with memory inputs
+(define_peephole2
+ [(match_scratch:SWI248 2 "r")
+ (set (match_operand:SWI248 0 "register_operand")
+ (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
+ [(reg FLAGS_REG) (const_int 0)])
+ (match_dup 0)
+ (match_operand:SWI248 3 "memory_operand")))]
+ "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
+ && optimize_insn_for_speed_p ()"
+ [(set (match_dup 2) (match_dup 3))
+ (set (match_dup 0)
+ (if_then_else:SWI248 (match_dup 1) (match_dup 0) (match_dup 2)))])
+
+(define_peephole2
+ [(match_scratch:SWI248 2 "r")
+ (set (match_operand:SWI248 0 "register_operand")
+ (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
+ [(reg FLAGS_REG) (const_int 0)])
+ (match_operand:SWI248 3 "memory_operand")
+ (match_dup 0)))]
+ "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
+ && optimize_insn_for_speed_p ()"
+ [(set (match_dup 2) (match_dup 3))
+ (set (match_dup 0)
+ (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 0)))])
+
(define_expand "mov<mode>cc"
[(set (match_operand:X87MODEF 0 "register_operand")
(if_then_else:X87MODEF
@@ -16209,6 +16256,59 @@
[(set_attr "type" "fcmov,fcmov,icmov,icmov")
(set_attr "mode" "SF,SF,SI,SI")])
+;; Don't do conditional moves with memory inputs. This splitter helps
+;; register starved x86_32 by forcing inputs into registers before reload.
+(define_split
+ [(set (match_operand:MODEF 0 "register_operand")
+ (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
+ [(reg FLAGS_REG) (const_int 0)])
+ (match_operand:MODEF 2 "nonimmediate_operand")
+ (match_operand:MODEF 3 "nonimmediate_operand")))]
+ "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
+ && TARGET_AVOID_MEM_OPND_FOR_CMOVE
+ && (MEM_P (operands[2]) || MEM_P (operands[3]))
+ && can_create_pseudo_p ()
+ && optimize_insn_for_speed_p ()"
+ [(set (match_dup 0)
+ (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
+{
+ if (MEM_P (operands[2]))
+ operands[2] = force_reg (<MODE>mode, operands[2]);
+ if (MEM_P (operands[3]))
+ operands[3] = force_reg (<MODE>mode, operands[3]);
+})
+
+;; Don't do conditional moves with memory inputs
+(define_peephole2
+ [(match_scratch:MODEF 2 "r")
+ (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
+ (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
+ [(reg FLAGS_REG) (const_int 0)])
+ (match_dup 0)
+ (match_operand:MODEF 3 "memory_operand")))]
+ "(<MODE>mode != DFmode || TARGET_64BIT)
+ && TARGET_80387 && TARGET_CMOVE
+ && TARGET_AVOID_MEM_OPND_FOR_CMOVE
+ && optimize_insn_for_speed_p ()"
+ [(set (match_dup 2) (match_dup 3))
+ (set (match_dup 0)
+ (if_then_else:MODEF (match_dup 1) (match_dup 0) (match_dup 2)))])
+
+(define_peephole2
+ [(match_scratch:MODEF 2 "r")
+ (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
+ (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
+ [(reg FLAGS_REG) (const_int 0)])
+ (match_operand:MODEF 3 "memory_operand")
+ (match_dup 0)))]
+ "(<MODE>mode != DFmode || TARGET_64BIT)
+ && TARGET_80387 && TARGET_CMOVE
+ && TARGET_AVOID_MEM_OPND_FOR_CMOVE
+ && optimize_insn_for_speed_p ()"
+ [(set (match_dup 2) (match_dup 3))
+ (set (match_dup 0)
+ (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 0)))])
+
;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
;; the scalar versions to have only XMM registers as operands.