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.