This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug tree-optimization/64718] New: Bad 16-bit bswap replacement
- From: "aaz at q-fu dot com" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Wed, 21 Jan 2015 17:42:35 +0000
- Subject: [Bug tree-optimization/64718] New: Bad 16-bit bswap replacement
- Auto-submitted: auto-generated
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64718
Bug ID: 64718
Summary: Bad 16-bit bswap replacement
Product: gcc
Version: 5.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: tree-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: aaz@q-fu.com
Target: i686-pc-linux-gnu
This code is reduced from htons((int)port) on FreeBSD.
The expression gets replaced with a rotation in a 32-bit register
instead of a 16-bit register, so the upper byte is lost.
int swap(int x) {
return (unsigned short)((unsigned short)x << 8 | (unsigned short)x >> 8);
}
gcc -O2 -S swap.c
swap:
movl 4(%esp), %eax
roll $8, %eax # should be %ax
movzwl %ax, %eax
ret
Complete program:
#include <stdio.h>
int swap(int x) {
return (unsigned short)((unsigned short)x << 8 | (unsigned short)x >> 8);
}
int a = 0x1234;
int main() {
int b = 0x1234;
printf("%x -> %x\n", a, swap(a));
printf("%x -> %x\n", b, swap(b));
}
gcc -O2 swap.c && ./a.out
1234 -> 3400
1234 -> 3412