On Mon, Jul 11, 2011 at 12:38:34PM +0200, Georg-Johann Lay wrote: > How do I write a pre-reload combine + pre-reload split correctly? > I'd like to avoid clobber reg. > > Thanks much for any hint.
The move patterns are always kind of funny, particularly during register allocation. Lets see given your pattern is: (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 (set (match_dup 0) (mult:HI (sign_extend:HI (match_dup 1)) (zero_extend:HI (match_dup 3))))] { operands[3] = gen_reg_rtx (QImode); }) I would probably rewrite it as: (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) (unspec:QI [(match_dup 2)] WRAPPER)) ; *mulsu (set (match_dup 0) (mult:HI (sign_extend:HI (match_dup 1)) (zero_extend:HI (match_dup 3))))] { operands[3] = gen_reg_rtx (QImode); }) (define_insn "*wrapper" [(set (match_operand:QI 0 "register_operand" "=&r") (unspec:QI [(match_operand:QI 1 "u8_operand" "n")] WRAPPER))] "AVR_HAVE_MUL" "...") That way you are using the unspec to make the move not look like a generic move. The other way to do it, would be to split it to another pattern that combines the move and the HI multiply, which you then split after reload. Something like: (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" [(parallel [(set (match_dup 3) (match_dup 2)) ; *mulsu (set (match_dup 0) (mult:HI (sign_extend:HI (match_dup 1)) (zero_extend:HI (match_dup 3))))])] { operands[3] = gen_reg_rtx (QImode); }) (define_insn_and_split "*mulsqihi3_const2" [(set (match_operand:QI 0 "register_operand" "r") (match_operand:QI 1 "u8_operand" "n")) (set (match_operand:HI 2 "register_operand" "r") (mult:HI (sign_extend:HI (match_operand:QI 3 "register_operand" "a")) (zero_extend:HI (match_dup 0))))] "AVR_HAV_MUL" "#" "&& reload_completed" [(set (match_dup 0) (match_dup 1)) (set (match_dup 2) (mult:HI (sign_extend:HI (match_dup 3)) (zero_extend:HI (match_dup 0))))] {}) -- Michael Meissner, IBM 5 Technology Place Drive, M/S 2757, Westford, MA 01886-3141, USA meiss...@linux.vnet.ibm.com fax +1 (978) 399-6899