https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65067
Bug ID: 65067 Summary: regression on accessing volatile bit field Product: gcc Version: 5.0 Status: UNCONFIRMED Severity: major Priority: P3 Component: rtl-optimization Assignee: unassigned at gcc dot gnu.org Reporter: terry.guo at arm dot com Due to the impact of option -fstrict-volatile-bitfields, current trunk gcc generate worse code to access volatile bitfield which can be nicely handled with gcc 4.8. Here is test case: $ cat y.c #include <stdint.h> struct tmp { uint32_t dummy; union { struct { uint32_t xyz : 1; uint32_t mode: 3; uint32_t res : 28; } bf; uint32_t wordval; } reg; }; void set_mode(int mode) { volatile struct tmp *t = (struct tmp *) 0x1000; t->reg.bf.mode = mode; } When compiled with gcc 4.8 and command "gcc-arm-none-eabi-4_8-2014q3/bin/arm-none-eabi-gcc -mthumb -mcpu=cortex-m3 -O2 -S y.c", the generated code is good and expected: mov r3, #4096 ldr r2, [r3, #4] bfi r2, r0, #1, #3 str r2, [r3, #4] bx lr But when compiled with current gcc 5.0 and same command, worse code is generated: mov r2, #4096 ldr r3, [r2, #4] and r0, r0, #7 bic r3, r3, #14 orr r3, r3, r0, lsl #1 str r3, [r2, #4] bx lr If turn off the option -fstrict-volatile-bitfields, we can get expected code. In my opinion, this gcc code is making bad decision: /* Handle -fstrict-volatile-bitfields in the cases where it applies. */ if (strict_volatile_bitfield_p (str_rtx, bitsize, bitnum, fieldmode, bitregion_start, bitregion_end)) { The function strict_volatile_bitfield_p should make correct decision that we don't need to consider strict volatile bitfield here for this case. When debug this function, the arguments are: Breakpoint 1, strict_volatile_bitfield_p (op0=0x7ffff6096e88, bitsize=3, bitnum=33, fieldmode=SImode, bitregion_start=32, bitregion_end=63) The mode of op0 is also SImode. So it should be easy to figure out that we are working on a perfect 32-bit entity and no boundary crossing here.