Skip to content
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

stage2 behavior tests for all targets passing with the LLVM backend #11583

Merged
merged 9 commits into from
May 5, 2022

Conversation

andrewrk
Copy link
Member

@andrewrk andrewrk commented May 4, 2022

The goal of this branch is to get this command to pass:

stage2/bin/zig build test-behavior

Status:

  • native
  • native, -lc
  • native, -fsingle-threaded
  • wasm32-wasi
  • wasm32-wasi -lc
  • x86_64-linux
  • x86_64-linux-gnu -lc
  • x86_64-linux-musl -lc
  • x86-linux
  • x86-linux-musl -lc
  • x86-linux-gnu -lc
  • aarch64-linux
  • aarch64-linux-musl -lc
  • aarch64-linux-gnu -lc
  • aarch64-windows -lc
  • arm-linux generic+v8a
  • arm-linux-musleabihf -lc generic+v8a
  • mips-linux
  • mips-linux-musl -lc
  • mipsel-linux
  • mipsel-linux-musl -lc
  • powerpc-linux
  • powerpc-linux-musl -lc
  • riscv64-linux
  • riscv64-linux-musl -lc
  • x86_64-macos
  • aarch64-macos
  • x86-windows-msvc
  • x86_64-windows-msvc
  • x86-windows-gnu -lc
  • x86_64-windows-gnu -lc
  • native -OReleaseFast
  • native -OReleaseFast -lc
  • native -OReleaseFast -lc -fsingle-threaded
  • native -OReleaseSafe
  • native -OReleaseSafe -lc
  • native -OReleaseSafe -lc -fsingle-threaded
  • native -OReleaseSmall
  • native -OReleaseSmall -lc
  • native -OReleaseSmall -lc -fsingle-threaded

@andrewrk
Copy link
Member Author

andrewrk commented May 5, 2022

Related: #2987

andrewrk added 4 commits May 4, 2022 17:34
Prior to this commit, the logic for ABI size and ABI alignment for
integers was naive and incorrect. This results in wasted hardware as
well as undefined behavior in the LLVM backend when we memset an
incorrect number of bytes to 0xaa due to disagreeing with LLVM about the
ABI size of integers.

This commit introduces a "max int align" value which is different per
Target. This value is used to derive the ABI size and alignment of all
integers.

This commit makes an interesting change from stage1, which treats
128-bit integers as 16-bytes aligned for x86_64-linux. stage1 is
incorrect. The maximum integer alignment on this system is only 8 bytes.
This change breaks the behavior test called "128-bit cmpxchg" because on
that target, 128-bit cmpxchg does require a 16-bytes aligned pointer to
a 128 bit integer. However, this alignment property does not belong on
*all* 128 bit integers - only on the pointer type in the `@cmpxchg`
builtin function prototype. The user can then use an alignment override
annotation on a 128-bit integer variable or struct field to obtain such
a pointer.
ZIR instructions updated: atomic_load, atomic_rmw, atomic_store, cmpxchg
These no longer construct a pointer type as the result location. This
solves a TODO that was preventing the pointer from possibly being
volatile, as well as properly handling allowzero and addrspace.
It also allows the pointer to be over-aligned, which may be needed
depending on the target. As a consequence, the element type needs to be
communicated in the ZIR. This is done by strategically making one of the
operands be ResultLoc.ty instead of ResultLoc.coerced_ty if possible, or
otherwise explicitly adding elem_type into the ZIR encoding, such as in
the case of atomic_load.

The pointer type of atomic operations is now checked in Sema by coercing
it to an expected pointer type, that maybe over-aligned according to
target requirements.

Together with the previous commit, Zig now has smaller alignment for
large integers, depending on the target, and yet still has type safety
for atomic operations that specially require higher alignment.
For x86_64, LLVMABIAlignmentOfType(i128) reports 8. However I think 16
is a better number for two reasons:
1. Better machine code when loading into SIMD register.
2. The C ABI wants 16 for extern structs.
@andrewrk andrewrk force-pushed the stage2-test-behavior branch from 290e44a to 2f6a01d Compare May 5, 2022 01:00
andrewrk added 5 commits May 4, 2022 18:45
These targets now have a similar disagreement with LLVM about the
alignment of 128-bit integers as x86_64:
 * riscv64
 * powerpc64
 * powerpc64le
 * mips64
 * mips64el
 * sparcv9

See #2987
So far it's supported by the LLVM backend only. I recommend for the
other backends to wait for the resolution of #10761 before adding
support for this feature.
 * sret logic needed a check for hasRuntimeBits()
 * lower f128 on windows targets with the "sse" class rather than
   "memory". For reference, clang emits a compile error when __float128
   is used with the MSVC ABI, saying that this type is not supported.
   The docs for the x64 calling convention have both of these sentences:
   - "Any argument that doesn't fit in 8 bytes, or isn't 1, 2, 4, or 8 bytes,
     must be passed by reference."
   - "All floating point operations are done using the 16 XMM registers."
 * For i128, however, it is clear that the Windows calling convention
   wants such an object to be passed by reference. I fixed the LLVM
   lowering for function parameters to make this work.
@andrewrk andrewrk merged commit 59905a6 into master May 5, 2022
@andrewrk andrewrk deleted the stage2-test-behavior branch May 5, 2022 16:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant