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