PR tree-optimization/58145
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 14 Aug 2013 20:34:56 +0000 (20:34 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 14 Aug 2013 20:34:56 +0000 (20:34 +0000)
* tree-sra.c (build_ref_for_offset): If prev_base has
TREE_THIS_VOLATILE or TREE_SIDE_EFFECTS, propagate it to MEM_REF.

* gcc.dg/pr58145-1.c: New test.
* gcc.dg/pr58145-2.c: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@201748 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr58145-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/pr58145-2.c [new file with mode: 0644]
gcc/tree-sra.c

index 5d846b1..c7f229b 100644 (file)
@@ -1,4 +1,11 @@
+2013-08-14  Jakub Jelinek  <jakub@redhat.com>
+
+       PR tree-optimization/58145
+       * tree-sra.c (build_ref_for_offset): If prev_base has
+       TREE_THIS_VOLATILE or TREE_SIDE_EFFECTS, propagate it to MEM_REF.
+
 2013-08-14  Xinliang David Li  <davidxl@google.com>
+
        * config/i386/i386.c (ix86_option_override_internal):
        Fix potential unitialized variable error.
 
index c6f97fc..c56c260 100644 (file)
@@ -1,3 +1,9 @@
+2013-08-14  Jakub Jelinek  <jakub@redhat.com>
+
+       PR tree-optimization/58145
+       * gcc.dg/pr58145-1.c: New test.
+       * gcc.dg/pr58145-2.c: New test.
+
 2013-08-14  Joern Rennecke <joern.rennecke@embecosm.com>
 
        * gcc.dg/debug/dwarf2/dwarf2.exp: Replace -gdwarf-2 with -gdwarf.
diff --git a/gcc/testsuite/gcc.dg/pr58145-1.c b/gcc/testsuite/gcc.dg/pr58145-1.c
new file mode 100644 (file)
index 0000000..0e236c0
--- /dev/null
@@ -0,0 +1,37 @@
+/* PR tree-optimization/58145 */
+/* { dg-do compile { target { int32plus } } } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+struct S { unsigned int data : 32; };
+struct T { unsigned int data; };
+volatile struct S s2;
+
+void
+f1 (int val)
+{
+  struct S s = { .data = val };
+  *(volatile struct S *) 0x880000UL = s;
+}
+
+void
+f2 (int val)
+{
+  struct T t = { .data = val };
+  *(volatile struct T *) 0x880000UL = t;
+}
+
+void
+f3 (int val)
+{
+  *(volatile unsigned int *) 0x880000UL = val;
+}
+
+void
+f4 (int val)
+{
+  struct S s = { .data = val };
+  s2 = s;
+}
+
+/* { dg-final { scan-tree-dump-times " ={v} " 4 "optimized" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/pr58145-2.c b/gcc/testsuite/gcc.dg/pr58145-2.c
new file mode 100644 (file)
index 0000000..840e982
--- /dev/null
@@ -0,0 +1,51 @@
+/* PR tree-optimization/58145 */
+/* { dg-do compile { target { int32plus } } } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+struct S { unsigned int data : 32; };
+struct T { unsigned int data; };
+volatile struct S s2;
+
+static inline void
+f1 (int val)
+{
+  struct S s = { .data = val };
+  *(volatile struct S *) 0x880000UL = s;
+}
+
+static inline void
+f2 (int val)
+{
+  struct T t = { .data = val };
+  *(volatile struct T *) 0x880000UL = t;
+}
+
+static inline void
+f3 (int val)
+{
+  *(volatile unsigned int *) 0x880000UL = val;
+}
+
+static inline void
+f4 (int val)
+{
+  struct S s = { .data = val };
+  s2 = s;
+}
+
+void
+f5 (void)
+{
+  int i;
+  for (i = 0; i < 100; i++)
+    f1 (0);
+  for (i = 0; i < 100; i++)
+    f2 (0);
+  for (i = 0; i < 100; i++)
+    f3 (0);
+  for (i = 0; i < 100; i++)
+    f4 (0);
+}
+
+/* { dg-final { scan-tree-dump-times " ={v} " 4 "optimized" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
index 2bce848..8e3bb81 100644 (file)
@@ -1466,6 +1466,7 @@ build_ref_for_offset (location_t loc, tree base, HOST_WIDE_INT offset,
 {
   tree prev_base = base;
   tree off;
+  tree mem_ref;
   HOST_WIDE_INT base_offset;
   unsigned HOST_WIDE_INT misalign;
   unsigned int align;
@@ -1516,7 +1517,12 @@ build_ref_for_offset (location_t loc, tree base, HOST_WIDE_INT offset,
   if (align < TYPE_ALIGN (exp_type))
     exp_type = build_aligned_type (exp_type, align);
 
-  return fold_build2_loc (loc, MEM_REF, exp_type, base, off);
+  mem_ref = fold_build2_loc (loc, MEM_REF, exp_type, base, off);
+  if (TREE_THIS_VOLATILE (prev_base))
+    TREE_THIS_VOLATILE (mem_ref) = 1;
+  if (TREE_SIDE_EFFECTS (prev_base))
+    TREE_SIDE_EFFECTS (mem_ref) = 1;
+  return mem_ref;
 }
 
 /* Construct a memory reference to a part of an aggregate BASE at the given