Article View: gnu.gcc.bug
Article #275GCC 2.2.2 bug in register allocation
From: Bruce Martin
Date: Sat, 25 Jul 1992 07:45
Date: Sat, 25 Jul 1992 07:45
173 lines
4923 bytes
4923 bytes
The following code will cause the GCC 2.2.2 C compiler to generate
incorrect assembler output when targeted for 'i386-mach'. The
register constraints specified in the asm() statements are not
obeyed during register allocation, even though there is no obvious
reason why they should be ignored.
GCC Target: i386-mach (should fail on any i386 target)
Compile-time flags: -O1
Version: 2.2.2 or ss-920724
Example code:
struct mumble {
char *is_nic;
int is_fifo_depth;
char *is_card;
int is_board_id;
} mumble[1];
static inline void
outb(unsigned short port, unsigned char data)
{
/* Must use %eax and %edx registers */
asm volatile("outb %1,%0"
:
: "d" (port), "a" (data));
}
int
doit(unit)
int unit;
{
struct mumble *is = &mumble[unit];
char * base = is->is_nic + 0x10;
int temp;
int count = 0;
while (foobar() && count < 10000)
count++;
if (count == 10000) {
printf("%s%d: doit(): would not reset.\n",
is->is_card, unit);
}
temp = ((is->is_fifo_depth & 0x0c) << 3) | 0x08;
if (is->is_board_id & 0x00080000)
temp |= 0x01;
outb (base+0x0E, temp);
/* the following statement fails to compile correctly */
outb (base+0x0D, 0);
return 1;
}
When compiled -O1, the last call to the 'outb' inline function is
generated incorrectly. outb() requires the use of the %eax and %edx
registers explicitly. Note: When this code is compiled, the
compiler generates warnings about the loss of information due to a
very bogus cast (a char * is cast to a short implicitly). However,
no errors are generated, and I believe that the compiler should
generate reasonable code in this situation (i.e. it should just
truncate the value).
Here is the last bit of assember output generated by the
ss-920724 C compiler:
L6:
leal 14(%esi),%ecx
movl %ecx,%edx
movl %edi,%eax
/APP
outb %al,%dx / next-to-last outb() call
/NO_APP
leal 13(%esi),%ecx
xorb %al,%al / note lack of %edx load
/APP
outb %al,%dx / last outb() call, which fails because
/ %dx has not been loaded.
/NO_APP
movl $1,%eax
leal -16(%ebp),%esp
popl %ebx
popl %esi
popl %edi
leave
ret
A comparison between the 'lreg' and 'greg' stage RTL output for this last
outb() call are interesting.
(note 85 82 88 "" NOTE_INSN_BLOCK_BEG)
(note 88 85 89 "" NOTE_INSN_DELETED)
(insn 89 88 91 (set (subreg:SI (reg:HI 36) 0)
(plus:SI (reg/v:SI 24)
(const_int 13))) 73 {addsi3} (nil)
(expr_list:REG_DEAD (reg/v:SI 24)
(nil)))
(insn/i 91 89 93 (asm_operands/v ("outb %1,%0") ("") 0[
(reg:HI 36)
(const_int 0)
]
[
(asm_input:HI ("d"))
(asm_input:QI ("a"))
]
("/Net/lono/users/bmartin/Projects/CC_LONO/cc_lono/gcc-2.2.2/bkm/in.c")
14) -1 (insn_list 89 (nil))
(expr_list:REG_DEAD (reg:HI 36)
(nil)))
(note 93 91 97 "" NOTE_INSN_BLOCK_END)
Output from the .greg stage:
(note 85 82 88 "" NOTE_INSN_BLOCK_BEG)
(note 88 85 89 "" NOTE_INSN_DELETED)
(insn 89 88 121 (set (subreg:SI (reg:HI 2) 0)
(plus:SI (reg/v:SI 4)
(const_int 13))) 73 {addsi3} (nil)
(expr_list:REG_DEAD (reg/v:SI 4)
(nil)))
(insn 121 89 91 (set (reg:QI 0)
(const_int 0)) 39 {movqi} (nil)
(nil))
(insn/i:HI 91 121 93 (asm_operands/v ("outb %1,%0") ("") 0[
(reg:HI 1)
(reg:QI 0)
]
[
(asm_input:HI ("d"))
(asm_input:QI ("a"))
]
("/Net/lono/users/bmartin/Projects/CC_LONO/cc_lono/gcc-2.2.2/bkm/in.c"
) 14) -1 (insn_list 89 (nil))
(expr_list:REG_DEAD (reg:HI 2)
(nil)))
(note 93 91 97 "" NOTE_INSN_BLOCK_END)
The number 36 psuedo register does not seem to have been assigned
consistently in this pass. At Insn 89 it is assigned hard register
2, but at insn 91 it is assigned hard reg 1.
Gcc bug or misuse of asm() statements?
...bruce
Technical Details
Message-ID:
<9207252145.AA11555@oz.NeXT.COM>Path:
arc1-ca.pugleaf.net!sparky!uunet!cis.ohio-state.edu!next.com!Bruce_MartinShow Full Headers
Complete Article Headers
Newsgroups: gnu.gcc.bug Path: arc1-ca.pugleaf.net!sparky!uunet!cis.ohio-state.edu!next.com!Bruce_Martin From: Bruce_Martin@next.com (Bruce Martin) Subject: GCC 2.2.2 bug in register allocation Message-ID: <9207252145.AA11555@oz.NeXT.COM> Sender: gnulists@ai.mit.edu Organization: GNUs Not Usenet Distribution: gnu Date: Sat, 25 Jul 1992 07:45:33 GMT Approved: bug-gcc@prep.ai.mit.edu Lines: 174