https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104335
--- Comment #4 from rdapp at linux dot ibm.com --- Hi Segher, originally ifcvt would only pass e.g. (unle (reg:SF 129 [ _29 ]) (reg/v:SF 118 [ highScore ])) as condition to rs6000_emit_cmove via emit_conditional_move (). (This is the example from the ICE). dest = (reg/f:DI 122 [ bestFuzz$__object ]) The check if (FLOAT_MODE_P (compare_mode) && !FLOAT_MODE_P (result_mode)) fails and we return false i.e. the expander fails and returns NULL_RTX. This is fine as we will just not do anything with it in ifcvt. Now with the patch rs6000_emit_cmove is passed (unle (reg:CCFP 153) (const_int 0 [0])). This CC comparison has already been computed before so the backend actually needs to do less work and could just use it without preparing a comparison. This helps costing on the ifcvt side. dest is the same as before but now we have FLOAT_MODE_P (compare_mode) == false and if (FLOAT_MODE_P (compare_mode) && !FLOAT_MODE_P (result_mode)) not causing a return false. We then call rs6000_emit_int_cmove which in turn calls rs6000_generate_compare. There we try to emit_insn (gen_rtx_SET (compare_result, gen_rtx_COMPARE (comp_mode, op0, op1))); but ICE since the modes don't match or make sense. >From an ifcvt point of view we would just expect a NULL_RTX if something cannot be handled. We did not pass CC compares to backends before, so I don't know how reasonable this assumption is :)