This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Fix C++0x memory model for -fno-strict-volatile-bitfields on ARM
- From: Richard Biener <richard dot guenther at gmail dot com>
- To: Bernd Edlinger <bernd dot edlinger at hotmail dot de>
- Cc: Jason Merrill <jason at redhat dot com>, "Joseph S. Myers" <joseph at codesourcery dot com>, "gcc-patches at gcc dot gnu dot org" <gcc-patches at gcc dot gnu dot org>, Sandra Loosemore <sandra at codesourcery dot com>
- Date: Fri, 15 Nov 2013 13:30:51 +0100
- Subject: Re: [PATCH] Fix C++0x memory model for -fno-strict-volatile-bitfields on ARM
- Authentication-results: sourceware.org; auth=none
- References: <DUB122-W15E51EED0BDD4E4BBB7280E40D0 at phx dot gbl> <CAFiYyc3B19C+KzWADqMuFftHBsf9R-BVmhx3byk4HMaHDZVCgQ at mail dot gmail dot com> <DUB122-W349FBC26ACB80FE7DB42E7E40D0 at phx dot gbl> <DUB122-W34629C286171333E30C282E40B0 at phx dot gbl> <CAFiYyc2rzP3kt3O8GcDRFbae=YXFgUrjSTkwRpYv-CA3BzrjAQ at mail dot gmail dot com> <DUB122-W30700270BEE314AA5EED7AE4FB0 at phx dot gbl>
On Fri, Nov 15, 2013 at 12:38 PM, Bernd Edlinger
<bernd.edlinger@hotmail.de> wrote:
>>
>> Err, well. This just means that the generic C++ memory model
>> handling isn't complete. We do
>>
>> if (TREE_CODE (to) == COMPONENT_REF
>> && DECL_BIT_FIELD_TYPE (TREE_OPERAND (to, 1)))
>> get_bit_range (&bitregion_start, &bitregion_end, to, &bitpos, &offset);
>>
>> and thus restrict ourselves to bitfields to initialize the region we may touch.
>> This just lacks computing bitregion_start / bitregion_end for other
>> fields.
>>
>> Btw, what does the C++ memory model say for
>>
>> struct { char x; short a; short b; } a __attribute__((packed));
>>
>> short *p = &a.a;
>>
>> *p = 1;
>>
>
> this is not allowed. It should get at least a warning, that p is assigned
> a value, which violates the alignment restrictions.
> with packed structures you always have to access as "a.a".
>
>> I suppose '*p' may not touch bits outside of a.a either? Or are
>> memory accesses via pointers less constrained? What about
>> array element accesses?
>>
>
> of course, *p may not access anything else than a short.
> but the code generation may assume the pointer is aligned.
>
>> That is, don't we need
>>
>> else
>> {
>> bitregion_start = 0;
>> bitregion_end = bitsize;
>> }
>>
>> ?
>>
>> Richard.
>>
>
> That looks like always pretending it is a bit field.
> But it is not a bit field, and bitregion_start=bitregion_end=0
> means it is an ordinary value.
I don't think it is supposed to mean that. It's supposed to mean
"the access is unconstrained".
> It is just the bottom half of the expansion in expmed.c that does
> not handle that really well, most of that code seems to ignore the
> C++ memory model. For instance store_split_bit_field only handles
> bitregion_end and not bitregion_start. And I do not see, why it
> tries to write beyond a packed field at all. But that was OK in the past.
>
> And then there is this:
>
> if (get_best_mem_extraction_insn (&insv, EP_insv, bitsize, bitnum,
> fieldmode)
> && store_bit_field_using_insv (&insv, op0, bitsize, bitnum, value))
> return true;
>
> which dies not even care about bitregion_start/end.
Hopefully insv targets exactly match bitnum/bitsize.
> An look at that code in store_bit_field:
>
> if (MEM_P (str_rtx) && bitregion_start> 0)
> {
> enum machine_mode bestmode;
> HOST_WIDE_INT offset, size;
>
> gcc_assert ((bitregion_start % BITS_PER_UNIT) == 0);
>
> offset = bitregion_start / BITS_PER_UNIT;
> bitnum -= bitregion_start;
> size = (bitnum + bitsize + BITS_PER_UNIT - 1) / BITS_PER_UNIT;
> bitregion_end -= bitregion_start;
> bitregion_start = 0;
> bestmode = get_best_mode (bitsize, bitnum,
> bitregion_start, bitregion_end,
> MEM_ALIGN (str_rtx), VOIDmode,
> MEM_VOLATILE_P (str_rtx));
> str_rtx = adjust_bitfield_address_size (str_rtx, bestmode, offset, size);
> }
>
> I'd bet 1 Euro, that the person who wrote that, did that because it was too difficult and error-prone
> to re-write all the code below, and found it much safer to change the bitregion_start/end
> here instead.
It wasn't me ;)
> My patch is just layered on this if-block to accomplish the task. And that is why I think it is the
> right place here.
Well. You are looking at the alignment of str_rtx which I'm not sure
whether it's the correct alignment at this point (we at least start
with the alignment of the base).
+ /* Treat unaligned fields like bit regions otherwise we might
+ touch bits outside the field. */
+ if (MEM_P (str_rtx) && bitregion_start == 0 && bitregion_end == 0
+ && bitsize > 0 && bitsize % BITS_PER_UNIT == 0
bitsize is always > 0, why restrict it to byte-sized accesses?
+ && bitnum % BITS_PER_UNIT == 0
and byte-aligned accesses?
+ && (bitsize % MIN (MEM_ALIGN (str_rtx), BITS_PER_WORD) > 0
+ || bitnum % MIN (MEM_ALIGN (str_rtx), BITS_PER_WORD) > 0))
and what's this BITS_PER_WORD doing here? It seems what you
are testing for (and should say so in the comment) is non-power-of-two
size accesses or accesses that are not naturally aligned.
But as said, I fail to see why doing this here instead of at the
point we compute the initial bitregion_start/end is appropriate - you
are after all affecting callers such as
calls.c: store_bit_field (reg, bitsize, endian_correction, 0, 0,
and not only those that will possibly start from a non-zero bitregion_start/end.
Richard.
+ {
+ bitregion_start = bitnum;
+ bitregion_end = bitnum + bitsize - 1;
+ }
> Bernd.