Skip to content

Commit 6a5ee11

Browse files
committed
Don't bitcast aggregate field.
1 parent af69cc0 commit 6a5ee11

File tree

1 file changed

+26
-1
lines changed

1 file changed

+26
-1
lines changed

compiler/rustc_codegen_ssa/src/mir/operand.rs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,13 +237,18 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
237237
};
238238

239239
match (&mut val, field.abi) {
240-
(OperandValue::Immediate(llval), _) => {
240+
(
241+
OperandValue::Immediate(llval),
242+
Abi::Scalar(_) | Abi::ScalarPair(..) | Abi::Vector { .. },
243+
) => {
241244
// Bools in union fields needs to be truncated.
242245
*llval = bx.to_immediate(*llval, field);
243246
// HACK(eddyb) have to bitcast pointers until LLVM removes pointee types.
244247
let ty = bx.cx().immediate_backend_type(field);
245248
if bx.type_kind(ty) == TypeKind::Pointer {
246249
*llval = bx.pointercast(*llval, ty);
250+
} else {
251+
*llval = bx.bitcast(*llval, ty);
247252
}
248253
}
249254
(OperandValue::Pair(a, b), Abi::ScalarPair(a_abi, b_abi)) => {
@@ -255,11 +260,31 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
255260
let b_ty = bx.cx().scalar_pair_element_backend_type(field, 1, true);
256261
if bx.type_kind(a_ty) == TypeKind::Pointer {
257262
*a = bx.pointercast(*a, a_ty);
263+
} else {
264+
*a = bx.bitcast(*a, a_ty);
258265
}
259266
if bx.type_kind(b_ty) == TypeKind::Pointer {
260267
*b = bx.pointercast(*b, b_ty);
268+
} else {
269+
*b = bx.bitcast(*b, b_ty);
261270
}
262271
}
272+
// Newtype vector of array, e.g. #[repr(simd)] struct S([i32; 4]);
273+
(OperandValue::Immediate(llval), Abi::Aggregate { sized: true }) => {
274+
assert!(matches!(self.layout.abi, Abi::Vector { .. }));
275+
276+
let llty = bx.cx().backend_type(self.layout);
277+
let llfield_ty = bx.cx().backend_type(field);
278+
279+
// Can't bitcast an aggregate, so round trip through memory.
280+
let lltemp = bx.alloca(llfield_ty, field.align.abi);
281+
let llptr = bx.pointercast(lltemp, bx.cx().type_ptr_to(llty));
282+
bx.store(*llval, llptr, field.align.abi);
283+
*llval = bx.load(llfield_ty, lltemp, field.align.abi);
284+
}
285+
(OperandValue::Immediate(_), Abi::Uninhabited | Abi::Aggregate { sized: false }) => {
286+
bug!()
287+
}
263288
(OperandValue::Pair(..), _) => bug!(),
264289
(OperandValue::Ref(..), _) => bug!(),
265290
}

0 commit comments

Comments
 (0)