http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58517
--- Comment #4 from Steven Bosscher <steven at gcc dot gnu.org> --- So if I understand correctly, this is what happens (sorry, reading LIPSy RTL is still just too unnatural to me! ;-)) before ifcvt-after-combine: r147:=(r424>r178) r190:=r423-r189 if (r147==0) goto L433 {r190:=(~r189)+r424; r147:=X} L433: after ifcvt-after-combine: r147:=(r424>r189) r190:=r423-r189 {r945:=(~r189)+r424; r147:=X} r946:=r423-r189 r190:=(r147==0) ? r946:r945 // but r147 was clobbered! r147:=(r190==0) if (r147==0) goto L501 This is noce_try_cmove_arith: /* if (test) x = a + b; else x = c - d; => y = a + b; x = c - d; if (test) x = y; */ with "(test)" being clobbered by the assignment to "y" or "x" on the code after the transformation has been applied. noce_try_cmove_arith does not expect that the arithmetic insns emitted to load vtrue or vfalse into general operands may clobber the condition. There should be tests like this: Index: ifcvt.c =================================================================== --- ifcvt.c (revision 203224) +++ ifcvt.c (working copy) @@ -1573,6 +1573,8 @@ noce_try_cmove_arith (struct noce_if_info *if_info optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn_a))); if (insn_cost == 0 || insn_cost > COSTS_N_INSNS (if_info->branch_cost)) return FALSE; + if (modified_in_p (if_info->cond, insn_a)) + return FALSE; } else insn_cost = 0; @@ -1584,6 +1586,8 @@ noce_try_cmove_arith (struct noce_if_info *if_info optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn_b))); if (insn_cost == 0 || insn_cost > COSTS_N_INSNS (if_info->branch_cost)) return FALSE; + if (modified_in_p (if_info->cond, insn_b)) + return FALSE; } /* Possibly rearrange operands to make things come out more natural. */ That's option 1 of comment #3. Option 2 is only viable if the insn computing "cond" is nearby (i.e. immediately above insn_a / insn_b), otherwise it'll be necessary to solve a code motion dataflow problem. Within one basic block that still would be doable (modified_between_p), but I doubt it's worth the trouble.