decl alignment not respected
authorAlan Modra <amodra@gmail.com>
Wed, 2 Mar 2016 14:05:21 +0000 (00:35 +1030)
committerAlan Modra <amodra@gcc.gnu.org>
Wed, 2 Mar 2016 14:05:21 +0000 (00:35 +1030)
This patch cures a problem with ICF of read-only variables at the
intersection of -fsection-anchors, -ftree-loop-vectorize, and targets
with alignment restrictions.

What happens with the testcase is:
- "c" is referenced in a constructor, thus make_decl_rtl for "c",
- make_decl_rtl puts "c" in an anchor block (-fsection-anchors),
- anchor block contents can't move, so "c" alignment can't change by
  ipa_increase_alignment (-ftree-loop-vectorize),
- however "a" alignment can be increased,
- ICF aliases "a" to "c".
So we have a decl for "a" saying it is aligned to 128 bits, using mem
for "c" which is only 16 bit aligned.

PR ipa/69990
gcc/
* ipa-icf.c (sem_variable::merge): Do not merge an alias with
larger alignment.
gcc/testsuite/
gcc.dg/pr69990.c: New.

From-SVN: r233906

gcc/ChangeLog
gcc/ipa-icf.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr69990.c [new file with mode: 0644]

index adc085c..75a31f5 100644 (file)
@@ -1,3 +1,9 @@
+2016-03-02  Alan Modra  <amodra@gmail.com>
+
+       PR ipa/69990
+       * ipa-icf.c (sem_variable::merge): Do not merge an alias with
+       larger alignment.
+
 2016-03-02  Jakub Jelinek  <jakub@redhat.com>
 
        PR target/70028
index ef04c55..d82eb87 100644 (file)
@@ -2209,6 +2209,16 @@ sem_variable::merge (sem_item *alias_item)
                 "adress of original and alias may be compared.\n\n");
       return false;
     }
+
+  if (DECL_ALIGN (original->decl) < DECL_ALIGN (alias->decl))
+    {
+      if (dump_file)
+       fprintf (dump_file, "Not unifying; "
+                "original and alias have incompatible alignments\n\n");
+
+      return false;
+    }
+
   if (DECL_COMDAT_GROUP (original->decl) != DECL_COMDAT_GROUP (alias->decl))
     {
       if (dump_file)
index e009deb..983063c 100644 (file)
@@ -1,3 +1,7 @@
+2016-03-02  Alan Modra  <amodra@gmail.com>
+
+       * gcc.dg/pr69990.c: New.
+
 2016-03-02  Jakub Jelinek  <jakub@redhat.com>
 
        PR c/68062
diff --git a/gcc/testsuite/gcc.dg/pr69990.c b/gcc/testsuite/gcc.dg/pr69990.c
new file mode 100644 (file)
index 0000000..efb835e
--- /dev/null
@@ -0,0 +1,24 @@
+/* { dg-do run } */
+/* { dg-require-effective-target section_anchors } */
+/* { dg-options "-O2 -fsection-anchors -ftree-loop-vectorize" } */
+
+#pragma pack(1)
+struct S0 {
+  volatile int f0:12;
+} static a[] = {{15}}, c[] = {{15}};
+
+struct S0 b[] = {{7}};
+
+int __attribute__ ((noinline, noclone))
+ok (int a, int b, int c)
+{
+  return a == 15 && b == 7 && c == 15 ? 0 : 1;
+}
+
+int
+main (void)
+{
+  struct S0 *f[] = { c, b };
+
+  return ok (a[0].f0, b[0].f0, f[0]->f0);
+}