http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58400
Jeffrey A. Law <law at redhat dot com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |kazu at gcc dot gnu.org, | |law at redhat dot com --- Comment #5 from Jeffrey A. Law <law at redhat dot com> --- Kazu, you added these patterns many years ago... Your thoughts would be appreciated. Compile the attached code with -O2 -mh -mint32 on the H8 port, using the trunk. It'll fail due to an insn not matching its constraints problem. The H8 port has the following insn: (define_insn_and_split "*tstsi_variable_bit_qi" [(set (cc0) (compare (zero_extract:SI (zero_extend:SI (match_operand:QI 0 "general_operand_src" "r,U,mn>")) (const_int 1) (and:SI (match_operand:SI 1 "register_operand" "r,r,r") (const_int 7))) (const_int 0))) (clobber (match_scratch:QI 2 "=X,X,&r"))] "TARGET_H8300H || TARGET_H8300S" "@ btst\\t%w1,%X0 btst\\t%w1,%X0 #" "&& reload_completed && !satisfies_constraint_U (operands[0])" [(set (match_dup 2) (match_dup 0)) (parallel [(set (cc0) (compare (zero_extract:SI (zero_extend:SI (match_dup 2)) (const_int 1) (and:SI (match_dup 1) (const_int 7))) (const_int 0))) (clobber (scratch:QI))])] "" [(set_attr "length" "2,8,10") (set_attr "cc" "set_zn,set_zn,set_zn")]) Now assume that operand 0 is initially a pseudo, something like this; (insn 50 49 51 5 (parallel [ (set (cc0) (compare (zero_extract:SI (zero_extend:SI (reg:QI 37 [ D.1545 ])) (const_int 1 [0x1]) (and:SI (reg:SI 59 [ D.1543 ]) (const_int 7 [0x7]))) (const_int 0 [0]))) (clobber (scratch:QI)) ]) j.c:36 113 {*tstsi_variable_bit_qi} (expr_list:REG_DEAD (reg:SI 59 [ D.1543 ]) (expr_list:REG_DEAD (reg:QI 37 [ D.1545 ]) (nil)))) That looks fine and good. Now assume reg:37 doesn't get a hard reg. reload will replace the reg with its equivalent stack slot resulting in: (insn 50 116 51 5 (parallel [ (set (cc0) (compare (zero_extract:SI (zero_extend:SI (mem/c:QI (plus:SI (reg/f:SI 6 r6) (const_int -17 [0xffffffffffffffef])) [7 %sfp+-9 S1 A8])) (const_int 1 [0x1]) (and:SI (reg:SI 3 r3) (const_int 7 [0x7]))) (const_int 0 [0]))) (clobber (scratch:QI)) ]) j.c:36 113 {*tstsi_variable_bit_qi} (nil)) Note that the insn no longer matches its strict constraints. It doesn't match alternatives 0 or 1 because of operand 0. It doesn't match alternative 2 because the SCRATCH is not a REG. I'm guessing you wanted reload to give you a scratch register that you could use for generating code when operand0 wasn't a suitable source for a single bit extraction. You'd then split the insn at insn output time using the scratch register to effectively reload operand0 yourself? Note there's another pattern tst_extzv_1_n that has potentially the same problem. The fundamental issue is that once reload is done, all insns must always satisfy their constraints, no exceptions. Thoughts on how this is supposed to work?