Investigating an ICE while trying to compile libgcc2.c:__udivmoddi4 for a new avr variant with different register set/allocation order, I found replace_reg_with_saved_mem falling over its own nonsense. The instruction:
(debug_insn 97 96 98 2 (var_location:SI __x2 (mult:SI (lshiftrt:SI (reg/v:SI 18 r18 [orig:58 q0 ] [58]) (const_int 16 [0x10])) (reg/v:SI 61 [ __vl ]))) ../../gcc/gcc/testsuite/gcc.target/avr/tiny-caller-save.c:67 -1 (nil)) would be transformed into: (debug_insn 97 96 98 2 (var_location:SI __x2 (mult:SI (lshiftrt:SI (concatn:SI [ (reg:SI 18 r18) (reg:SI 19 r19) (mem/c:QI (plus:HI (reg/f:HI 28 r28) (const_int 43 [0x2b])) [6 S1 A8]) (mem/c:QI (plus:HI (reg/f:HI 28 r28) (const_int 44 [0x2c])) [6 S1 A8]) ]) (const_int 16 [0x10])) (reg/v:SI 61 [ __vl ]))) ../../gcc/gcc/testsuite/gcc.target/avr/tiny-caller-save.c:67 -1 Note that r18 and r19 inside the concatn are supposed to be single hard registers, but as the word size of this processor is 8 bit, SImode extends actually over four hard registers. save_mode is SImode because four registers can be saved/restored at once. The attached patch fixes the failure by using word_mode if smode would cover multiple hard registers. bootstrapped & regtested on i686-pc-linux-gnu. OK to apply?
caller-save-patch
Description: Binary data