Skip to content

Commit dfb5d16

Browse files
committed
Use bitcast to transmute where possible
1 parent 9cf1bce commit dfb5d16

File tree

1 file changed

+23
-6
lines changed

1 file changed

+23
-6
lines changed

src/intrinsics/mod.rs

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -631,12 +631,29 @@ pub(crate) fn codegen_intrinsic_call<'tcx>(
631631
ret.write_cvalue(fx, CValue::by_val(res, base.layout()));
632632
};
633633

634-
transmute, <src_ty, dst_ty> (c from) {
635-
assert_eq!(from.layout().ty, src_ty);
636-
let (addr, meta) = from.force_stack(fx);
637-
assert!(meta.is_none());
638-
let dst_layout = fx.layout_of(dst_ty);
639-
ret.write_cvalue(fx, CValue::by_ref(addr, dst_layout))
634+
transmute, (c from) {
635+
assert_eq!(from.layout().size, ret.layout().size);
636+
if from.layout().ty.kind == ret.layout().ty.kind {
637+
ret.write_cvalue(fx, from);
638+
} else if let (Some(src_ty), Some(dst_ty)) = (fx.clif_type(from.layout().ty), fx.clif_type(ret.layout().ty)) {
639+
let from = from.load_scalar(fx);
640+
let val = match (src_ty, dst_ty) {
641+
(_, _) if src_ty == dst_ty => from,
642+
(types::I32, types::F32) | (types::F32, types::I32)
643+
| (types::I64, types::F64) | (types::F64, types::I64) => {
644+
fx.bcx.ins().bitcast(dst_ty, from)
645+
}
646+
(_, _) if src_ty.is_vector() && dst_ty.is_vector() => {
647+
fx.bcx.ins().raw_bitcast(dst_ty, from)
648+
}
649+
_ => unreachable!("{:?} -> {:?}", src_ty, dst_ty),
650+
};
651+
ret.write_cvalue(fx, CValue::by_val(val, ret.layout()));
652+
} else {
653+
let (addr, meta) = from.force_stack(fx);
654+
assert!(meta.is_none());
655+
ret.write_cvalue(fx, CValue::by_ref(addr, ret.layout()));
656+
}
640657
};
641658
write_bytes, (c dst, v val, v count) {
642659
let pointee_ty = dst.layout().ty.builtin_deref(true).unwrap().ty;

0 commit comments

Comments
 (0)