diff options
author | Bernd Edlinger <bernd.edlinger@hotmail.de> | 2015-03-05 18:56:37 +0000 |
---|---|---|
committer | Bernd Edlinger <edlinger@gcc.gnu.org> | 2015-03-05 18:56:37 +0000 |
commit | 53c615a2769209147ad242d646051954b3a2b8f4 (patch) | |
tree | 9e9c800b382c8690b9fcedb6e5aaba6e7dd1e858 /gcc | |
parent | 9374ef820b2e1b5410bfd9ccb4c2dbd023a369c6 (diff) | |
download | gcc-53c615a2769209147ad242d646051954b3a2b8f4.zip gcc-53c615a2769209147ad242d646051954b3a2b8f4.tar.gz gcc-53c615a2769209147ad242d646051954b3a2b8f4.tar.bz2 |
re PR rtl-optimization/65067 (regression on accessing volatile bit field)
gcc:
2015-03-05 Bernd Edlinger <bernd.edlinger@hotmail.de>
PR rtl-optimization/65067
* expmed.c (store_bit_field, extract_bit_field): Reworked the
strict volatile bitfield handling.
testsuite:
2015-03-05 Bernd Edlinger <bernd.edlinger@hotmail.de>
* gcc.target/arm/pr65067.c: New test.
From-SVN: r221222
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/expmed.c | 34 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/arm/pr65067.c | 22 |
4 files changed, 49 insertions, 17 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f780919..3ec2d1c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2015-03-05 Bernd Edlinger <bernd.edlinger@hotmail.de> + + PR rtl-optimization/65067 + * expmed.c (store_bit_field, extract_bit_field): Reworked the + strict volatile bitfield handling. + 2015-03-05 Martin Liska <mliska@suse.cz> PR ipa/65318 diff --git a/gcc/expmed.c b/gcc/expmed.c index 18e62a0..0034203 100644 --- a/gcc/expmed.c +++ b/gcc/expmed.c @@ -976,7 +976,7 @@ store_bit_field (rtx str_rtx, unsigned HOST_WIDE_INT bitsize, /* Storing any naturally aligned field can be done with a simple store. For targets that support fast unaligned memory, any naturally sized, unit aligned field can be done directly. */ - if (simple_mem_bitfield_p (str_rtx, bitsize, bitnum, fieldmode)) + if (bitsize == GET_MODE_BITSIZE (fieldmode)) { str_rtx = adjust_bitfield_address (str_rtx, fieldmode, bitnum / BITS_PER_UNIT); @@ -984,12 +984,16 @@ store_bit_field (rtx str_rtx, unsigned HOST_WIDE_INT bitsize, } else { + rtx temp; + str_rtx = narrow_bit_field_mem (str_rtx, fieldmode, bitsize, bitnum, &bitnum); - /* Explicitly override the C/C++ memory model; ignore the - bit range so that we can do the access in the mode mandated - by -fstrict-volatile-bitfields instead. */ - store_fixed_bit_field_1 (str_rtx, bitsize, bitnum, value); + temp = copy_to_reg (str_rtx); + if (!store_bit_field_1 (temp, bitsize, bitnum, 0, 0, + fieldmode, value, true)) + gcc_unreachable (); + + emit_move_insn (str_rtx, temp); } return; @@ -1786,24 +1790,20 @@ extract_bit_field (rtx str_rtx, unsigned HOST_WIDE_INT bitsize, if (strict_volatile_bitfield_p (str_rtx, bitsize, bitnum, mode1, 0, 0)) { - rtx result; - /* Extraction of a full MODE1 value can be done with a load as long as the field is on a byte boundary and is sufficiently aligned. */ - if (simple_mem_bitfield_p (str_rtx, bitsize, bitnum, mode1)) - result = adjust_bitfield_address (str_rtx, mode1, - bitnum / BITS_PER_UNIT); - else + if (bitsize == GET_MODE_BITSIZE(mode1)) { - str_rtx = narrow_bit_field_mem (str_rtx, mode1, bitsize, bitnum, - &bitnum); - result = extract_fixed_bit_field_1 (mode, str_rtx, bitsize, bitnum, - target, unsignedp); + rtx result = adjust_bitfield_address (str_rtx, mode1, + bitnum / BITS_PER_UNIT); + return convert_extracted_bit_field (result, mode, tmode, unsignedp); } - return convert_extracted_bit_field (result, mode, tmode, unsignedp); + str_rtx = narrow_bit_field_mem (str_rtx, mode1, bitsize, bitnum, + &bitnum); + str_rtx = copy_to_reg (str_rtx); } - + return extract_bit_field_1 (str_rtx, bitsize, bitnum, unsignedp, target, mode, tmode, true); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 09d42b3..321db12 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2015-03-05 Bernd Edlinger <bernd.edlinger@hotmail.de> + + * gcc.target/arm/pr65067.c: New test. + 2015-03-05 Martin Liska <mliska@suse.cz> PR ipa/65318 diff --git a/gcc/testsuite/gcc.target/arm/pr65067.c b/gcc/testsuite/gcc.target/arm/pr65067.c new file mode 100644 index 0000000..9ddd7bb --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/pr65067.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-options "-mthumb -mcpu=cortex-m3 -O2" } */ + +struct tmp { + unsigned int dummy; + union { + struct { + unsigned int xyz : 1; + unsigned int mode: 3; + unsigned int res : 28; + } bf; + unsigned int wordval; + } reg; +}; + +void set_mode(int mode) +{ + volatile struct tmp *t = (struct tmp *) 0x1000; + t->reg.bf.mode = mode; +} + +/* { dg-final { scan-assembler "bfi" } } */ |