------- Comment #5 from bonzini at gnu dot org 2010-06-30 11:51 ------- I agree that the problem is a wrong pattern.
Here you have non-matching mode between the udiv/umod and the first argument: > (ior:HI (ashift:HI (zero_extend:HI (umod:QI (reg:HI 68) > (reg:QI 61 [ D.2750 ]))) > (const_int 8 [0x8])) > (zero_extend:HI (udiv:QI (reg:HI 68) > (reg:QI 61 [ D.2750 ])))) Instead you need to have this before reload: (set (match_operand:HI "register_operand" "=a") (ior:HI (ashift:HI (zero_extend:HI (umod:QI (match_operand:QI "register_operand" "0") (match_operand:QI "register_operand" "q"))) (const_int 8 [0x8])) (zero_extend:HI (udiv:QI (match_dup 1) (match_dup 2)))) and after reload split it into a zero/sign extension of al into ax followed by (set (match_dup 0) (ior:HI (ashift:HI (umod:HI (match_dup 0) (zero_extend:HI (match_dup 2))) (const_int 8 [0x8])) (udiv:HI (match_dup 0) (zero_extend:HI (match_dup 2)))) (or maybe sign extend into eax? QImode->SImode is definitely cheaper for zero extension, I don't know about the cost of cbw because of partial register stalls). -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=44695