@@ -713,14 +713,21 @@ fn codegen_regular_intrinsic_call<'tcx>(
713
713
ret. write_cvalue( fx, val) ;
714
714
} ;
715
715
716
- ptr_offset_from, ( v ptr, v base) {
716
+ ptr_offset_from | ptr_offset_from_unsigned , ( v ptr, v base) {
717
717
let ty = substs. type_at( 0 ) ;
718
718
let isize_layout = fx. layout_of( fx. tcx. types. isize ) ;
719
719
720
720
let pointee_size: u64 = fx. layout_of( ty) . size. bytes( ) ;
721
- let diff = fx. bcx. ins( ) . isub( ptr, base) ;
721
+ let diff_bytes = fx. bcx. ins( ) . isub( ptr, base) ;
722
722
// FIXME this can be an exact division.
723
- let val = CValue :: by_val( fx. bcx. ins( ) . sdiv_imm( diff, pointee_size as i64 ) , isize_layout) ;
723
+ let diff = if intrinsic == sym:: ptr_offset_from_unsigned {
724
+ // Because diff_bytes ULE isize::MAX, this would be fine as signed,
725
+ // but unsigned is slightly easier to codegen, so might as well.
726
+ fx. bcx. ins( ) . udiv_imm( diff_bytes, pointee_size as i64 )
727
+ } else {
728
+ fx. bcx. ins( ) . sdiv_imm( diff_bytes, pointee_size as i64 )
729
+ } ;
730
+ let val = CValue :: by_val( diff, isize_layout) ;
724
731
ret. write_cvalue( fx, val) ;
725
732
} ;
726
733
0 commit comments