@@ -6,6 +6,7 @@ use rustc_middle::{mir, ty};
6
6
use rustc_middle:: ty:: layout:: IntegerExt ;
7
7
use rustc_apfloat:: { Float , Round } ;
8
8
use rustc_target:: abi:: { Align , Integer , LayoutOf } ;
9
+ use rustc_span:: symbol:: sym;
9
10
10
11
use crate :: * ;
11
12
use helpers:: check_arg_count;
@@ -20,17 +21,19 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
20
21
unwind : Option < mir:: BasicBlock > ,
21
22
) -> InterpResult < ' tcx > {
22
23
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) ? {
24
32
return Ok ( ( ) ) ;
25
33
}
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 ( ) ;
32
34
33
35
// First handle intrinsics without return place.
36
+ let intrinsic_name = & * intrinsic_name. as_str ( ) ;
34
37
let ( dest, ret) = match ret {
35
38
None => match intrinsic_name {
36
39
"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
42
45
43
46
// Then handle terminating intrinsics.
44
47
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
+
45
62
// Raw memory accesses
46
63
#[ rustfmt:: skip]
47
64
| "copy"
48
65
| "copy_nonoverlapping"
49
66
=> {
50
67
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 ) ;
52
69
let elem_layout = this. layout_of ( elem_ty) ?;
53
70
let count = this. read_scalar ( count) ?. to_machine_usize ( this) ?;
54
71
let elem_align = elem_layout. align . abi ;
@@ -89,7 +106,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
89
106
90
107
"write_bytes" => {
91
108
let & [ ptr, val_byte, count] = check_arg_count ( args) ?;
92
- let ty = substs. type_at ( 0 ) ;
109
+ let ty = instance . substs . type_at ( 0 ) ;
93
110
let ty_layout = this. layout_of ( ty) ?;
94
111
let val_byte = this. read_scalar ( val_byte) ?. to_u8 ( ) ?;
95
112
let ptr = this. read_scalar ( ptr) ?. not_undef ( ) ?;
@@ -455,7 +472,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
455
472
"assert_zero_valid" |
456
473
"assert_uninit_valid" => {
457
474
let & [ ] = check_arg_count ( args) ?;
458
- let ty = substs. type_at ( 0 ) ;
475
+ let ty = instance . substs . type_at ( 0 ) ;
459
476
let layout = this. layout_of ( ty) ?;
460
477
// Abort here because the caller might not be panic safe.
461
478
if layout. abi . is_uninhabited ( ) {
0 commit comments