@@ -1115,6 +1115,45 @@ pub(crate) fn codegen_intrinsic_call<'tcx>(
1115
1115
);
1116
1116
ret.write_cvalue(fx, CValue::by_val(res, ret.layout()));
1117
1117
};
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
+ };
1118
1157
}
1119
1158
1120
1159
if let Some((_, dest)) = destination {
0 commit comments