Index: cgraph.h
===================================================================
--- cgraph.h	(revision 237999)
+++ cgraph.h	(working copy)
@@ -2175,6 +2175,9 @@ public:
   /* Set the DECL_ASSEMBLER_NAME and update symtab hashtables.  */
   void change_decl_assembler_name (tree decl, tree name);
 
+  /* Hash asmnames ignoring the user specified marks.  */
+  static hashval_t decl_assembler_name_hash (const_tree asmname);
+
   /* Return true if assembler names NAME1 and NAME2 leads to the same symbol
      name.  */
   static bool assembler_names_equal_p (const char *name1, const char *name2);
@@ -2243,9 +2246,6 @@ private:
   /* Remove NODE from assembler name hash.  */
   void unlink_from_assembler_name_hash (symtab_node *node, bool with_clones);
 
-  /* Hash asmnames ignoring the user specified marks.  */
-  static hashval_t decl_assembler_name_hash (const_tree asmname);
-
   /* Compare ASMNAME with the DECL_ASSEMBLER_NAME of DECL.  */
   static bool decl_assembler_name_equal (tree decl, const_tree asmname);
 
Index: fold-const.c
===================================================================
--- fold-const.c	(revision 237999)
+++ fold-const.c	(working copy)
@@ -3226,6 +3226,17 @@ operand_equal_p (const_tree arg0, const_
 	}
 
     case tcc_declaration:
+      /* During WPA we can be called before the DECL nodes are merged.  */
+      if (flag_wpa
+	  && TREE_CODE (arg0) == VAR_DECL
+	  && (TREE_PUBLIC (arg0) || DECL_EXTERNAL (arg0))
+	  && (TREE_PUBLIC (arg1) || DECL_EXTERNAL (arg1)))
+	return symbol_table::assembler_names_equal_p
+		 (IDENTIFIER_POINTER
+		    (DECL_ASSEMBLER_NAME (const_cast<tree> (arg0))),
+		  IDENTIFIER_POINTER
+		    (DECL_ASSEMBLER_NAME (const_cast<tree> (arg1))));
+
       /* Consider __builtin_sqrt equal to sqrt.  */
       return (TREE_CODE (arg0) == FUNCTION_DECL
 	      && DECL_BUILT_IN (arg0) && DECL_BUILT_IN (arg1)
Index: lto/lto.c
===================================================================
--- lto/lto.c	(revision 237999)
+++ lto/lto.c	(working copy)
@@ -2506,15 +2506,55 @@ lto_wpa_write_files (void)
   timevar_pop (TV_WHOPR_WPA_IO);
 }
 
+/* Look inside *EXPR into simple arithmetic operations involving constants.
+   Return the address of the outermost non-arithmetic or non-constant node.
+   This should be equivalent to tree.c:skip_simple_constant_arithmetic.  */
 
-/* If TT is a variable or function decl replace it with its
-   prevailing variant.  */
+static tree *
+walk_simple_constant_arithmetic (tree *expr)
+{
+  while (TREE_CODE (*expr) == NON_LVALUE_EXPR)
+    expr = &TREE_OPERAND (*expr, 0);
+
+  while (true)
+    {
+      if (UNARY_CLASS_P (*expr))
+	expr = &TREE_OPERAND (*expr, 0);
+      else if (BINARY_CLASS_P (*expr))
+	{
+	  if (TREE_CONSTANT (TREE_OPERAND (*expr, 1)))
+	    expr = &TREE_OPERAND (*expr, 0);
+	  else if (TREE_CONSTANT (TREE_OPERAND (*expr, 0)))
+	    expr = &TREE_OPERAND (*expr, 1);
+	  else
+	    break;
+	}
+      else
+	break;
+    }
+
+  return expr;
+}
+
+/* If TT is a variable or function decl or a simple expression containing one,
+   replace the occurrence with its prevailing variant.  This should be able to
+   deal with all the expressions attached to _DECL and _TYPE nodes which were
+   streamed into the GIMPLE IR.  */
 #define LTO_SET_PREVAIL(tt) \
   do {\
+    tree *loc; \
     if ((tt) && VAR_OR_FUNCTION_DECL_P (tt) \
 	&& (TREE_PUBLIC (tt) || DECL_EXTERNAL (tt))) \
       { \
-        tt = lto_symtab_prevailing_decl (tt); \
+	tt = lto_symtab_prevailing_decl (tt); \
+	fixed = true; \
+      } \
+    else if ((tt) && EXPR_P (tt) \
+	     && (loc = walk_simple_constant_arithmetic (&tt)) \
+	     && VAR_OR_FUNCTION_DECL_P (*loc) \
+	     && (TREE_PUBLIC (*loc) || DECL_EXTERNAL (*loc))) \
+      { \
+	*loc = lto_symtab_prevailing_decl (*loc); \
 	fixed = true; \
       } \
   } while (0)
Index: tree.c
===================================================================
--- tree.c	(revision 237999)
+++ tree.c	(working copy)
@@ -7878,8 +7878,17 @@ add_expr (const_tree t, inchash::hash &h
 
       if (tclass == tcc_declaration)
 	{
-	  /* DECL's have a unique ID */
-	  hstate.add_wide_int (DECL_UID (t));
+	  /* During WPA we can be called before the DECL nodes are merged.  */
+	  if (flag_wpa
+	      && TREE_CODE (t) == VAR_DECL
+	      && (TREE_PUBLIC (t) || DECL_EXTERNAL (t)))
+	    {
+	      tree x = DECL_ASSEMBLER_NAME (const_cast <tree> (t));
+	      hstate.merge_hash (symbol_table::decl_assembler_name_hash (x));
+	    }
+	  else
+	    /* DECL's have a unique ID */
+	    hstate.add_wide_int (DECL_UID (t));
 	}
       else if (tclass == tcc_comparison && !commutative_tree_code (code))
 	{
