]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR ipa/70760 (wrong generated code for std::make_unique with -fipa-pta)
authorRichard Biener <rguenther@suse.de>
Wed, 27 Apr 2016 14:10:04 +0000 (14:10 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Wed, 27 Apr 2016 14:10:04 +0000 (14:10 +0000)
2016-04-27  Richard Biener  <rguenther@suse.de>

PR ipa/70760
* tree-ssa-structalias.c (find_func_aliases_for_call): Use
aggregate_value_p to determine if a function result is
returned by reference.
(ipa_pta_execute): Functions having their address taken are
not automatically nonlocal.

* g++.dg/ipa/ipa-pta-2.C: New testcase.
* gcc.dg/ipa/ipa-pta-1.c: Adjust.

From-SVN: r235511

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/ipa/ipa-pta-2.C [new file with mode: 0644]
gcc/testsuite/gcc.dg/ipa/ipa-pta-1.c
gcc/tree-ssa-structalias.c

index 6d26cb00a95d013e7bac5457fb31ea65a7a723df..cbfae1ffe66d7f345b5043f39a4dd7afc4b83812 100644 (file)
@@ -1,3 +1,12 @@
+2016-04-27  Richard Biener  <rguenther@suse.de>
+
+       PR ipa/70760
+       * tree-ssa-structalias.c (find_func_aliases_for_call): Use
+       aggregate_value_p to determine if a function result is
+       returned by reference.
+       (ipa_pta_execute): Functions having their address taken are
+       not automatically nonlocal.
+
 2016-04-27  Jakub Jelinek  <jakub@redhat.com>
 
        PR sanitizer/70683
index e51f3bf2c8821e1191afe58929cf8dce2e87d14d..34dd7783938b32dc1662aa23d3d40edcaccb969c 100644 (file)
@@ -1,3 +1,9 @@
+2016-04-27  Richard Biener  <rguenther@suse.de>
+
+       PR ipa/70760
+       * g++.dg/ipa/ipa-pta-2.C: New testcase.
+       * gcc.dg/ipa/ipa-pta-1.c: Adjust.
+
 2016-04-27  Nathan Sidwell  <nathan@acm.org>
 
        * g++.dg/cpp0x/constexpr-recursion3.C: New.
diff --git a/gcc/testsuite/g++.dg/ipa/ipa-pta-2.C b/gcc/testsuite/g++.dg/ipa/ipa-pta-2.C
new file mode 100644 (file)
index 0000000..fd7c793
--- /dev/null
@@ -0,0 +1,37 @@
+// { dg-do run }
+// { dg-options "-O2 -fipa-pta" }
+
+extern "C" void abort (void);
+
+struct Y { ~Y(); int i; };
+
+Y::~Y () {}
+
+static Y __attribute__((noinline)) foo ()
+{
+  Y res;
+  res.i = 3;
+  return res;
+}
+
+static Y __attribute__((noinline)) bar ()
+{
+  Y res;
+  res.i = 42;
+  return res;
+}
+
+static Y (*fn) ();
+
+int a;
+int main()
+{
+  if (a)
+    fn = foo;
+  else
+    fn = bar;
+  Y res = fn ();
+  if (res.i != 42)
+    abort ();
+  return 0;
+}
index bc631f8856de3a65794b47f0e211db8ccdec01d1..4fdd25cc7364efaf1592d8f8f0a406e4ca0c61fd 100644 (file)
@@ -40,13 +40,10 @@ int main()
 }
 
 /* IPA PTA needs to handle indirect calls properly.  Verify that
-   both bar and foo get a (and only a) in their arguments points-to sets.
-   ???  As bar and foo have their address taken there might be callers
-   not seen by IPA PTA (if the address escapes the unit which we only compute
-   during IPA PTA...).  Thus the solution also includes NONLOCAL.  */
+   both bar and foo get a (and only a) in their arguments points-to sets.  */
 
 /* { dg-final { scan-ipa-dump "fn_1 = { bar foo }" "pta2" } } */
-/* { dg-final { scan-ipa-dump "bar.arg0 = { NONLOCAL a }" "pta2" } } */
-/* { dg-final { scan-ipa-dump "bar.arg1 = { NONLOCAL a }" "pta2" } } */
-/* { dg-final { scan-ipa-dump "foo.arg0 = { NONLOCAL a }" "pta2" } } */
-/* { dg-final { scan-ipa-dump "foo.arg1 = { NONLOCAL a }" "pta2" } } */
+/* { dg-final { scan-ipa-dump "bar.arg0 = { a }" "pta2" } } */
+/* { dg-final { scan-ipa-dump "bar.arg1 = { a }" "pta2" } } */
+/* { dg-final { scan-ipa-dump "foo.arg0 = { a }" "pta2" } } */
+/* { dg-final { scan-ipa-dump "foo.arg1 = { a }" "pta2" } } */
index 8c25af7088d747cd23e67498c3bb083a3a8edfb0..0a4149489a9e8687a3c91923b9adc50484931e85 100644 (file)
@@ -4641,12 +4641,11 @@ find_func_aliases_for_call (struct function *fn, gcall *t)
          auto_vec<ce_s, 2> lhsc;
          struct constraint_expr rhs;
          struct constraint_expr *lhsp;
+         bool aggr_p = aggregate_value_p (lhsop, gimple_call_fntype (t));
 
          get_constraint_for (lhsop, &lhsc);
          rhs = get_function_part_constraint (fi, fi_result);
-         if (fndecl
-             && DECL_RESULT (fndecl)
-             && DECL_BY_REFERENCE (DECL_RESULT (fndecl)))
+         if (aggr_p)
            {
              auto_vec<ce_s, 2> tem;
              tem.quick_push (rhs);
@@ -4656,22 +4655,19 @@ find_func_aliases_for_call (struct function *fn, gcall *t)
            }
          FOR_EACH_VEC_ELT (lhsc, j, lhsp)
            process_constraint (new_constraint (*lhsp, rhs));
-       }
 
-      /* If we pass the result decl by reference, honor that.  */
-      if (lhsop
-         && fndecl
-         && DECL_RESULT (fndecl)
-         && DECL_BY_REFERENCE (DECL_RESULT (fndecl)))
-       {
-         struct constraint_expr lhs;
-         struct constraint_expr *rhsp;
+         /* If we pass the result decl by reference, honor that.  */
+         if (aggr_p)
+           {
+             struct constraint_expr lhs;
+             struct constraint_expr *rhsp;
 
-         get_constraint_for_address_of (lhsop, &rhsc);
-         lhs = get_function_part_constraint (fi, fi_result);
-         FOR_EACH_VEC_ELT (rhsc, j, rhsp)
-           process_constraint (new_constraint (lhs, *rhsp));
-         rhsc.truncate (0);
+             get_constraint_for_address_of (lhsop, &rhsc);
+             lhs = get_function_part_constraint (fi, fi_result);
+             FOR_EACH_VEC_ELT (rhsc, j, rhsp)
+                 process_constraint (new_constraint (lhs, *rhsp));
+             rhsc.truncate (0);
+           }
        }
 
       /* If we use a static chain, pass it along.  */
@@ -7686,30 +7682,13 @@ ipa_pta_execute (void)
 
       gcc_assert (!node->clone_of);
 
-      /* When parallelizing a code region, we split the region off into a
-        separate function, to be run by several threads in parallel.  So for a
-        function foo, we split off a region into a function
-        foo._0 (void *foodata), and replace the region with some variant of a
-        function call run_on_threads (&foo._0, data).  The '&foo._0' sets the
-        address_taken bit for function foo._0, which would make it non-local.
-        But for the purpose of ipa-pta, we can regard the run_on_threads call
-        as a local call foo._0 (data),  so we ignore address_taken on nodes
-        with parallelized_function set.
-        Note: this is only safe, if foo and foo._0 are in the same lto
-        partition.  */
-      bool node_address_taken = ((node->parallelized_function
-                                 && !node->used_from_other_partition)
-                                ? false
-                                : node->address_taken);
-
       /* For externally visible or attribute used annotated functions use
         local constraints for their arguments.
         For local functions we see all callers and thus do not need initial
         constraints for parameters.  */
       bool nonlocal_p = (node->used_from_other_partition
                         || node->externally_visible
-                        || node->force_output
-                        || node_address_taken);
+                        || node->force_output);
       node->call_for_symbol_thunks_and_aliases (refered_from_nonlocal_fn,
                                                &nonlocal_p, true);