@@ -6,6 +6,7 @@ use rustc_middle::{mir, ty};
66use rustc_middle:: ty:: layout:: IntegerExt ;
77use rustc_apfloat:: { Float , Round } ;
88use rustc_target:: abi:: { Align , Integer , LayoutOf } ;
9+ use rustc_span:: symbol:: sym;
910
1011use crate :: * ;
1112use helpers:: check_arg_count;
@@ -20,17 +21,19 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
2021 unwind : Option < mir:: BasicBlock > ,
2122 ) -> InterpResult < ' tcx > {
2223 let this = self . eval_context_mut ( ) ;
23- if this. emulate_intrinsic ( instance, args, ret) ? {
24+ let intrinsic_name = this. tcx . item_name ( instance. def_id ( ) ) ;
25+ // We want to overwrite some of the intrinsic implementations that CTFE uses.
26+ let prefer_miri_intrinsic = match intrinsic_name {
27+ sym:: ptr_guaranteed_eq | sym:: ptr_guaranteed_ne => true ,
28+ _ => false ,
29+ } ;
30+
31+ if !prefer_miri_intrinsic && this. emulate_intrinsic ( instance, args, ret) ? {
2432 return Ok ( ( ) ) ;
2533 }
26- let substs = instance. substs ;
27-
28- // All these intrinsics take raw pointers, so if we access memory directly
29- // (as opposed to through a place), we have to remember to erase any tag
30- // that might still hang around!
31- let intrinsic_name = & * this. tcx . item_name ( instance. def_id ( ) ) . as_str ( ) ;
3234
3335 // First handle intrinsics without return place.
36+ let intrinsic_name = & * intrinsic_name. as_str ( ) ;
3437 let ( dest, ret) = match ret {
3538 None => match intrinsic_name {
3639 "miri_start_panic" => return this. handle_miri_start_panic ( args, unwind) ,
@@ -42,13 +45,27 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
4245
4346 // Then handle terminating intrinsics.
4447 match intrinsic_name {
48+ // Miri overwriting CTFE intrinsics.
49+ "ptr_guaranteed_eq" => {
50+ let & [ left, right] = check_arg_count ( args) ?;
51+ let left = this. read_immediate ( left) ?;
52+ let right = this. read_immediate ( right) ?;
53+ this. binop_ignore_overflow ( mir:: BinOp :: Eq , left, right, dest) ?;
54+ }
55+ "ptr_guaranteed_ne" => {
56+ let & [ left, right] = check_arg_count ( args) ?;
57+ let left = this. read_immediate ( left) ?;
58+ let right = this. read_immediate ( right) ?;
59+ this. binop_ignore_overflow ( mir:: BinOp :: Ne , left, right, dest) ?;
60+ }
61+
4562 // Raw memory accesses
4663 #[ rustfmt:: skip]
4764 | "copy"
4865 | "copy_nonoverlapping"
4966 => {
5067 let & [ src, dest, count] = check_arg_count ( args) ?;
51- let elem_ty = substs. type_at ( 0 ) ;
68+ let elem_ty = instance . substs . type_at ( 0 ) ;
5269 let elem_layout = this. layout_of ( elem_ty) ?;
5370 let count = this. read_scalar ( count) ?. to_machine_usize ( this) ?;
5471 let elem_align = elem_layout. align . abi ;
@@ -89,7 +106,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
89106
90107 "write_bytes" => {
91108 let & [ ptr, val_byte, count] = check_arg_count ( args) ?;
92- let ty = substs. type_at ( 0 ) ;
109+ let ty = instance . substs . type_at ( 0 ) ;
93110 let ty_layout = this. layout_of ( ty) ?;
94111 let val_byte = this. read_scalar ( val_byte) ?. to_u8 ( ) ?;
95112 let ptr = this. read_scalar ( ptr) ?. not_undef ( ) ?;
@@ -455,7 +472,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
455472 "assert_zero_valid" |
456473 "assert_uninit_valid" => {
457474 let & [ ] = check_arg_count ( args) ?;
458- let ty = substs. type_at ( 0 ) ;
475+ let ty = instance . substs . type_at ( 0 ) ;
459476 let layout = this. layout_of ( ty) ?;
460477 // Abort here because the caller might not be panic safe.
461478 if layout. abi . is_uninhabited ( ) {
0 commit comments