@@ -5,16 +5,18 @@ use rustc_abi::Size;
55use rustc_const_eval:: interpret:: { InterpResult , interp_ok} ;
66use rustc_data_structures:: fx:: FxHashSet ;
77use rustc_middle:: mir;
8+ use rustc_middle:: mir:: interpret;
89use rustc_middle:: ty:: ScalarInt ;
910use rustc_span:: Span ;
1011use tracing:: debug;
1112
1213use super :: GenmcScalar ;
13- use crate :: diagnostics:: EvalContextExt ;
14+ use crate :: alloc_addresses:: EvalContextExt as _;
15+ use crate :: diagnostics:: EvalContextExt as _;
1416use crate :: intrinsics:: AtomicRmwOp ;
1517use crate :: {
16- AtomicFenceOrd , AtomicReadOrd , AtomicRwOrd , AtomicWriteOrd , InterpCx , MiriInterpCx ,
17- MiriMachine , NonHaltingDiagnostic , Scalar , throw_unsup_format,
18+ AtomicFenceOrd , AtomicReadOrd , AtomicRwOrd , AtomicWriteOrd , BorTag , GenmcCtx , InterpCx ,
19+ MiriInterpCx , MiriMachine , NonHaltingDiagnostic , Scalar , machine , throw_unsup_format,
1820} ;
1921
2022/// Maximum size memory access in bytes that GenMC supports.
@@ -80,19 +82,30 @@ pub fn split_access(address: Size, size: Size) -> impl Iterator<Item = (u64, u64
8082/// We cannot use the `AllocId` instead of the base address, since Miri has no control over the `AllocId`, and it may change across executions.
8183/// Pointers with `Wildcard` provenance are not supported.
8284pub fn scalar_to_genmc_scalar < ' tcx > (
83- _ecx : & MiriInterpCx < ' tcx > ,
85+ ecx : & MiriInterpCx < ' tcx > ,
86+ genmc_ctx : & GenmcCtx ,
8487 scalar : Scalar ,
8588) -> InterpResult < ' tcx , GenmcScalar > {
8689 interp_ok ( match scalar {
8790 rustc_const_eval:: interpret:: Scalar :: Int ( scalar_int) => {
8891 // FIXME(genmc): Add u128 support once GenMC supports it.
8992 let value: u64 = scalar_int. to_uint ( scalar_int. size ( ) ) . try_into ( ) . unwrap ( ) ;
90- GenmcScalar { value, is_init : true }
93+ GenmcScalar { value, extra : 0 , is_init : true }
94+ }
95+ rustc_const_eval:: interpret:: Scalar :: Ptr ( pointer, size) => {
96+ // FIXME(genmc,borrow tracking): Borrow tracking information is lost.
97+ let addr = crate :: Pointer :: from ( pointer) . addr ( ) ;
98+ if let crate :: Provenance :: Wildcard = pointer. provenance {
99+ throw_unsup_format ! ( "Pointers with wildcard provenance not allowed in GenMC mode" ) ;
100+ }
101+ let ( alloc_id, _size, _prov_extra) =
102+ rustc_const_eval:: interpret:: Machine :: ptr_get_alloc ( ecx, pointer, size. into ( ) )
103+ . unwrap ( ) ;
104+ let base_addr = ecx. addr_from_alloc_id ( alloc_id, None ) ?;
105+ // Add the base_addr alloc_id pair to the map.
106+ genmc_ctx. exec_state . genmc_shared_allocs_map . borrow_mut ( ) . insert ( base_addr, alloc_id) ;
107+ GenmcScalar { value : addr. bytes ( ) , extra : base_addr, is_init : true }
91108 }
92- rustc_const_eval:: interpret:: Scalar :: Ptr ( _pointer, _size) =>
93- throw_unsup_format ! (
94- "FIXME(genmc): Implement sending pointers (with provenance) to GenMC."
95- ) ,
96109 } )
97110}
98111
@@ -101,16 +114,25 @@ pub fn scalar_to_genmc_scalar<'tcx>(
101114/// Convert a `GenmcScalar` back into a Miri `Scalar`.
102115/// For pointers, attempt to convert the stored base address of their allocation back into an `AllocId`.
103116pub fn genmc_scalar_to_scalar < ' tcx > (
104- _ecx : & MiriInterpCx < ' tcx > ,
117+ ecx : & MiriInterpCx < ' tcx > ,
118+ genmc_ctx : & GenmcCtx ,
105119 scalar : GenmcScalar ,
106120 size : Size ,
107121) -> InterpResult < ' tcx , Scalar > {
108- // FIXME(genmc): Add GenmcScalar to Miri Pointer conversion.
109-
110- // NOTE: GenMC always returns 64 bit values, and the upper bits are not yet truncated.
111- // FIXME(genmc): GenMC should be doing the truncation, not Miri.
112- let ( value_scalar_int, _got_truncated) = ScalarInt :: truncate_from_uint ( scalar. value , size) ;
113- interp_ok ( Scalar :: Int ( value_scalar_int) )
122+ // If `extra` is zero, we have a regular integer.
123+ if scalar. extra == 0 {
124+ // NOTE: GenMC always returns 64 bit values, and the upper bits are not yet truncated.
125+ // FIXME(genmc): GenMC should be doing the truncation, not Miri.
126+ let ( value_scalar_int, _got_truncated) = ScalarInt :: truncate_from_uint ( scalar. value , size) ;
127+ return interp_ok ( Scalar :: from ( value_scalar_int) ) ;
128+ }
129+ // `extra` is non-zero, we have a pointer.
130+ // When we get a pointer from GenMC, then we must have sent it to GenMC before in the same execution (since the reads-from relation is always respected).
131+ let alloc_id = genmc_ctx. exec_state . genmc_shared_allocs_map . borrow ( ) [ & scalar. extra ] ;
132+ // FIXME(genmc,borrow tracking): Borrow tracking not yet supported.
133+ let provenance = machine:: Provenance :: Concrete { alloc_id, tag : BorTag :: default ( ) } ;
134+ let ptr = interpret:: Pointer :: new ( provenance, Size :: from_bytes ( scalar. value ) ) ;
135+ interp_ok ( Scalar :: from_pointer ( ptr, & ecx. tcx ) )
114136}
115137
116138impl AtomicReadOrd {
0 commit comments