On 11/07/2014 10:52 AM, Jan Hubicka wrote:
>> On 11/05/14 07:09, Jiong Wang wrote:
>>> the same ICE will happen on x86-64, if compile with -O2 -fPIC.
>>>
>>> the reason is for the following two functions, they are identical, so
>>> IPA-ICF
>>> pass try to transform the second function to call the first one directly.
>>>
>>> int
>>> atomic_compare_exchange_STRONG_RELEASE_ACQUIRE (int a, int b)
>>> {
>>>   return __atomic_compare_exchange (&v, &a, &b,
>>>                     STRONG, __ATOMIC_RELEASE,
>>>                     __ATOMIC_ACQUIRE);
>>> }
>>>
>>> int
>>> atomic_compare_exchange_n_STRONG_RELEASE_ACQUIRE (int a, int b)
>>> {
>>>   return __atomic_compare_exchange_n (&v, &a, b,
>>>                       STRONG, __ATOMIC_RELEASE,
>>>                       __ATOMIC_ACQUIRE);
>>> }
>>>
>>> while during this transformation, looks like there are something wrong
>>> with the
>>> function argument handling. take "a" for example, because later there
>>> are "&a",
>>> so it's marked as addressable. while after transformation, if we turn the
>>> second function into
>>>
>>> int atomic_compare_exchange_n_STRONG_RELEASE_ACQUIRE (int a, int b)
>>> {
>>>   return atomic_compare_exchange_STRONG_RELEASE_ACQUIRE (a, b)
>>> }
>>>
>>> then argument a is no longer addressable.
>>>
>>> so, in cgraph_node::release_body, when making the wrapper, except
>>> clearing the
>>> function body, we should also clear the addressable flag for function args
>>> because they are decided by the function body which is cleared.
>>>
>>> bootstrap ok on x86-64 and no regression.
>>> bootstrap ok on aarch64 juno.
>>> ICE gone away on arm & x86-64
>>>
>>> ok for trunk?
>>>
>>> gcc/
>>>
>>>   PR  tree-optimization/63721
>>>   * cgraph.c (cgraph_node::release_body): Clear addressable flag for
>>> function args.
>> While I understand the need to clear the addressable flag, I think
>> release_body probably isn't the best place to do this.  Seems to me
>> that ought to happen when we emit the thunk or otherwise transform
>> the body into something that doesn't take the address of those
>> parameters.
> 
> Yep, I would just move it into expand_thunk - the TREE_ADDRESSABLE bits are 
> not really
> well defined before we build the gimple body.
> 
> Honza
>>
>> jeff

Hello.

I think the bug is a duplicate of PR63580 and there's working patch that can 
bootstrap on x86_64-linux and no regression has been seen.

Ready for trunk?
Thanks,
Martin
gcc/ChangeLog:

2014-11-07  Martin Liska  <mli...@suse.cz>

        * cgraphunit.c (cgraph_node::create_wrapper):
        TREE_ADDRESSABLE is set to false for a newly created thunk.

gcc/testsuite/ChangeLog:

2014-11-07  Martin Liska  <mli...@suse.cz>

        * g++.dg/ipa/pr63580.C: New test.
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index 6f61f5c..89c96dc 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -2342,6 +2342,14 @@ cgraph_node::create_wrapper (cgraph_node *target)
 
     cgraph_edge *e = create_edge (target, NULL, 0, CGRAPH_FREQ_BASE);
 
+    tree arguments = DECL_ARGUMENTS (decl);
+
+    while (arguments)
+      {
+	TREE_ADDRESSABLE (arguments) = false;
+	arguments = TREE_CHAIN (arguments);
+      }
+
     expand_thunk (false, true);
     e->call_stmt_cannot_inline_p = true;
 
diff --git a/gcc/testsuite/g++.dg/ipa/pr63580.C b/gcc/testsuite/g++.dg/ipa/pr63580.C
new file mode 100644
index 0000000..904195a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ipa/pr63580.C
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-ipa-icf"  } */
+
+struct A
+{
+};
+template <class L, class R> A operator%(L, R);
+template <class A0, class A1, class A2, class A3>
+void make_tuple (A0 &, A1, A2, A3);
+A
+bar (int p1, char p2, int p3, double p4)
+{
+  A a;
+  make_tuple (p1, p2, p3, p4);
+  return "int; char; string; double; " % a;
+}
+A
+foo (int p1, char p2, int p3, double p4)
+{
+  A b;
+  make_tuple (p1, p2, p3, p4);
+  return "int; char; string; double; " % b;
+}
+
+/* { dg-final { scan-ipa-dump "Equal symbols: 1" "icf"  } } */
+/* { dg-final { cleanup-ipa-dump "icf" } } */

Reply via email to