diff --git a/gcc/ipa-icf-gimple.c b/gcc/ipa-icf-gimple.c
index f75951f7c49..26337dd7384 100644
--- a/gcc/ipa-icf-gimple.c
+++ b/gcc/ipa-icf-gimple.c
@@ -40,6 +40,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "attribs.h"
 #include "gimple-walk.h"
 
+#include "tree-ssa-alias-compare.h"
 #include "ipa-icf-gimple.h"
 
 namespace ipa_icf_gimple {
@@ -52,13 +53,13 @@ namespace ipa_icf_gimple {
    of declarations that can be skipped.  */
 
 func_checker::func_checker (tree source_func_decl, tree target_func_decl,
-			    bool ignore_labels,
+			    bool ignore_labels, bool tbaa,
 			    hash_set<symtab_node *> *ignored_source_nodes,
 			    hash_set<symtab_node *> *ignored_target_nodes)
   : m_source_func_decl (source_func_decl), m_target_func_decl (target_func_decl),
     m_ignored_source_nodes (ignored_source_nodes),
     m_ignored_target_nodes (ignored_target_nodes),
-    m_ignore_labels (ignore_labels)
+    m_ignore_labels (ignore_labels), m_tbaa (tbaa)
 {
   function *source_func = DECL_STRUCT_FUNCTION (source_func_decl);
   function *target_func = DECL_STRUCT_FUNCTION (target_func_decl);
@@ -252,9 +253,16 @@ func_checker::hash_operand (const_tree arg, inchash::hash &hstate,
 
 void
 func_checker::hash_operand (const_tree arg, inchash::hash &hstate,
-			    unsigned int flags, operand_access_type)
+			    unsigned int flags, operand_access_type access)
 {
-  return hash_operand (arg, hstate, flags);
+  if (access == OP_MEMORY)
+    {
+      ao_ref ref;
+      ao_ref_init (&ref, const_cast <tree> (arg));
+      return hash_ao_ref (&ref, lto_streaming_expected_p (), m_tbaa, hstate);
+    }
+  else
+    return hash_operand (arg, hstate, flags);
 }
 
 bool
@@ -314,18 +322,40 @@ func_checker::compare_operand (tree t1, tree t2, operand_access_type access)
     return true;
   else if (!t1 || !t2)
     return false;
-  if (operand_equal_p (t1, t2, OEP_MATCH_SIDE_EFFECTS))
-    return true;
-  switch (access)
+  if (access == OP_MEMORY)
     {
-    case OP_MEMORY:
-      return return_false_with_msg
-		 ("operand_equal_p failed (access == memory)");
-    case OP_NORMAL:
+      ao_ref ref1, ref2;
+      ao_ref_init (&ref1, const_cast <tree> (t1));
+      ao_ref_init (&ref2, const_cast <tree> (t2));
+      int flags = compare_ao_refs (&ref1, &ref2,
+				   lto_streaming_expected_p (), m_tbaa);
+
+      if (!flags)
+	return true;
+      if (flags & SEMANTICS)
+	return return_false_with_msg
+		("compare_ao_refs failed (semantic difference)");
+      if (flags & BASE_ALIAS_SET)
+	return return_false_with_msg
+		("compare_ao_refs failed (base alias set difference)");
+      if (flags & REF_ALIAS_SET)
+	return return_false_with_msg
+		 ("compare_ao_refs failed (ref alias set difference)");
+      if (flags & ACCESS_PATH)
+	return return_false_with_msg
+		 ("compare_ao_refs failed (access path difference)");
+      if (flags & DEPENDENCE_CLIQUE)
+	return return_false_with_msg
+		 ("compare_ao_refs failed (dependence clique difference)");
+      gcc_unreachable ();
+    }
+  else
+    {
+      if (operand_equal_p (t1, t2, OEP_MATCH_SIDE_EFFECTS))
+	return true;
       return return_false_with_msg
-		 ("operand_equal_p failed (access == normal)");
+		 ("operand_equal_p failed");
     }
-  gcc_unreachable ();
 }
 
 bool
@@ -658,10 +695,10 @@ func_checker::compare_gimple_assign (gimple *s1, gimple *s2)
       arg2 = gimple_op (s2, i);
 
       /* Compare types for LHS.  */
-      if (i == 0)
+      if (i == 0 && !gimple_store_p (s1))
 	{
 	  if (!compatible_types_p (TREE_TYPE (arg1), TREE_TYPE (arg2)))
-	    return return_false_with_msg ("GIMPLE NOP LHS type mismatch");
+	    return return_false_with_msg ("GIMPLE LHS type mismatch");
 	}
 
       if (!compare_operand (arg1, arg2, get_operand_access_type (&map, arg1)))
diff --git a/gcc/ipa-icf-gimple.h b/gcc/ipa-icf-gimple.h
index f251d08100f..dd4ef13c716 100644
--- a/gcc/ipa-icf-gimple.h
+++ b/gcc/ipa-icf-gimple.h
@@ -118,14 +118,14 @@ public:
 
 /* A class aggregating all connections and semantic equivalents
    for a given pair of semantic function candidates.  */
-class func_checker : operand_compare
+class func_checker : ao_compare
 {
 public:
   /* Default constructor.  */
   func_checker ():
     m_source_func_decl (NULL_TREE), m_target_func_decl (NULL_TREE),
     m_ignored_source_nodes (NULL), m_ignored_target_nodes (NULL),
-    m_ignore_labels (false)
+    m_ignore_labels (false), m_tbaa (true)
   {
     m_source_ssa_names.create (0);
     m_target_ssa_names.create (0);
@@ -139,6 +139,7 @@ public:
      of declarations that can be skipped.  */
   func_checker (tree source_func_decl, tree target_func_decl,
 		bool ignore_labels = false,
+		bool tbaa = true,
 		hash_set<symtab_node *> *ignored_source_nodes = NULL,
 		hash_set<symtab_node *> *ignored_target_nodes = NULL);
 
@@ -275,6 +276,9 @@ private:
   /* Flag if ignore labels in comparison.  */
   bool m_ignore_labels;
 
+  /* Flag if we should compare type based alias analysis info.  */
+  bool m_tbaa;
+
 public:
   /* Return true if two operands are equal.  The flags fields can be used
      to specify OEP flags described above.  */
diff --git a/gcc/ipa-icf.c b/gcc/ipa-icf.c
index 83f9786b4b2..a283195a487 100644
--- a/gcc/ipa-icf.c
+++ b/gcc/ipa-icf.c
@@ -78,6 +78,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "attribs.h"
 #include "print-tree.h"
 #include "ipa-utils.h"
+#include "tree-ssa-alias-compare.h"
 #include "ipa-icf-gimple.h"
 #include "fibonacci_heap.h"
 #include "ipa-icf.h"
@@ -843,6 +844,8 @@ sem_function::equals_private (sem_item *item)
 
   m_checker = new func_checker (decl, m_compared_func->decl,
 				false,
+				opt_for_fn (m_compared_func->decl,
+					    flag_strict_aliasing),
 				&refs_set,
 				&m_compared_func->refs_set);
   arg1 = DECL_ARGUMENTS (decl);
diff --git a/gcc/ipa-utils.h b/gcc/ipa-utils.h
index 178c2cbe446..880e527c590 100644
--- a/gcc/ipa-utils.h
+++ b/gcc/ipa-utils.h
@@ -265,4 +265,16 @@ get_odr_name_for_type (tree type)
   return IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (type_name));
 }
 
+/* Return true if we are going to do LTO streaming.  */
+
+inline bool
+lto_streaming_expected_p ()
+{
+  /* Compilation before LTO stremaing.  */
+  if (flag_lto && !in_lto_p && symtab->state < IPA_SSA_AFTER_INLINING)
+    return true;
+  /* WPA or incremental link.  */
+  return (flag_wpa || flag_incremental_link == INCREMENTAL_LINK_LTO);
+}
+
 #endif  /* GCC_IPA_UTILS_H  */
diff --git a/gcc/tree-ssa-alias-compare.h b/gcc/tree-ssa-alias-compare.h
new file mode 100644
index 00000000000..0e8409a7565
--- /dev/null
+++ b/gcc/tree-ssa-alias-compare.h
@@ -0,0 +1,43 @@
+/* Comparsion of AO ref.
+   Copyright (C) 2020 Free Software Foundation, Inc.
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   GCC is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GCC; see the file COPYING3.  If not see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef TREE_SSA_ALIAS_COMPARE_H
+#define TREE_SSA_ALIAS_COMPARE_H
+
+class operand_compare;
+/* A class aggregating all connections and semantic equivalents
+   for a given pair of semantic function candidates.  */
+class ao_compare : public operand_compare
+{
+  public:
+  enum ao_ref_diff
+  {
+    SEMANTICS = 1,
+    BASE_ALIAS_SET = 2,
+    REF_ALIAS_SET = 4,
+    ACCESS_PATH = 8,
+    DEPENDENCE_CLIQUE = 16
+  };
+  int compare_ao_refs (ao_ref *ref1, ao_ref *ref2, bool lto_streaming_safe,
+		       bool tbaa);
+  void hash_ao_ref (ao_ref *ref, bool lto_streaming_safe, bool tbaa,
+		    inchash::hash &hstate);
+};
+
+#endif
diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c
index baee352f2dc..06b3eb55181 100644
--- a/gcc/tree-ssa-alias.c
+++ b/gcc/tree-ssa-alias.c
@@ -45,6 +45,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "dbgcnt.h"
 #include "gimple-pretty-print.h"
 #include "print-tree.h"
+#include "tree-ssa-alias-compare.h"
+#include "builtins.h"
 
 /* Broad overview of how alias analysis on gimple works:
 
@@ -1980,6 +1982,20 @@ decl_refs_may_alias_p (tree ref1, tree base1,
   return true;     
 }
 
+/* Return true if access with BASE is view converted.
+   Base must not be stripped from inner MEM_REF (&decl)
+   which is done by ao_ref_base and thus one extra walk
+   of handled components is needed.  */
+
+static bool
+view_converted_memref_p (tree base)
+{
+  if (TREE_CODE (base) != MEM_REF && TREE_CODE (base) != TARGET_MEM_REF)
+    return false;
+  return same_type_for_tbaa (TREE_TYPE (base),
+			     TREE_TYPE (TREE_OPERAND (base, 1))) != 1;
+}
+
 /* Return true if an indirect reference based on *PTR1 constrained
    to [OFFSET1, OFFSET1 + MAX_SIZE1) may alias a variable based on BASE2
    constrained to [OFFSET2, OFFSET2 + MAX_SIZE2).  *PTR1 and BASE2 have
@@ -3861,3 +3877,273 @@ attr_fnspec::verify ()
   if (err)
     internal_error ("invalid fn spec attribute \"%s\"", str);
 }
+
+ /* Return true if type1 and type2 will always give same answers from
+    smae_type_for_tbaa_p when compared with other types.  */
+
+static bool
+types_equal_for_same_type_for_tbaa_p (tree type1, tree type2,
+				      bool lto_streaming_safe)
+{
+  /* We use same_type_for_tbaa_p to match types in the access path.
+     This check is overly conservative.  */
+  type1 = TYPE_MAIN_VARIANT (type1);
+  type2 = TYPE_MAIN_VARIANT (type2);
+
+  if (TYPE_STRUCTURAL_EQUALITY_P (type1)
+      != TYPE_STRUCTURAL_EQUALITY_P (type2))
+    return false;
+  if (TYPE_STRUCTURAL_EQUALITY_P (type1))
+    return true;
+
+  if (lto_streaming_safe)
+    return type1 == type2;
+  else
+    return TYPE_CANONICAL (type1) == TYPE_CANONICAL (type2);
+}
+
+/* Compare REF1 and REF2 and return flags specifying their differences.
+   If LTO_STREAMING_SAFE is true do not use alias sets and canonical
+   types that are going to be recomputed.
+   If TBAA is true also compare TBAA metadata.  */
+
+int
+ao_compare::compare_ao_refs (ao_ref *ref1, ao_ref *ref2,
+			     bool lto_streaming_safe,
+			     bool tbaa)
+{
+  if (TREE_THIS_VOLATILE (ref1->ref) != TREE_THIS_VOLATILE (ref2->ref))
+    return SEMANTICS;
+  tree base1 = ao_ref_base (ref1);
+  tree base2 = ao_ref_base (ref2);
+
+  if (!known_eq (ref1->offset, ref2->offset)
+      || !known_eq (ref1->size, ref2->size)
+      || !known_eq (ref1->max_size, ref2->max_size))
+    return SEMANTICS;
+
+  /* For variable accesses we need to compare actual paths
+     to check that both refs are accessing same address and the access size.  */
+  if (!known_eq (ref1->size, ref1->max_size)
+      && (!operand_equal_p (ref1->ref, ref2->ref, OEP_ADDRESS_OF)
+	  || !operand_equal_p (TYPE_SIZE (TREE_TYPE (ref1->ref)),
+			       TYPE_SIZE (TREE_TYPE (ref2->ref)), 0)))
+    return SEMANTICS;
+  /* For constant accesses we get more matches by comparing offset only.  */
+  else if (!operand_equal_p (base1, base2, OEP_ADDRESS_OF))
+    return SEMANTICS;
+
+  /* ao_ref_base strips inner MEM_REF [&decl], recover from that here.  */
+  tree rbase1 = ref1->ref;
+  if (rbase1)
+    while (handled_component_p (rbase1))
+      rbase1 = TREE_OPERAND (rbase1, 0);
+  tree rbase2 = ref2->ref;
+  while (handled_component_p (rbase2))
+    rbase2 = TREE_OPERAND (rbase2, 0);
+
+  /* We can't simply use get_object_alignment_1 on the full
+     reference as for accesses with variable indexes this reports
+     too conservative alignment.  */
+  unsigned int align1, align2;
+  unsigned HOST_WIDE_INT bitpos1, bitpos2;
+  bool known1 = get_object_alignment_1 (base1, &align1, &bitpos1);
+  bool known2 = get_object_alignment_1 (base2, &align2, &bitpos2);
+  /* ??? For MEMREF get_object_alignment_1 determines aligned from
+     TYPE_ALIGN but still returns false.  This seem to contradict
+     its description.  So compare even if alignment is unknown.   */
+  if (known1 != known2
+      || (bitpos1 != bitpos2 || align1 != align2))
+    return SEMANTICS;
+
+  /* Now we know that accesses are semantically same.  */
+  int flags = 0;
+
+  /* MEM_REFs and TARGET_MEM_REFs record dependence cliques which are used to
+     implement restrict pointers.  MR_DEPENDENCE_CLIQUE 0 means no information.
+     Otherwise we need to match bases and cliques.  */
+  if ((((TREE_CODE (base1) == MEM_REF || TREE_CODE (base1) == TARGET_MEM_REF)
+	&& MR_DEPENDENCE_CLIQUE (base1))
+       || ((TREE_CODE (base2) == MEM_REF || TREE_CODE (base2) == TARGET_MEM_REF)
+	   && MR_DEPENDENCE_CLIQUE (base2)))
+      && (TREE_CODE (base1) != TREE_CODE (base2)
+	  || MR_DEPENDENCE_CLIQUE (base1) != MR_DEPENDENCE_CLIQUE (base2)
+	  || (MR_DEPENDENCE_BASE (base1) != MR_DEPENDENCE_BASE (base2))))
+    flags |= DEPENDENCE_CLIQUE;
+
+  if (!tbaa)
+    return flags;
+
+  /* Alias sets are not stable across LTO sreaming; be conservative here
+     and compare types the alias sets are ultimately based on.  */
+  if (lto_streaming_safe)
+    {
+      tree t1 = ao_ref_alias_ptr_type (ref1);
+      tree t2 = ao_ref_alias_ptr_type (ref2);
+      if (!alias_ptr_types_compatible_p (t1, t2))
+	flags |= REF_ALIAS_SET;
+
+      t1 = ao_ref_base_alias_ptr_type (ref1);
+      t2 = ao_ref_base_alias_ptr_type (ref2);
+      if (!alias_ptr_types_compatible_p (t1, t2))
+	flags |= BASE_ALIAS_SET;
+    }
+  else
+    {
+      if (ao_ref_alias_set (ref1) != ao_ref_alias_set (ref2))
+	flags |= REF_ALIAS_SET;
+      if (ao_ref_base_alias_set (ref1) != ao_ref_base_alias_set (ref2))
+	flags |= BASE_ALIAS_SET;
+    }
+
+  /* Access path is used only on non-view-converted references.  */
+  bool view_converted = view_converted_memref_p (rbase1);
+  if (view_converted_memref_p (rbase2) != view_converted)
+    return flags | ACCESS_PATH;
+  else if (view_converted)
+    return flags;
+
+
+  /* Find start of access paths and look for trailing arrays.  */
+  tree c1 = ref1->ref, c2 = ref2->ref;
+  tree end_struct_ref1 = NULL, end_struct_ref2 = NULL;
+  int nskipped1 = 0, nskipped2 = 0;
+  int i = 0;
+
+  for (tree p1 = ref1->ref; handled_component_p (p1); p1 = TREE_OPERAND (p1, 0))
+    {
+      if (component_ref_to_zero_sized_trailing_array_p (p1))
+	end_struct_ref1 = p1;
+      if (ends_tbaa_access_path_p (p1))
+	c1 = p1, nskipped1 = i;
+      i++;
+    }
+  for (tree p2 = ref2->ref; handled_component_p (p2); p2 = TREE_OPERAND (p2, 0))
+    {
+      if (component_ref_to_zero_sized_trailing_array_p (p2))
+	end_struct_ref2 = p2;
+      if (ends_tbaa_access_path_p (p2))
+	c2 = p2, nskipped1 = i;
+      i++;
+    }
+
+  /* For variable accesses we can not rely on offset match bellow.
+     We know that paths are struturally same, so only check that
+     starts of TBAA paths did not diverge.  */
+  if (!known_eq (ref1->size, ref1->max_size)
+      && nskipped1 != nskipped2)
+    return flags | ACCESS_PATH;
+
+  /* Information about trailing refs is used by
+     aliasing_component_refs_p that is applied only if paths
+     has handled components..  */
+  if (!handled_component_p (c1) && !handled_component_p (c2))
+    ;
+  else if ((end_struct_ref1 != NULL) != (end_struct_ref2 != NULL))
+    return flags | ACCESS_PATH;
+  if (end_struct_ref1
+      && TYPE_MAIN_VARIANT (TREE_TYPE (end_struct_ref1))
+	 != TYPE_MAIN_VARIANT (TREE_TYPE (end_struct_ref2)))
+    return flags | ACCESS_PATH;
+
+  /* Now compare all handled components of the access path.
+     We have three oracles that cares about access paths:
+       - aliasing_component_refs_p
+       - nonoverlapping_refs_since_match_p
+       - nonoverlapping_component_refs_p
+     We need to match things these oracles compare.
+     Note that nonoverlapping_refs_since_match_p can also
+     analyze the remainder of access path for address computations
+     but these are already known to match and thus wee need to only
+     inspect the portion of access path relevant for TBAA.  */
+  while (true)
+    {
+      bool comp1 = handled_component_p (c1);
+      bool comp2 = handled_component_p (c2);
+
+      if (comp1 != comp2)
+	return flags | ACCESS_PATH;
+      if (!comp1)
+	break;
+
+      if (TREE_CODE (c1) != TREE_CODE (c2))
+	return flags | ACCESS_PATH;
+
+      /* aliasing_component_refs_p attempts to find type match within
+	 the paths.  For that reason both types needs to be equal
+	 with respect to same_type_for_tbaa_p.  */
+      if (!types_equal_for_same_type_for_tbaa_p (TREE_TYPE (c1),
+						 TREE_TYPE (c2),
+						 lto_streaming_safe))
+	return flags | ACCESS_PATH;
+      if (component_ref_to_zero_sized_trailing_array_p (c1)
+	  != component_ref_to_zero_sized_trailing_array_p (c2))
+	return flags | ACCESS_PATH;
+
+      /* aliasing_matching_component_refs_p compares
+	 offsets within the path.  Other properties are ignored.
+	 Do not bother to verify offsets in variable accesses.  Here we
+	 already compared them by operand_equal_p so they are
+	 structurally same.  */
+      if (!known_eq (ref1->size, ref1->max_size))
+	{
+	  poly_int64 offadj1, sztmc1, msztmc1;
+	  bool reverse1;
+	  get_ref_base_and_extent (c1, &offadj1, &sztmc1, &msztmc1, &reverse1);
+	  poly_int64 offadj2, sztmc2, msztmc2;
+	  bool reverse2;
+	  get_ref_base_and_extent (c2, &offadj2, &sztmc2, &msztmc2, &reverse2);
+	  if (!known_eq (offadj1, offadj2))
+	    return flags | ACCESS_PATH;
+	}
+
+      /* nonoverlapping_array_refs_p looks into offset computations done
+	 by array refs.  */
+      if (TREE_CODE (c1) == ARRAY_REF)
+	if (nonoverlapping_array_refs_p (c1, c2))
+	  return flags | ACCESS_PATH;
+      /* nonoverlapping_component_refs_p cares about offset coputations done
+	 by component refs.  */
+      if (TREE_CODE (c1) == COMPONENT_REF)
+	{
+	  tree field1 = TREE_OPERAND (c1, 1);
+	  tree field2 = TREE_OPERAND (c2, 1);
+
+	  if (nonoverlapping_component_refs_p_1 (field1, field2))
+	    return flags | ACCESS_PATH;
+	}
+      c1 = TREE_OPERAND (c1, 0);
+      c2 = TREE_OPERAND (c2, 0);
+    }
+  /* Finally test the access type.  */
+  if (!types_equal_for_same_type_for_tbaa_p (TREE_TYPE (c1),
+					     TREE_TYPE (c2),
+					     lto_streaming_safe))
+    return flags | ACCESS_PATH;
+  return flags;
+}
+
+/* Hash REF to HSTATE.  If LTO_STREAMING_SAFE do not use alias sets
+   and canonical types.  */
+void
+ao_compare::hash_ao_ref (ao_ref *ref, bool lto_streaming_safe, bool tbaa,
+			 inchash::hash &hstate)
+{
+  tree base = ao_ref_base (ref);
+  tree tbase = base;
+
+  if (!known_eq (ref->size, ref->max_size))
+    {
+      hash_operand (TYPE_SIZE (TREE_TYPE (ref->ref)), hstate, 0);
+      hash_operand (ref->ref, hstate, OEP_ADDRESS_OF);
+    }
+  else
+    {
+      hash_operand (tbase, hstate, OEP_ADDRESS_OF);
+      hstate.add_poly_int (ref->offset);
+      hstate.add_poly_int (ref->size);
+      hstate.add_poly_int (ref->max_size);
+    }
+  if (!lto_streaming_safe && tbaa)
+    {
+      hstate.add_int (ao_ref_alias_set (ref));
+      hstate.add_int (ao_ref_base_alias_set (ref));
+    }
+}
diff --git a/gcc/testsuite/c-c++-common/Wstringop-overflow-2.c b/gcc/testsuite/c-c++-common/Wstringop-overflow-2.c
index 7c7932e3cf0..63b1a309564 100644
--- a/gcc/testsuite/c-c++-common/Wstringop-overflow-2.c
+++ b/gcc/testsuite/c-c++-common/Wstringop-overflow-2.c
@@ -1,7 +1,7 @@
 /* PR middle-end/91458 - inconsistent warning for writing past the end
    of an array member
    { dg-do compile }
-   { dg-options "-O2 -Wall -Wno-array-bounds" } */
+   { dg-options "-O2 -Wall -Wno-array-bounds -fno-ipa-icf" } */
 
 void sink (void*);
 
diff --git a/gcc/testsuite/g++.dg/warn/Warray-bounds-8.C b/gcc/testsuite/g++.dg/warn/Warray-bounds-8.C
index 6db20135668..6e0d7f3ccc4 100644
--- a/gcc/testsuite/g++.dg/warn/Warray-bounds-8.C
+++ b/gcc/testsuite/g++.dg/warn/Warray-bounds-8.C
@@ -3,7 +3,7 @@
    See Wstringop-overflow-3.C for the same test that exercises the other
    warning.
    { dg-do compile }
-   { dg-options "-O2 -Wall -Wno-stringop-overflow" }
+   { dg-options "-O2 -Wall -Wno-stringop-overflow -fno-ipa-icf" }
    { dg-skip-if "" { *-*-aix* } } */
 
 void sink (void*);
