Hi, The avr target has a bunch of patterns that directly set hard regs at expand time, like so
(define_expand "cpymemhi" [(parallel [(set (match_operand:BLK 0 "memory_operand" "") (match_operand:BLK 1 "memory_operand" "")) (use (match_operand:HI 2 "const_int_operand" "")) (use (match_operand:HI 3 "const_int_operand" ""))])] "" { if (avr_emit_cpymemhi (operands)) DONE; FAIL; }) where avr_emit_cpymemhi generates (insn 14 13 15 4 (set (reg:HI 30 r30) (reg:HI 48 [ ivtmp.10 ])) "pr53505.c":21:22 -1 (nil)) (insn 15 14 16 4 (set (reg:HI 26 r26) (reg/f:HI 38 virtual-stack-vars)) "pr53505.c":21:22 -1 (nil)) (insn 16 15 17 4 (parallel [ (set (mem:BLK (reg:HI 26 r26) [0 A8]) (mem:BLK (reg:HI 30 r30) [0 A8])) (unspec [ (const_int 0 [0]) ] UNSPEC_CPYMEM) (use (reg:QI 52)) (clobber (reg:HI 26 r26)) (clobber (reg:HI 30 r30)) (clobber (reg:QI 0 r0)) (clobber (reg:QI 52)) ]) "pr53505.c":21:22 -1 (nil)) Classic reload knows about these - find_reg masks out bad_spill_regs, and bad_spill_regs when ORed with chain->live_throughout in order_regs_for_reload picks up r30. LRA, however, appears to not consider that, and proceeds to use such regs as reload regs. For the same source, it generates <snip> Choosing alt 0 in insn 15: (0) =r (1) r {*movhi_split} Creating newreg=70, assigning class GENERAL_REGS to r70 15: r26:HI=r70:HI REG_EQUAL r28:HI+0x1 Inserting insn reload before: 58: r70:HI=r28:HI+0x1 Choosing alt 3 in insn 58: (0) d (1) 0 (2) nYnn {*addhi3_split} Creating newreg=71 from oldreg=70, assigning class LD_REGS to r71 58: r71:HI=r71:HI+0x1 Inserting insn reload before: 59: r71:HI=r28:HI Inserting insn reload after: 60: r70:HI=r71:HI ********** Assignment #1: ********** Assigning to 71 (cl=LD_REGS, orig=70, freq=3000, tfirst=71, tfreq=3000)... Assign 30 to reload r71 (freq=3000) Hard reg 26 is preferable by r70 with profit 1000 Hard reg 30 is preferable by r70 with profit 1000 Assigning to 70 (cl=GENERAL_REGS, orig=70, freq=2000, tfirst=70, tfreq=2000)... Assign 30 to reload r70 (freq=2000) (insn 14 13 59 3 (set (reg:HI 30 r30) (reg:HI 18 r18 [orig:48 ivtmp.10 ] [48])) "pr53505.c":21:22 101 {*movhi_split} (nil)) (insn 59 14 58 3 (set (reg:HI 30 r30 [70]) (reg/f:HI 28 r28)) "pr53505.c":21:22 101 {*movhi_split} (nil)) (insn 58 59 15 3 (set (reg:HI 30 r30 [70]) (plus:HI (reg:HI 30 r30 [70]) (const_int 1 [0x1]))) "pr53505.c":21:22 165 {*addhi3_split} (nil)) (insn 15 58 16 3 (set (reg:HI 26 r26) (reg:HI 30 r30 [70])) "pr53505.c":21:22 101 {*movhi_split} (expr_list:REG_EQUAL (plus:HI (reg/f:HI 28 r28) (const_int 1 [0x1])) (nil))) (insn 16 15 17 3 (parallel [ (set (mem:BLK (reg:HI 26 r26) [0 A8]) (mem:BLK (reg:HI 30 r30) [0 A8])) (unspec [ (const_int 0 [0]) ] UNSPEC_CPYMEM) (use (reg:QI 22 r22 [52])) (clobber (reg:HI 26 r26)) (clobber (reg:HI 30 r30)) (clobber (reg:QI 0 r0)) (clobber (reg:QI 22 r22 [52])) ]) "pr53505.c":21:22 132 {cpymem_qi} (nil)) LRA generates insn 59 that clobbers r30 set in insn 14, causing an execution failure down the line. How should the avr backend deal with this? Regards Senthil