@@ -297,28 +297,40 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
297
297
}
298
298
299
299
sym:: raw_eq => {
300
+ use abi:: Abi :: * ;
300
301
let tp_ty = substs. type_at ( 0 ) ;
301
- let ( size, align) = self . size_and_align_of ( tp_ty) ;
302
+ let layout = self . layout_of ( tp_ty) . layout ;
303
+ let use_integer_compare = match layout. abi {
304
+ Scalar ( _) | ScalarPair ( _, _) => true ,
305
+ Uninhabited | Vector { .. } => false ,
306
+ Aggregate { .. } => {
307
+ // For rusty ABIs, small aggregates are actually passed
308
+ // as `RegKind::Integer` (see `FnAbi::adjust_for_abi`),
309
+ // so we re-use that same threshold here.
310
+ layout. size <= self . data_layout ( ) . pointer_size * 2
311
+ }
312
+ } ;
313
+
302
314
let a = args[ 0 ] . immediate ( ) ;
303
315
let b = args[ 1 ] . immediate ( ) ;
304
- if size. bytes ( ) == 0 {
316
+ if layout . size . bytes ( ) == 0 {
305
317
self . const_bool ( true )
306
- } else if size > self . data_layout ( ) . pointer_size * 4 {
318
+ } else if use_integer_compare {
319
+ let integer_ty = self . type_ix ( layout. size . bits ( ) ) ;
320
+ let ptr_ty = self . type_ptr_to ( integer_ty) ;
321
+ let a_ptr = self . bitcast ( a, ptr_ty) ;
322
+ let a_val = self . load ( a_ptr, layout. align . abi ) ;
323
+ let b_ptr = self . bitcast ( b, ptr_ty) ;
324
+ let b_val = self . load ( b_ptr, layout. align . abi ) ;
325
+ self . icmp ( IntPredicate :: IntEQ , a_val, b_val)
326
+ } else {
307
327
let i8p_ty = self . type_i8p ( ) ;
308
328
let a_ptr = self . bitcast ( a, i8p_ty) ;
309
329
let b_ptr = self . bitcast ( b, i8p_ty) ;
310
- let n = self . const_usize ( size. bytes ( ) ) ;
330
+ let n = self . const_usize ( layout . size . bytes ( ) ) ;
311
331
let llfn = self . get_intrinsic ( "memcmp" ) ;
312
332
let cmp = self . call ( llfn, & [ a_ptr, b_ptr, n] , None ) ;
313
333
self . icmp ( IntPredicate :: IntEQ , cmp, self . const_i32 ( 0 ) )
314
- } else {
315
- let integer_ty = self . type_ix ( size. bits ( ) ) ;
316
- let ptr_ty = self . type_ptr_to ( integer_ty) ;
317
- let a_ptr = self . bitcast ( a, ptr_ty) ;
318
- let a_val = self . load ( a_ptr, align) ;
319
- let b_ptr = self . bitcast ( b, ptr_ty) ;
320
- let b_val = self . load ( b_ptr, align) ;
321
- self . icmp ( IntPredicate :: IntEQ , a_val, b_val)
322
334
}
323
335
}
324
336
0 commit comments