mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-01 06:51:58 +00:00
Adjust the threshold to look at the ABI, not just the size
This commit is contained in:
parent
6444f24a29
commit
07fb5ee78f
@ -297,28 +297,40 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
|
||||
}
|
||||
|
||||
sym::raw_eq => {
|
||||
use abi::Abi::*;
|
||||
let tp_ty = substs.type_at(0);
|
||||
let (size, align) = self.size_and_align_of(tp_ty);
|
||||
let layout = self.layout_of(tp_ty).layout;
|
||||
let use_integer_compare = match layout.abi {
|
||||
Scalar(_) | ScalarPair(_, _) => true,
|
||||
Uninhabited | Vector { .. } => false,
|
||||
Aggregate { .. } => {
|
||||
// For rusty ABIs, small aggregates are actually passed
|
||||
// as `RegKind::Integer` (see `FnAbi::adjust_for_abi`),
|
||||
// so we re-use that same threshold here.
|
||||
layout.size <= self.data_layout().pointer_size * 2
|
||||
}
|
||||
};
|
||||
|
||||
let a = args[0].immediate();
|
||||
let b = args[1].immediate();
|
||||
if size.bytes() == 0 {
|
||||
if layout.size.bytes() == 0 {
|
||||
self.const_bool(true)
|
||||
} else if size > self.data_layout().pointer_size * 4 {
|
||||
} else if use_integer_compare {
|
||||
let integer_ty = self.type_ix(layout.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, layout.align.abi);
|
||||
let b_ptr = self.bitcast(b, ptr_ty);
|
||||
let b_val = self.load(b_ptr, layout.align.abi);
|
||||
self.icmp(IntPredicate::IntEQ, a_val, b_val)
|
||||
} else {
|
||||
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 n = self.const_usize(layout.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)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,18 @@ pub fn array_eq_ref(a: &[u16; 6], b: &[u16; 6]) -> bool {
|
||||
a == b
|
||||
}
|
||||
|
||||
// CHECK-LABEL: @array_eq_value_still_passed_by_pointer
|
||||
#[no_mangle]
|
||||
pub fn array_eq_value_still_passed_by_pointer(a: [u16; 9], b: [u16; 9]) -> bool {
|
||||
// CHECK-NEXT: start:
|
||||
// CHECK-NEXT: bitcast
|
||||
// CHECK-NEXT: bitcast
|
||||
// CHECK-NEXT: %[[CMP:.+]] = tail call i32 @{{bcmp|memcmp}}(i8* nonnull dereferenceable(18) %{{.+}}, i8* nonnull dereferenceable(18) %{{.+}}, i64 18)
|
||||
// CHECK-NEXT: %[[EQ:.+]] = icmp eq i32 %[[CMP]], 0
|
||||
// CHECK-NEXT: ret i1 %[[EQ]]
|
||||
a == b
|
||||
}
|
||||
|
||||
// CHECK-LABEL: @array_eq_long
|
||||
#[no_mangle]
|
||||
pub fn array_eq_long(a: &[u16; 1234], b: &[u16; 1234]) -> bool {
|
||||
|
Loading…
Reference in New Issue
Block a user