diff options
author | Alex Crichton <alex@alexcrichton.com> | 2018-10-14 12:27:22 -0700 |
---|---|---|
committer | Alex Crichton <alex@alexcrichton.com> | 2018-10-19 02:35:00 -0700 |
commit | 3cc8f738d4247a9b475d8e074b621e602ac2b7be (patch) | |
tree | dba6d11f4bc2476e5e8bc3ed47d5986343651f06 /src/librustc_llvm | |
parent | b1bdf04c97dd6631c627fe1a9d7fe2bb68e35dfd (diff) | |
download | rust-3cc8f738d4247a9b475d8e074b621e602ac2b7be.tar.gz |
rustc: Fix (again) simd vectors by-val in ABI
The issue of passing around SIMD types as values between functions has
seen [quite a lot] of [discussion], and although we thought [we fixed
it][quite a lot] it [wasn't]! This PR is a change to rustc to, again,
try to fix this issue.
The fundamental problem here remains the same, if a SIMD vector argument
is passed by-value in LLVM's function type, then if the caller and
callee disagree on target features a miscompile happens. We solve this
by never passing SIMD vectors by-value, but LLVM will still thwart us
with its argument promotion pass to promote by-ref SIMD arguments to
by-val SIMD arguments.
This commit is an attempt to thwart LLVM thwarting us. We, just before
codegen, will take yet another look at the LLVM module and demote any
by-value SIMD arguments we see. This is a very manual attempt by us to
ensure the codegen for a module keeps working, and it unfortunately is
likely producing suboptimal code, even in release mode. The saving grace
for this, in theory, is that if SIMD types are passed by-value across
a boundary in release mode it's pretty unlikely to be performance
sensitive (as it's already doing a load/store, and otherwise
perf-sensitive bits should be inlined).
The implementation here is basically a big wad of C++. It was largely
copied from LLVM's own argument promotion pass, only doing the reverse.
In local testing this...
Closes #50154
Closes #52636
Closes #54583
Closes #55059
[quite a lot]: https://github.com/rust-lang/rust/pull/47743
[discussion]: https://github.com/rust-lang/rust/issues/44367
[wasn't]: https://github.com/rust-lang/rust/issues/50154
Diffstat (limited to 'src/librustc_llvm')
-rw-r--r-- | src/librustc_llvm/build.rs | 4 |
1 files changed, 3 insertions, 1 deletions
diff --git a/src/librustc_llvm/build.rs b/src/librustc_llvm/build.rs index 7d01ed556c8..ad5db19839e 100644 --- a/src/librustc_llvm/build.rs +++ b/src/librustc_llvm/build.rs @@ -162,7 +162,9 @@ fn main() { } build_helper::rerun_if_changed_anything_in_dir(Path::new("../rustllvm")); - cfg.file("../rustllvm/PassWrapper.cpp") + cfg + .file("../rustllvm/DemoteSimd.cpp") + .file("../rustllvm/PassWrapper.cpp") .file("../rustllvm/RustWrapper.cpp") .file("../rustllvm/ArchiveWrapper.cpp") .file("../rustllvm/Linker.cpp") |