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

adds simd_select intrinsic #49141

Merged
merged 3 commits into from
Mar 25, 2018
Merged

adds simd_select intrinsic #49141

merged 3 commits into from
Mar 25, 2018

Conversation

gnzlbg
Copy link
Contributor

@gnzlbg gnzlbg commented Mar 18, 2018

The select SIMD intrinsic is used to select elements from two SIMD vectors using a mask:

let mask = b8x4::new(true, false, false, true);
let a = f32x4::new(1., 2., 3., 4.);
let b = f32x4::new(5., 6., 7., 8.);
assert_eq!(simd_select(mask, a, b), f32x4::new(1., 6., 7., 4.));

The number of lanes between the mask and the vectors must match, but the vector width of the mask does not need to match that of the vectors. The mask is required to be a vector of signed integers.

Note: this intrinsic will be exposed via std::simd's vector masks - users are not expected to use it directly.

@rust-highfive
Copy link
Collaborator

r? @pnkfelix

(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 Mar 18, 2018
@gnzlbg
Copy link
Contributor Author

gnzlbg commented Mar 18, 2018

r? @alexcrichton

@hanna-kruppe
Copy link
Contributor

LGTM, though I would have expected a codegen test.

But I'll leave the decision whether to add this intrinsic to @alexcrichton since I don't have a good overview over the portable SIMD story that this ties into.

@gnzlbg
Copy link
Contributor Author

gnzlbg commented Mar 18, 2018

@rkruppe could you point me to a codegen test ? I'll try to add one.

The select intrinsic should generate: https://llvm.org/docs/LangRef.html#select-instruction

<result> = select selty <cond>, <ty> <val1>, <ty> <val2>             ; yields ty
; selty is either i1 or {<N x i1>}

@hanna-kruppe
Copy link
Contributor

There's plenty of them in src/test/codegen. One example that seems conceptually close to what you're doing here is https://github.com/rust-lang/rust/blob/master/src/test/codegen/float_math.rs

@gnzlbg
Copy link
Contributor Author

gnzlbg commented Mar 18, 2018

@rkruppe I've added a codegen test :)

@sanxiyn
Copy link
Member

sanxiyn commented Mar 19, 2018

@bors r+

@bors
Copy link
Contributor

bors commented Mar 19, 2018

📌 Commit cca2604 has been approved by sanxiyn

@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 Mar 19, 2018
@kennytm
Copy link
Member

kennytm commented Mar 20, 2018

@bors r-

Emscripten does not support the trunc <4 x i8> %242 to <4 x i1> LLVM instruction in the new run-pass test.

[01:34:23] failures:
[01:34:23] 
[01:34:23] ---- [run-pass] run-pass/simd-intrinsic-generic-select.rs stdout ----
[01:34:23] 	
[01:34:23] error: compilation failed!
[01:34:23] status: exit code: 101
[01:34:23] command: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/src/test/run-pass/simd-intrinsic-generic-select.rs" "-L" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/run-pass" "--target=asmjs-unknown-emscripten" "-C" "prefer-dynamic" "-o" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/run-pass/simd-intrinsic-generic-select.stage2-asmjs-unknown-emscripten.js" "-Crpath" "-Zmiri" "-Zunstable-options" "-Lnative=/checkout/obj/build/asmjs-unknown-emscripten/native/rust-test-helpers" "-L" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/run-pass/simd-intrinsic-generic-select.stage2-asmjs-unknown-emscripten.aux"
[01:34:23] stdout:
[01:34:23] ------------------------------------------
[01:34:23] 
[01:34:23] ------------------------------------------
[01:34:23] stderr:
[01:34:23] ------------------------------------------
[01:34:23] warning: type `u32x4` should have a camel case name such as `U32x4`
[01:34:23]   --> /checkout/src/test/run-pass/simd-intrinsic-generic-select.rs:22:1
[01:34:23]    |
[01:34:23] 22 | struct u32x4(pub u32, pub u32, pub u32, pub u32);
[01:34:23]    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[01:34:23]    |
[01:34:23]    = note: #[warn(non_camel_case_types)] on by default
[01:34:23] 
[01:34:23] warning: type `f32x4` should have a camel case name such as `F32x4`
[01:34:23]   --> /checkout/src/test/run-pass/simd-intrinsic-generic-select.rs:26:1
[01:34:23]    |
[01:34:23] 26 | struct f32x4(pub f32, pub f32, pub f32, pub f32);
[01:34:23]    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[01:34:23] 
[01:34:23] warning: type `b8x4` should have a camel case name such as `B8x4`
[01:34:23]   --> /checkout/src/test/run-pass/simd-intrinsic-generic-select.rs:30:1
[01:34:23]    |
[01:34:23] 30 | struct b8x4(pub i8, pub i8, pub i8, pub i8);
[01:34:23]    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[01:34:23] 
[01:34:23] error: linking with `emcc` failed: exit code: 1
[01:34:23]   |
[01:34:23]   = note: "emcc" "-s" "DISABLE_EXCEPTION_CATCHING=0" "-L" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/asmjs-unknown-emscripten/lib" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/run-pass/simd-intrinsic-generic-select.simd_intrinsic_generic_select0.rcgu.o" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/run-pass/simd-intrinsic-generic-select.simd_intrinsic_generic_select1.rcgu.o" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/run-pass/simd-intrinsic-generic-select.simd_intrinsic_generic_select2.rcgu.o" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/run-pass/simd-intrinsic-generic-select.simd_intrinsic_generic_select3.rcgu.o" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/run-pass/simd-intrinsic-generic-select.simd_intrinsic_generic_select4.rcgu.o" "-o" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/run-pass/simd-intrinsic-generic-select.stage2-asmjs-unknown-emscripten.js" "-s" "EXPORTED_FUNCTIONS=[\"_main\",\"_rust_eh_personality\"]" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/run-pass/simd-intrinsic-generic-select.crate.allocator.rcgu.o" "-O0" "--memory-init-file" "0" "-g0" "-s" "DEFAULT_LIBRARY_FUNCS_TO_INCLUDE=[]" "-L" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/run-pass" "-L" "/checkout/obj/build/asmjs-unknown-emscripten/native/rust-test-helpers" "-L" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/run-pass/simd-intrinsic-generic-select.stage2-asmjs-unknown-emscripten.aux" "-L" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/asmjs-unknown-emscripten/lib" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/asmjs-unknown-emscripten/lib/libstd-7beb25be610b1dc7.rlib" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/asmjs-unknown-emscripten/lib/libpanic_unwind-3120ca6f0abf7a1c.rlib" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/asmjs-unknown-emscripten/lib/libunwind-aa0e4e666207dc49.rlib" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/asmjs-unknown-emscripten/lib/liballoc_system-46e5367b25f6a1bd.rlib" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/asmjs-unknown-emscripten/lib/liblibc-70db4fd830eb0511.rlib" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/asmjs-unknown-emscripten/lib/liballoc-2213efc3149321df.rlib" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/asmjs-unknown-emscripten/lib/libstd_unicode-f6f336308541ac07.rlib" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/asmjs-unknown-emscripten/lib/libcore-6db47a0e2830c329.rlib" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/asmjs-unknown-emscripten/lib/libcompiler_builtins-8d5a0f793c60ffb6.rlib" "-l" "c" "-s" "ERROR_ON_UNDEFINED_SYMBOLS=1" "-s" "ABORTING_MALLOC=0"
[01:34:23]   = note:   %245 = trunc <4 x i8> %242 to <4 x i1>
[01:34:23]           LLVM ERROR: invalid vector instr
[01:34:23]           Traceback (most recent call last):
[01:34:23]             File "/emsdk-portable/emscripten/1.37.13//emcc", line 13, in <module>
[01:34:23]               emcc.run()
[01:34:23]             File "/emsdk-portable/emscripten/1.37.13/emcc.py", line 1526, in run
[01:34:23]               final = shared.Building.emscripten(final, append_ext=False, extra_args=extra_args)
[01:34:23]             File "/emsdk-portable/emscripten/1.37.13/tools/shared.py", line 1963, in emscripten
[01:34:23]               call_emscripten(cmdline)
[01:34:23]             File "/emsdk-portable/emscripten/1.37.13/emscripten.py", line 2190, in _main
[01:34:23]               temp_files.run_and_clean(lambda: main(
[01:34:23]             File "/emsdk-portable/emscripten/1.37.13/tools/tempfiles.py", line 78, in run_and_clean
[01:34:23]               return func()
[01:34:23]             File "/emsdk-portable/emscripten/1.37.13/emscripten.py", line 2195, in <lambda>
[01:34:23]               DEBUG=DEBUG,
[01:34:23]             File "/emsdk-portable/emscripten/1.37.13/emscripten.py", line 2095, in main
[01:34:23]               temp_files=temp_files, DEBUG=DEBUG)
[01:34:23]             File "/emsdk-portable/emscripten/1.37.13/emscripten.py", line 93, in emscript
[01:34:23]               backend_output = compile_js(infile, settings, temp_files, DEBUG)
[01:34:23]             File "/emsdk-portable/emscripten/1.37.13/emscripten.py", line 127, in compile_js
[01:34:23]               backend_output = open(temp_js).read()
[01:34:23]           IOError: [Errno 2] No such file or directory: '/tmp/tmpukKlpP.4.js'
[01:34:23]           
[01:34:23] 
[01:34:23] error: aborting due to previous error
[01:34:23] 
[01:34:23] 
[01:34:23] ------------------------------------------
[01:34:23] 
[01:34:23] thread '[run-pass] run-pass/simd-intrinsic-generic-select.rs' panicked at 'explicit panic', tools/compiletest/src/runtest.rs:2903:9
[01:34:23] note: Run with `RUST_BACKTRACE=1` for a backtrace.
[01:34:23] 
[01:34:23] 
[01:34:23] failures:
[01:34:23]     [run-pass] run-pass/simd-intrinsic-generic-select.rs

(Do not rollup this PR in the future.)

@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 Mar 20, 2018
@gnzlbg
Copy link
Contributor Author

gnzlbg commented Mar 20, 2018

@kennytm i've added an // ignore emscripten to the run-pass test. I made a similar mistake of not doing that in my previous PR, is there a way for me to test these locally?

@kennytm
Copy link
Member

kennytm commented Mar 20, 2018

@gnzlbg I... don't know a solution besides adding the asmjs/wasm targets in config.toml and run them using ./x.py test --target asmjs-unknown-emscripten src/run-pass, which will take a long time to compile locally 😞

BTW I think you do want to check if this test works on wasm32-unknown-unknown, I'm not sure if this instruction is supported there.

@gnzlbg
Copy link
Contributor Author

gnzlbg commented Mar 20, 2018

BTW I think you do want to check if this test works on wasm32-unknown-unknown, I'm not sure if this instruction is supported there.

It should work there, but that does not mean it will build successfully :/

@alexcrichton
Copy link
Member

@bors: r+

@bors
Copy link
Contributor

bors commented Mar 20, 2018

📌 Commit 4eff4d9 has been approved by alexcrichton

@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 Mar 20, 2018
alexcrichton added a commit to alexcrichton/rust that referenced this pull request Mar 23, 2018
adds simd_select intrinsic

The select SIMD intrinsic is used to select elements from two SIMD vectors using a mask:

```rust
let mask = b8x4::new(true, false, false, true);
let a = f32x4::new(1., 2., 3., 4.);
let b = f32x4::new(5., 6., 7., 8.);
assert_eq!(simd_select(mask, a, b), f32x4::new(1., 6., 7., 4.));
```

The number of lanes between the mask and the vectors must match, but the vector width of the mask does not need to match that of the vectors. The mask is required to be a vector of signed integers.

Note: this intrinsic will be exposed via `std::simd`'s vector masks - users are not expected to use it directly.
bors added a commit that referenced this pull request Mar 25, 2018
adds simd_select intrinsic

The select SIMD intrinsic is used to select elements from two SIMD vectors using a mask:

```rust
let mask = b8x4::new(true, false, false, true);
let a = f32x4::new(1., 2., 3., 4.);
let b = f32x4::new(5., 6., 7., 8.);
assert_eq!(simd_select(mask, a, b), f32x4::new(1., 6., 7., 4.));
```

The number of lanes between the mask and the vectors must match, but the vector width of the mask does not need to match that of the vectors. The mask is required to be a vector of signed integers.

Note: this intrinsic will be exposed via `std::simd`'s vector masks - users are not expected to use it directly.
@bors
Copy link
Contributor

bors commented Mar 25, 2018

⌛ Testing commit 4eff4d9 with merge 77e2bcb...

@bors
Copy link
Contributor

bors commented Mar 25, 2018

☀️ Test successful - status-appveyor, status-travis
Approved by: alexcrichton
Pushing 77e2bcb to master...

@bors bors merged commit 4eff4d9 into rust-lang:master Mar 25, 2018
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
Development

Successfully merging this pull request may close these issues.

8 participants