@@ -2528,6 +2528,34 @@ noce_can_store_speculate_p (basic_block top_bb,
const_rtx mem)
return false;
}
+/* Check X clobber CC reg or not. */
+
+static bool
+clobber_cc_p (rtx x)
+{
+ RTX_CODE code = GET_CODE (x);
+ int i;
+
+ if (code == CLOBBER
+ && REG_P (XEXP (x, 0))
+ && (GET_MODE_CLASS (GET_MODE (XEXP (x, 0))) == MODE_CC))
+ return TRUE;
+ else if (code == PARALLEL)
+ for (i = 0; i < XVECLEN (x, 0); i++)
+ if (clobber_cc_p (XVECEXP (x, 0, i)))
+ return TRUE;
+ return FALSE;
+}
+
+/* Check CC reg is used in COND or not. */
+
+static bool
+use_cc_p (rtx cond)
+{
+ return (HAVE_cbranchcc4)
+ && (GET_MODE_CLASS (GET_MODE (XEXP (cond, 0))) == MODE_CC);
+}
+
/* Given a simple IF-THEN-JOIN or IF-THEN-ELSE-JOIN block, attempt to
convert
it without using conditional execution. Return TRUE if we were
successful
at converting the block. */
@@ -2655,6 +2683,12 @@ noce_process_if_block (struct noce_if_info *if_info)
if_info->a = a;
if_info->b = b;
+ /* Skip it if the instruction to be moved might clobber CC. */
+ if (use_cc_p (if_info->cond)
+ && (clobber_cc_p (PATTERN (insn_a))
+ || (insn_b && clobber_cc_p (PATTERN (insn_b)))))
+ return FALSE;
+
/* Try optimizations in some approximation of a useful order. */
/* ??? Should first look to see if X is live incoming at all. If it
isn't, we don't need anything but an unconditional set. */
@@ -2868,6 +2902,10 @@ check_cond_move_block (basic_block bb,
&& modified_between_p (src, insn, NEXT_INSN (BB_END (bb))))
return FALSE;
+ /* Skip it if the instruction to be moved might clobber CC. */
+ if (use_cc_p (cond) && clobber_cc_p (PATTERN (insn)))
+ return FALSE;
+
vals->put (dest, src);
regs->safe_push (dest);
b/gcc/testsuite/gcc.target/i386/floatsitf.c
new file mode 100644
@@ -0,0 +1,48 @@
+/* { dg-do compile { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
+/* { dg-options "-O2 -fdump-rtl-ce2" } */
+
+typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__)));
+void __sfp_handle_exceptions (int);
+
+typedef int QItype __attribute__ ((mode (QI)));
+typedef int SItype __attribute__ ((mode (SI)));
+typedef int DItype __attribute__ ((mode (DI)));
+typedef unsigned int UQItype __attribute__ ((mode (QI)));
+typedef unsigned int USItype __attribute__ ((mode (SI)));
+typedef unsigned int UDItype __attribute__ ((mode (DI)));
+
+typedef unsigned int UHWtype __attribute__ ((mode (HI)));
+extern const UQItype __clz_tab[256] ;
+
+extern void abort (void);
+typedef float TFtype __attribute__ ((mode (TF)));
+
+union _FP_UNION_Q
+{
+ TFtype flt;
+ struct
+ {
+ unsigned long frac0 : 32;
+ unsigned long frac1 : 32;
+ unsigned long frac2 : 32;
+ unsigned long frac3 : 113 - (((unsigned int) 1 << (113 -1) % 32) !=
0)-(32 * 3);
+ unsigned exp : 15;
+ unsigned sign : 1;
+
+ } bits __attribute__ ((packed));
+};
+
+TFtype
+__floatsitf (SItype i)
+{
+ int A_c __attribute__ ((unused)); int A_s __attribute__ ((unused)); int
A_e __attribute__ ((unused)); unsigned int A_f[4];
+ TFtype a;
+
+ do { if ((i)) { USItype _FP_FROM_INT_ur; if ((A_s = (((i)) < 0))) ((i)) =
-(USItype) ((i)); _FP_FROM_INT_ur = (USItype) ((i)); (void) (((((8 * (int)
sizeof (SItype)))) <= 32) ? ({ int _FP_FROM_INT_lz; do { if (sizeof
(unsigned int) == sizeof (unsigned int)) (_FP_FROM_INT_lz) = __builtin_clz
((unsigned int) _FP_FROM_INT_ur); else if (sizeof (unsigned int) == sizeof
(unsigned long)) (_FP_FROM_INT_lz) = __builtin_clzl ((unsigned int)
_FP_FROM_INT_ur); else if (sizeof (unsigned int) == sizeof (unsigned long