This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Invalid reload inheritance with paradoxical subregs
- From: Uros Bizjak <ubizjak at gmail dot com>
- To: GCC Development <gcc at gcc dot gnu dot org>
- Date: Wed, 1 Apr 2009 15:15:15 +0200
- Subject: Invalid reload inheritance with paradoxical subregs
Hello!
I have encountered a problem with a private RISC target, where invalid
reload is generated when paradoxical registers are involved.
In a lreg pass, I have a sequence of instructions:
(insn 112 182 114 2 t.c:22 (set (mem/s/j/c:SI (plus:SI (reg/f:SI 35 frame)
(const_int -20 [0xffffffec])) [0+4 S4 A32])
(reg:SI 129)) 9 {*movsi_internal_ba1} (nil))
...
(insn 116 115 117 2 t.c:22 (set (mem/s/c:HI (plus:SI (reg/f:SI 35 frame)
(const_int -8 [0xfffffff8])) [2 y+4 S2 A32])
(subreg:HI (reg:SI 129) 0)) 2 {*movhi_internal_ba1}
(expr_list:REG_DEAD (reg:SI 129)
(nil)))
...
(insn 121 120 125 2 t.c:22 (set (reg:SI 48 [ y$k.115 ])
(lshiftrt:SI (subreg:SI (mem/s/c:HI (plus:SI (reg/f:SI 35 frame)
(const_int -8 [0xfffffff8])) [0+4 S2 A32]) 0)
(const_int 5 [0x5]))) 62 {lshrsi3} (nil))
(reg 129) is stored in HImode to a HImode stack slot. Since this is
ZERO_EXTEND LOAD_EXTEND_OP RISC target with WORD_REGISTER_OPERATIONS,
we zero extend the value when the value is loaded from memory in (insn
121). Effectively, we clear top 16 bits before we shift them.
After reload, this same sequence reads as:
(insn 112 182 114 2 t.c:22 (set (mem/s/j/c:SI (plus:SI (reg/f:SI 1 r1)
(const_int 4 [0x4])) [0+4 S4 A32])
(reg:SI 7 r7 [129])) 9 {*movsi_internal_ba1} (nil))
...
(insn 116 115 117 2 t.c:22 (set (mem/s/c:HI (plus:SI (reg/f:SI 1 r1)
(const_int 16 [0x10])) [2 y+4 S2 A32])
(reg:HI 7 r7 [129])) 2 {*movhi_internal_ba1} (nil))
...
(insn 121 120 125 2 t.c:22 (set (reg:SI 6 r6 [orig:48 y$k.115 ] [48])
(lshiftrt:SI (reg:SI 7 r7)
(const_int 5 [0x5]))) 62 {lshrsi3} (nil))
A SImode value is stored in (insn 112) and a HImode lowpart value is
stored from the same register to different value in (insn 116).
However, in (insn 121) a HImode store/load sequence that would clear
top 16 bits is simply replaced with a SImode register access. Since
the top 16 bits are _not_ guaranteed to be zero in (insn 121),
undefined bits are shifted in, leading to the wrong value in r6.
I would like to fix this problem, so if anybody (a reload expert
perhaps ;) has any advice where to look in reload1.c, I'd be more than
happy to debug and test the fix for this problem.
Thanks,
Uros.