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

Resurrect: rustc_target: Add alignment to indirectly-passed by-value types, correcting the alignment of byval on x86 in the process. #111551

Closed
wants to merge 0 commits into from

Conversation

erikdesjardins
Copy link
Contributor

This resurrects PR #103830, which has sat idle for a while.

I have applied the test changes requested by @wesleywiser and @nikic here and here in the latest commits.

r? @wesleywiser


@pcwalton's original PR description is reproduced below:

Commit 88e4d2c from five years ago removed
support for alignment on indirectly-passed arguments because of problems with
the i686-pc-windows-msvc target. Unfortunately, the memcpy optimizations I
recently added to LLVM 16 depend on this to forward memcpys. This commit
attempts to fix the problems with byval parameters on that target and now
correctly adds the align attribute.

The problem is summarized in this comment by @eddyb. Briefly, 32-bit x86 has
special alignment rules for byval parameters: for the most part, their
alignment is forced to 4. This is not well-documented anywhere but in the Clang
source. I looked at the logic in Clang TargetInfo.cpp and tried to replicate
it here. The relevant methods in that file are
X86_32ABIInfo::getIndirectResult() and
X86_32ABIInfo::getTypeStackAlignInBytes(). The align parameter attribute
for byval parameters in LLVM must match the platform ABI, or miscompilations
will occur. Note that this doesn't use the approach suggested by eddyb, because
I felt it was overkill to store the alignment in on_stack when special
handling is really only needed for 32-bit x86.

As a side effect, this should fix #80127, because it will make the align
parameter attribute for byval parameters match the platform ABI on LLVM
x86-64.

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels May 14, 2023
tests/codegen/align-byval.rs Outdated Show resolved Hide resolved
@nikic
Copy link
Contributor

nikic commented May 15, 2023

@bors r+ rollup=never

@bors
Copy link
Contributor

bors commented May 15, 2023

📌 Commit cbd8f2ad9bf82e1a633be5ce2c158fa3480a0e44 has been approved by nikic

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels May 15, 2023
@bors
Copy link
Contributor

bors commented May 15, 2023

⌛ Testing commit cbd8f2ad9bf82e1a633be5ce2c158fa3480a0e44 with merge efd471c2299c272c2a42764ae6dfb4aed5c033ce...

@rust-log-analyzer

This comment has been minimized.

@bors
Copy link
Contributor

bors commented May 15, 2023

💔 Test failed - checks-actions

@bors bors added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels May 15, 2023
@nikic
Copy link
Contributor

nikic commented May 16, 2023

@bors r+

@bors
Copy link
Contributor

bors commented May 16, 2023

📌 Commit d44c17586ff2f3dcf99d0e26d3c321ee7f7cebb9 has been approved by nikic

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels May 16, 2023
@bors
Copy link
Contributor

bors commented May 16, 2023

⌛ Testing commit d44c17586ff2f3dcf99d0e26d3c321ee7f7cebb9 with merge 4d0ee3b6a07bebe0a7841a08c7f96f9adbe58f6d...

@rust-log-analyzer

This comment has been minimized.

@bors
Copy link
Contributor

bors commented May 16, 2023

💔 Test failed - checks-actions

@bors bors added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels May 16, 2023
@erikdesjardins
Copy link
Contributor Author

Rebased and updated the newly added addr-of-mutate test

@bors bors added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels May 19, 2023
@erikdesjardins
Copy link
Contributor Author

erikdesjardins commented May 19, 2023

Running the test binary just fails with no output? Do assertion failures not output anything on MSVC?

failures:

---- [run-make] tests\run-make\extern-fn-explicit-align stdout ----

error: make failed
status: exit code: 2
command: "make"
--- stdout -------------------------------
make[1]: Entering directory '/c/a/rust/rust/tests/run-make/extern-fn-explicit-align'
'C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.29.30133\bin\HostX64\x86\cl.exe' -nologo -MT -Brepro -c -Fo:`cygpath -w /c/a/rust/rust/build/i686-pc-windows-msvc/test/run-make/extern-fn-explicit-align/extern-fn-explicit-align/libtest.o` test.c
test.c
'C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.29.30133\bin\HostX64\x86\lib.exe' -nologo -out:`cygpath -w /c/a/rust/rust/build/i686-pc-windows-msvc/test/run-make/extern-fn-explicit-align/extern-fn-explicit-align/test.lib` /c/a/rust/rust/build/i686-pc-windows-msvc/test/run-make/extern-fn-explicit-align/extern-fn-explicit-align/libtest.o
PATH="/c/a/rust/rust/build/i686-pc-windows-msvc/test/run-make/extern-fn-explicit-align/extern-fn-explicit-align:C:\a\rust\rust\build\i686-pc-windows-msvc\stage2\bin:/c/Program Files (x86)/Windows Kits/10/bin/x64:/c/Program Files (x86)/Windows Kits/10/bin/10.0.22621.0/x64:/c/Program Files (x86)/Microsoft Visual Studio/2019/Enterprise/VC/Tools/MSVC/14.29.30133/bin/HostX64/x64:/c/Program Files (x86)/Microsoft Visual Studio/2019/Enterprise/VC/Tools/MSVC/14.29.30133/bin/HostX64/x86:/c/a/rust/rust/build/i686-pc-windows-msvc/stage0-bootstrap-tools/i686-pc-windows-msvc/release/deps:/c/a/rust/rust/build/i686-pc-windows-msvc/stage0/bin:/c/a/rust/rust/ninja:/c/a/rust/rust/msys2/mingw32/bin:/c/hostedtoolcache/windows/Python/3.11.3/x64/Scripts:/c/hostedtoolcache/windows/Python/3.11.3/x64:/usr/bin:/c/a/rust/rust/sccache:/c/Program Files/MongoDB/Server/5.0/bin:/c/aliyun-cli:/c/vcpkg:/c/cf-cli:/c/Program Files (x86)/NSIS:/c/tools/zstd:/c/Program Files/Mercurial:/c/hostedtoolcache/windows/stack/2.9.3/x64:/c/cabal/bin:/c/ghcup/bin:/c/Program Files/dotnet:/c/mysql/bin:/c/Program Files/R/R-4.3.0/bin/x64:/c/SeleniumWebDrivers/GeckoDriver:/c/Program Files (x86)/sbt/bin:/c/Program Files (x86)/GitHub CLI:/c/Program Files/Git/bin:/c/Program Files (x86)/pipx_bin:/c/npm/prefix:/c/hostedtoolcache/windows/go/1.20.3/x64/bin:/c/hostedtoolcache/windows/Python/3.7.9/x64/Scripts:/c/hostedtoolcache/windows/Python/3.7.9/x64:/c/hostedtoolcache/windows/Ruby/2.5.9/x64/bin:/c/Program Files/OpenSSL/bin:/c/tools/kotlinc/bin:/c/hostedtoolcache/windows/Java_Temurin-Hotspot_jdk/8.0.372-7/x64/bin:/c/Program Files/ImageMagick-7.1.1-Q16-HDRI:/c/Program Files (x86)/Microsoft SDKs/Azure/CLI2/wbin:/c/ProgramData/kind:/c/Program Files/Eclipse Foundation/jdk-8.0.302.8-hotspot/bin:/c/Windows/system32:/c/Windows:/c/Windows/System32/Wbem:/c/Windows/System32/WindowsPowerShell/v1.0:/c/Windows/System32/OpenSSH:/c/ProgramData/Chocolatey/bin:/c/Program Files/PowerShell/7:/c/Program Files/Microsoft/Web Platform Installer:/c/Program Files/Microsoft SQL Server/130/Tools/Binn:/c/Program Files/Microsoft SQL Server/Client SDK/ODBC/170/Tools/Binn:/c/Program Files (x86)/Windows Kits/10/Windows Performance Toolkit:/c/Program Files (x86)/Microsoft SQL Server/110/DTS/Binn:/c/Program Files (x86)/Microsoft SQL Server/120/DTS/Binn:/c/Program Files (x86)/Microsoft SQL Server/130/DTS/Binn:/c/Program Files (x86)/Microsoft SQL Server/140/DTS/Binn:/c/Program Files (x86)/Microsoft SQL Server/150/DTS/Binn:/c/Program Files (x86)/Microsoft SQL Server/160/DTS/Binn:/c/Strawberry/c/bin:/c/Strawberry/perl/site/bin:/c/Strawberry/perl/bin:/c/ProgramData/chocolatey/lib/pulumi/tools/Pulumi/bin:/c/Program Files/TortoiseSVN/bin:/c/Program Files/CMake/bin:/c/ProgramData/chocolatey/lib/maven/apache-maven-3.8.7/bin:/c/Program Files/Microsoft Service Fabric/bin/Fabric/Fabric.Code:/c/Program Files/Microsoft SDKs/Service Fabric/Tools/ServiceFabricLocalClusterManager:/c/Program Files/nodejs:/c/Program Files/Git/cmd:/c/Program Files/Git/mingw64/bin:/c/Program Files/Git/usr/bin:/c/Program Files/GitHub CLI:/c/tools/php:/c/Program Files (x86)/sbt/bin:/c/SeleniumWebDrivers/ChromeDriver:/c/SeleniumWebDrivers/EdgeDriver:/c/Program Files/Amazon/AWSCLIV2:/c/Program Files/Amazon/SessionManagerPlugin/bin:/c/Program Files/Amazon/AWSSAMCLI/bin:/c/Program Files (x86)/Google/Cloud SDK/google-cloud-sdk/bin:/c/Program Files (x86)/Microsoft BizTalk Server:/c/Program Files/LLVM/bin:/c/Users/runneradmin/.dotnet/tools:/c/Users/runneradmin/.cargo/bin:/c/Users/runneradmin/AppData/Local/Microsoft/WindowsApps" 'C:\a\rust\rust\build\i686-pc-windows-msvc\stage2\bin\rustc.exe' --out-dir /c/a/rust/rust/build/i686-pc-windows-msvc/test/run-make/extern-fn-explicit-align/extern-fn-explicit-align -L /c/a/rust/rust/build/i686-pc-windows-msvc/test/run-make/extern-fn-explicit-align/extern-fn-explicit-align  test.rs
PATH="/c/Program Files (x86)/Windows Kits/10/bin/x64:/c/Program Files (x86)/Windows Kits/10/bin/10.0.22621.0/x64:/c/Program Files (x86)/Microsoft Visual Studio/2019/Enterprise/VC/Tools/MSVC/14.29.30133/bin/HostX64/x64:/c/Program Files (x86)/Microsoft Visual Studio/2019/Enterprise/VC/Tools/MSVC/14.29.30133/bin/HostX64/x86:/c/a/rust/rust/build/i686-pc-windows-msvc/stage0-bootstrap-tools/i686-pc-windows-msvc/release/deps:/c/a/rust/rust/build/i686-pc-windows-msvc/stage0/bin:/c/a/rust/rust/ninja:/c/a/rust/rust/msys2/mingw32/bin:/c/hostedtoolcache/windows/Python/3.11.3/x64/Scripts:/c/hostedtoolcache/windows/Python/3.11.3/x64:/usr/bin:/c/a/rust/rust/sccache:/c/Program Files/MongoDB/Server/5.0/bin:/c/aliyun-cli:/c/vcpkg:/c/cf-cli:/c/Program Files (x86)/NSIS:/c/tools/zstd:/c/Program Files/Mercurial:/c/hostedtoolcache/windows/stack/2.9.3/x64:/c/cabal/bin:/c/ghcup/bin:/c/Program Files/dotnet:/c/mysql/bin:/c/Program Files/R/R-4.3.0/bin/x64:/c/SeleniumWebDrivers/GeckoDriver:/c/Program Files (x86)/sbt/bin:/c/Program Files (x86)/GitHub CLI:/c/Program Files/Git/bin:/c/Program Files (x86)/pipx_bin:/c/npm/prefix:/c/hostedtoolcache/windows/go/1.20.3/x64/bin:/c/hostedtoolcache/windows/Python/3.7.9/x64/Scripts:/c/hostedtoolcache/windows/Python/3.7.9/x64:/c/hostedtoolcache/windows/Ruby/2.5.9/x64/bin:/c/Program Files/OpenSSL/bin:/c/tools/kotlinc/bin:/c/hostedtoolcache/windows/Java_Temurin-Hotspot_jdk/8.0.372-7/x64/bin:/c/Program Files/ImageMagick-7.1.1-Q16-HDRI:/c/Program Files (x86)/Microsoft SDKs/Azure/CLI2/wbin:/c/ProgramData/kind:/c/Program Files/Eclipse Foundation/jdk-8.0.302.8-hotspot/bin:/c/Windows/system32:/c/Windows:/c/Windows/System32/Wbem:/c/Windows/System32/WindowsPowerShell/v1.0:/c/Windows/System32/OpenSSH:/c/ProgramData/Chocolatey/bin:/c/Program Files/PowerShell/7:/c/Program Files/Microsoft/Web Platform Installer:/c/Program Files/Microsoft SQL Server/130/Tools/Binn:/c/Program Files/Microsoft SQL Server/Client SDK/ODBC/170/Tools/Binn:/c/Program Files (x86)/Windows Kits/10/Windows Performance Toolkit:/c/Program Files (x86)/Microsoft SQL Server/110/DTS/Binn:/c/Program Files (x86)/Microsoft SQL Server/120/DTS/Binn:/c/Program Files (x86)/Microsoft SQL Server/130/DTS/Binn:/c/Program Files (x86)/Microsoft SQL Server/140/DTS/Binn:/c/Program Files (x86)/Microsoft SQL Server/150/DTS/Binn:/c/Program Files (x86)/Microsoft SQL Server/160/DTS/Binn:/c/Strawberry/c/bin:/c/Strawberry/perl/site/bin:/c/Strawberry/perl/bin:/c/ProgramData/chocolatey/lib/pulumi/tools/Pulumi/bin:/c/Program Files/TortoiseSVN/bin:/c/Program Files/CMake/bin:/c/ProgramData/chocolatey/lib/maven/apache-maven-3.8.7/bin:/c/Program Files/Microsoft Service Fabric/bin/Fabric/Fabric.Code:/c/Program Files/Microsoft SDKs/Service Fabric/Tools/ServiceFabricLocalClusterManager:/c/Program Files/nodejs:/c/Program Files/Git/cmd:/c/Program Files/Git/mingw64/bin:/c/Program Files/Git/usr/bin:/c/Program Files/GitHub CLI:/c/tools/php:/c/Program Files (x86)/sbt/bin:/c/SeleniumWebDrivers/ChromeDriver:/c/SeleniumWebDrivers/EdgeDriver:/c/Program Files/Amazon/AWSCLIV2:/c/Program Files/Amazon/SessionManagerPlugin/bin:/c/Program Files/Amazon/AWSSAMCLI/bin:/c/Program Files (x86)/Google/Cloud SDK/google-cloud-sdk/bin:/c/Program Files (x86)/Microsoft BizTalk Server:/c/Program Files/LLVM/bin:/c/Users/runneradmin/.dotnet/tools:/c/Users/runneradmin/.cargo/bin:/c/Users/runneradmin/AppData/Local/Microsoft/WindowsApps:C:\a\rust\rust\build\i686-pc-windows-msvc\stage2\lib\rustlib\i686-pc-windows-msvc\lib" /c/a/rust/rust/build/i686-pc-windows-msvc/test/run-make/extern-fn-explicit-align/extern-fn-explicit-align/test || exit 1
rm /c/a/rust/rust/build/i686-pc-windows-msvc/test/run-make/extern-fn-explicit-align/extern-fn-explicit-align/libtest.o
make[1]: Leaving directory '/c/a/rust/rust/tests/run-make/extern-fn-explicit-align'
------------------------------------------
--- stderr -------------------------------
make[1]: *** [Makefile:6: all] Error 1
------------------------------------------

failures:
    [run-make] tests\run-make\extern-fn-explicit-align

test result: FAILED. 232 passed; 1 failed; 89 ignored; 0 measured; 0 filtered out; finished in 73.90s

Trying to reproduce this in a fresh Windows VM, it segfaults building stage1 core, even on master. I'll try to figure out why... (it's not OOM) Edit: "cross-compiling" from x64 windows to x86 works, so it probably was OOM, of a sort (32 bit address space exhaustion)

@erikdesjardins
Copy link
Contributor Author

erikdesjardins commented May 20, 2023

Okay, it seems like our handling of the i686-windows ABI is messed up. Both before and after this change, the added extern-fn-explicit-align test fails due to ABI incompatibility.

This appears to be our fault and not LLVM's, since Clang gets it right: https://godbolt.org/z/cG35c7TrE

Note the difference in the signature of the many_args function. This is more obvious if we remove all the other args (https://godbolt.org/z/1vbzahPdh), where this Rust:

#[repr(C)]
#[repr(align(16))]
pub struct TwoU64s {
    pub a: u64,
    pub b: u64,
}

extern "C" {
    fn many_args(h: TwoU64s) -> i32;
}

generates the following signature, passing by stack (using byval):

declare noundef i32 @many_args(ptr noalias nocapture noundef byval(%TwoU64s) dereferenceable(16))

while the equivalent C:

#ifdef _MSC_VER
__declspec(align(16))
struct TwoU64s
{
    uint64_t a;
    uint64_t b;
};
#endif

extern int32_t many_args(struct TwoU64s h);

generates the following signature, passing by reference:

declare i32 @many_args(ptr noundef)

Without the alignment attribute (https://godbolt.org/z/v8dc11MEK) it's even worse, since Rust still uses byval:

declare noundef i32 @many_args(ptr noalias nocapture noundef byval({ i64, i64 }) dereferenceable(16))

while Clang passes the struct by value in two LLVM arguments:

declare dso_local i32 @many_args(i64, i64)

Edit: actually this second example ends up generating equivalent code in both cases (by accident?), since those "by value" arguments get passed on the stack like byval, as the ABI requires

@erikdesjardins
Copy link
Contributor Author

This looks relevant: https://reviews.llvm.org/D72114

MSVC 2013 would refuse to pass highly aligned things (typically vectors
and aggregates) by value. Users would receive this error:

t.cpp(11) : error C2719: 'w': formal parameter with __declspec(align('32')) won't be aligned
t.cpp(11) : error C2719: 'q': formal parameter with __declspec(align('32')) won't be aligned

However, in MSVC 2015, this behavior was changed, and highly aligned
things are now passed indirectly. To avoid breaking backwards
incompatibility, objects that do not have a required high alignment
(i.e. double) are still passed directly, even though they are not
naturally aligned. This change implements the new behavior of passing
things indirectly.

The new behavior is:

  • up to three vector parameters can be passed in [XYZ]MM0-2
  • remaining arguments with required alignment greater than 4 bytes are passed indirectly

@erikdesjardins
Copy link
Contributor Author

erikdesjardins commented May 20, 2023

(The tests will still fail until I implement the overaligned special case, don't r+)

@rustbot author

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels May 20, 2023
@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@erikdesjardins
Copy link
Contributor Author

Okay, now it should work

r? @nikic

@rustbot review

@rustbot rustbot assigned nikic and unassigned wesleywiser May 20, 2023
@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels May 20, 2023
@erikdesjardins
Copy link
Contributor Author

ping @nikic

@erikdesjardins
Copy link
Contributor Author

erikdesjardins commented Jun 1, 2023

Pushed the wrong branch. Wish github didn't (permanently) autoclose when there's no diff...

bors added a commit to rust-lang-ci/rust that referenced this pull request Jul 15, 2023
Resurrect: rustc_target: Add alignment to indirectly-passed by-value types, correcting the alignment of byval on x86 in the process.

Same as rust-lang#111551, which I [accidentally closed](rust-lang#111551 (comment)) :/

---

This resurrects PR rust-lang#103830, which has sat idle for a while.

Beyond rust-lang#103830, this also:
- fixes byval alignment for types containing vectors on Darwin (see `tests/codegen/align-byval-vector.rs`)
- fixes byval alignment for overaligned types on x86 Windows (see `tests/codegen/align-byval.rs`)
- fixes ABI for types with 128bit requested alignment on ARM64 Linux (see `tests/codegen/aarch64-struct-align-128.rs`)

r? `@nikic`

---

`@pcwalton's` original PR description is reproduced below:

Commit 88e4d2c from five years ago removed
support for alignment on indirectly-passed arguments because of problems with
the `i686-pc-windows-msvc` target. Unfortunately, the `memcpy` optimizations I
recently added to LLVM 16 depend on this to forward `memcpy`s. This commit
attempts to fix the problems with `byval` parameters on that target and now
correctly adds the `align` attribute.

The problem is summarized in [this comment] by `@eddyb.` Briefly, 32-bit x86 has
special alignment rules for `byval` parameters: for the most part, their
alignment is forced to 4. This is not well-documented anywhere but in the Clang
source. I looked at the logic in Clang `TargetInfo.cpp` and tried to replicate
it here. The relevant methods in that file are
`X86_32ABIInfo::getIndirectResult()` and
`X86_32ABIInfo::getTypeStackAlignInBytes()`. The `align` parameter attribute
for `byval` parameters in LLVM must match the platform ABI, or miscompilations
will occur. Note that this doesn't use the approach suggested by eddyb, because
I felt it was overkill to store the alignment in `on_stack` when special
handling is really only needed for 32-bit x86.

As a side effect, this should fix rust-lang#80127, because it will make the `align`
parameter attribute for `byval` parameters match the platform ABI on LLVM
x86-64.

[this comment]: rust-lang#80822 (comment)
github-actions bot pushed a commit to rust-lang/miri that referenced this pull request Jul 16, 2023
Resurrect: rustc_target: Add alignment to indirectly-passed by-value types, correcting the alignment of byval on x86 in the process.

Same as #111551, which I [accidentally closed](rust-lang/rust#111551 (comment)) :/

---

This resurrects PR #103830, which has sat idle for a while.

Beyond #103830, this also:
- fixes byval alignment for types containing vectors on Darwin (see `tests/codegen/align-byval-vector.rs`)
- fixes byval alignment for overaligned types on x86 Windows (see `tests/codegen/align-byval.rs`)
- fixes ABI for types with 128bit requested alignment on ARM64 Linux (see `tests/codegen/aarch64-struct-align-128.rs`)

r? `@nikic`

---

`@pcwalton's` original PR description is reproduced below:

Commit 88e4d2c from five years ago removed
support for alignment on indirectly-passed arguments because of problems with
the `i686-pc-windows-msvc` target. Unfortunately, the `memcpy` optimizations I
recently added to LLVM 16 depend on this to forward `memcpy`s. This commit
attempts to fix the problems with `byval` parameters on that target and now
correctly adds the `align` attribute.

The problem is summarized in [this comment] by `@eddyb.` Briefly, 32-bit x86 has
special alignment rules for `byval` parameters: for the most part, their
alignment is forced to 4. This is not well-documented anywhere but in the Clang
source. I looked at the logic in Clang `TargetInfo.cpp` and tried to replicate
it here. The relevant methods in that file are
`X86_32ABIInfo::getIndirectResult()` and
`X86_32ABIInfo::getTypeStackAlignInBytes()`. The `align` parameter attribute
for `byval` parameters in LLVM must match the platform ABI, or miscompilations
will occur. Note that this doesn't use the approach suggested by eddyb, because
I felt it was overkill to store the alignment in `on_stack` when special
handling is really only needed for 32-bit x86.

As a side effect, this should fix #80127, because it will make the `align`
parameter attribute for `byval` parameters match the platform ABI on LLVM
x86-64.

[this comment]: #80822 (comment)
bjorn3 pushed a commit to rust-lang/rustc_codegen_cranelift that referenced this pull request Jul 22, 2023
Resurrect: rustc_target: Add alignment to indirectly-passed by-value types, correcting the alignment of byval on x86 in the process.

Same as #111551, which I [accidentally closed](rust-lang/rust#111551 (comment)) :/

---

This resurrects PR #103830, which has sat idle for a while.

Beyond #103830, this also:
- fixes byval alignment for types containing vectors on Darwin (see `tests/codegen/align-byval-vector.rs`)
- fixes byval alignment for overaligned types on x86 Windows (see `tests/codegen/align-byval.rs`)
- fixes ABI for types with 128bit requested alignment on ARM64 Linux (see `tests/codegen/aarch64-struct-align-128.rs`)

r? `@nikic`

---

`@pcwalton's` original PR description is reproduced below:

Commit 88e4d2c from five years ago removed
support for alignment on indirectly-passed arguments because of problems with
the `i686-pc-windows-msvc` target. Unfortunately, the `memcpy` optimizations I
recently added to LLVM 16 depend on this to forward `memcpy`s. This commit
attempts to fix the problems with `byval` parameters on that target and now
correctly adds the `align` attribute.

The problem is summarized in [this comment] by `@eddyb.` Briefly, 32-bit x86 has
special alignment rules for `byval` parameters: for the most part, their
alignment is forced to 4. This is not well-documented anywhere but in the Clang
source. I looked at the logic in Clang `TargetInfo.cpp` and tried to replicate
it here. The relevant methods in that file are
`X86_32ABIInfo::getIndirectResult()` and
`X86_32ABIInfo::getTypeStackAlignInBytes()`. The `align` parameter attribute
for `byval` parameters in LLVM must match the platform ABI, or miscompilations
will occur. Note that this doesn't use the approach suggested by eddyb, because
I felt it was overkill to store the alignment in `on_stack` when special
handling is really only needed for 32-bit x86.

As a side effect, this should fix #80127, because it will make the `align`
parameter attribute for `byval` parameters match the platform ABI on LLVM
x86-64.

[this comment]: #80822 (comment)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

rustc has wrong signature for C function with 16-byte aligned stack argument in x86_64 Linux
7 participants