Hi!

As the following testcase shows, for thunks the expansion code sometimes
requires that arguments with gimple reg type aren't addressable,
thunk needs to be simple passing of arguments directly to another call, not
having extra statements in between that.

In particular, for pass_by_reference arguments calls.c has if
call_from_thunk_p:
              /* We may have turned the parameter value into an SSA name.
                 Go back to the original parameter so we can take the
                 address.  */
              if (TREE_CODE (args[i].tree_value) == SSA_NAME)
                {
                  gcc_assert (SSA_NAME_IS_DEFAULT_DEF (args[i].tree_value));
                  args[i].tree_value = SSA_NAME_VAR (args[i].tree_value);
                  gcc_assert (TREE_CODE (args[i].tree_value) == PARM_DECL);
                }
which is not the case if the PARM_DECL is TREE_ADDRESSABLE, then the def
stmt of the SSA_NAME is an assignment which loads the PARM_DECL value from
"memory".

TREE_ADDRESSABLE on the arguments is copied from the ctor from which it is
cloned (and which will be called by the thunk).  In this case the argument
needs to be addressable because vector[idx] folding takes address of vector.
In the thunk itself that doesn't matter though, it just passes the argument
to another function, so the following patch clears the TREE_ADDRESSABLE bit
there.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2019-02-05  Jakub Jelinek  <ja...@redhat.com>

        PR c++/89187
        * optimize.c (maybe_thunk_body): Clear TREE_ADDRESSABLE on
        non-aggregate PARM_DECLs of the thunk.

        * g++.dg/opt/pr89187.C: New test.

--- gcc/cp/optimize.c.jj        2019-01-21 23:32:43.000000000 +0100
+++ gcc/cp/optimize.c   2019-02-04 16:40:21.354179933 +0100
@@ -417,6 +417,12 @@ maybe_thunk_body (tree fn, bool force)
                  gcc_assert (clone_parm);
                  DECL_ABSTRACT_ORIGIN (clone_parm) = NULL;
                  args[parmno] = clone_parm;
+                 /* Clear TREE_ADDRESSABLE on arguments with non-aggregate
+                    types, the thunk will not take addresses of those
+                    arguments, will just pass them through to another
+                    call.  */
+                 if (!AGGREGATE_TYPE_P (TREE_TYPE (clone_parm)))
+                   TREE_ADDRESSABLE (clone_parm) = 0;
                  clone_parm = TREE_CHAIN (clone_parm);
                }
              if (fn_parm_typelist)
--- gcc/testsuite/g++.dg/opt/pr89187.C.jj       2019-02-04 17:34:13.973847193 
+0100
+++ gcc/testsuite/g++.dg/opt/pr89187.C  2019-02-04 17:34:41.191396316 +0100
@@ -0,0 +1,23 @@
+// PR c++/89187
+// { dg-do compile { target c++11 } }
+// { dg-options "-Os -fno-tree-ccp -fno-tree-sra -fno-inline" }
+
+template <typename T, int N> struct A {
+  typedef T __attribute__((vector_size (N))) type;
+};
+template <typename T, int N> using B = typename A<T, N>::type;
+template <typename T> using C = B<T, 4>;
+struct D {
+  D (C<int> x) : d{x[3]} {}
+  D foo () { return d; }
+  C<int> d;
+};
+extern D d;
+struct { D bar () { return d; } } l;
+struct E { void baz () const; };
+
+void
+E::baz () const
+{
+  l.bar ().foo ();
+}

        Jakub

Reply via email to