1
0
mirror of https://github.com/skeeto/w64devkit.git synced 2026-10-23 06:08:56 +03:00

Keep long long locals 8-byte aligned on i686

GCC 16 lowered the 32-bit cygming preferred stack boundary to 4 bytes,
and the i386 back end then places long long locals at 4-byte alignment
even though -malign-double, the default on these targets, makes
_Alignof(long long) 8. Such locals trap under -fsanitize=alignment.
Treat them as the back end already treats doubles.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Christopher Wellons
2026-10-18 10:24:39 -04:00
parent 3eff223c6d
commit 0de8f0763a
2 changed files with 44 additions and 0 deletions

View File

@@ -0,0 +1,43 @@
Keep long long locals 8-byte aligned on i686 Windows. GCC 16 lowered
the default preferred stack boundary for 32-bit cygming targets to 4
bytes. With a 4-byte boundary, the i386 back end lowers the alignment
of long long locals to 4 bytes to avoid dynamic stack realignment, both
when laying out declarations (ix86_local_alignment) and when deciding
whether a frame needs realignment (ix86_minimum_alignment). That is
valid for the System V i386 ABI, where long long has 4-byte ABI
alignment, but these targets default to -malign-double, so
_Alignof(long long) is 8. Lowering then places objects below their
type's alignment, and -fsanitize=alignment traps on them:
void store(long long *p) { *p = 1; }
void f(void) { long long x; store(&x); } // &x % 8 == 4
Doubles and address-taken long long parameters are already realigned;
this treats long long locals the same way whenever -malign-double is in
effect. Spill slots that are not visible to the program are realigned
too, but the cost is small: on zstd and xxHash at -O2, about 0.6% more
instructions.
--- a/gcc/config/i386/i386.cc
+++ b/gcc/config/i386/i386.cc
@@ -18763,7 +18763,7 @@
/* Don't do dynamic stack realignment for long long objects with
-mpreferred-stack-boundary=2. */
if (may_lower
- && !TARGET_64BIT
+ && !TARGET_64BIT && !TARGET_ALIGN_DOUBLE
&& align == 64
&& ix86_preferred_stack_boundary < 64
&& (mode == DImode || (type && TYPE_MODE (type) == DImode))
@@ -18873,7 +18873,10 @@
decl = NULL;
}
- if (TARGET_64BIT || align != 64 || ix86_preferred_stack_boundary >= 64)
+ /* With -malign-double the ABI alignment of long long is 64 bits, so
+ it cannot be lowered (see x86_field_alignment). */
+ if (TARGET_64BIT || TARGET_ALIGN_DOUBLE
+ || align != 64 || ix86_preferred_stack_boundary >= 64)
return align;
/* Don't do dynamic stack realignment for long long objects with

View File

@@ -3,3 +3,4 @@ dynamic-load-tzdb.patch
libgfortran-mapview.patch
trap-terminate.patch
system-clock-y2038.patch
align-double-locals.patch