On 2/2/21 2:21 AM, Jakub Jelinek via Gcc-patches wrote:
> Hi!
>
> The following testcase has ice-on-invalid, it can't be reloaded, but we
> shouldn't ICE the compiler because the user typed non-sense.
>
> In current_insn_transform we have:
> if (process_alt_operands (reused_alternative_num))
> alt_p = true;
>
> if (check_only_p)
> return ! alt_p || best_losers != 0;
>
> /* If insn is commutative (it's safe to exchange a certain pair of
> operands) then we need to try each alternative twice, the second
> time matching those two operands as if we had exchanged them. To
> do this, really exchange them in operands.
>
> If we have just tried the alternatives the second time, return
> operands to normal and drop through. */
>
> if (reused_alternative_num < 0 && commutative >= 0)
> {
> curr_swapped = !curr_swapped;
> if (curr_swapped)
> {
> swap_operands (commutative);
> goto try_swapped;
> }
> else
> swap_operands (commutative);
> }
>
> if (! alt_p && ! sec_mem_p)
> {
> /* No alternative works with reloads?? */
> if (INSN_CODE (curr_insn) >= 0)
> fatal_insn ("unable to generate reloads for:", curr_insn);
> error_for_asm (curr_insn,
> "inconsistent operand constraints in an %<asm%>");
> lra_asm_error_p = true;
> ...
> and so handle inline asms there differently (and delete/nullify them after
> this) - fatal_insn is only called for non-inline asm.
> But in process_alt_operands we do:
> /* Both the earlyclobber operand and conflicting operand
> cannot both be user defined hard registers. */
> if (HARD_REGISTER_P (operand_reg[i])
> && REG_USERVAR_P (operand_reg[i])
> && operand_reg[j] != NULL_RTX
> && HARD_REGISTER_P (operand_reg[j])
> && REG_USERVAR_P (operand_reg[j]))
> fatal_insn ("unable to generate reloads for "
> "impossible constraints:", curr_insn);
> and thus ICE even for inline-asms.
>
> I think it is inappropriate to delete/nullify the insn in
> process_alt_operands, as it could be done e.g. in the check_only_p mode,
> so this patch just returns false in that case, which results in the
> caller have alt_p false, and as inline asm isn't simple move, sec_mem_p
> will be also false (and it isn't commutative either), so for check_only_p
> it will suggests to the callers it isn't ok and otherwise will emit
> error and delete/nullify the inline asm insn.
>
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
>
> 2021-02-02 Jakub Jelinek <ja...@redhat.com>
>
> PR middle-end/97971
> * lra-constraints.c (process_alt_operands): For inline asm, don't call
> fatal_insn, but instead return false.
>
> * gcc.target/i386/pr97971.c: New test.
OK
jeff