diff --git a/gcc/ipa-prop.cc b/gcc/ipa-prop.cc
index e55fe2776f2..72aa3e2f60d 100644
--- a/gcc/ipa-prop.cc
+++ b/gcc/ipa-prop.cc
@@ -4181,6 +4181,20 @@ propagate_controlled_uses (struct cgraph_edge *cs)
 	  int d = ipa_get_controlled_uses (old_root_info, i);
 	  int c = rdesc->refcount;
 	  rdesc->refcount = combine_controlled_uses_counters (c, d);
+	  if (rdesc->refcount != IPA_UNDESCRIBED_USE
+	      && ipa_get_param_load_dereferenced (old_root_info, i))
+	    {
+	      tree cst = ipa_get_jf_constant (jf);
+	      gcc_checking_assert (TREE_CODE (cst) == ADDR_EXPR
+				   && (TREE_CODE (TREE_OPERAND (cst, 0))
+				       == VAR_DECL));
+	      symtab_node *n = symtab_node::get (TREE_OPERAND (cst, 0));
+	      new_root->create_reference (n, IPA_REF_LOAD, NULL);
+	      if (dump_file)
+		fprintf (dump_file, "ipa-prop: Address IPA constant will reach "
+			 "a load so adding LOAD reference from %s to %s.\n",
+			 new_root->dump_name (), n->dump_name ());
+	    }
 	  if (rdesc->refcount == 0)
 	    {
 	      tree cst = ipa_get_jf_constant (jf);
@@ -4193,20 +4207,8 @@ propagate_controlled_uses (struct cgraph_edge *cs)
 	      symtab_node *n = symtab_node::get (TREE_OPERAND (cst, 0));
 	      if (n)
 		{
-		  struct cgraph_node *clone;
-		  bool removed = remove_described_reference (n, rdesc);
-		  /* The reference might have been removed by IPA-CP.  */
-		  if (removed
-		      && ipa_get_param_load_dereferenced (old_root_info, i))
-		    {
-		      new_root->create_reference (n, IPA_REF_LOAD, NULL);
-		      if (dump_file)
-			fprintf (dump_file, "ipa-prop: ...replaced it with "
-				 "LOAD one from %s to %s.\n",
-				 new_root->dump_name (), n->dump_name ());
-		    }
-
-		  clone = cs->caller;
+		  remove_described_reference (n, rdesc);
+		  cgraph_node *clone = cs->caller;
 		  while (clone->inlined_to
 			 && clone->ipcp_clone
 			 && clone != rdesc->cs->caller)
diff --git a/gcc/testsuite/gcc.dg/ipa/remref-6.c b/gcc/testsuite/gcc.dg/ipa/remref-6.c
index 7deae3114a4..f31f4c14319 100644
--- a/gcc/testsuite/gcc.dg/ipa/remref-6.c
+++ b/gcc/testsuite/gcc.dg/ipa/remref-6.c
@@ -20,5 +20,5 @@ void entry()
 }
 
 /* { dg-final { scan-ipa-dump "Removed a reference"  "inline" } }  */
-/* { dg-final { scan-ipa-dump "replaced it with LOAD"  "inline"  } } */
+/* { dg-final { scan-ipa-dump "adding LOAD reference"  "inline"  } } */
 /* { dg-final { scan-tree-dump-not "builtin_exp"  "optimized"  } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/remref-7.c b/gcc/testsuite/gcc.dg/ipa/remref-7.c
new file mode 100644
index 00000000000..b2c26ab7fd5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/remref-7.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fno-early-inlining -fno-ipa-sra -fdump-ipa-inline"  }  */
+
+int rglobal = 0;
+int g;
+
+int c;
+double *array;
+
+/* unused parameter */
+static void bar(int *p)
+{
+  int i;
+  for (i = 0; i < c; i++)
+    {
+      /* something big so that it is inlined second. */
+      array[i] = __builtin_exp(array[i]+1)*2;
+    }
+}
+
+void foo(int *p) {
+  g = *p;
+  bar(p);
+}
+
+void entry()
+{
+  foo(&rglobal);
+}
+
+/* { dg-final { scan-ipa-dump "Removed a reference"  "inline" } }  */
+/* { dg-final { scan-ipa-dump "adding LOAD reference"  "inline"  } } */
+
diff --git a/gcc/testsuite/gcc.dg/lto/pr103171_0.c b/gcc/testsuite/gcc.dg/lto/pr103171_0.c
new file mode 100644
index 00000000000..5dc17d6c6c8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/lto/pr103171_0.c
@@ -0,0 +1,11 @@
+/* { dg-lto-do link } */
+/* { dg-lto-options { { -O2 -flto -flto-partition=1to1 -fno-early-inlining -fno-ipa-sra -w } } } */
+
+extern void __attribute__((noinline)) entry(void);
+
+int
+main (int argc, char **argv)
+{
+  entry();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/lto/pr103171_1.c b/gcc/testsuite/gcc.dg/lto/pr103171_1.c
new file mode 100644
index 00000000000..39aed25daf7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/lto/pr103171_1.c
@@ -0,0 +1,35 @@
+int rglobal = 0;
+
+volatile int g;
+volatile int c;
+volatile double *array;
+
+/* unused parameter */
+static void
+bar(int *p)
+{
+  int i;
+  for (i = 0; i < c; i++)
+    {
+      /* something big so that it is inlined second. */
+      array[i] = (array[i+1]+array[i]+1)*2;
+    }
+}
+
+void foo(int *p) {
+  g = *p;
+  bar(p);
+}
+
+void __attribute__((noinline))
+entry(void)
+{
+  foo(&rglobal);
+}
+
+void __attribute__((used))
+blah(int *p)
+{
+  bar(p);
+}
+
