diff mbox

Fix for ipa/63595

Message ID 545C9F2D.7000905@suse.cz
State New
Headers show

Commit Message

Martin Liška Nov. 7, 2014, 10:30 a.m. UTC
Hello.

Following patch fixes PR/63595, where IPA ICF creates a thunk that passes argument by reference. Patch can bootstrap x86_64-linux and there's no new regression introduced.

Patch was preapproved by Honza.

Thanks,
Martin
gcc/testsuite/ChangeLog:

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

	PR ipa/63595
	* g++.dg/ipa/pr63595.C: New test.


gcc/ChangeLog:

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

	PR ipa/63595
	* g++.dg/ipa/pr63595.C: New test.
	* cgraphunit.c (cgraph_node::expand_thunk): DECL_BY_REFERENCE
	is correctly handled for thunks created by IPA ICF.
diff mbox

Patch

diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index 6f61f5c..2e4af6a 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -1546,7 +1546,15 @@  cgraph_node::expand_thunk (bool output_asm_thunks, bool force_gimple_thunk)
       if (!VOID_TYPE_P (restype))
 	{
 	  if (DECL_BY_REFERENCE (resdecl))
-	    restmp = gimple_fold_indirect_ref (resdecl);
+	    {
+	      restmp = gimple_fold_indirect_ref (resdecl);
+	      if (!restmp)
+		restmp = build2 (MEM_REF,
+				 TREE_TYPE (TREE_TYPE (DECL_RESULT (alias))),
+				 resdecl,
+				 build_int_cst (TREE_TYPE
+				   (DECL_RESULT (alias)), 0));
+	    }
 	  else if (!is_gimple_reg_type (restype))
 	    {
 	      restmp = resdecl;
@@ -1641,7 +1649,11 @@  cgraph_node::expand_thunk (bool output_asm_thunks, bool force_gimple_thunk)
 	    gimple_call_set_tail (call, true);
 
 	  /* Build return value.  */
-	  ret = gimple_build_return (restmp);
+	  if (!DECL_BY_REFERENCE (resdecl))
+	    ret = gimple_build_return (restmp);
+	  else
+	    ret = gimple_build_return (resdecl);
+
 	  gsi_insert_after (&bsi, ret, GSI_NEW_STMT);
 	}
       else
diff --git a/gcc/testsuite/g++.dg/ipa/pr63595.C b/gcc/testsuite/g++.dg/ipa/pr63595.C
new file mode 100644
index 0000000..30e9303
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ipa/pr63595.C
@@ -0,0 +1,80 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-ipa-icf-details"  } */
+
+template <int dim> class B;
+template <int, int dim> class TriaObjectAccessor;
+template <int, typename Accessor> class A;
+template <int dim> class TriaDimensionInfo {
+public:
+  typedef A<3, TriaObjectAccessor<2, 3> > raw_quad_iterator;
+  typedef A<3, B<3> > raw_hex_iterator;
+  typedef raw_hex_iterator raw_cell_iterator;
+};
+template <int dim> class Triangulation : public TriaDimensionInfo<1> {
+  public:
+  typedef typename TriaDimensionInfo<dim>::raw_quad_iterator raw_quad_iterator;
+  TriaDimensionInfo::raw_cell_iterator end() const;
+  raw_quad_iterator end_quad() const {
+    return raw_quad_iterator(const_cast<Triangulation *>(this), 0, 0);
+  }
+};
+template <int dim> class TriaAccessor {
+public:
+  typedef void AccessorData;
+  TriaAccessor(const Triangulation<dim> * = 0);
+  Triangulation<1> *tria;
+
+  int a, b, c;
+};
+template <int dim> class TriaObjectAccessor<2, dim> : public TriaAccessor<dim> {
+public:
+  typedef typename TriaAccessor<dim>::AccessorData AccessorData;
+  TriaObjectAccessor(const Triangulation<dim> * = 0);
+};
+template <int dim> class TriaObjectAccessor<3, dim> : public TriaAccessor<dim> {
+public:
+  typedef typename TriaAccessor<dim>::AccessorData AccessorData;
+  TriaObjectAccessor(const Triangulation<dim> * = 0);
+};
+template <int dim> class B : public TriaObjectAccessor<dim, dim> {
+public:
+  typedef typename TriaObjectAccessor<dim, dim>::AccessorData AccessorData;
+  B(const Triangulation<dim> * = 0);
+};
+template <int dim, typename Accessor> class A {
+public:
+  A(const A &);
+  A(const Triangulation<dim> *, int, int);
+  Accessor accessor;
+};
+template class Triangulation<3>;
+template <int dim, typename Accessor>
+A<dim, Accessor>::A(const Triangulation<dim> *, int, int) {}
+template <int dim>
+TriaAccessor<dim>::TriaAccessor(const Triangulation<dim> *)
+    : tria(), a(-1), b(-2), c(-3) {}
+template <int dim>
+TriaObjectAccessor<2, dim>::TriaObjectAccessor(const Triangulation<dim> *) {}
+template <int dim>
+TriaObjectAccessor<3, dim>::TriaObjectAccessor(const Triangulation<dim> *) {}
+template <int dim> B<dim>::B(const Triangulation<dim> *) {}
+template <>
+TriaDimensionInfo<3>::raw_cell_iterator Triangulation<3>::end() const {
+  return raw_hex_iterator(const_cast<Triangulation *>(this), 0, 0);
+}
+
+#pragma GCC optimize ("-O0")
+int main()
+{
+  Triangulation <3> t;
+  Triangulation<3>::raw_quad_iterator i1 = t.end_quad();
+  TriaDimensionInfo<3>::raw_cell_iterator i2 = t.end();
+
+  if(i2.accessor.c != -3)
+    return 1;
+
+  return 0;
+}
+
+/* { dg-final { scan-ipa-dump "Equal symbols: 1" "icf"  } } */
+/* { dg-final { cleanup-ipa-dump "icf" } } */