aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Krebbel <krebbel@linux.ibm.com>2024-03-14 09:54:31 +0100
committerAndreas Krebbel <krebbel@linux.ibm.com>2024-03-14 10:51:57 +0100
commit90a7da695284da49182446ba45fbcddb9eb7fc91 (patch)
tree6ba55dd468343a688561e0af94262a465f73ff08
parent8f6e0814b4bfd0a399055e9214562aebfcd902ad (diff)
downloadgcc-90a7da695284da49182446ba45fbcddb9eb7fc91.zip
gcc-90a7da695284da49182446ba45fbcddb9eb7fc91.tar.gz
gcc-90a7da695284da49182446ba45fbcddb9eb7fc91.tar.bz2
IBM Z: Fix -munaligned-symbols
With this fix we make sure that only symbols with a natural alignment smaller than 2 are considered misaligned with -munaligned-symbols. Background is that -munaligned-symbols is only supposed to affect symbols whose natural alignment wouldn't be enough to fulfill our ABI requirement of having all symbols at even addresses. Because only these are the cases where we differ from other architectures. gcc/ChangeLog: * config/s390/s390.cc (s390_encode_section_info): Adjust the check for misaligned symbols. * config/s390/s390.opt: Improve documentation. gcc/testsuite/ChangeLog: * gcc.target/s390/aligned-1.c: Add weak and void variables incorporating the cases from unaligned-2.c. * gcc.target/s390/unaligned-1.c: Likewise. * gcc.target/s390/unaligned-2.c: Removed.
-rw-r--r--gcc/config/s390/s390.cc15
-rw-r--r--gcc/config/s390/s390.opt7
-rw-r--r--gcc/testsuite/gcc.target/s390/aligned-1.c101
-rw-r--r--gcc/testsuite/gcc.target/s390/unaligned-1.c103
-rw-r--r--gcc/testsuite/gcc.target/s390/unaligned-2.c16
5 files changed, 201 insertions, 41 deletions
diff --git a/gcc/config/s390/s390.cc b/gcc/config/s390/s390.cc
index e639655..372a232 100644
--- a/gcc/config/s390/s390.cc
+++ b/gcc/config/s390/s390.cc
@@ -13802,10 +13802,19 @@ s390_encode_section_info (tree decl, rtx rtl, int first)
that can go wrong (i.e. no FUNC_DECLs).
All symbols without an explicit alignment are assumed to be 2
byte aligned as mandated by our ABI. This behavior can be
- overridden for external symbols with the -munaligned-symbols
- switch. */
+ overridden for external and weak symbols with the
+ -munaligned-symbols switch.
+ For all external symbols without explicit alignment
+ DECL_ALIGN is already trimmed down to 8, however for weak
+ symbols this does not happen. These cases are catched by the
+ type size check. */
+ const_tree size = TYPE_SIZE (TREE_TYPE (decl));
+ unsigned HOST_WIDE_INT size_num = (tree_fits_uhwi_p (size)
+ ? tree_to_uhwi (size) : 0);
if ((DECL_USER_ALIGN (decl) && DECL_ALIGN (decl) % 16)
- || (s390_unaligned_symbols_p && !decl_binds_to_current_def_p (decl)))
+ || (s390_unaligned_symbols_p
+ && !decl_binds_to_current_def_p (decl)
+ && (DECL_USER_ALIGN (decl) ? DECL_ALIGN (decl) % 16 : size_num < 16)))
SYMBOL_FLAG_SET_NOTALIGN2 (XEXP (rtl, 0));
else if (DECL_ALIGN (decl) % 32)
SYMBOL_FLAG_SET_NOTALIGN4 (XEXP (rtl, 0));
diff --git a/gcc/config/s390/s390.opt b/gcc/config/s390/s390.opt
index 901ae4b..a5b5aa9 100644
--- a/gcc/config/s390/s390.opt
+++ b/gcc/config/s390/s390.opt
@@ -332,7 +332,8 @@ Store all argument registers on the stack.
munaligned-symbols
Target Var(s390_unaligned_symbols_p) Init(0)
-Assume external symbols to be potentially unaligned. By default all
-symbols without explicit alignment are assumed to reside on a 2 byte
-boundary as mandated by the IBM Z ABI.
+Assume external symbols, whose natural alignment would be 1, to be
+potentially unaligned. By default all symbols without explicit
+alignment are assumed to reside on a 2 byte boundary as mandated by
+the IBM Z ABI.
diff --git a/gcc/testsuite/gcc.target/s390/aligned-1.c b/gcc/testsuite/gcc.target/s390/aligned-1.c
index 2dc99cf..3f5a261 100644
--- a/gcc/testsuite/gcc.target/s390/aligned-1.c
+++ b/gcc/testsuite/gcc.target/s390/aligned-1.c
@@ -1,20 +1,103 @@
-/* Even symbols without explicite alignment are assumed to reside on a
+/* Even symbols without explicit alignment are assumed to reside on a
2 byte boundary, as mandated by the IBM Z ELF ABI, and therefore
can be accessed using the larl instruction. */
/* { dg-do compile } */
/* { dg-options "-O3 -march=z900 -fno-section-anchors" } */
-extern unsigned char extern_implicitly_aligned;
-extern unsigned char extern_explicitly_aligned __attribute__((aligned(2)));
-unsigned char aligned;
+extern unsigned char extern_char;
+extern unsigned char extern_explicitly_aligned_char __attribute__((aligned(2)));
+extern unsigned char extern_explicitly_unaligned_char __attribute__((aligned(1)));
+extern unsigned char __attribute__((weak)) extern_weak_char;
+extern unsigned char extern_explicitly_aligned_weak_char __attribute__((weak,aligned(2)));
+extern unsigned char extern_explicitly_unaligned_weak_char __attribute__((weak,aligned(1)));
-unsigned char
+unsigned char normal_char;
+unsigned char explicitly_unaligned_char __attribute__((aligned(1)));
+unsigned char __attribute__((weak)) weak_char = 0;
+unsigned char explicitly_aligned_weak_char __attribute__((weak,aligned(2)));
+unsigned char explicitly_unaligned_weak_char __attribute__((weak,aligned(1)));
+
+extern unsigned int extern_int;
+extern unsigned int extern_explicitly_aligned_int __attribute__((aligned(4)));
+extern unsigned int extern_explicitly_unaligned_int __attribute__((aligned(1)));
+extern unsigned int __attribute__((weak)) extern_weak_int;
+extern unsigned int extern_explicitly_aligned_weak_int __attribute__((weak,aligned(4)));
+extern unsigned int extern_explicitly_unaligned_weak_int __attribute__((weak,aligned(1)));
+
+unsigned int normal_int;
+unsigned int explicitly_unaligned_int __attribute__((aligned(1)));
+unsigned int __attribute__((weak)) weak_int = 0;
+unsigned int explicitly_aligned_weak_int __attribute__((weak,aligned(4)));
+unsigned int explicitly_unaligned_weak_int __attribute__((weak,aligned(1)));
+
+extern const void extern_void;
+extern const void extern_explicitly_aligned_void __attribute__((aligned(2)));
+extern const void extern_explicitly_unaligned_void __attribute__((aligned(1)));
+extern const void __attribute__((weak)) extern_weak_void;
+extern const void extern_explicitly_aligned_weak_void __attribute__((weak,aligned(2)));
+extern const void extern_explicitly_unaligned_weak_void __attribute__((weak,aligned(1)));
+
+
+unsigned int
foo ()
{
- return extern_implicitly_aligned + extern_explicitly_aligned + aligned;
+ return extern_char + extern_explicitly_aligned_char
+ + extern_explicitly_unaligned_char
+ + extern_weak_char + extern_explicitly_aligned_weak_char
+ + extern_explicitly_unaligned_weak_char
+
+ + normal_char + explicitly_unaligned_char
+ + weak_char + explicitly_aligned_weak_char
+ + explicitly_unaligned_weak_char
+
+ + extern_int + extern_explicitly_aligned_int
+ + extern_explicitly_unaligned_int
+ + extern_weak_int + extern_explicitly_aligned_weak_int
+ + extern_explicitly_unaligned_weak_int
+
+ + normal_int + explicitly_unaligned_int
+ + weak_int + explicitly_aligned_weak_int
+ + explicitly_unaligned_weak_int;
}
-/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_implicitly_aligned\n" 1 } } */
-/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_explicitly_aligned\n" 1 } } */
-/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,aligned\n" 1 } } */
+const void *f1(void) { return &extern_void; }
+const void *f2(void) { return &extern_explicitly_aligned_void; }
+const void *f3(void) { return &extern_explicitly_unaligned_void; }
+const void *f4(void) { return &extern_weak_void; }
+const void *f5(void) { return &extern_explicitly_aligned_weak_void; }
+const void *f6(void) { return &extern_explicitly_unaligned_weak_void; }
+
+
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_char\n" 1 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_explicitly_aligned_char\n" 1 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_explicitly_unaligned_char\n" 0 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_weak_char\n" 1 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_explicitly_aligned_weak_char\n" 1 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_explicitly_unaligned_weak_char\n" 0 } } */
+
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,normal_char\n" 1 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,explicitly_unaligned_char\n" 0 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,weak_char\n" 1 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,explicitly_aligned_weak_char\n" 1 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,explicitly_unaligned_weak_char\n" 0 } } */
+
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_int\n" 1 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_explicitly_aligned_int\n" 1 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_explicitly_unaligned_int\n" 0 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_weak_int\n" 1 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_explicitly_aligned_weak_int\n" 1 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_explicitly_unaligned_weak_int\n" 0 } } */
+
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,normal_int\n" 1 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,explicitly_unaligned_int\n" 0 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,weak_int\n" 1 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,explicitly_aligned_weak_int\n" 1 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,explicitly_unaligned_weak_int\n" 0 } } */
+
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_void\n" 1 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_explicitly_aligned_void\n" 1 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_explicitly_unaligned_void\n" 0 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_weak_void\n" 1 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_explicitly_aligned_weak_void\n" 1 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_explicitly_unaligned_weak_void\n" 0 } } */
diff --git a/gcc/testsuite/gcc.target/s390/unaligned-1.c b/gcc/testsuite/gcc.target/s390/unaligned-1.c
index 421330a..47d7716 100644
--- a/gcc/testsuite/gcc.target/s390/unaligned-1.c
+++ b/gcc/testsuite/gcc.target/s390/unaligned-1.c
@@ -1,20 +1,103 @@
-/* With the -munaligned-symbols option all external symbols without
- explicite alignment are assumed to be potentially unaligned and
- therefore cannot be accessed with larl. */
+/* With the -munaligned-symbols option all external and weak symbols
+ without explicit alignment are assumed to be potentially unaligned
+ and therefore cannot be accessed with larl. */
/* { dg-do compile } */
/* { dg-options "-O3 -march=z900 -fno-section-anchors -munaligned-symbols" } */
-extern unsigned char extern_unaligned;
-extern unsigned char extern_explicitly_aligned __attribute__((aligned(2)));
-unsigned char aligned;
+extern unsigned char extern_char;
+extern unsigned char extern_explicitly_aligned_char __attribute__((aligned(2)));
+extern unsigned char extern_explicitly_unaligned_char __attribute__((aligned(1)));
+extern unsigned char __attribute__((weak)) extern_weak_char;
+extern unsigned char extern_explicitly_aligned_weak_char __attribute__((weak,aligned(2)));
+extern unsigned char extern_explicitly_unaligned_weak_char __attribute__((weak,aligned(1)));
+
+unsigned char normal_char;
+unsigned char explicitly_unaligned_char __attribute__((aligned(1)));
+unsigned char __attribute__((weak)) weak_char = 0;
+unsigned char explicitly_aligned_weak_char __attribute__((weak,aligned(2)));
+unsigned char explicitly_unaligned_weak_char __attribute__((weak,aligned(1)));
+
+extern unsigned int extern_int;
+extern unsigned int extern_explicitly_aligned_int __attribute__((aligned(4)));
+extern unsigned int extern_explicitly_unaligned_int __attribute__((aligned(1)));
+extern unsigned int __attribute__((weak)) extern_weak_int;
+extern unsigned int extern_explicitly_aligned_weak_int __attribute__((weak,aligned(4)));
+extern unsigned int extern_explicitly_unaligned_weak_int __attribute__((weak,aligned(1)));
+
+unsigned int normal_int;
+unsigned int explicitly_unaligned_int __attribute__((aligned(1)));
+unsigned int __attribute__((weak)) weak_int = 0;
+unsigned int explicitly_aligned_weak_int __attribute__((weak,aligned(4)));
+unsigned int explicitly_unaligned_weak_int __attribute__((weak,aligned(1)));
+
+extern const void extern_void;
+extern const void extern_explicitly_aligned_void __attribute__((aligned(2)));
+extern const void extern_explicitly_unaligned_void __attribute__((aligned(1)));
+extern const void __attribute__((weak)) extern_weak_void;
+extern const void extern_explicitly_aligned_weak_void __attribute__((weak,aligned(2)));
+extern const void extern_explicitly_unaligned_weak_void __attribute__((weak,aligned(1)));
+
unsigned char
foo ()
{
- return extern_unaligned + extern_explicitly_aligned + aligned;
+ return extern_char + extern_explicitly_aligned_char
+ + extern_explicitly_unaligned_char
+ + extern_weak_char + extern_explicitly_aligned_weak_char
+ + extern_explicitly_unaligned_weak_char
+
+ + normal_char + explicitly_unaligned_char
+ + weak_char + explicitly_aligned_weak_char
+ + explicitly_unaligned_weak_char
+
+ + extern_int + extern_explicitly_aligned_int
+ + extern_explicitly_unaligned_int
+ + extern_weak_int + extern_explicitly_aligned_weak_int
+ + extern_explicitly_unaligned_weak_int
+
+ + normal_int + explicitly_unaligned_int
+ + weak_int + explicitly_aligned_weak_int
+ + explicitly_unaligned_weak_int;
}
-/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_unaligned\n" 0 } } */
-/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_explicitly_aligned\n" 1 } } */
-/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,aligned\n" 1 } } */
+const void *f1(void) { return &extern_void; }
+const void *f2(void) { return &extern_explicitly_aligned_void; }
+const void *f3(void) { return &extern_explicitly_unaligned_void; }
+const void *f4(void) { return &extern_weak_void; }
+const void *f5(void) { return &extern_explicitly_aligned_weak_void; }
+const void *f6(void) { return &extern_explicitly_unaligned_weak_void; }
+
+
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_char\n" 0 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_explicitly_aligned_char\n" 1 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_explicitly_unaligned_char\n" 0 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_weak_char\n" 0 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_explicitly_aligned_weak_char\n" 1 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_explicitly_unaligned_weak_char\n" 0 } } */
+
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,normal_char\n" 1 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,explicitly_unaligned_char\n" 0 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,weak_char\n" 0 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,explicitly_aligned_weak_char\n" 1 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,explicitly_unaligned_weak_char\n" 0 } } */
+
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_int\n" 1 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_explicitly_aligned_int\n" 1 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_explicitly_unaligned_int\n" 0 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_weak_int\n" 1 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_explicitly_aligned_weak_int\n" 1 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_explicitly_unaligned_weak_int\n" 0 } } */
+
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,normal_int\n" 1 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,explicitly_unaligned_int\n" 0 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,weak_int\n" 1 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,explicitly_aligned_weak_int\n" 1 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,explicitly_unaligned_weak_int\n" 0 } } */
+
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_void\n" 0 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_explicitly_aligned_void\n" 1 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_explicitly_unaligned_void\n" 0 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_weak_void\n" 0 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_explicitly_aligned_weak_void\n" 1 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_explicitly_unaligned_weak_void\n" 0 } } */
diff --git a/gcc/testsuite/gcc.target/s390/unaligned-2.c b/gcc/testsuite/gcc.target/s390/unaligned-2.c
deleted file mode 100644
index c1ece6d..0000000
--- a/gcc/testsuite/gcc.target/s390/unaligned-2.c
+++ /dev/null
@@ -1,16 +0,0 @@
-/* weak symbols might get overridden in another module by symbols
- which are not aligned on a 2-byte boundary. Although this violates
- the zABI we try to handle this gracefully by not using larl on
- these symbols if -munaligned-symbols has been specified. */
-
-/* { dg-do compile } */
-/* { dg-options "-O3 -march=z900 -fno-section-anchors -munaligned-symbols" } */
-unsigned char __attribute__((weak)) weaksym = 0;
-
-unsigned char
-foo ()
-{
- return weaksym;
-}
-
-/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,weaksym\n" 0 } } */