On 2/2/21 2:29 AM, Jakub Jelinek wrote:
> Hi!
>
> As the testcase shows, RTL ifcvt can throw random RTL (whatever it found in
> some insns) at expand_binop or expand_unop and expects it to do something
> (and then will check if it created valid insns and punts if not).
> These functions in the end if the operands don't match try to
> copy_to_mode_reg the operands, which does
> if (!general_operand (x, VOIDmode))
> x = force_operand (x, temp);
> but, force_operand is far from handling all possible RTLs, it will ICE for
> all more unusual RTL codes. Basically handles just simple arithmetic and
> unary RTL operations if they have an optab and
> expand_simple_binop/expand_simple_unop ICE on others.
>
> The following patch fixes it by adding some operand verification (whether
> there is a hope that copy_to_mode_reg will succeed on those). It is added
> both to noce_emit_move_insn (not needed for this exact testcase,
> that function simply tries to recog the insn as is and if it fails,
> handles some simple binop/unop cases; the patch performs the verification
> of their operands) and noce_try_sign_mask.
>
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
>
> 2021-02-02 Jakub Jelinek <ja...@redhat.com>
>
> PR middle-end/97487
> * ifcvt.c (noce_can_force_operand): New function.
> (noce_emit_move_insn): Use it.
> (noce_try_sign_mask): Likewise. Formatting fix.
>
> * gcc.dg/pr97487-1.c: New test.
> * gcc.dg/pr97487-2.c: New test.
OK. One might consider having force_operand call can_force_operand but
that feels more like a future thing than something we'd want to do right
now.
Jeff