https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67246
Bug ID: 67246 Summary: MIPS: lw (load word) is generated for byte bitfield, leading to unaligned access Product: gcc Version: 5.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: kugel at rockbox dot org Target Milestone: --- Created attachment 36194 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=36194&action=edit test program Hello, I hit a problem with unaligned accesses in the Linux kernel. The kernel defines struct iphdr { #if defined(__LITTLE_ENDIAN_BITFIELD) __u8 ihl:4, version:4; #elif defined (__BIG_ENDIAN_BITFIELD) __u8 version:4, ihl:4; #endif ... more fields ... }; Then, in a source file it does (net/core/flow_dissector.c) nhoff += iph->ihl * 4; GCC generates a lw for that 248: 8e220000 lw v0,0(s1) 24c: 8fa40044 lw a0,68(sp) 250: 7c421e00 ext v0,v0,0x18,0x4 254: 00021080 sll v0,v0,0x2 258: 00821021 addu v0,a0,v0 The problem is that iphdr can be 16bit aligned (due to ethernet header being 14 bytes, and iphdr usually follows). If that happens, this code generates a unaligned access which is really unwanted. I would expect that GCC uses a lbu to load that value, avoiding the unaligned access. I think GCCs behavior is buggy in this instance. I attached a small test program that also shows the problem.