https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116353

--- Comment #4 from Manolis Tsamis <tsamismanolis at gmail dot com> ---
The ICE happens when this RTX is given to try_emit_cmove_seq:

set: (set (reg/v:DI 110 [ xor1 ])
    (vec_select:DI (reg:V2DI 100 [ vect__15.36 ])
        (parallel [
                (const_int 1 [0x1])
            ])))

This is given to emit_conditional_move, and as the stack trace of the ticket
shows, it ends up in maybe_legitimize_operand. The RTX there is:

(vec_select:DI (reg:V2DI 100 [ vect__15.36 ])
    (parallel [
            (const_int 1 [0x1])
        ]))

Since this operand doesn't match, maybe_legitimize_operand subsequently calls
copy_to_mode_reg for it which in turn will call force_operand. But, as the
function's comment implies, force_operand doesn't expect an argument like that.
When checking the rtx_code we end up at the switch statement's default case
(expr.cc:8687) where the operand ends up tp expand_simple_binop, which results
in the crash.

I was assuming that ifcvt's try_emit_cmove_seq would handle any RTX and return
NULL if it's not possible to emit the cmove, but that was an incorrect
assumption. After this analysis I found that ifcvt has noce_can_force_operand
which looks to be what needs to be called if we plan to give arbitrary RTX to
try_emit_cmove_seq.

I'm currently testing a fix based on that.

Reply via email to