Implement the raw_eq intrinsic in codegen_cranelift
This commit is contained in:
parent
fb92375755
commit
ea8d9aefda
@ -1115,6 +1115,45 @@ fn swap(bcx: &mut FunctionBuilder<'_>, v: Value) -> Value {
|
||||
);
|
||||
ret.write_cvalue(fx, CValue::by_val(res, ret.layout()));
|
||||
};
|
||||
|
||||
raw_eq, <T>(v lhs_ref, v rhs_ref) {
|
||||
fn type_by_size(size: Size) -> Option<Type> {
|
||||
Some(match size.bits() {
|
||||
8 => types::I8,
|
||||
16 => types::I16,
|
||||
32 => types::I32,
|
||||
64 => types::I64,
|
||||
128 => types::I128,
|
||||
_ => return None,
|
||||
})
|
||||
}
|
||||
|
||||
let size = fx.layout_of(T).layout.size;
|
||||
let is_eq_value =
|
||||
if size == Size::ZERO {
|
||||
// No bytes means they're trivially equal
|
||||
fx.bcx.ins().bconst(types::B1, true)
|
||||
} else if let Some(clty) = type_by_size(size) {
|
||||
// Can't use `trusted` for these loads; they could be unaligned.
|
||||
let mut flags = MemFlags::new();
|
||||
flags.set_notrap();
|
||||
let lhs_val = fx.bcx.ins().load(clty, flags, lhs_ref, 0);
|
||||
let rhs_val = fx.bcx.ins().load(clty, flags, rhs_ref, 0);
|
||||
fx.bcx.ins().icmp(IntCC::Equal, lhs_val, rhs_val)
|
||||
} else {
|
||||
// Just call `memcmp` (like slices do in core) when the
|
||||
// size is too large or it's not a power-of-two.
|
||||
let ptr_ty = pointer_ty(fx.tcx);
|
||||
let signed_bytes = i64::try_from(size.bytes()).unwrap();
|
||||
let bytes_val = fx.bcx.ins().iconst(ptr_ty, signed_bytes);
|
||||
let params = vec![AbiParam::new(ptr_ty); 3];
|
||||
let returns = vec![AbiParam::new(types::I32)];
|
||||
let args = &[lhs_ref, rhs_ref, bytes_val];
|
||||
let cmp = fx.lib_call("memcmp", params, returns, args)[0];
|
||||
fx.bcx.ins().icmp_imm(IntCC::Equal, cmp, 0)
|
||||
};
|
||||
ret.write_cvalue(fx, CValue::by_val(is_eq_value, ret.layout()));
|
||||
};
|
||||
}
|
||||
|
||||
if let Some((_, dest)) = destination {
|
||||
|
@ -437,6 +437,12 @@ fn transmute_value<'tcx>(
|
||||
| (types::F32, types::I32)
|
||||
| (types::I64, types::F64)
|
||||
| (types::F64, types::I64) => fx.bcx.ins().bitcast(dst_ty, data),
|
||||
|
||||
// Widen an abstract SSA boolean to something that can be stored in memory
|
||||
(types::B1, types::I8 | types::I16 | types::I32 | types::I64 | types::I128) => {
|
||||
fx.bcx.ins().bint(dst_ty, data)
|
||||
}
|
||||
|
||||
_ if src_ty.is_vector() && dst_ty.is_vector() => {
|
||||
fx.bcx.ins().raw_bitcast(dst_ty, data)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user