Paul Edwards wrote: > I've managed to isolate the problem to a small test program. > > Any suggestions on how to debug this?
> bug27.c:28: error: unrecognizable insn: > (insn 116 34 35 2 (set (reg:SI 5 5) > (plus:SI (plus:SI (reg:SI 2 2 [orig:54 i ] [54]) > (reg/f:SI 13 13)) > (const_int 104 [0x68]))) -1 (nil) > (nil)) Ah, yes. The problem is that reload assumes any valid address can be loaded into a register with a single instruction, and it will thus simply generate such instructions unconditionally -- and if the target then doesn't actually provide such a pattern, it will fail with "unrecognizable insn". The "LA" pattern you showed accepts only "(certain) single register + constant", which doesn't match the pattern above "register + register + constant". The difficulty is now that while "LA" *does* actually support adding base + index + displacement, you cannot simply add a pattern expressing that, because LA only does a 31-bit add, so it must only be used to add addresses, not when adding general 32-bit SImode values. The way I handle this in the s390 port is to provide a "forced" LA instruction pattern using a magic marker that prevents the pattern from being matched by regular instructions, and then add a secondary reload to emit that "forced" LA when reload needs to load an address. Here's the relevant snippets from the 3.4 s390 back-end: /* We need a secondary reload when loading a PLUS which is not a valid operand for LOAD ADDRESS. */ #define SECONDARY_INPUT_RELOAD_CLASS(CLASS, MODE, IN) \ s390_secondary_input_reload_class ((CLASS), (MODE), (IN)) (define_insn "*la_31" [(set (match_operand:SI 0 "register_operand" "=d,d") (match_operand:QI 1 "address_operand" "U,W"))] "!TARGET_64BIT && legitimate_la_operand_p (operands[1])" "@ la\t%0,%a1 lay\t%0,%a1" [(set_attr "op_type" "RX,RXY") (set_attr "type" "la")]) (define_insn "force_la_31" [(set (match_operand:SI 0 "register_operand" "=d,d") (match_operand:QI 1 "address_operand" "U,W")) (use (const_int 0))] "!TARGET_64BIT" "@ la\t%0,%a1 lay\t%0,%a1" [(set_attr "op_type" "RX") (set_attr "type" "la")]) (define_expand "reload_insi" [(parallel [(match_operand:SI 0 "register_operand" "=a") (match_operand:SI 1 "s390_plus_operand" "") (match_operand:SI 2 "register_operand" "=&a")])] "!TARGET_64BIT" { s390_expand_plus_operand (operands[0], operands[1], operands[2]); DONE; }) (and of course the functions in s390.c called by these.) You ought to be able to do something similar in your backend ... Bye, Ulrich -- Dr. Ulrich Weigand GNU Toolchain for Linux on System z and Cell BE ulrich.weig...@de.ibm.com