re PR tree-optimization/47005 (ACATS c62002a is miscompiled at -O2)
authorEric Botcazou <ebotcazou@adacore.com>
Wed, 5 Jan 2011 11:23:40 +0000 (11:23 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Wed, 5 Jan 2011 11:23:40 +0000 (11:23 +0000)
PR tree-optimization/47005
* tree-sra.c (struct access): Add 'non_addressable' bit.
(create_access): Set it for a DECL_NONADDRESSABLE_P field.
(decide_one_param_reduction): Return 0 if the parameter is passed by
reference and one of the accesses in the group is non_addressable.

From-SVN: r168508

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gnat.dg/opt14.adb [new file with mode: 0644]
gcc/tree-sra.c

index 01412bd09614389b69a035716b4177f02af5779d..d25e30c1bd13ebeb0354af4d39704a6d43a9d995 100644 (file)
@@ -1,3 +1,11 @@
+2011-01-05  Eric Botcazou  <ebotcazou@adacore.com>
+
+       PR tree-optimization/47005
+       * tree-sra.c (struct access): Add 'non_addressable' bit.
+       (create_access): Set it for a DECL_NONADDRESSABLE_P field.
+       (decide_one_param_reduction): Return 0 if the parameter is passed by
+       reference and one of the accesses in the group is non_addressable.
+
 2011-01-04  Eric Botcazou  <ebotcazou@adacore.com>
 
        PR tree-optimization/47056
index 208304ce79aade84a16fffb4b3cbfe3b75356d8d..867e6a09550bf847286316250e8be8189a5fb914 100644 (file)
@@ -1,3 +1,7 @@
+2011-01-05  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * gnat.dg/opt14.adb: New test.
+
 2011-01-05  Thomas Koenig  <tkoenig@gcc.gnu.org>
 
        PR fortran/46017
diff --git a/gcc/testsuite/gnat.dg/opt14.adb b/gcc/testsuite/gnat.dg/opt14.adb
new file mode 100644 (file)
index 0000000..61bc731
--- /dev/null
@@ -0,0 +1,25 @@
+-- { dg-do run }
+-- { dg-options "-O2" }
+
+procedure Opt14 is
+
+  type Rec is record
+    I1, I2, I3 : Integer;
+  end record;
+
+  type Ptr is access Rec;
+
+  P : Ptr := new Rec'(0,0,0);
+
+  procedure Sub (R : In Out Rec) is
+  begin
+    R.I3 := R.I3 - 1;
+  end;
+
+begin
+  P.all := (1,2,3);
+  Sub (P.all);
+  if P.all /= (1,2,2) then
+    raise Program_Error;
+  end if;
+end;
index 14fef477485cef1262f67da921bd5b173d10a18a..c2ec20429322f23eba5e7c257bab80e75d9b57d4 100644 (file)
@@ -173,6 +173,9 @@ struct access
      entirely? */
   unsigned total_scalarization : 1;
 
+  /* Is this access an access to a non-addressable field? */
+  unsigned non_addressable : 1;
+
   /* Is this access currently in the work queue?  */
   unsigned grp_queued : 1;
 
@@ -816,6 +819,10 @@ create_access (tree expr, gimple stmt, bool write)
   access->grp_unscalarizable_region = unscalarizable_region;
   access->stmt = stmt;
 
+  if (TREE_CODE (expr) == COMPONENT_REF
+      && DECL_NONADDRESSABLE_P (TREE_OPERAND (expr, 1)))
+    access->non_addressable = 1;
+
   return access;
 }
 
@@ -3666,13 +3673,18 @@ decide_one_param_reduction (struct access *repr)
   for (; repr; repr = repr->next_grp)
     {
       gcc_assert (parm == repr->base);
-      new_param_count++;
+
+      /* Taking the address of a non-addressable field is verboten.  */
+      if (by_ref && repr->non_addressable)
+       return 0;
 
       if (!by_ref || (!repr->grp_maybe_modified
                      && !repr->grp_not_necessarilly_dereferenced))
        total_size += repr->size;
       else
        total_size += cur_parm_size;
+
+      new_param_count++;
     }
 
   gcc_assert (new_param_count > 0);