[pushed] Darwin: Update rules for handling alignment of globals.

Iain Sandoe iains.gcc@gmail.com
Fri Dec 24 10:52:09 GMT 2021


The current rule was too strict and has not been required since Darwin11.

This relaxes the constraint to allow up to 2^28 alignment for non-common
entities.  Common is still restricted to a maximum aligment of 2^15.

When the host is an older version of Darwin ( earlier that 11 ) then the
existing constraint is still applied.  Note that this is a host constraint
not a target one (so that a compilation on 10.7 targeting 10.6 is allowed
to use a greater alignment than the tools on 10.6 support).  This matches
the behaviour of clang.

This showed up in testcases on the aarch64 branch, but is equally an issue
on both i686 and x86_64 for Darwin versions >= 11.  Tested on i686, powerpc
x86_64 and aarch64 darwin, pushed to master, thanks,
Iain

Signed-off-by: Iain Sandoe <iain@sandoe.co.uk>

gcc/ChangeLog:

	* config.gcc: Emit L2_MAX_OFILE_ALIGNMENT with suitable
	values for the host.
	* config/darwin.c (darwin_emit_common): Error for alignment
	values > 32768.
	* config/darwin.h (MAX_OFILE_ALIGNMENT): Rework to use the
	configured L2_MAX_OFILE_ALIGNMENT.

gcc/testsuite/ChangeLog:

	* gcc.dg/darwin-aligned-globals.c: New test.
	* gcc.dg/darwin-comm-1.c: New test.
	* gcc.dg/attr-aligned.c: Amend for new alignment values on
	Darwin.
	* gcc.target/i386/pr89261.c: Likewise.
---
 gcc/config.gcc                                | 14 +++++++++++
 gcc/config/darwin.c                           | 17 +++++++++----
 gcc/config/darwin.h                           |  9 ++++---
 gcc/testsuite/gcc.dg/attr-aligned.c           |  8 +++++--
 gcc/testsuite/gcc.dg/darwin-aligned-globals.c | 24 +++++++++++++++++++
 gcc/testsuite/gcc.dg/darwin-comm-1.c          |  5 ++++
 gcc/testsuite/gcc.target/i386/pr89261.c       |  3 ++-
 7 files changed, 68 insertions(+), 12 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/darwin-aligned-globals.c
 create mode 100644 gcc/testsuite/gcc.dg/darwin-comm-1.c

diff --git a/gcc/config.gcc b/gcc/config.gcc
index bf1c7454e05..294f3123e38 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -677,6 +677,20 @@ case ${target} in
     macos_min=0
   fi
   def_ld64=85.2
+  # Tools hosted on earlier versions of Darwin constrained all object
+  # alignment to be 2^15 or smaller.  From Darwin11 (macOS 10.7) the
+  # alignment of non-common is allowed to be up to 2^28.  Note that the
+  # larger alignment is permitted when targeting 10.6 from 10.7 so that
+  # the constraint only need be applied per host (and only if the host
+  # is Darwin).
+  case ${host} in
+      *-*-darwin[4-9]* | *-*-darwin10*)
+          tm_defines="$tm_defines L2_MAX_OFILE_ALIGNMENT=15U"
+          ;;
+      *)
+          tm_defines="$tm_defines L2_MAX_OFILE_ALIGNMENT=28U"
+          ;;
+  esac
   case ${target} in
       # Darwin 4 to 19 correspond to macOS 10.0 to 10.15
       *-*-darwin[4-9]* | *-*-darwin1[0-9]*)
diff --git a/gcc/config/darwin.c b/gcc/config/darwin.c
index e580319f761..5045b68e8af 100644
--- a/gcc/config/darwin.c
+++ b/gcc/config/darwin.c
@@ -2558,7 +2558,6 @@ darwin_emit_common (FILE *fp, const char *name,
     rounded = (size + (align-1)) & ~(align-1);
 
   l2align = floor_log2 (align);
-  gcc_assert (l2align <= L2_MAX_OFILE_ALIGNMENT);
 
   in_section = comm_section;
   /* We mustn't allow multiple public symbols to share an address when using
@@ -2709,6 +2708,10 @@ darwin_asm_output_aligned_decl_common (FILE *fp, tree decl, const char *name,
 #ifdef DEBUG_DARWIN_MEM_ALLOCATORS
 fprintf (fp, "# adcom: %s (%d,%d) decl=0x0\n", name, (int)size, (int)align);
 #endif
+     /* Common variables are limited to a maximum alignment of 2^15.  */
+      if (align > 32768)
+	error_at (UNKNOWN_LOCATION, "common variables must have an alignment"
+		  " of 32678 or less");
       darwin_emit_common (fp, name, size, align);
       return;
     }
@@ -2736,7 +2739,7 @@ fprintf (fp, "# adcom: %s (%lld,%d) ro %d cst %d stat %d com %d pub %d"
     }
 
   /* We shouldn't be messing with this if the decl has a section name.  */
-  gcc_assert (DECL_SECTION_NAME (decl) == NULL);
+  gcc_checking_assert (DECL_SECTION_NAME (decl) == NULL);
 
   /* We would rather not have to check this here - but it seems that we might
      be passed a decl that should be in coalesced space.  */
@@ -2765,10 +2768,16 @@ fprintf (fp, "# adcom: %s (%lld,%d) ro %d cst %d stat %d com %d pub %d"
 
   l2align = floor_log2 (align / BITS_PER_UNIT);
   /* Check we aren't asking for more aligment than the platform allows.  */
-  gcc_assert (l2align <= L2_MAX_OFILE_ALIGNMENT);
+  gcc_checking_assert (l2align <= L2_MAX_OFILE_ALIGNMENT);
 
   if (TREE_PUBLIC (decl) != 0)
-    darwin_emit_common (fp, name, size, align);
+    {
+      /* Common variables are limited to a maximum alignment of 2^15.  */
+      if (l2align > 15)
+	error_at (DECL_SOURCE_LOCATION (decl), "common variables must have"
+		  " an alignment of 32678 or less");
+      darwin_emit_common (fp, name, size, align);
+    }
   else
     darwin_emit_local_bss (fp, decl, name, size, l2align);
 }
diff --git a/gcc/config/darwin.h b/gcc/config/darwin.h
index c175eade887..d6f52e7dc3c 100644
--- a/gcc/config/darwin.h
+++ b/gcc/config/darwin.h
@@ -873,13 +873,12 @@ int darwin_label_is_anonymous_local_objc_name (const char *name);
   if ((LOG) != 0)			\
     fprintf (FILE, "\t%s\t%d\n", ALIGN_ASM_OP, (LOG))
 
-/* The maximum alignment which the object file format can support in
-   bits.  For Mach-O, this is 2^15 bytes.  */
+/* The maximum alignment which the object file format can support in bits
+   which depends on the OS version and whether the object is a common
+   variable.  */
 
 #undef	MAX_OFILE_ALIGNMENT
-#define MAX_OFILE_ALIGNMENT (0x8000 * 8)
-
-#define L2_MAX_OFILE_ALIGNMENT 15
+#define MAX_OFILE_ALIGNMENT ((1U << L2_MAX_OFILE_ALIGNMENT) * 8U)
 
 /*  These are the three variants that emit referenced blank space.  */
 #define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN)		\
diff --git a/gcc/testsuite/gcc.dg/attr-aligned.c b/gcc/testsuite/gcc.dg/attr-aligned.c
index ec545639f79..a2e11c96180 100644
--- a/gcc/testsuite/gcc.dg/attr-aligned.c
+++ b/gcc/testsuite/gcc.dg/attr-aligned.c
@@ -12,8 +12,12 @@
 #  define ALIGN_MAX_STATIC      0x1000
    /* Excessive alignment for functions and objects with static storage
       duration that's expected to trigger an error.  */
-#elif __MACH__
-#  define ALIGN_MAX_STATIC      0x8000
+#elif __APPLE__
+# if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1070
+#   define ALIGN_MAX_STATIC      0x8000
+# else
+#   define ALIGN_MAX_STATIC      ALIGN_MAX_HARD
+# endif
 #elif pdp11
 #  define ALIGN_MAX_STATIC      2
 /* Work around a pdp11 ICE (see PR target/87821).  */
diff --git a/gcc/testsuite/gcc.dg/darwin-aligned-globals.c b/gcc/testsuite/gcc.dg/darwin-aligned-globals.c
new file mode 100644
index 00000000000..18b71e7e327
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/darwin-aligned-globals.c
@@ -0,0 +1,24 @@
+/* { dg-do compile { target *-*-darwin* } } */
+/* { dg-additional-options "-fcommon" } */
+
+/* Test alignment rules which differ for earlier hosts (so we must
+   work on the principle that this test will be exercised by self-
+   hosted compilers. */
+
+#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1070
+#define align_OK (1ul << 28)
+#define align_BAD (1ul << 29)
+#else
+#define align_OK (1ul << 15)
+#define align_BAD (1ul << 16)
+#endif
+
+/* All non common vars are allowed larger alignment on modern systems.  */
+static int xn __attribute__ ((aligned (align_OK)));
+static int xi __attribute__ ((aligned (align_OK))) = 5  ;
+int gxi __attribute__ ((aligned (align_OK))) = 6 ;
+
+/* test that we detect bad cases.  */
+static int yn __attribute__ ((aligned (align_BAD))); /* { dg-error {requested alignment .[0-9]+. exceeds object file maximum} } */
+static int yi __attribute__ ((aligned (align_BAD))) = 5;  /* { dg-error {requested alignment .[0-9]+. exceeds object file maximum} } */
+int yni __attribute__ ((aligned (align_BAD))) = 6;  /* { dg-error {requested alignment .[0-9]+. exceeds object file maximum} } */
diff --git a/gcc/testsuite/gcc.dg/darwin-comm-1.c b/gcc/testsuite/gcc.dg/darwin-comm-1.c
new file mode 100644
index 00000000000..46519984fd8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/darwin-comm-1.c
@@ -0,0 +1,5 @@
+/* { dg-do compile { target *-*-darwin[912]* } } */
+/* { dg-options "-fcommon" } */
+
+/* In all cases, common has a max alignment of 2^15.  */
+int badcommon __attribute__ ((aligned (65536))); /* { dg-error "common variables must have an alignment" } */
diff --git a/gcc/testsuite/gcc.target/i386/pr89261.c b/gcc/testsuite/gcc.target/i386/pr89261.c
index c5c4273439b..b599d49fd48 100644
--- a/gcc/testsuite/gcc.target/i386/pr89261.c
+++ b/gcc/testsuite/gcc.target/i386/pr89261.c
@@ -5,6 +5,7 @@
 typedef double __v2df __attribute__ ((vector_size (16), aligned (1 << 28)));
 
 __v2df foo = { 1.0, 2.0 };
-/* { dg-error {alignment of 'foo' is greater than maximum object file alignment 32768} "" { target *-*-darwin* } .-1 } */
+/* { dg-error {alignment of 'foo' is greater than maximum object file alignment 32768} "" { target { *-*-darwin[89]*  *-*-darwin10* } } .-1 } */
 
 /* { dg-final { scan-assembler "\.align\[ \t]+268435456" { target { ! *-*-darwin* } } } } */
+/* { dg-final { scan-assembler "\.align\[ \t]+28" { target { *-*-darwin1[1-9]* *-*-darwin2* } } } } */
-- 
2.24.3 (Apple Git-128)



More information about the Gcc-patches mailing list