This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: IRA: matches insn even though !reload_in_progress
- From: Georg-Johann Lay <avr at gjlay dot de>
- To: gcc at gcc dot gnu dot org
- Date: Mon, 11 Jul 2011 13:16:27 +0200
- Subject: Re: IRA: matches insn even though !reload_in_progress
- References: <4E1AD2AA.6000406@gjlay.de>
Georg-Johann Lay wrote:
> The following pattern shall be generated by insn combine
> and then be split by pre-reload split:
>
> (define_insn_and_split "*mulsqihi3.const"
> [(set (match_operand:HI 0 "register_operand"
> "=&r")
> (mult:HI (sign_extend:HI (match_operand:QI 1
> "register_operand" "a"))
> (match_operand:HI 2 "u8_operand"
> "n")))]
> "AVR_HAVE_MUL
> && !reload_completed
> && !reload_in_progress"
> { gcc_unreachable(); }
> "&& 1"
> [(set (match_dup 3)
> (match_dup 2))
> ; *mulsu
> (mult:HI (sign_extend:HI (match_dup 1))
> (zero_extend:HI (match_dup 3)))]
> {
> operands[3] = gen_reg_rtx (QImode);
> })
>
> All works, and in .asmcons insns look like that:
>
> (insn 7 6 8 2 (set (reg:HI 48)
> (const_int 155 [0x9b])) wmul.c:29 10 {*movhi}
> (nil))
>
> (insn 8 7 21 2 (set (reg:HI 46)
> (mult:HI (sign_extend:HI (reg:QI 24 r24 [ x ]))
> (reg:HI 48))) wmul.c:29 38 {*mulsqihi3}
> (expr_list:REG_DEAD (reg:HI 48)
> (expr_list:REG_DEAD (reg:QI 24 r24 [ x ])
> (nil))))
>
> IRA now propagates insn 7 into insn 8 so that in insn-output gcc runs
> into the gcc_unreachable() even though !reload_in_progress etc should
> keep IRA/reload from generating the insn.
>
> After IRA/reload the code is:
>
> (insn 8 6 21 2 (set (reg:HI 24 r24 [46])
> (mult:HI (sign_extend:HI (reg:QI 24 r24 [ x ]))
> (const_int 155 [0x9b]))) wmul.c:29 39 {*mulsqihi3.const}
> (nil))
>
> which of course must crash.
>
> How do I write a pre-reload combine + pre-reload split correctly?
> I'd like to avoid clobber reg.
This solution with (clobber (scratch:QI)) appears to work.
(clobber (match_scratch:QI 3 "=&d")) does not.
(define_insn_and_split "*mulsqihi3.const"
[(set (match_operand:HI 0 "register_operand" "=&r")
(mult:HI (sign_extend:HI (match_operand:QI 1
"register_operand" "a"))
(match_operand:HI 2 "u8_operand"
"n")))
(clobber (scratch:QI))]
"AVR_HAVE_MUL
&& !reload_completed
&& !reload_in_progress"
{ gcc_unreachable(); }
"&& 1"
[(set (match_dup 3)
(match_dup 2))
; *mulsu
(mult:HI (sign_extend:HI (match_dup 1))
(zero_extend:HI (match_dup 3)))]
{
if (SCRATCH == GET_CODE (operands[3]))
operands[3] = gen_reg_rtx (QImode);
})
Is that the correct approach?
Johann