@@ -2,6 +2,7 @@ use super::place::PlaceRef;
22use super :: { FunctionCx , LocalRef } ;
33
44use crate :: base;
5+ use crate :: common:: TypeKind ;
56use crate :: glue;
67use crate :: traits:: * ;
78use crate :: MemFlags ;
@@ -236,19 +237,47 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
236237 } ;
237238
238239 match ( & mut val, field. abi ) {
239- ( OperandValue :: Immediate ( llval) , _) => {
240+ (
241+ OperandValue :: Immediate ( llval) ,
242+ Abi :: Scalar ( _) | Abi :: ScalarPair ( ..) | Abi :: Vector { .. } ,
243+ ) => {
240244 // Bools in union fields needs to be truncated.
241245 * llval = bx. to_immediate ( * llval, field) ;
242246 // HACK(eddyb) have to bitcast pointers until LLVM removes pointee types.
243- * llval = bx. bitcast ( * llval, bx. cx ( ) . immediate_backend_type ( field) ) ;
247+ let ty = bx. cx ( ) . immediate_backend_type ( field) ;
248+ if bx. type_kind ( ty) == TypeKind :: Pointer {
249+ * llval = bx. pointercast ( * llval, ty) ;
250+ }
244251 }
245252 ( OperandValue :: Pair ( a, b) , Abi :: ScalarPair ( a_abi, b_abi) ) => {
246253 // Bools in union fields needs to be truncated.
247254 * a = bx. to_immediate_scalar ( * a, a_abi) ;
248255 * b = bx. to_immediate_scalar ( * b, b_abi) ;
249256 // HACK(eddyb) have to bitcast pointers until LLVM removes pointee types.
250- * a = bx. bitcast ( * a, bx. cx ( ) . scalar_pair_element_backend_type ( field, 0 , true ) ) ;
251- * b = bx. bitcast ( * b, bx. cx ( ) . scalar_pair_element_backend_type ( field, 1 , true ) ) ;
257+ let a_ty = bx. cx ( ) . scalar_pair_element_backend_type ( field, 0 , true ) ;
258+ let b_ty = bx. cx ( ) . scalar_pair_element_backend_type ( field, 1 , true ) ;
259+ if bx. type_kind ( a_ty) == TypeKind :: Pointer {
260+ * a = bx. pointercast ( * a, a_ty) ;
261+ }
262+ if bx. type_kind ( b_ty) == TypeKind :: Pointer {
263+ * b = bx. pointercast ( * b, b_ty) ;
264+ }
265+ }
266+ // Newtype vector of array, e.g. #[repr(simd)] struct S([i32; 4]);
267+ ( OperandValue :: Immediate ( llval) , Abi :: Aggregate { sized : true } ) => {
268+ assert ! ( matches!( self . layout. abi, Abi :: Vector { .. } ) ) ;
269+
270+ let llty = bx. cx ( ) . backend_type ( self . layout ) ;
271+ let llfield_ty = bx. cx ( ) . backend_type ( field) ;
272+
273+ // Can't bitcast an aggregate, so round trip through memory.
274+ let lltemp = bx. alloca ( llfield_ty, field. align . abi ) ;
275+ let llptr = bx. pointercast ( lltemp, bx. cx ( ) . type_ptr_to ( llty) ) ;
276+ bx. store ( * llval, llptr, field. align . abi ) ;
277+ * llval = bx. load ( llfield_ty, lltemp, field. align . abi ) ;
278+ }
279+ ( OperandValue :: Immediate ( _) , Abi :: Uninhabited | Abi :: Aggregate { sized : false } ) => {
280+ bug ! ( )
252281 }
253282 ( OperandValue :: Pair ( ..) , _) => bug ! ( ) ,
254283 ( OperandValue :: Ref ( ..) , _) => bug ! ( ) ,
0 commit comments