🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: gnu.gcc.bug
Article #736

Is (subreg:SI (mem:QI ...)) valid or what

#736
From: Tom Wood
Date: Fri, 20 Oct 1989 15:08
95 lines
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!wood

Show 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