OSDN Git Service

2012-02-14 Richard Guenther <rguenther@suse.de>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 14 Feb 2012 15:33:56 +0000 (15:33 +0000)
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 14 Feb 2012 15:33:56 +0000 (15:33 +0000)
PR tree-optimization/52244
PR tree-optimization/51528
* tree-sra.c (analyze_access_subtree): Only create INTEGER_TYPE
replacements for integral types.

* gcc.dg/torture/pr52244.c: New testcase.

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

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr52244.c [new file with mode: 0644]
gcc/tree-sra.c

index eca470c..407a61f 100644 (file)
@@ -1,3 +1,10 @@
+2012-02-14  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/52244
+       PR tree-optimization/51528
+       * tree-sra.c (analyze_access_subtree): Only create INTEGER_TYPE
+       replacements for integral types.
+
 2012-02-14  Walter Lee  <walt@tilera.com>
 
        * config.gcc: Handle tilegx and tilepro.
index 05a6af0..963e1bf 100644 (file)
@@ -1,3 +1,9 @@
+2012-02-14  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/52244
+       PR tree-optimization/51528
+       * gcc.dg/torture/pr52244.c: New testcase.
+
 2012-02-14  Walter Lee  <walt@tilera.com>
 
        * g++.dg/other/PR23205.C: Disable test on tile.
diff --git a/gcc/testsuite/gcc.dg/torture/pr52244.c b/gcc/testsuite/gcc.dg/torture/pr52244.c
new file mode 100644 (file)
index 0000000..2a29e3c
--- /dev/null
@@ -0,0 +1,36 @@
+/* { dg-do run } */
+
+extern void abort (void);
+
+typedef union u_r 
+{
+  _Bool b;
+  unsigned char c;
+} u_t;
+
+u_t
+bar (void)
+{
+  u_t u;
+  u.c = 0x12;
+  return u;
+}
+
+u_t  __attribute__ ((noinline))
+foo (void)
+{
+  u_t u;
+
+  u.b = 1;
+  u = bar ();
+
+  return u;
+}
+
+int main (int argc, char **argv)
+{
+  u_t u = foo ();
+  if (u.c != 0x12)
+    abort ();
+  return 0;
+}
index e2091e5..1439c43 100644 (file)
@@ -2172,11 +2172,21 @@ analyze_access_subtree (struct access *root, struct access *parent,
              && (root->grp_scalar_write || root->grp_assignment_write))))
     {
       bool new_integer_type;
-      if (TREE_CODE (root->type) == ENUMERAL_TYPE)
+      /* Always create access replacements that cover the whole access.
+         For integral types this means the precision has to match.
+        Avoid assumptions based on the integral type kind, too.  */
+      if (INTEGRAL_TYPE_P (root->type)
+         && (TREE_CODE (root->type) != INTEGER_TYPE
+             || TYPE_PRECISION (root->type) != root->size)
+         /* But leave bitfield accesses alone.  */
+         && (root->offset % BITS_PER_UNIT) == 0)
        {
          tree rt = root->type;
-         root->type = build_nonstandard_integer_type (TYPE_PRECISION (rt),
+         root->type = build_nonstandard_integer_type (root->size,
                                                       TYPE_UNSIGNED (rt));
+         root->expr = build_ref_for_offset (UNKNOWN_LOCATION,
+                                            root->base, root->offset,
+                                            root->type, NULL, false);
          new_integer_type = true;
        }
       else