Skip to content

add core::intrinsics::simd::{simd_extract_dyn, simd_insert_dyn} #137447

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

Merged
merged 1 commit into from
Apr 11, 2025

Conversation

folkertdev
Copy link
Contributor

@folkertdev folkertdev commented Feb 22, 2025

fixes #137372

adds core::intrinsics::simd::{simd_extract_dyn, simd_insert_dyn}, which contrary to their non-dyn counterparts allow a non-const index. Many platforms (but notably not x86_64 or aarch64) have dedicated instructions for this operation, which stdarch can emit with this change.

Future work is to also make the Index operation on the Simd type emit this operation, but the intrinsic can't be used directly. We'll need some MIR shenanigans for that.

r? @ghost

@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. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Feb 22, 2025
@folkertdev
Copy link
Contributor Author

folkertdev commented Feb 23, 2025

right so this works with the LLVM implementation (so the fallback is not used), is there some try job that would run tests/ui/simd/intrinsic/generic-elements-pass.rs with the fallback (e.g. with miri?)

@workingjubilee
Copy link
Member

you should be able to just ./x.py test miri I think

@folkertdev
Copy link
Contributor Author

I don't think that runs this test? or it does work. I've added a commit that disables the custom LLVM implementation, so the fallback should be used. Locally that errors with

--- stderr -------------------------------
error: internal compiler error: /home/folkertdev/rust/rust/compiler/rustc_codegen_ssa/src/mir/block.rs:987:29: intrinsic simd_insert_dyn must be overridden by codegen backend, but isn't
  --> /home/folkertdev/rust/rust/tests/ui/simd/intrinsic/generic-elements-pass.rs:88:17
   |
LL |         all_eq!(simd_insert_dyn(x2, 0, 100), i32x2([100, 21]));
   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^


thread 'rustc' panicked at /home/folkertdev/rust/rust/compiler/rustc_codegen_ssa/src/mir/block.rs:987:29:

@rust-log-analyzer

This comment has been minimized.

@workingjubilee
Copy link
Member

odd.

@scottmcm
Copy link
Member

is there some try job that would run tests/ui/simd/intrinsic/generic-elements-pass.rs with the fallback (e.g. with miri?)

It looks like something you could make const fn, right?

If so, you can test the fallback in CTFE. (Might need #[miri::intrinsic_fallback_is_spec]; I forget.)

@folkertdev
Copy link
Contributor Author

none of that solves the actual problem of rustc somehow believing that this intrinsic must be overwritten by the backend. The only place where LLVM matches on the "simd_" prefix, I've disabled. But renaming to dyn_simd_{extract, insert} also does not fix the issue.

I can mark the functions as const (though extract needs to do a forget on the vector, which may or may not be correct). But even if that fixes the situation for miri, it does not for gcc and cranelift.

@folkertdev folkertdev force-pushed the simd-extract-insert-dyn branch from aa1b187 to dbda1dc Compare February 23, 2025 14:02
@rust-log-analyzer

This comment has been minimized.

@folkertdev
Copy link
Contributor Author

right, with the standard imports it's now hitting the LLVM codegen test, hence the fallback is actually used (but generates something different from what the test expects).

So, that should be sufficient right? Then the logic that prevents the LLVM implementation from being used can be removed and the hard work here should be done.

@folkertdev folkertdev force-pushed the simd-extract-insert-dyn branch from dbda1dc to 47d48fb Compare February 24, 2025 08:35
@folkertdev folkertdev marked this pull request as ready for review February 24, 2025 10:02
@rustbot
Copy link
Collaborator

rustbot commented Feb 24, 2025

Some changes occurred to the platform-builtins intrinsics. Make sure the
LLVM backend as well as portable-simd gets adapted for the changes.

cc @antoyo, @GuillaumeGomez, @bjorn3, @calebzulawski, @programmerjake

Some changes occurred to the intrinsics. Make sure the CTFE / Miri interpreter
gets adapted for the changes, if necessary.

cc @rust-lang/miri, @rust-lang/wg-const-eval

@RalfJung
Copy link
Member

is there some try job that would run tests/ui/simd/intrinsic/generic-elements-pass.rs with the fallback (e.g. with miri?)

No, Miri has its own test suite.

If so, you can test the fallback in CTFE. (Might need #[miri::intrinsic_fallback_is_spec]; I forget.)

You're mixing up a few things here.^^ CTFE doesn't care about #[miri::intrinsic_fallback_is_spec], only Miri does. CTEF also doesn't implement most of the SIMD intrinsics.

If you add that attribute, note that it has a semantic meaning! It means the fallback must fully cover every case of the spec, including UB and non-determinism.

What would the fallback implementation even be here, given that all the types are unknown?

@RalfJung
Copy link
Member

RalfJung commented Feb 24, 2025

What would the fallback implementation even be here, given that all the types are unknown?

Ah, I have found the old implementations in the diffs.

unsafe { (&mut x as *mut T as *mut U).add(idx as usize).write(val) }

Adding intrinsic_fallback_is_spec here would be not correct! If the idx is out-of-bounds, this will not reliably trigger UB, instead it might override data that's outside the index but still inbounds of some allocation.

IOW, it would not be correct to specify the intrinsic as (&mut x as *mut T as *mut U).add(idx as usize).write(val), and therefore saying "the fallback implementation is the spec" would be wrong.

@workingjubilee
Copy link
Member

Adding intrinsic_fallback_is_spec here would be not correct! If the idx is out-of-bounds, this will not reliably trigger UB, instead it might override data that's outside the index but still inbounds of some allocation.

How? The allocation would be the SIMD type itself, wouldn't it? Since that moves by-value into the function.

@workingjubilee
Copy link
Member

I suppose it needs a copy bound, but

@RalfJung
Copy link
Member

How? The allocation would be the SIMD type itself, wouldn't it? Since that moves by-value into the function.

Ah, fair, I forgot that this is not a reference/pointer.

@folkertdev
Copy link
Contributor Author

not 100% following here: should I add #[miri::intrinsic_fallback_is_spec] to the new functions?

@RalfJung
Copy link
Member

RalfJung commented Feb 24, 2025 via email

@RalfJung
Copy link
Member

As far as I can tell, the implementation should be a trivial matter of adding | syn::simd_insert_dyn here

and the same with simd_extract_dyn a few lines down.

@folkertdev
Copy link
Contributor Author

well there is some related discussion over on zullip on whether this is the best approach

#project-portable-simd > simd extraction/insertion with a non-`const` index

I think we've sort of settled on this being the best approach at the moment, but idk maybe it needs more discussion still.

@folkertdev
Copy link
Contributor Author

well I believe this is ready and there's not been any further discussion I think this just needs review at this point

@rustbot ready

@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 Apr 3, 2025
Copy link
Member

@scottmcm scottmcm left a comment

Choose a reason for hiding this comment

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

I think this is mostly fine, but did have some requested cleanup that I think would be good.

@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 Apr 10, 2025
@folkertdev folkertdev force-pushed the simd-extract-insert-dyn branch from 9239a91 to 82f321d Compare April 10, 2025 08:59
@folkertdev
Copy link
Contributor Author

@rustbot ready

@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 Apr 10, 2025
@@ -0,0 +1,75 @@
//@compile-flags: -C no-prepopulate-passes -Z merge-functions=disabled
Copy link
Member

Choose a reason for hiding this comment

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

You probably still want

Suggested change
//@compile-flags: -C no-prepopulate-passes -Z merge-functions=disabled
//@compile-flags: -C opt-level=3 -C no-prepopulate-passes

so that rust always treats it as optimized, emitting things like noundef parameter attributes, so that (as you say) you get consistent output no matter the default optimization level.

-C no-prepopulate-passes just turns off the LLVM passes so that it doesn't change what rustc emitted.

Copy link
Member

Choose a reason for hiding this comment

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

(Which also means it turns off the function merging pass you so you don't need to worry about -Z merge-function.)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Got it, fixed that

@folkertdev folkertdev force-pushed the simd-extract-insert-dyn branch from 82f321d to 59c5533 Compare April 10, 2025 19:22
@scottmcm
Copy link
Member

@bors r+

@bors
Copy link
Collaborator

bors commented Apr 11, 2025

📌 Commit 59c5533 has been approved by scottmcm

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 Apr 11, 2025
bors added a commit to rust-lang-ci/rust that referenced this pull request Apr 11, 2025
Rollup of 12 pull requests

Successful merges:

 - rust-lang#137447 (add `core::intrinsics::simd::{simd_extract_dyn, simd_insert_dyn}`)
 - rust-lang#138182 (rustc_target: update x86_win64 to match the documented calling convention for f128)
 - rust-lang#138682 (Allow drivers to supply a list of extra symbols to intern)
 - rust-lang#138904 (Test linking and running `no_std` binaries)
 - rust-lang#138998 (Don't suggest the use of  `impl Trait` in closure parameter)
 - rust-lang#139447 (doc changes: debug assertions -> overflow checks)
 - rust-lang#139469 (Introduce a `//@ needs-crate-type` compiletest directive)
 - rust-lang#139564 (Deeply normalize obligations in `BestObligation` folder)
 - rust-lang#139574 (bootstrap: improve `channel` handling)
 - rust-lang#139600 (Update `compiler-builtins` to 0.1.153)
 - rust-lang#139641 (Allow parenthesis around inferred array lengths)
 - rust-lang#139654 (Improve `AssocItem::descr`.)

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit 45ebc40 into rust-lang:master Apr 11, 2025
6 checks passed
@rustbot rustbot added this to the 1.88.0 milestone Apr 11, 2025
rust-timer added a commit to rust-lang-ci/rust that referenced this pull request Apr 11, 2025
Rollup merge of rust-lang#137447 - folkertdev:simd-extract-insert-dyn, r=scottmcm

add `core::intrinsics::simd::{simd_extract_dyn, simd_insert_dyn}`

fixes rust-lang#137372

adds `core::intrinsics::simd::{simd_extract_dyn, simd_insert_dyn}`, which contrary to their non-dyn counterparts allow a non-const index. Many platforms (but notably not x86_64 or aarch64) have dedicated instructions for this operation, which stdarch can emit with this change.

Future work is to also make the `Index` operation on the `Simd` type emit this operation, but the intrinsic can't be used directly. We'll need some MIR shenanigans for that.

r? `@ghost`
github-actions bot pushed a commit to model-checking/verify-rust-std that referenced this pull request Apr 19, 2025
…, r=scottmcm

add `core::intrinsics::simd::{simd_extract_dyn, simd_insert_dyn}`

fixes rust-lang#137372

adds `core::intrinsics::simd::{simd_extract_dyn, simd_insert_dyn}`, which contrary to their non-dyn counterparts allow a non-const index. Many platforms (but notably not x86_64 or aarch64) have dedicated instructions for this operation, which stdarch can emit with this change.

Future work is to also make the `Index` operation on the `Simd` type emit this operation, but the intrinsic can't be used directly. We'll need some MIR shenanigans for that.

r? `@ghost`
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. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

s390x: extracting an element at a non-const index from a SIMD vector generates bad code
8 participants