-
Notifications
You must be signed in to change notification settings - Fork 14.1k
Fix inaccurate std::intrinsics::simd documentation
#137828
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
Conversation
|
Some changes occurred to the intrinsics. Make sure the CTFE / Miri interpreter cc @rust-lang/miri, @rust-lang/wg-const-eval Some changes occurred to the platform-builtins intrinsics. Make sure the cc @antoyo, @GuillaumeGomez, @bjorn3, @calebzulawski, @programmerjake |
| /// `U` must be a vector of pointers to the element type of `T`, with the same length as `T`. | ||
| /// | ||
| /// `V` must be a vector of integers with the same length as `T` (but any element size). | ||
| /// `V` must be a vector of signed integers with the same length as `T` (but any element size). |
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.
Maybe outside the scope of this PR, but this would need to be checked in codegen and emit an ICE
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.
what exactly? you get a monomorphization error when these rules are violated. They are not the prettiest errros, but they are not ICEs either. Unless I'm missing something. e.g. https://godbolt.org/z/f5j5re5z8
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.
Yep, that's a post-mono error.
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.
Oh, good. I misunderstood and thought you meant the intrinsic was permitting invalid behavior.
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.
yeah this is just bringing the docs up to date with the behavior that we already have and enforce.
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.
Looking at this in the LLVM backend I don't even see such a widening cast. This code converts the masks to i1 vectors which LLVM seems to use for them, and it does that with lshr and trunc. The lshr is entirely unnecessary for correctness as we require the input to be all-1 or all-0, but
/// The rust simd semantics are that each element should either consist of all ones or all zeroes,
/// but this information is not available to llvm. Truncating the vector effectively uses the lowest bit,
/// but codegen for several targets is better if we consider the highest bit by shifting.
But I can't find anything that would go wrong with unsigned integers.
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 personally agree, in that an intrinsic (that normal users should never have to worry about), we could either demand that the lane width matches the other arguments, or that the mask uses sign extension no matter the signedness of the argument.
From what I can tell the codegen backends already handle this, because e.g. in llvm (and from what i can see, also cranelift and gcc) the integers are just a bunch of bits.
The counter-argument was that performing sign extension on what rust believes is a vector with unsigned types would violate type safety.
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.
The counter-argument was that performing sign extension on what rust believes is a vector with unsigned types would violate type safety.
I don't know what you mean by that. There's no sign extension happening, as far as I can tell. Also, all the backends have to do is implement the intended mask semantics, which is described in a bitwise way. If they use sign extension as part of that, that's completely fine. There's no type safety violation here.
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 agree, the backends support it, and the intrinsic could (and in my opinion should) support it too. I'm just relaying the response I got when I suggested exactly that https://rust-lang.zulipchat.com/#narrow/channel/257879-project-portable-simd/topic/add.20.60simd_max.60.20and.20.60simd_min.60/near/502647748
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.
Let's move this discussion to Zulip: https://rust-lang.zulipchat.com/#narrow/channel/257879-project-portable-simd/topic/On.20the.20sign.20of.20masks
these all also accept integer vectors as arguments
78636b7 to
417c51c
Compare
this is because they may be widened, and that only works when sign extension is used: zero extension would produce invalid results
417c51c to
854e9f4
Compare
|
cool! looks good to me. test improvement stuff sounds nice as followup if people want but isn't required here and now. @bors r+ rollup |
…s, r=workingjubilee Fix inaccurate `std::intrinsics::simd` documentation This addresses two issues: - the docs on comparison operators (`simd_gt` etc.) said they only work for floating-point vectors, but they work for integer vectors too. - the docs on various functions that use a mask did not document that the mask must be a signed integer vector. Unsigned integer vectors would cause invalid behavior when the mask vector is widened (unsigned integers would use zero extension, producing incorrect results). r? `@workingjubilee`
This addresses two issues:
simd_gtetc.) said they only work for floating-point vectors, but they work for integer vectors too.r? @workingjubilee