aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2016-03-03 00:35:21 +1030
committerAlan Modra <amodra@gcc.gnu.org>2016-03-03 00:35:21 +1030
commit90a7a40b65d1057bff07961dd9c8b0c05c345ba8 (patch)
tree215bc42509d8654673447e88532ee1fb0a10bcf3 /gcc
parentde752fb0d2d3e27407ea5735604577d5aa76bcac (diff)
downloadgcc-90a7a40b65d1057bff07961dd9c8b0c05c345ba8.zip
gcc-90a7a40b65d1057bff07961dd9c8b0c05c345ba8.tar.gz
gcc-90a7a40b65d1057bff07961dd9c8b0c05c345ba8.tar.bz2
decl alignment not respected
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/ipa-icf.c10
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/pr69990.c24
4 files changed, 44 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index adc085c..75a31f5 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/ipa-icf.c b/gcc/ipa-icf.c
index ef04c55..d82eb87 100644
--- a/gcc/ipa-icf.c
+++ b/gcc/ipa-icf.c
@@ -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)
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index e009deb..983063c 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..efb835e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr69990.c
@@ -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);
+}