re PR rtl-optimization/65067 (regression on accessing volatile bit field)
authorBernd Edlinger <bernd.edlinger@hotmail.de>
Thu, 5 Mar 2015 18:56:37 +0000 (18:56 +0000)
committerBernd Edlinger <edlinger@gcc.gnu.org>
Thu, 5 Mar 2015 18:56:37 +0000 (18:56 +0000)
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

gcc/ChangeLog
gcc/expmed.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/arm/pr65067.c [new file with mode: 0644]

index f78091957da115ee2244d1ea57b362beaaff51da..3ec2d1c726825bd3e172eeb9263737ea6dbce0d1 100644 (file)
@@ -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
index 18e62a000b4b8e8558924d30276f82d0693723ba..0034203c2f707eb317d51cda762414022d7df3e7 100644 (file)
@@ -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);
 }
index 09d42b3d851b43b38cb51d2ed1fe7372ff603725..321db122f76632dfa39e94dd2df944e00443a159 100644 (file)
@@ -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 (file)
index 0000000..9ddd7bb
--- /dev/null
@@ -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" } } */