This makes IPA ICF compare alignment of accesses.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied.

Richard.

2015-03-02  Richard Biener  <rguent...@suse.de>

        PR ipa/65270
        * ipa-icf-gimple.c: Include builtins.h.
        (func_checker::compare_memory_operand): Compare base alignment.

Index: gcc/ipa-icf-gimple.c
===================================================================
--- gcc/ipa-icf-gimple.c        (revision 221100)
+++ gcc/ipa-icf-gimple.c        (working copy)
@@ -77,6 +77,7 @@ along with GCC; see the file COPYING3.
 #include <list>
 #include "tree-ssanames.h"
 #include "tree-eh.h"
+#include "builtins.h"
 
 #include "ipa-icf-gimple.h"
 #include "ipa-icf.h"
@@ -286,6 +287,24 @@ func_checker::compare_memory_operand (tr
       if (ao_ref_alias_set (&r1) != ao_ref_alias_set (&r2)
          || ao_ref_base_alias_set (&r1) != ao_ref_base_alias_set (&r2))
        return return_false_with_msg ("ao alias sets are different");
+
+      /* We can't simply use get_object_alignment_1 on the full
+         reference as for accesses with variable indexes this reports
+        too conservative alignment.  We also can't use the ao_ref_base
+        base objects as ao_ref_base happily strips MEM_REFs around
+        decls even though that may carry alignment info.  */
+      b1 = t1;
+      while (handled_component_p (b1))
+       b1 = TREE_OPERAND (b1, 0);
+      b2 = t2;
+      while (handled_component_p (b2))
+       b2 = TREE_OPERAND (b2, 0);
+      unsigned int align1, align2;
+      unsigned HOST_WIDE_INT tem;
+      get_object_alignment_1 (b1, &align1, &tem);
+      get_object_alignment_1 (b2, &align2, &tem);
+      if (align1 != align2)
+       return return_false_with_msg ("different access alignment");
     }
 
   return compare_operand (t1, t2);

Reply via email to