Hi,
This modified test case exposes a bug in the already approved part of the
strict-volatile-bitfields patch:
#include <stdlib.h>
typedef struct {
char pad;
int arr[0];
} __attribute__((packed)) str;
str *
foo (int* src)
{
str *s = malloc (sizeof (str) + sizeof (int));
s->arr[0] = 0x12345678;
asm volatile("":::"memory");
*src = s->arr[0];
return s;
}
As we know this test case triggered a recursion in the store_bit_field on ARM
and on PowerPC,
which is no longer reproducible after this patch is applied:
http://gcc.gnu.org/ml/gcc-patches/2013-11/msg02025.html
Additionally it triggered a recursion on extract_bit_field, but _only_ on my
local copy of the trunk.
I had this patch installed, but did not expect it to change anything unless the
values are volatile.
That was cased by this hunk in the strict-volatile-bitfields v4 patch:
@@ -1691,45 +1736,19 @@ extract_fixed_bit_field (enum machine_mo
includes the entire field. If such a mode would be larger than
a word, we won't be doing the extraction the normal way. */
- if (MEM_VOLATILE_P (op0)
- && flag_strict_volatile_bitfields> 0)
- {
- if (GET_MODE_BITSIZE (GET_MODE (op0))> 0)
- mode = GET_MODE (op0);
- else if (target && GET_MODE_BITSIZE (GET_MODE (target))> 0)
- mode = GET_MODE (target);
- else
- mode = tmode;
- }
- else
- mode = get_best_mode (bitsize, bitnum, 0, 0,
- MEM_ALIGN (op0), word_mode, MEM_VOLATILE_P (op0));
+ mode = GET_MODE (op0);
+ if (GET_MODE_BITSIZE (mode) == 0
+ || GET_MODE_BITSIZE (mode)> GET_MODE_BITSIZE (word_mode))
+ mode = word_mode;
+ mode = get_best_mode (bitsize, bitnum, 0, 0,
+ MEM_ALIGN (op0), mode, MEM_VOLATILE_P (op0));
if (mode == VOIDmode)
/* The only way this should occur is if the field spans word
boundaries. */
return extract_split_bit_field (op0, bitsize, bitnum, unsignedp);
So the problem started, because initially this function did not look at
GET_MODE(op0)
and always used word_mode. That was changed, but now also affected non-volatile
data.
Now, if we solve this differently and install the C++ memory model patch,
we can avoid to introduce the recursion in the extract path,
and remove these two hunks in the update patch at the same time:
+ else if (MEM_P (str_rtx)
+ && MEM_VOLATILE_P (str_rtx)
+ && flag_strict_volatile_bitfields> 0)
+ /* This is a case where -fstrict-volatile-bitfields doesn't apply
+ because we can't do a single access in the declared mode of the field.
+ Since the incoming STR_RTX has already been adjusted to that mode,
+ fall back to word mode for subsequent logic. */
+ str_rtx = adjust_address (str_rtx, word_mode, 0);
Attached you'll find a new version of the bitfields-update patch,
it is again relative to the already approved version of the volatile-bitfields
patch v4, part 1/2.
Boot-strapped and regression-tested on X86_64-linux-gnu.
additionally tested with an ARM cross-compiler.
OK for trunk?
Thanks
Bernd. 2013-11-18 Bernd Edlinger <[email protected]> Sandra Loosemore <[email protected]> PR middle-end/23623 PR middle-end/48784 PR middle-end/56341 PR middle-end/56997 * expmed.c (strict_volatile_bitfield_p): Add bitregion_start and bitregion_end parameters. Test for compliance with C++ memory model. (store_bit_field): Adjust call to strict_volatile_bitfield_p. Add fallback logic for cases where -fstrict-volatile-bitfields is supposed to apply, but cannot. (extract_bit_field): Likewise. Use narrow_bit_field_mem and extract_fixed_bit_field_1 to do the extraction. (extract_fixed_bit_field): Revert to previous mode selection algorithm. Call extract_fixed_bit_field_1 to do the real work. (extract_fixed_bit_field_1): New function. testsuite: 2013-11-18 Bernd Edlinger <[email protected]> Sandra Loosemore <[email protected]> * gcc.dg/pr23623.c: Update to test interaction with C++ memory model.
patch-bitfields-update-1.diff
Description: Binary data
