Path: 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 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