This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug optimization/14613] New: Fails to convert byte loads/stores to word/long loads/stores
- From: "cesarb at nitnet dot com dot br" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 17 Mar 2004 00:13:12 -0000
- Subject: [Bug optimization/14613] New: Fails to convert byte loads/stores to word/long loads/stores
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
If you try to read a sequence of four bytes and treat it as a long in the native
byte order, gcc doesn't notice it could simply use a dword load. The same
happens on stores and for words.
Reading specs from /usr/lib/gcc-snapshot/lib/gcc/i486-linux/3.4.0/specs
Configured with: ../src/configure -v
--enable-languages=c,c++,java,f77,objc,ada,treelang
--prefix=/usr/lib/gcc-snapshot --enable-shared --with-system-zlib --enable-nls
--enable-threads=posix --without-included-gettext --enable-__cxa_atexit
--enable-clocale=gnu --enable-libstdcxx-debug --enable-java-gc=boehm
--enable-java-awt=xlib,gtk --with-cpp-install-dir=bin --disable-werror i486-linux
Thread model: posix
gcc version 3.4.0 20040314 (prerelease)
Testcase:
#include <stdint.h>
uint32_t intel_to_native32(uint8_t in[4])
{
return (uint32_t)in[0]
| ((uint32_t)in[1] << 8)
| ((uint32_t)in[2] << 16)
| ((uint32_t)in[3] << 24);
}
void native_to_intel32(uint8_t out[4], uint32_t in)
{
out[0] = in;
out[1] = in >> 8;
out[2] = in >> 16;
out[3] = in >> 24;
}
uint16_t intel_to_native16(uint8_t in[2])
{
return (uint16_t)in[0]
| ((uint16_t)in[1] << 8);
}
void native_to_intel16(uint8_t out[2], uint16_t in)
{
out[0] = in;
out[1] = in >> 8;
}
Compilation command line:
gcc -Wall -Wextra -march=athlon -O3 -save-temps -c testcase.c
Testcase output:
.file "testcase.i"
.text
.p2align 4,,15
.globl intel_to_native32
.type intel_to_native32, @function
intel_to_native32:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %ecx
movzbl 1(%ecx), %edx
movzbl (%ecx), %eax
sall $8, %edx
orl %edx, %eax
movzbl 2(%ecx), %edx
sall $16, %edx
orl %edx, %eax
movzbl 3(%ecx), %edx
leave
sall $24, %edx
orl %edx, %eax
ret
.size intel_to_native32, .-intel_to_native32
.p2align 4,,15
.globl native_to_intel32
.type native_to_intel32, @function
native_to_intel32:
pushl %ebp
movl %esp, %ebp
movl 12(%ebp), %eax
movl 8(%ebp), %edx
movb %al, (%edx)
shrl $8, %eax
movb %al, 1(%edx)
shrl $8, %eax
movb %al, 2(%edx)
shrl $8, %eax
movb %al, 3(%edx)
leave
ret
.size native_to_intel32, .-native_to_intel32
.p2align 4,,15
.globl intel_to_native16
.type intel_to_native16, @function
intel_to_native16:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %eax
movzbl 1(%eax), %edx
movzbl (%eax), %eax
leave
sall $8, %edx
orl %edx, %eax
ret
.size intel_to_native16, .-intel_to_native16
.p2align 4,,15
.globl native_to_intel16
.type native_to_intel16, @function
native_to_intel16:
pushl %ebp
movl %esp, %ebp
movl 12(%ebp), %eax
movl 8(%ebp), %edx
movb %al, (%edx)
shrw $8, %ax
movb %al, 1(%edx)
leave
ret
.size native_to_intel16, .-native_to_intel16
.section .note.GNU-stack,"",@progbits
.ident "GCC: (GNU) 3.4.0 20040314 (prerelease)"
Notice it used lots of byte memory accesses and shifts instead of a (possible
unaligned) dword or word access.
gcc should notice the code in (for instance) intel_to_native32 is, when compiled
for the x86 architecture, equivalent to
uint32_t intel_to_native32(uint8_t in[4])
{
return *(uint32_t*)in;
}
--
Summary: Fails to convert byte loads/stores to word/long
loads/stores
Product: gcc
Version: 3.4.0
Status: UNCONFIRMED
Severity: normal
Priority: P2
Component: optimization
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: cesarb at nitnet dot com dot br
CC: gcc-bugs at gcc dot gnu dot org
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=14613