@@ -1115,6 +1115,45 @@ pub(crate) fn codegen_intrinsic_call<'tcx>(
1115
1115
) ;
1116
1116
ret. write_cvalue( fx, CValue :: by_val( res, ret. layout( ) ) ) ;
1117
1117
} ;
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
+ } ;
1118
1157
}
1119
1158
1120
1159
if let Some ( ( _, dest) ) = destination {
0 commit comments