> Looks ok to me, but can you add a testcase please? > > Also check if 4.9 is affected.
Sorry for the delay, this finally made it back to the top of my to-do list. Testcase included which fails without and passes with this patch. 4.9 is affected and the same patch fixes it. Tested on rx-elf, x86 32/64, and arm32. 2014-10-29 DJ Delorie <d...@redhat.com> * expmed.c (strict_volatile_bitfield_p): Fix off-by-one error. 2014-10-29 DJ Delorie <d...@redhat.com> * gcc.dg/20141029-1.c: New. Index: expmed.c =================================================================== --- expmed.c (revision 216811) +++ expmed.c (working copy) @@ -454,13 +454,13 @@ strict_volatile_bitfield_p (rtx op0, uns && bitnum % GET_MODE_ALIGNMENT (fieldmode) + bitsize > modesize)) return false; /* Check for cases where the C++ memory model applies. */ if (bitregion_end != 0 && (bitnum - bitnum % modesize < bitregion_start - || bitnum - bitnum % modesize + modesize > bitregion_end)) + || bitnum - bitnum % modesize + modesize - 1 > bitregion_end)) return false; return true; } /* Return true if OP is a memory and if a bitfield of size BITSIZE at Index: testsuite/gcc.dg/20141029-1.c =================================================================== --- testsuite/gcc.dg/20141029-1.c (revision 0) +++ testsuite/gcc.dg/20141029-1.c (revision 0) @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-options "-fstrict-volatile-bitfields -fdump-rtl-final" } */ + +#define PERIPH (*(volatile struct system_periph *)0x81234) + +struct system_periph { + union { + unsigned short WORD; + struct { + unsigned short a:1; + unsigned short b:1; + unsigned short :5; + unsigned short c:1; + unsigned short :8; + } BIT; + } ALL; +}; + +void +foo() +{ + while (1) + { + PERIPH.ALL.BIT.a = 1; + } +} +/* { dg-final { scan-rtl-dump-times "mem/v(/.)*:HI" 4 "final" } } */ +/* { dg-final { cleanup-rtl-dump "final" } } */