Joern Rennecke
2014-10-06 08:51:56 UTC
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?
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?