diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e6a2763e6e87cccbd01da5c73c54dc7794a927ed..39bbf199f0d678d0ad2188e405e51a48a7c9aaf2 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2015-12-14  Martin Jambor  <mjambor@suse.cz>
+
+	PR ipa/66616
+	* ipa-cp.c (propagate_constants_accross_call): Move thuk check...
+	(call_passes_through_thunk_p): ...here.
+	(find_more_scalar_values_for_callers_subset): Perform thunk checks
+	like propagate_constants_accross_call does.
+
 2015-12-14  Jakub Jelinek  <jakub@redhat.com>
 
 	PR rtl-optimization/68730
diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
index ee285500608664720a8b617761db8403b5c0f50b..8087f661d3e8bbb8df036a3d71c874e528b5b295 100644
--- a/gcc/ipa-cp.c
+++ b/gcc/ipa-cp.c
@@ -1877,6 +1877,18 @@ propagate_aggs_accross_jump_function (struct cgraph_edge *cs,
   return ret;
 }
 
+/* Return true if on the way cfrom CS->caller to the final (non-alias and
+   non-thunk) destination, the call passes through a thunk.  */
+
+static bool
+call_passes_through_thunk_p (cgraph_edge *cs)
+{
+  cgraph_node *alias_or_thunk = cs->callee;
+  while (alias_or_thunk->alias)
+    alias_or_thunk = alias_or_thunk->get_alias_target ();
+  return alias_or_thunk->thunk.thunk_p;
+}
+
 /* Propagate constants from the caller to the callee of CS.  INFO describes the
    caller.  */
 
@@ -1885,7 +1897,7 @@ propagate_constants_accross_call (struct cgraph_edge *cs)
 {
   struct ipa_node_params *callee_info;
   enum availability availability;
-  struct cgraph_node *callee, *alias_or_thunk;
+  cgraph_node *callee;
   struct ipa_edge_args *args;
   bool ret = false;
   int i, args_count, parms_count;
@@ -1923,10 +1935,7 @@ propagate_constants_accross_call (struct cgraph_edge *cs)
   /* If this call goes through a thunk we must not propagate to the first (0th)
      parameter.  However, we might need to uncover a thunk from below a series
      of aliases first.  */
-  alias_or_thunk = cs->callee;
-  while (alias_or_thunk->alias)
-    alias_or_thunk = alias_or_thunk->get_alias_target ();
-  if (alias_or_thunk->thunk.thunk_p)
+  if (call_passes_through_thunk_p (cs))
     {
       ret |= set_all_contains_variable (ipa_get_parm_lattices (callee_info,
 							       0));
@@ -3499,7 +3508,11 @@ find_more_scalar_values_for_callers_subset (struct cgraph_node *node,
 	  struct ipa_jump_func *jump_func;
 	  tree t;
 
-          if (i >= ipa_get_cs_argument_count (IPA_EDGE_REF (cs)))
+          if (i >= ipa_get_cs_argument_count (IPA_EDGE_REF (cs))
+	      || (i == 0
+		  && call_passes_through_thunk_p (cs))
+	      || (!cs->callee->instrumentation_clone
+		  && cs->callee->function_symbol ()->instrumentation_clone))
             {
               newval = NULL_TREE;
               break;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 2b900bfabac3f38d24095674375407ffd3150c76..cc8b9e2bdba1d3aa99b6fbce5491b2131bb722e0 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2015-12-14  Martin Jambor  <mjambor@suse.cz>
+
+	PR ipa/66616
+	* g++.dg/ipa/pr66616.C: New test.
+
 2015-12-14  Jakub Jelinek  <jakub@redhat.com>
 
 	PR rtl-optimization/68730
diff --git a/gcc/testsuite/g++.dg/ipa/pr66616.C b/gcc/testsuite/g++.dg/ipa/pr66616.C
new file mode 100644
index 0000000000000000000000000000000000000000..440ea6c6bfc1b75d370882bdf5415fa712541c2b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ipa/pr66616.C
@@ -0,0 +1,54 @@
+// { dg-do run }
+// { dg-options "-O2 -fipa-cp-clone" }
+
+struct Distraction
+{
+  char fc[8];
+  virtual Distraction * return_self ()
+  { return this; }
+};
+
+static int go;
+
+struct A;
+
+struct A
+{
+  int fi;
+
+  A () : fi(0) {}
+  A (int pi) : fi (pi) {}
+  virtual void foo (int p) = 0;
+};
+
+struct B;
+
+struct B : public Distraction, A
+{
+  B () : Distraction(), A() { }
+  B (int pi) : Distraction (), A (pi) {}
+  virtual void foo (int p)
+  {
+    int o = fi;
+    for (int i = 0; i < p; i++)
+      o += i + i * i;
+    go = o;
+  }
+};
+
+struct B gb2 (2);
+
+extern "C" void abort (void);
+
+int
+main (void)
+{
+  for (int i = 0; i < 2; i++)
+    {
+      struct A *p = &gb2;
+      p->foo (0);
+      if (go != 2)
+	abort ();
+    }
+  return 0;
+}