@@ -5,6 +5,7 @@ use crate::ty::LayoutLlvmExt;
5
5
use crate :: { builder:: Builder , context:: CodegenCx } ;
6
6
use rustc_codegen_ssa:: common:: span_invalid_monomorphization_error;
7
7
use rustc_codegen_ssa:: mir:: place:: PlaceRef ;
8
+ use rustc_codegen_ssa:: traits:: DerivedTypeMethods ;
8
9
use rustc_codegen_ssa:: traits:: { BaseTypeMethods , BuilderMethods , ConstMethods , OverflowOp } ;
9
10
use rustc_codegen_ssa:: { mir:: operand:: OperandRef , traits:: IntrinsicCallMethods } ;
10
11
use rustc_middle:: ty:: layout:: { HasTyCtxt , LayoutOf } ;
@@ -425,6 +426,44 @@ impl<'a, 'll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
425
426
}
426
427
}
427
428
}
429
+ sym:: raw_eq => {
430
+ use abi:: Abi :: * ;
431
+ use rustc_codegen_ssa:: common:: IntPredicate ;
432
+ let tp_ty = substs. type_at ( 0 ) ;
433
+ let layout = self . layout_of ( tp_ty) . layout ;
434
+ let use_integer_compare = match layout. abi {
435
+ Scalar ( _) | ScalarPair ( _, _) => true ,
436
+ Uninhabited | Vector { .. } => false ,
437
+ Aggregate { .. } => {
438
+ // For rusty ABIs, small aggregates are actually passed
439
+ // as `RegKind::Integer` (see `FnAbi::adjust_for_abi`),
440
+ // so we re-use that same threshold here.
441
+ layout. size <= self . data_layout ( ) . pointer_size * 2
442
+ }
443
+ } ;
444
+
445
+ let a = args[ 0 ] . immediate ( ) ;
446
+ let b = args[ 1 ] . immediate ( ) ;
447
+ if layout. size . bytes ( ) == 0 {
448
+ self . const_bool ( true )
449
+ } else if use_integer_compare {
450
+ let integer_ty = self . type_ix ( layout. size . bits ( ) ) ;
451
+ let ptr_ty = self . type_ptr_to ( integer_ty) ;
452
+ let a_ptr = self . bitcast ( a, ptr_ty) ;
453
+ let a_val = self . load ( integer_ty, a_ptr, layout. align . abi ) ;
454
+ let b_ptr = self . bitcast ( b, ptr_ty) ;
455
+ let b_val = self . load ( integer_ty, b_ptr, layout. align . abi ) ;
456
+ self . icmp ( IntPredicate :: IntEQ , a_val, b_val)
457
+ } else {
458
+ let i8p_ty = self . type_i8p ( ) ;
459
+ let a_ptr = self . bitcast ( a, i8p_ty) ;
460
+ let b_ptr = self . bitcast ( b, i8p_ty) ;
461
+ let n = self . const_usize ( layout. size . bytes ( ) ) ;
462
+ let intrinsic = self . get_intrinsic ( "memcmp" ) ;
463
+ let cmp = self . call ( self . type_i1 ( ) , intrinsic, & [ a_ptr, b_ptr, n] , None ) ;
464
+ self . icmp ( IntPredicate :: IntEQ , cmp, self . const_i32 ( 0 ) )
465
+ }
466
+ }
428
467
// is this even supported by nvvm? i did not find a definitive answer
429
468
_ if name_str. starts_with ( "simd_" ) => todo ! ( "simd intrinsics" ) ,
430
469
_ => bug ! ( "unknown intrinsic '{}'" , name) ,
0 commit comments