[backport r171347 from gcc-4.7/trunk, part 1/2 of ARM PR51442 fix ] Date: Wed, 23 Mar 2011 12:00:34 +0000 From: Julian Brown Subject: Re: [PATCH] Volatile bitfields vs. inline asm memory constraints List-Archive: On Wed, 9 Feb 2011 09:37:41 -0500 Diego Novillo wrote: > On Mon, Nov 22, 2010 at 08:28, Julian Brown > wrote: > > Hi, > > > > This patch fixes the issue in the (Launchpad, not GCC) bug tracker: > > > > https://bugs.launchpad.net/gcc-linaro/+bug/675347 > > > > The problem was introduced by the patch from DJ to honour volatile > > bitfield types: > > > > http://gcc.gnu.org/ml/gcc-patches/2010-06/msg01167.html > > > > but not exposed (on ARM) until the option was made the default (on > > the Linaro branch) -- it's not yet the default on mainline. > > > > The issue is as follows: after DJ's patch and with > > -fstrict-volatile-bitfields, in expr.c:expand_expr_real_1, the if > > condition with the comment "In cases where an aligned union has an > > unaligned object as a field, we might be extracting a BLKmode value > > from an integer-mode (e.g., SImode) object [...]" triggers for a > > normal (non-bitfield) volatile field of a struct/class. > > > > Could you add a comment before the test to describe why you are > excluding non-natural alignments? > > OK with that change, though I think you'll have to stage this for 4.7. I've committed this version now we're in stage 1. (I also re-tested it for good measure, no regressions with cross to ARM Linux.) Thanks, Julian gcc/ 2011-03-23 Julian Brown * expr.c (expand_expr_real_1): Only use BLKmode for volatile accesses which are not naturally aligned. --- gcc-4.6.2/gcc/expr.c.~1~ 2011-08-10 11:17:32.000000000 +0200 +++ gcc-4.6.2/gcc/expr.c 2011-12-10 14:20:50.000000000 +0100 @@ -9189,8 +9189,11 @@ expand_expr_real_1 (tree exp, rtx target && modifier != EXPAND_CONST_ADDRESS && modifier != EXPAND_INITIALIZER) /* If the field is volatile, we always want an aligned - access. */ - || (volatilep && flag_strict_volatile_bitfields > 0) + access. Only do this if the access is not already naturally + aligned, otherwise "normal" (non-bitfield) volatile fields + become non-addressable. */ + || (volatilep && flag_strict_volatile_bitfields > 0 + && (bitpos % GET_MODE_ALIGNMENT (mode) != 0)) /* If the field isn't aligned enough to fetch as a memref, fetch it as a bit field. */ || (mode1 != BLKmode