diff mbox series

[Committed] IBM Z: Fix -munaligned-symbols

Message ID 20240314095337.10608-1-krebbel@linux.ibm.com
State New
Headers show
Series [Committed] IBM Z: Fix -munaligned-symbols | expand

Commit Message

Andreas Krebbel March 14, 2024, 9:53 a.m. UTC
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.

This fixes the unaligned-1 testcase, no regressions. Committed to mainline.

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.
---
 gcc/config/s390/s390.cc                     |  15 ++-
 gcc/config/s390/s390.opt                    |   7 +-
 gcc/testsuite/gcc.target/s390/aligned-1.c   | 101 +++++++++++++++++--
 gcc/testsuite/gcc.target/s390/unaligned-1.c | 103 ++++++++++++++++++--
 gcc/testsuite/gcc.target/s390/unaligned-2.c |  16 ---
 5 files changed, 201 insertions(+), 41 deletions(-)
 delete mode 100644 gcc/testsuite/gcc.target/s390/unaligned-2.c
diff mbox series

Patch

diff --git a/gcc/config/s390/s390.cc b/gcc/config/s390/s390.cc
index e63965578f1..372a2324403 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 901ae4beb01..a5b5aa95a12 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 2dc99cf66bd..3f5a2611ef1 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 421330aded1..47d77160266 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 c1ece6d5935..00000000000
--- 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 } } */