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 :)