@@ -1115,6 +1115,45 @@ pub(crate) fn codegen_intrinsic_call<'tcx>(
11151115 ) ;
11161116 ret. write_cvalue( fx, CValue :: by_val( res, ret. layout( ) ) ) ;
11171117 } ;
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+ } ;
11181157 }
11191158
11201159 if let Some ( ( _, dest) ) = destination {
0 commit comments