-
Notifications
You must be signed in to change notification settings - Fork 559
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
perl 5.40.0: Crash while trying to compile perl on i686 with quadmath and SSE. #22577
Comments
Were you able to build older versions of Perl (e.g., perl-5.38.*) on this platform with the same configuration arguments? |
I've done |
For reference:
|
An artifact from ancient times! Let's hope that @jhi spots this. In the meantime, would it be possible for you to (1) either (a) download and unpack a perl-5.40.0 tarball or (b) do a checkout of tag
... and then (3) paste the content of Thanks. |
In perl.h, we deal with a __float128 alignment issue (that affects only gcc builds on Windows) with the following:
@abatyiev, perhaps that same technique could be useful to you ? |
Reproduced with blead on i686 debian. It looks like alignbytes is being set correctly. I expect |
On i686 systems with -msse __float128 requires 16 byte alignment, but for XPVNV bodies the hack used by new_body_allocated() to avoid allocating the unused xmg_stash and xmg_u fields means that the base of the XPVNV body ends up mis-aligned on 32-bit systems. One 64-bit systems the combined size of those fields is 16-bytes so the modified pointer is still properly aligned. Fixes Perl#22577
It may be that the PR fixes the ming64 misalignments too, though you might need to set alignbytes=16 in the config file. |
Windows 32-bit quadmath builds are already trouble-free. Nevertheless, for the 32-bit quadmath builds, I did try setting MEM_ALIGNBYTES and $Config{alignbytes} to 16. With the alignment values set to 16, and the current alignment fiddling removed from perl.h and win32/vmem.h, I found no trouble in running
It seems that doing away with our current alignment fiddling on the 64-bit builds might be difficult, and the 32-bit builds work so easily and simply that there's not much point in introducing any changes to them. I don't mind poking around some more if you have some advice on what else I can try to get MSWin32-x64-multi-thread-quadmath to build successfully when the alignment values are 16. |
With that aligned(8) disabled, I didn't see a crash with:
gcc is:
|
Perl SV body structures include xmg_stash and xmg_u fields at the front, which are only valid for type SVt_PVMG and higher. This allows those fields to be at a constant offset from the start of the body. To save memory perl generally allocates the bodies where type < SVt_PVMG without the space needed for these two fields, offsetting the body pointer back by the size of the two fields. At least for the first body in an arena this is technically undefined behaviour, but we've done it forever. With -msse __float128 requires 16 byte alignment, but for XPVNV bodies the hack used here means that the base of the XPVNV body ends up mis-aligned on 32-bit systems. On 64-bit systems the combined size of those fields is 16-bytes so the modified pointer is still properly aligned. To fix this allocate the full XPVNV structure when 16 byte alignment is required for NV, NV is more than 8 bytes and pointers are small enough that the NV would have been mis-aligned. Fixes Perl#22577
The aligned(16) occurrences in win32/vmem.h (which I assume you've left in place) were introduced some time after the aligned(8) modification in perl.h - ie when gcc-12 arrived on the scene. UPDATE: Today, gcc-12 is working fine. I'll do some more testing using older (but not too old) versions of gcc and submit a PR that removes the "aligned(8)" stuff in perl.h once I'm satisfied that it can be done safely.
|
It depends on which symbols are missing, it may be fixable. I did test my fix against i686 builds on Windows with -msse, which crashes in similar ways to the report here. Unfortunately I don't think this is fixable on Windows, since the underlying problem is that malloc() returns 8 byte aligned memory, not 16-byte. With UCRT we could use _aligned_malloc but that works by calling malloc() with some extra space and returning a pointer offset from the allocation to align, which is wasteful for general use (see |
As I've mentioned in the update to my previous post, I'll provide a PR that removes the aligned(8) stuff from perl.h if some more testing reveals that can be done safely. I couldn't get anywhere with -msse builds - probably something that can be looked at separately. |
Remove a Win32-specific memory alignment instruction as discussed in Perl#22577.
Remove a Win32-specific memory alignment instruction as discussed in #22577.
I found the review comments in #22609 a bit hard to follow. Is it pending another reviewer or needs more testing? (I'm just asking as OP here linked it over in the Gentoo bug and wondering if I should backport it now or wait). |
Perl SV body structures include xmg_stash and xmg_u fields at the front, which are only valid for type SVt_PVMG and higher. This allows those fields to be at a constant offset from the start of the body. To save memory perl generally allocates the bodies where type < SVt_PVMG without the space needed for these two fields, offsetting the body pointer back by the size of the two fields. At least for the first body in an arena this is technically undefined behaviour, but we've done it forever. With -msse __float128 requires 16 byte alignment, but for XPVNV bodies the hack used here means that the base of the XPVNV body ends up mis-aligned on 32-bit systems. On 64-bit systems the combined size of those fields is 16-bytes so the modified pointer is still properly aligned. To fix this allocate the full XPVNV structure when 16 byte alignment is required for NV, NV is more than 8 bytes and pointers are small enough that the NV would have been mis-aligned. Fixes #22577
I was hoping for an approval, but it's pretty esoteric, I've applied it anyway. |
Module: core
Description
I'm trying to build perl on 32bit Gentoo Linux box with SSE enabled
Steps to Reproduce
I'm trying to compile perl via following configure:
sh ./Configure -des -Dusequadmath -Accflags="-O2 -fwrapv -pipe -msse" -Doptimize="-O2 -fwrapv -pipe -msse"
However,
miniperl
binary crashes during build.Investigation
Crash in
Perl_init_constants
(sv.c:16516
) is due to misaligned access toPL_sv_no
of__float128
type, because it requires 16 bytes alignment while perl's allocator (new_XPVNV
) provides only 8 byte alignment.Compiler uses
movaps
instruction that is part of SSE instruction set that triggers the crash.Perl's allocator seem to allocate memory in blocks of 40 bytes on i686. Crash does not reproduce on x64 due to bigger allocated block (64 bytes) that provides correct alignment.
The text was updated successfully, but these errors were encountered: