This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug optimization/14613] New: Fails to convert byte loads/stores to word/long loads/stores


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]