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

Reply via email to