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 } } */
