===================================================================
@@ -563,10 +563,26 @@
Validate that PREV_CLOBBER itself does in fact refer to IN_A. Do
recall that we've already validated the shape of PREV_CLOBBER. */
x = XVECEXP (PATTERN (insn), 0, 0);
- if (!rtx_equal_p (SET_DEST (x), in_a))
+ if (rtx_equal_p (SET_DEST (x), in_a))
+ cmp_src = SET_SRC (x);
+
+ /* Also check operations with implicit extensions, e.g.:
+ [(set (reg:DI)
+ (zero_extend:DI (plus:SI (reg:SI)(reg:SI))))
+ (set (reg:CCZ flags)
+ (compare:CCZ
+ (plus:SI (reg:SI)(reg:SI))
+ (const_int 0)))] */
+ else if (REG_P (SET_DEST (x))
+ && REG_P (in_a)
+ && REGNO (SET_DEST (x)) == REGNO (in_a)
+ && (GET_CODE (SET_SRC (x)) == ZERO_EXTEND
+ || GET_CODE (SET_SRC (x)) == SIGN_EXTEND)
+ && GET_MODE (XEXP (SET_SRC (x), 0)) == GET_MODE (in_a))
+ cmp_src = XEXP (SET_SRC (x), 0);
+ else
return false;
- cmp_src = SET_SRC (x);
-
+
/* Determine if we ought to use a different CC_MODE here. */
flags = maybe_select_cc_mode (cmp, cmp_src, cmp->in_b);
if (flags == NULL)
===================================================================
@@ -17861,19 +17861,31 @@
emit_insn (gen_rtx_SET (VOIDmode, dest, x));
}
-/* Return TRUE or FALSE depending on whether the first SET in INSN
- has source and destination with matching CC modes, and that the
+/* Return TRUE or FALSE depending on whether the first SET from COMPARE
+ in INSN has source and destination with matching CC modes, and that the
CC mode is at least as constrained as REQ_MODE. */
bool
ix86_match_ccmode (rtx insn, enum machine_mode req_mode)
{
- rtx set;
+ rtx pat, set;
enum machine_mode set_mode;
+ int i;
- set = PATTERN (insn);
- if (GET_CODE (set) == PARALLEL)
- set = XVECEXP (set, 0, 0);
+ pat = PATTERN (insn);
+ if (GET_CODE (pat) == PARALLEL)
+ {
+ for (i = 0; i < XVECLEN (pat, 0); i++)
+ {
+ set = XVECEXP (pat, 0, i);
+ if (GET_CODE (set) == SET
+ && GET_CODE (SET_SRC (set)) == COMPARE)
+ break;
+ }
+ }
+ else
+ set = pat;
+
gcc_assert (GET_CODE (set) == SET);
gcc_assert (GET_CODE (SET_SRC (set)) == COMPARE);
@@ -39090,6 +39102,8 @@
#define TARGET_FIXED_CONDITION_CODE_REGS ix86_fixed_condition_code_regs
#undef TARGET_CC_MODES_COMPATIBLE
#define TARGET_CC_MODES_COMPATIBLE ix86_cc_modes_compatible
+#undef TARGET_FLAGS_REGNUM
+#define TARGET_FLAGS_REGNUM FLAGS_REG
#undef TARGET_MACHINE_DEPENDENT_REORG
#define TARGET_MACHINE_DEPENDENT_REORG ix86_reorg
===================================================================
@@ -5808,14 +5808,14 @@
(zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
(define_insn "*add<mode>_2"
- [(set (reg FLAGS_REG)
+ [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
+ (plus:SWI
+ (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
+ (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0")))
+ (set (reg FLAGS_REG)
(compare
- (plus:SWI
- (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
- (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
- (const_int 0)))
- (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
- (plus:SWI (match_dup 1) (match_dup 2)))]
+ (plus:SWI (match_dup 1) (match_dup 2))
+ (const_int 0)))]
"ix86_match_ccmode (insn, CCGOCmode)
&& ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
{
@@ -5857,13 +5857,14 @@
;; See comment for addsi_1_zext why we do use nonimmediate_operand
(define_insn "*addsi_2_zext"
- [(set (reg FLAGS_REG)
+ [(set (match_operand:DI 0 "register_operand" "=r,r")
+ (zero_extend:DI
+ (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
+ (match_operand:SI 2 "x86_64_general_operand" "rme,0"))))
+ (set (reg FLAGS_REG)
(compare
- (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
- (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
- (const_int 0)))
- (set (match_operand:DI 0 "register_operand" "=r,r")
- (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
+ (plus:SI (match_dup 1) (match_dup 2))
+ (const_int 0)))]
"TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
&& ix86_binary_operator_ok (PLUS, SImode, operands)"
{
@@ -6090,7 +6091,7 @@
(match_operand:SWI 2 "<general_operand>" "<g>,0"))
(const_int 0)))
(clobber (match_scratch:SWI 0 "=<r>,<r>"))]
- "ix86_match_ccmode (insn, CCGOCmode)
+ "0 && ix86_match_ccmode (insn, CCGOCmode)
&& !(MEM_P (operands[1]) && MEM_P (operands[2]))"
{
switch (get_attr_type (insn))