-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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: Use LLVM's new saturating float-to-int intrinsics #84339
Conversation
(rust-highfive has picked a reviewer for you, use r? to override) |
For comparison, this is the difference on x86_64 of the codegen differences. |
a3e784c
to
f168bfe
Compare
Also, on second though, I went ahead and removed as many WebAssembly-specific bits here as I could, so I think that this represents the final state of what this will look like in the long run (until pre-LLVM-12 is dropped). The consequences of this though is that WebAssembly targets on pre-LLVM-12 won't work (because the intrinsic won't be defined) and the WebAssembly target with |
r? @nagisa I don't believe @matthewjasper been active lately. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This broadly speaking seems good to me, but see remarks inline on some sticking points.
r=me once those are resolved.
// Note that we skip the wasm intrinsics for vector types where `fptoui` | ||
// must be used instead. | ||
if self.wasm_and_missing_nontrapping_fptoint() { | ||
// This intrinsic is only used with non-saturating casts that have UB on |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: this is not really an intrinsic, but rather a builder method/instruction builder/etc?
From this comment it is no longer clear why it is important that we specifically go through an effort on wasm to pick a behaviour for what's otherwise an undefined behaviour. It would be good to keep the remark about the intrinsics producing better machine code.
(as a side note: From spelunking it seems that simd_cast
also uses this (cc @workingjubilee @calebzulawski) which is potentially undesired (similar to the issue fixed in #84274). This implementation would also crash in a simd setting on wasm, but that's a future improvement)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It does seem a little odd to trap on UB, my understanding is that this function is really only for {f32,f64}::to_int_unchecked
which assumes the caller already checked the bounds.
This doesn't crash on wasm simd (we test the simd version of to_int_unchecked
on wasm)--it looks like it falls back to the generic llvm instruction which supports vectors
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've changed "intrinsic" to "method", and I've elaborated on the comment to hopefully help explain why wasm is different here.
This should work for SIMD types since it specifically avoids (a few lines below) any input types that are vectors.
Cranelift specifically only has a saturating and trapping version of the float-to-int conversion instruction. There is none that has UB or returns a bogus result. |
This commit updates rustc, with an applicable LLVM version, to use LLVM's new `llvm.fpto{u,s}i.sat.*.*` intrinsics to implement saturating floating-point-to-int conversions. This results in a little bit tighter codegen for x86/x86_64, but the main purpose of this is to prepare for upcoming changes to the WebAssembly backend in LLVM where wasm's saturating float-to-int instructions will now be implemented with these intrinsics. This change allows simplifying a good deal of surrounding code, namely removing a lot of wasm-specific behavior. WebAssembly no longer has any special-casing of saturating arithmetic instructions and the need for `fptoint_may_trap` is gone and all handling code for that is now removed. This means that the only wasm-specific logic is in the `fpto{s,u}i` instructions which only get used for "out of bounds is undefined behavior". This does mean that for the WebAssembly target specifically the Rust compiler will no longer be 100% compatible with pre-LLVM 12 versions, but it seems like that's unlikely to be relied on by too many folks. Note that this change does immediately regress the codegen of saturating float-to-int casts on WebAssembly due to the specialization of the LLVM intrinsic not being present in our LLVM fork just yet. I'll be following up with an LLVM update to pull in those patches, but affects a few other SIMD things in flight for WebAssembly so I wanted to separate this change. Eventually the entire `cast_float_to_int` function can be removed when LLVM 12 is the minimum version, but that will require sinking the complexity of it into other backends such as Cranelfit.
f168bfe
to
de2a460
Compare
Great! Then when LLVM 12 is the minimum supported version we can delete even more code and just assume the builder methods do the right thing. |
@bors: r=nagisa |
📌 Commit de2a460 has been approved by |
🌲 The tree is currently closed for pull requests below priority 1000. This pull request will be tested once the tree is reopened. |
…gisa rustc: Use LLVM's new saturating float-to-int intrinsics This commit updates rustc, with an applicable LLVM version, to use LLVM's new `llvm.fpto{u,s}i.sat.*.*` intrinsics to implement saturating floating-point-to-int conversions. This results in a little bit tighter codegen for x86/x86_64, but the main purpose of this is to prepare for upcoming changes to the WebAssembly backend in LLVM where wasm's saturating float-to-int instructions will now be implemented with these intrinsics. This change allows simplifying a good deal of surrounding code, namely removing a lot of wasm-specific behavior. WebAssembly no longer has any special-casing of saturating arithmetic instructions and the need for `fptoint_may_trap` is gone and all handling code for that is now removed. This means that the only wasm-specific logic is in the `fpto{s,u}i` instructions which only get used for "out of bounds is undefined behavior". This does mean that for the WebAssembly target specifically the Rust compiler will no longer be 100% compatible with pre-LLVM 12 versions, but it seems like that's unlikely to be relied on by too many folks. Note that this change does immediately regress the codegen of saturating float-to-int casts on WebAssembly due to the specialization of the LLVM intrinsic not being present in our LLVM fork just yet. I'll be following up with an LLVM update to pull in those patches, but affects a few other SIMD things in flight for WebAssembly so I wanted to separate this change. Eventually the entire `cast_float_to_int` function can be removed when LLVM 12 is the minimum version, but that will require sinking the complexity of it into other backends such as Cranelfit.
…gisa rustc: Use LLVM's new saturating float-to-int intrinsics This commit updates rustc, with an applicable LLVM version, to use LLVM's new `llvm.fpto{u,s}i.sat.*.*` intrinsics to implement saturating floating-point-to-int conversions. This results in a little bit tighter codegen for x86/x86_64, but the main purpose of this is to prepare for upcoming changes to the WebAssembly backend in LLVM where wasm's saturating float-to-int instructions will now be implemented with these intrinsics. This change allows simplifying a good deal of surrounding code, namely removing a lot of wasm-specific behavior. WebAssembly no longer has any special-casing of saturating arithmetic instructions and the need for `fptoint_may_trap` is gone and all handling code for that is now removed. This means that the only wasm-specific logic is in the `fpto{s,u}i` instructions which only get used for "out of bounds is undefined behavior". This does mean that for the WebAssembly target specifically the Rust compiler will no longer be 100% compatible with pre-LLVM 12 versions, but it seems like that's unlikely to be relied on by too many folks. Note that this change does immediately regress the codegen of saturating float-to-int casts on WebAssembly due to the specialization of the LLVM intrinsic not being present in our LLVM fork just yet. I'll be following up with an LLVM update to pull in those patches, but affects a few other SIMD things in flight for WebAssembly so I wanted to separate this change. Eventually the entire `cast_float_to_int` function can be removed when LLVM 12 is the minimum version, but that will require sinking the complexity of it into other backends such as Cranelfit.
@bors r- This failed on the |
@bors r+ |
📌 Commit 35ae752 has been approved by |
⌛ Testing commit 35ae752 with merge 1e747ccec99be0974f47d70abed4d94eafa1d4d9... |
This comment has been minimized.
This comment has been minimized.
💔 Test failed - checks-actions |
I updated the assertions in @bors: r=nagisa |
📌 Commit ed6dd40 has been approved by |
☀️ Test successful - checks-actions |
This fixes the temporary regression introduced in rust-lang#84339 where the wasm target uses `fpto{s,u}i` intrinsics but the codegen for those intrinsics with the `+nontrapping-fptoint` LLVM feature wasn't very good (aka it didn't use the wasm instruction). The fixes brought in here fix that and also implement the second-to-last simd instruction in LLVM.
Update LLVM for more wasm simd updates This fixes the temporary regression introduced in rust-lang#84339 where the wasm target uses `fpto{s,u}i` intrinsics but the codegen for those intrinsics with the `+nontrapping-fptoint` LLVM feature wasn't very good (aka it didn't use the wasm instruction). The fixes brought in here fix that and also implement the second-to-last simd instruction in LLVM.
Update LLVM for more wasm simd updates This fixes the temporary regression introduced in rust-lang#84339 where the wasm target uses `fpto{s,u}i` intrinsics but the codegen for those intrinsics with the `+nontrapping-fptoint` LLVM feature wasn't very good (aka it didn't use the wasm instruction). The fixes brought in here fix that and also implement the second-to-last simd instruction in LLVM.
Update LLVM for more wasm simd updates This fixes the temporary regression introduced in rust-lang#84339 where the wasm target uses `fpto{s,u}i` intrinsics but the codegen for those intrinsics with the `+nontrapping-fptoint` LLVM feature wasn't very good (aka it didn't use the wasm instruction). The fixes brought in here fix that and also implement the second-to-last simd instruction in LLVM.
This fixes the temporary regression introduced in rust-lang#84339 where the wasm target uses `fpto{s,u}i` intrinsics but the codegen for those intrinsics with the `+nontrapping-fptoint` LLVM feature wasn't very good (aka it didn't use the wasm instruction). The fixes brought in here fix that and also implement the second-to-last simd instruction in LLVM.
Update LLVM for more wasm simd updates This fixes the temporary regression introduced in rust-lang#84339 where the wasm target uses `fpto{s,u}i` intrinsics but the codegen for those intrinsics with the `+nontrapping-fptoint` LLVM feature wasn't very good (aka it didn't use the wasm instruction). The fixes brought in here fix that and also implement the second-to-last simd instruction in LLVM.
This commit updates rustc, with an applicable LLVM version, to use
LLVM's new
llvm.fpto{u,s}i.sat.*.*
intrinsics to implement saturatingfloating-point-to-int conversions. This results in a little bit tighter
codegen for x86/x86_64, but the main purpose of this is to prepare for
upcoming changes to the WebAssembly backend in LLVM where wasm's
saturating float-to-int instructions will now be implemented with these
intrinsics.
This change allows simplifying a good deal of surrounding code, namely
removing a lot of wasm-specific behavior. WebAssembly no longer has any
special-casing of saturating arithmetic instructions and the need for
fptoint_may_trap
is gone and all handling code for that is nowremoved. This means that the only wasm-specific logic is in the
fpto{s,u}i
instructions which only get used for "out of bounds isundefined behavior". This does mean that for the WebAssembly target
specifically the Rust compiler will no longer be 100% compatible with
pre-LLVM 12 versions, but it seems like that's unlikely to be relied on
by too many folks.
Note that this change does immediately regress the codegen of saturating
float-to-int casts on WebAssembly due to the specialization of the LLVM
intrinsic not being present in our LLVM fork just yet. I'll be following
up with an LLVM update to pull in those patches, but affects a few other
SIMD things in flight for WebAssembly so I wanted to separate this change.
Eventually the entire
cast_float_to_int
function can be removed whenLLVM 12 is the minimum version, but that will require sinking the
complexity of it into other backends such as Cranelfit.