Rollup merge of #143194 - folkertdev:fix-single-element-simd-bitcast, r=workingjubilee
fix bitcast of single-element SIMD vectors in effect this reverts https://github.com/rust-lang/rust/pull/142768 and adds additional tests. That PR relaxed the conditions on an early return in an incorrect way that would create broken LLVM IR. https://godbolt.org/z/PaaGWTv5a ```rust #![feature(repr_simd)] #[repr(simd)] #[derive(Clone, Copy)] struct S([i64; 1]); #[no_mangle] pub extern "C" fn single_element_simd(b: S) -> i64 { unsafe { std::mem::transmute(b) } } ``` at the time of writing generates this LLVM IR, where the type of the return is different from the function's return type. ```llvm define noundef i64 ``````@single_element_simd(<1`````` x i64> %b) unnamed_addr { start: ret <1 x i64> %b } ``` The test output is actually the same for the existing tests, showing that the change didn't actually matter for any tested behavior. It is probably a bit faster to do the early return, but, well, it's incorrect in general. zullip thread: [#t-compiler > Is transmuting a `T` to `Tx1` (one-element SIMD vector) UB?](https://rust-lang.zulipchat.com/#narrow/channel/131828-t-compiler/topic/Is.20transmuting.20a.20.60T.60.20to.20.60Tx1.60.20.28one-element.20SIMD.20vector.29.20UB.3F/with/526262799) cc ``````@sayantn`````` r? ``````@scottmcm``````
This commit is contained in:
@@ -1117,7 +1117,7 @@ pub(super) fn transmute_immediate<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
|
||||
// While optimizations will remove no-op transmutes, they might still be
|
||||
// there in debug or things that aren't no-op in MIR because they change
|
||||
// the Rust type but not the underlying layout/niche.
|
||||
if from_scalar == to_scalar {
|
||||
if from_scalar == to_scalar && from_backend_ty == to_backend_ty {
|
||||
return imm;
|
||||
}
|
||||
|
||||
@@ -1136,13 +1136,7 @@ pub(super) fn transmute_immediate<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
|
||||
assume_scalar_range(bx, imm, from_scalar, from_backend_ty);
|
||||
|
||||
imm = match (from_scalar.primitive(), to_scalar.primitive()) {
|
||||
(Int(..) | Float(_), Int(..) | Float(_)) => {
|
||||
if from_backend_ty == to_backend_ty {
|
||||
imm
|
||||
} else {
|
||||
bx.bitcast(imm, to_backend_ty)
|
||||
}
|
||||
}
|
||||
(Int(..) | Float(_), Int(..) | Float(_)) => bx.bitcast(imm, to_backend_ty),
|
||||
(Pointer(..), Pointer(..)) => bx.pointercast(imm, to_backend_ty),
|
||||
(Int(..), Pointer(..)) => bx.ptradd(bx.const_null(bx.type_ptr()), imm),
|
||||
(Pointer(..), Int(..)) => {
|
||||
|
||||
Reference in New Issue
Block a user