This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Unable to generate reloads
- To: gcc at gcc dot gnu dot org
- Subject: Re: Unable to generate reloads
- From: Lars Brinkhoff <lars dot spam at nocrew dot org>
- Date: 24 Sep 2001 15:37:28 +0200
- Organization: nocrew
- References: <85d74k7krk.fsf@junk.nocrew.org>
Lars Brinkhoff <lars@nocrew.org> writes:
> In my back end, there is an instruction that can load a value from
> memory (or another register) and then conditionally jump depending on
> how the value compares with zero:
>
> (define_insn "*move_and_skipsi"
> [(set (pc)
> (if_then_else (match_operator 0 "comparison_operator"
> [(match_operand:SI 2 "reg_or_mem_operand" "rm")
> (const_int 0)])
> (label_ref (match_operand 3 "" ""))
> (pc)))
> (set (match_operand:SI 1 "register_operand" "=r")
> (match_dup 2))]
> ...)
>
> A few files in the testsuite generate the "Unable to generate reloads
> for:" error for this instruction. Example:
>
> testsuite/gcc.c-torture/compile/920625-1.c:279: Unable to generate reloads for:
> (jump_insn 45 4975 5103 (parallel[
> (set (pc)
> (if_then_else (ge (reg:SI 1217)
> (const_int 0 [0x0]))
> (label_ref 48)
> (pc)))
> (set (reg/v:SI 30)
> (reg:SI 1217))
> ] ) 68 {*move_and_skipsi} (nil)
> (expr_list:REG_DEAD (reg:SI 1217)
> (expr_list:REG_BR_PROB (const_int 8900 [0x22c4])
> (nil))))
It seems that the explanation to this is in reload.c:find_reloads:
/* JUMP_INSNs and CALL_INSNs are not allowed to have any output reloads;
neither are insns that SET cc0. Insns that use CC0 are not allowed
to have any input reloads. */
if (GET_CODE (insn) == JUMP_INSN || GET_CODE (insn) == CALL_INSN)
no_output_reloads = 1;
If the register being loaded (pseudo 30 above) didn't get a hard
register, the instruction fails later in find_reloads:
/* Alternative loses if it requires a type of reload not
permitted for this insn. We can always reload SCRATCH
and objects with a REG_UNUSED note. */
else if (GET_CODE (operand) != SCRATCH
&& modified[i] != RELOAD_READ && no_output_reloads
&& ! find_reg_note (insn, REG_UNUSED, operand))
bad = 1;
Does this mean that I must add an alternative to operand 1 to store
into a memory location?