[Bug middle-end/33989] New: Extra load/store for float with union
pinskia at gcc dot gnu dot org
gcc-bugzilla@gcc.gnu.org
Sat Nov 3 17:47:00 GMT 2007
Testcase:
union a
{
int i;
float f;
};
void f(float *a, int *b, float e)
{
union a c;
c.f = *a + e;
*b = c.i;
}
--- CUT ---
Currently we get (on x86):
subl $28, %esp
movl 32(%esp), %eax
flds 40(%esp)
fadds (%eax)
movl 36(%esp), %eax
fstps 12(%esp) <--- extra store
movl 12(%esp), %edx <--- extra load
movl %edx, (%eax) <--- store result to *b
addl $28, %esp
ret
Or with -mfpmath=sse:
_f:
subl $28, %esp
movl 32(%esp), %eax
movss 40(%esp), %xmm0
addss (%eax), %xmm0
movl 36(%esp), %eax
movss %xmm0, 12(%esp) <--- extra store
movl 12(%esp), %edx <--- extra load
movl %edx, (%eax) <---store result to *b
addl $28, %esp
ret
Or on PPC:
f:
lfs 0,0(3)
stwu 1,-16(1)
fadds 0,1,0
stfs 0,8(1) <--- extra store
lwz 0,8(1) <--- extra load
addi 1,1,16
stw 0,0(4) <--- store result to *b
blr
The issue is that SFmode cannot be in integer registers.
The rtl looks like:
(insn 8 7 9 3 t1.c:10 (set (reg:SF 124)
(mem:SF (reg/v/f:SI 120 [ a ]) [2 S4 A32])) -1 (nil))
(insn 9 8 10 3 t1.c:10 (set (reg:SF 123)
(plus:SF (reg/v:SF 122 [ e ])
(reg:SF 124))) -1 (nil))
(insn 10 9 11 3 t1.c:10 (set (subreg:SF (reg/v:SI 119 [ c ]) 0)
(reg:SF 123)) -1 (nil))
(insn 11 10 16 3 t1.c:11 (set (mem:SI (reg/v/f:SI 121 [ b ]) [3 S4 A32])
(reg/v:SI 119 [ c ])) -1 (nil))
See how we could translate register 119 (SImode) into a register that is in
SFmode and get away with it.
--
Summary: Extra load/store for float with union
Product: gcc
Version: 4.3.0
Status: UNCONFIRMED
Keywords: missed-optimization
Severity: enhancement
Priority: P3
Component: middle-end
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: pinskia at gcc dot gnu dot org
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33989
More information about the Gcc-bugs
mailing list