Bug 36661 - x86 asm "+r" operands cause unnecessary spills/copies
Summary: x86 asm "+r" operands cause unnecessary spills/copies
Status: UNCONFIRMED
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 4.4.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: inline-asm
Depends on:
Blocks:
 
Reported: 2008-06-28 23:34 UTC by astrange+gcc@gmail.com
Modified: 2021-09-13 21:33 UTC (History)
1 user (show)

See Also:
Host:
Target: i?86-*-*
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments
testcase (325 bytes, text/plain)
2008-06-28 23:35 UTC, astrange+gcc@gmail.com
Details

Note You need to log in before you can comment on or make changes to this bug.
Description astrange+gcc@gmail.com 2008-06-28 23:34:31 UTC
Compiling the attached source on i386 with:
> gcc -O3  -fomit-frame-pointer -fno-pic -S asm-spills.i
produces:
	.text
	.align 4,0x90
.globl _get_cabac_noinline
_get_cabac_noinline:
	subl	$76, %esp
	movl	%esi, 64(%esp)
	movl	%edi, 68(%esp)
	movl	%ebp, 72(%esp)
	movl	%ebx, 60(%esp)
	movl	80(%esp), %esi
	movl	84(%esp), %edi
	movl	(%esi), %edx
	movl	4(%esi), %ebx
	movl	%edx, 28(%esp) # unused spill
	movl	%edx, %ebp # pointless move
# 24 "../strange-spills.i" 1
	#%eax %bp %ebx 16(%esi) %edx (%edi)
# 0 "" 2
	movl	%ebp, (%esi)
	movl	%ebx, 4(%esi)
	andl	$1, %eax
	movl	60(%esp), %ebx
	movl	%eax, 44(%esp) #unused spill
	movl	64(%esp), %esi
	movl	68(%esp), %edi
	movl	72(%esp), %ebp
	addl	$76, %esp
	ret
	.subsections_via_symbols

which has several unnecessary stack spills.

Reading through RTL dumps:
- everything is fine before asmcons
- asmcons inserts copies of c->low/range after they're loaded. There's no point to this, since the original is never used later, but I guess there isn't a problem as long as it's cleaned up.
- Somehow, the RA gets confused by the asmcons copy and the later one to copy the return value into eax. Instead of assigning both sides of the copy to the same register (which is obviously possible), or even using mov, it spills and reloads them into different registers.
- Later passes optimize away the reloads but keep the stores.

This isn't a regression (gcc 3.4 isn't much better) and still happens in the IRA branch. For some reason, changing "=&q"(tmp) to "=&d" improves IRA but not trunk.

This is about the same source as http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36539.
Comment 1 astrange+gcc@gmail.com 2008-06-28 23:35:04 UTC
Created attachment 15823 [details]
testcase