Stop generating alloca
s+memcmp
for simple array equality
This commit is contained in:
parent
d05eafae2f
commit
2456495a26
12 changed files with 238 additions and 4 deletions
|
@ -500,6 +500,7 @@ impl CodegenCx<'b, 'tcx> {
|
|||
let t_i32 = self.type_i32();
|
||||
let t_i64 = self.type_i64();
|
||||
let t_i128 = self.type_i128();
|
||||
let t_isize = self.type_isize();
|
||||
let t_f32 = self.type_f32();
|
||||
let t_f64 = self.type_f64();
|
||||
|
||||
|
@ -712,6 +713,10 @@ impl CodegenCx<'b, 'tcx> {
|
|||
ifn!("llvm.assume", fn(i1) -> void);
|
||||
ifn!("llvm.prefetch", fn(i8p, t_i32, t_i32, t_i32) -> void);
|
||||
|
||||
// This isn't an "LLVM intrinsic", but LLVM's optimization passes
|
||||
// recognize it like one and we assume it exists in `core::slice::cmp`
|
||||
ifn!("memcmp", fn(i8p, i8p, t_isize) -> t_i32);
|
||||
|
||||
// variadic intrinsics
|
||||
ifn!("llvm.va_start", fn(i8p) -> void);
|
||||
ifn!("llvm.va_end", fn(i8p) -> void);
|
||||
|
|
|
@ -296,6 +296,32 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
sym::raw_eq => {
|
||||
let tp_ty = substs.type_at(0);
|
||||
let (size, align) = self.size_and_align_of(tp_ty);
|
||||
let a = args[0].immediate();
|
||||
let b = args[1].immediate();
|
||||
if size.bytes() == 0 {
|
||||
self.const_bool(true)
|
||||
} else if size > self.data_layout().pointer_size * 4 {
|
||||
let i8p_ty = self.type_i8p();
|
||||
let a_ptr = self.bitcast(a, i8p_ty);
|
||||
let b_ptr = self.bitcast(b, i8p_ty);
|
||||
let n = self.const_usize(size.bytes());
|
||||
let llfn = self.get_intrinsic("memcmp");
|
||||
let cmp = self.call(llfn, &[a_ptr, b_ptr, n], None);
|
||||
self.icmp(IntPredicate::IntEQ, cmp, self.const_i32(0))
|
||||
} else {
|
||||
let integer_ty = self.type_ix(size.bits());
|
||||
let ptr_ty = self.type_ptr_to(integer_ty);
|
||||
let a_ptr = self.bitcast(a, ptr_ty);
|
||||
let a_val = self.load(a_ptr, align);
|
||||
let b_ptr = self.bitcast(b, ptr_ty);
|
||||
let b_val = self.load(b_ptr, align);
|
||||
self.icmp(IntPredicate::IntEQ, a_val, b_val)
|
||||
}
|
||||
}
|
||||
|
||||
_ if name_str.starts_with("simd_") => {
|
||||
match generic_simd_intrinsic(self, name, callee_ty, args, ret_ty, llret_ty, span) {
|
||||
Ok(llval) => llval,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue