Article View: gnu.gcc.bug
Article #736Is (subreg:SI (mem:QI ...)) valid or what
From: Tom Wood
Date: Fri, 20 Oct 1989 15:08
Date: Fri, 20 Oct 1989 15:08
95 lines
3366 bytes
3366 bytes
I'm thoroughly stumped with this one. We're attempting to rev up to
1.36 with the m88k compiler. The code generated for this procedure
generates a bus error for the line "p->a = 5". Here's the test case:
typedef struct { int a:5; double b; } T;
void set_T(p)
T *p;
{
p->a = 5;
p->b = 2.0;
}
The body of the procedure is wrong when it is optimized. It is:
ld.b r11,r0,r2
st.b r11,r30,0x0008
ld r11,r30,0x0005 ; This is the bug.
mask r11,r11,0x0007
or r11,r11,0x0028
st r11,r30,0x000c
ld.b r11,r30,0x000f
st.b r11,r0,r2
or.u r11,r0,hi16(0x40000000) ; double 2.00000
or r12,r0,r0
st.d r11,r2,0x0008
A number of things are going wrong. I'll work backwards from the bogus
instruction. The instruction comes from the insn,
(insn 20 8 9 (set (reg:SI 11)
(mem:SI (plus:SI (reg:SI 30)
(const_int 5)))) 83 (nil)
(nil))
generated by alter_subreg. final_scan_insn uses alter_subreg on the insn
(insn 20 8 9 (set (reg:SI 11)
(subreg:SI (mem:QI (plus:SI (reg:SI 30)
(const_int 8))) 0)) 83 (nil)
(nil))
What is wrong here? Is this a valid translation? If so, then the insn
being altered is wrong. This insn is produced during global_alloc as a
result of spilling a pseudo register. This in itself is bogus. A
trivial program is causing a register spill!? Anyway, the insn (from
.c.lreg) in question,
(insn 8 6 9 (set (reg:QI 33)
(mem:QI (reg/v:SI 32))) 87 (insn_list 4 (nil))
(nil))
is translated into the three insns (from .c.greg),
(insn 19 6 8 (set (reg:QI 11)
(mem:QI (reg/v:SI 2))) -1 (nil)
(nil))
(insn:QI 8 19 20 (set (mem:QI (plus:SI (reg:SI 30)
(const_int 8)))
(reg:QI 11)) 87 (insn_list 4 (nil))
(nil))
(insn 20 8 9 (set (reg:SI 11)
(subreg:SI (mem:QI (plus:SI (reg:SI 30)
(const_int 8))) 0)) -1 (nil)
(nil))
Here are the insns after reload_as_needed has completed, but before
eliminating all pseudo registers. reload was called as the last action
of global_alloc.
(insn 19 6 8 (set (reg:QI 11)
(mem:QI (reg/v:SI 2))) -1 (nil)
(nil))
(insn:QI 8 19 20 (set (reg:QI 33)
(reg:QI 11)) 87 (insn_list 4 (nil))
(nil))
(insn 20 8 9 (set (reg:SI 11)
(subreg:SI (reg:QI 33) 0)) -1 (nil)
(nil))
I see two problems happening:
1) global_alloc is choosing to spill values it shouldn't.
2) When a register widening subreg is applied to a pseudo register
that is spilled, the subreg should go away.
All comments, suggestions, clues, and patches are welcome!
---
Tom Wood (919) 248-6067
Data General, Research Triangle Park, NC
{the known world}!rti!xyzzy!wood
Technical Details
Message-ID:
<2012@xyzzy.UUCP>Path:
arc1-ca.pugleaf.net!utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!uwm.edu!uakari.primate.wisc.edu!xanth!mcnc!rti!xyzzy!dg-rtp.dg.com!woodShow Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!uwm.edu!uakari.primate.wisc.edu!xanth!mcnc!rti!xyzzy!dg-rtp.dg.com!wood From: wood@dg-rtp.dg.com (Tom Wood) Newsgroups: gnu.gcc.bug Subject: Is (subreg:SI (mem:QI ...)) valid or what Message-ID: <2012@xyzzy.UUCP> Date: 20 Oct 89 15:08:17 GMT Sender: usenet@xyzzy.UUCP Reply-To: wood@dg-rtp.dg.com (Tom Wood) Distribution: na Organization: Data General Corporation, Research Triangle Park, NC Lines: 94