From 48af94c080d37a5396dd4452c21cd8006f38fba4 Mon Sep 17 00:00:00 2001 From: Luqman Aden Date: Sun, 11 Dec 2022 19:11:41 -0800 Subject: [PATCH 1/7] Operand::extract_field: only cast llval if it's a pointer and replace bitcast w/ pointercast. --- compiler/rustc_codegen_ssa/src/mir/operand.rs | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs index b37797fef4ce..957ec8629faa 100644 --- a/compiler/rustc_codegen_ssa/src/mir/operand.rs +++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs @@ -2,6 +2,7 @@ use super::place::PlaceRef; use super::{FunctionCx, LocalRef}; use crate::base; +use crate::common::TypeKind; use crate::glue; use crate::traits::*; use crate::MemFlags; @@ -240,15 +241,24 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { // Bools in union fields needs to be truncated. *llval = bx.to_immediate(*llval, field); // HACK(eddyb) have to bitcast pointers until LLVM removes pointee types. - *llval = bx.bitcast(*llval, bx.cx().immediate_backend_type(field)); + let ty = bx.cx().immediate_backend_type(field); + if bx.type_kind(ty) == TypeKind::Pointer { + *llval = bx.pointercast(*llval, ty); + } } (OperandValue::Pair(a, b), Abi::ScalarPair(a_abi, b_abi)) => { // Bools in union fields needs to be truncated. *a = bx.to_immediate_scalar(*a, a_abi); *b = bx.to_immediate_scalar(*b, b_abi); // HACK(eddyb) have to bitcast pointers until LLVM removes pointee types. - *a = bx.bitcast(*a, bx.cx().scalar_pair_element_backend_type(field, 0, true)); - *b = bx.bitcast(*b, bx.cx().scalar_pair_element_backend_type(field, 1, true)); + let a_ty = bx.cx().scalar_pair_element_backend_type(field, 0, true); + let b_ty = bx.cx().scalar_pair_element_backend_type(field, 1, true); + if bx.type_kind(a_ty) == TypeKind::Pointer { + *a = bx.pointercast(*a, a_ty); + } + if bx.type_kind(b_ty) == TypeKind::Pointer { + *b = bx.pointercast(*b, b_ty); + } } (OperandValue::Pair(..), _) => bug!(), (OperandValue::Ref(..), _) => bug!(), From 75f3fafa72a4149e730d17e755c3ad96aa40ad9a Mon Sep 17 00:00:00 2001 From: Luqman Aden Date: Sun, 11 Dec 2022 19:21:51 -0800 Subject: [PATCH 2/7] Add test. --- src/test/ui/simd/issue-105439.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 src/test/ui/simd/issue-105439.rs diff --git a/src/test/ui/simd/issue-105439.rs b/src/test/ui/simd/issue-105439.rs new file mode 100644 index 000000000000..3376449598ca --- /dev/null +++ b/src/test/ui/simd/issue-105439.rs @@ -0,0 +1,14 @@ +// This is used to ICE with MIR inlining enabled due to an invalid bitcast. +// run-pass +// compile-flags: -O -Zmir-opt-level=3 +#![feature(portable_simd)] + +use std::simd::Simd; + +fn main() { + let a = Simd::from_array([0, 4, 1, 5]); + let b = Simd::from_array([2, 6, 3, 7]); + let (x, y) = a.deinterleave(b); + assert_eq!(x.to_array(), [0, 1, 2, 3]); + assert_eq!(y.to_array(), [4, 5, 6, 7]); +} From af69cc0ea0698d47b281e6b5da78d4794dc5df04 Mon Sep 17 00:00:00 2001 From: Luqman Aden Date: Mon, 12 Dec 2022 15:52:02 -0800 Subject: [PATCH 3/7] Make test more targeted. --- src/test/ui/simd/issue-105439.rs | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/src/test/ui/simd/issue-105439.rs b/src/test/ui/simd/issue-105439.rs index 3376449598ca..f3291f1bffea 100644 --- a/src/test/ui/simd/issue-105439.rs +++ b/src/test/ui/simd/issue-105439.rs @@ -1,14 +1,16 @@ -// This is used to ICE with MIR inlining enabled due to an invalid bitcast. -// run-pass -// compile-flags: -O -Zmir-opt-level=3 -#![feature(portable_simd)] - -use std::simd::Simd; - -fn main() { - let a = Simd::from_array([0, 4, 1, 5]); - let b = Simd::from_array([2, 6, 3, 7]); - let (x, y) = a.deinterleave(b); - assert_eq!(x.to_array(), [0, 1, 2, 3]); - assert_eq!(y.to_array(), [4, 5, 6, 7]); +// build-pass + +#![crate_type = "lib"] + +#![feature(repr_simd)] +#![feature(platform_intrinsics)] + +#[allow(non_camel_case_types)] +#[derive(Clone, Copy)] +#[repr(simd)] +pub struct i32x4([i32; 4]); + +pub fn f(a: i32x4) -> [i32; 4] { + let b = a; + b.0 } From 6a5ee110276aa0f24e569c15d10172e3fc40752f Mon Sep 17 00:00:00 2001 From: Luqman Aden Date: Thu, 15 Dec 2022 23:18:25 -0800 Subject: [PATCH 4/7] Don't bitcast aggregate field. --- compiler/rustc_codegen_ssa/src/mir/operand.rs | 27 ++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs index 957ec8629faa..7623daeb96fd 100644 --- a/compiler/rustc_codegen_ssa/src/mir/operand.rs +++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs @@ -237,13 +237,18 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { }; match (&mut val, field.abi) { - (OperandValue::Immediate(llval), _) => { + ( + OperandValue::Immediate(llval), + Abi::Scalar(_) | Abi::ScalarPair(..) | Abi::Vector { .. }, + ) => { // Bools in union fields needs to be truncated. *llval = bx.to_immediate(*llval, field); // HACK(eddyb) have to bitcast pointers until LLVM removes pointee types. let ty = bx.cx().immediate_backend_type(field); if bx.type_kind(ty) == TypeKind::Pointer { *llval = bx.pointercast(*llval, ty); + } else { + *llval = bx.bitcast(*llval, ty); } } (OperandValue::Pair(a, b), Abi::ScalarPair(a_abi, b_abi)) => { @@ -255,11 +260,31 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { let b_ty = bx.cx().scalar_pair_element_backend_type(field, 1, true); if bx.type_kind(a_ty) == TypeKind::Pointer { *a = bx.pointercast(*a, a_ty); + } else { + *a = bx.bitcast(*a, a_ty); } if bx.type_kind(b_ty) == TypeKind::Pointer { *b = bx.pointercast(*b, b_ty); + } else { + *b = bx.bitcast(*b, b_ty); } } + // Newtype vector of array, e.g. #[repr(simd)] struct S([i32; 4]); + (OperandValue::Immediate(llval), Abi::Aggregate { sized: true }) => { + assert!(matches!(self.layout.abi, Abi::Vector { .. })); + + let llty = bx.cx().backend_type(self.layout); + let llfield_ty = bx.cx().backend_type(field); + + // Can't bitcast an aggregate, so round trip through memory. + let lltemp = bx.alloca(llfield_ty, field.align.abi); + let llptr = bx.pointercast(lltemp, bx.cx().type_ptr_to(llty)); + bx.store(*llval, llptr, field.align.abi); + *llval = bx.load(llfield_ty, lltemp, field.align.abi); + } + (OperandValue::Immediate(_), Abi::Uninhabited | Abi::Aggregate { sized: false }) => { + bug!() + } (OperandValue::Pair(..), _) => bug!(), (OperandValue::Ref(..), _) => bug!(), } From 2942121736a389d4779c3b1ec908aee2d5151c73 Mon Sep 17 00:00:00 2001 From: Luqman Aden Date: Fri, 5 May 2023 14:43:20 -0700 Subject: [PATCH 5/7] Update test location. --- {src/test => tests}/ui/simd/issue-105439.rs | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {src/test => tests}/ui/simd/issue-105439.rs (100%) diff --git a/src/test/ui/simd/issue-105439.rs b/tests/ui/simd/issue-105439.rs similarity index 100% rename from src/test/ui/simd/issue-105439.rs rename to tests/ui/simd/issue-105439.rs From 7b1eedaae81326567e0439d058546d93f9e7f73a Mon Sep 17 00:00:00 2001 From: Luqman Aden Date: Fri, 5 May 2023 14:58:52 -0700 Subject: [PATCH 6/7] Switch test back to run-pass. --- tests/ui/simd/issue-105439.rs | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/tests/ui/simd/issue-105439.rs b/tests/ui/simd/issue-105439.rs index f3291f1bffea..35ca76e989b9 100644 --- a/tests/ui/simd/issue-105439.rs +++ b/tests/ui/simd/issue-105439.rs @@ -1,6 +1,5 @@ -// build-pass - -#![crate_type = "lib"] +// run-pass +// compile-flags: -O -Zverify-llvm-ir #![feature(repr_simd)] #![feature(platform_intrinsics)] @@ -8,9 +7,19 @@ #[allow(non_camel_case_types)] #[derive(Clone, Copy)] #[repr(simd)] -pub struct i32x4([i32; 4]); +struct i32x4([i32; 4]); + +extern "platform-intrinsic" { + pub(crate) fn simd_add(x: T, y: T) -> T; +} + +#[inline(always)] +fn to_array(a: i32x4) -> [i32; 4] { + a.0 +} -pub fn f(a: i32x4) -> [i32; 4] { - let b = a; - b.0 +fn main() { + let a = i32x4([1, 2, 3, 4]); + let b = unsafe { simd_add(a, a) }; + assert_eq!(to_array(b), [2, 4, 6, 8]); } From c7c042ad31766a6f70a2c850457f086cf6a03153 Mon Sep 17 00:00:00 2001 From: Luqman Aden Date: Fri, 5 May 2023 15:13:18 -0700 Subject: [PATCH 7/7] Address review comments. Remove bitcasts in OperandRef::extract_field; only pointercasts should be needed. --- compiler/rustc_codegen_ssa/src/mir/operand.rs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs index 7623daeb96fd..9efbb34b515b 100644 --- a/compiler/rustc_codegen_ssa/src/mir/operand.rs +++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs @@ -247,8 +247,6 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { let ty = bx.cx().immediate_backend_type(field); if bx.type_kind(ty) == TypeKind::Pointer { *llval = bx.pointercast(*llval, ty); - } else { - *llval = bx.bitcast(*llval, ty); } } (OperandValue::Pair(a, b), Abi::ScalarPair(a_abi, b_abi)) => { @@ -260,13 +258,9 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { let b_ty = bx.cx().scalar_pair_element_backend_type(field, 1, true); if bx.type_kind(a_ty) == TypeKind::Pointer { *a = bx.pointercast(*a, a_ty); - } else { - *a = bx.bitcast(*a, a_ty); } if bx.type_kind(b_ty) == TypeKind::Pointer { *b = bx.pointercast(*b, b_ty); - } else { - *b = bx.bitcast(*b, b_ty); } } // Newtype vector of array, e.g. #[repr(simd)] struct S([i32; 4]);