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.

Reply via email to