Skip to content

Commit 1216353

Browse files
committed
Implement the raw_eq intrinsic in codegen_cranelift
1 parent b63b2f1 commit 1216353

File tree

2 files changed

+45
-0
lines changed

2 files changed

+45
-0
lines changed

compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1115,6 +1115,45 @@ pub(crate) fn codegen_intrinsic_call<'tcx>(
11151115
);
11161116
ret.write_cvalue(fx, CValue::by_val(res, ret.layout()));
11171117
};
1118+
1119+
raw_eq, <T>(v lhs_ref, v rhs_ref) {
1120+
fn type_by_size(size: Size) -> Option<Type> {
1121+
Some(match size.bits() {
1122+
8 => types::I8,
1123+
16 => types::I16,
1124+
32 => types::I32,
1125+
64 => types::I64,
1126+
128 => types::I128,
1127+
_ => return None,
1128+
})
1129+
}
1130+
1131+
let size = fx.layout_of(T).layout.size;
1132+
let is_eq_value =
1133+
if size == Size::ZERO {
1134+
// No bytes means they're trivially equal
1135+
fx.bcx.ins().bconst(types::B1, true)
1136+
} else if let Some(clty) = type_by_size(size) {
1137+
// Can't use `trusted` for these loads; they could be unaligned.
1138+
let mut flags = MemFlags::new();
1139+
flags.set_notrap();
1140+
let lhs_val = fx.bcx.ins().load(clty, flags, lhs_ref, 0);
1141+
let rhs_val = fx.bcx.ins().load(clty, flags, rhs_ref, 0);
1142+
fx.bcx.ins().icmp(IntCC::Equal, lhs_val, rhs_val)
1143+
} else {
1144+
// Just call `memcmp` (like slices do in core) when the
1145+
// size is too large or it's not a power-of-two.
1146+
let ptr_ty = pointer_ty(fx.tcx);
1147+
let signed_bytes = i64::try_from(size.bytes()).unwrap();
1148+
let bytes_val = fx.bcx.ins().iconst(ptr_ty, signed_bytes);
1149+
let params = vec![AbiParam::new(ptr_ty); 3];
1150+
let returns = vec![AbiParam::new(types::I32)];
1151+
let args = &[lhs_ref, rhs_ref, bytes_val];
1152+
let cmp = fx.lib_call("memcmp", params, returns, args)[0];
1153+
fx.bcx.ins().icmp_imm(IntCC::Equal, cmp, 0)
1154+
};
1155+
ret.write_cvalue(fx, CValue::by_val(is_eq_value, ret.layout()));
1156+
};
11181157
}
11191158

11201159
if let Some((_, dest)) = destination {

compiler/rustc_codegen_cranelift/src/value_and_place.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,12 @@ impl<'tcx> CPlace<'tcx> {
437437
| (types::F32, types::I32)
438438
| (types::I64, types::F64)
439439
| (types::F64, types::I64) => fx.bcx.ins().bitcast(dst_ty, data),
440+
441+
// Widen an abstract SSA boolean to something that can be stored in memory
442+
(types::B1, types::I8 | types::I16 | types::I32 | types::I64 | types::I128) => {
443+
fx.bcx.ins().bint(dst_ty, data)
444+
}
445+
440446
_ if src_ty.is_vector() && dst_ty.is_vector() => {
441447
fx.bcx.ins().raw_bitcast(dst_ty, data)
442448
}

0 commit comments

Comments
 (0)