1- use rustc_middle:: { mir, mir:: BinOp } ;
1+ use rustc_middle:: { mir, mir:: BinOp , ty } ;
22use rustc_target:: abi:: Align ;
33
44use crate :: * ;
55use helpers:: check_arg_count;
66
77pub enum AtomicOp {
8+ /// The `bool` indicates whether the result of the operation should be negated
9+ /// (must be a boolean-typed operation).
810 MirOp ( mir:: BinOp , bool ) ,
911 Max ,
1012 Min ,
@@ -20,236 +22,99 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
2022 dest : & PlaceTy < ' tcx , Tag > ,
2123 ) -> InterpResult < ' tcx > {
2224 let this = self . eval_context_mut ( ) ;
23- match intrinsic_name {
24- "load_seqcst" => this. atomic_load ( args, dest, AtomicReadOrd :: SeqCst ) ?,
25- "load_relaxed" => this. atomic_load ( args, dest, AtomicReadOrd :: Relaxed ) ?,
26- "load_acquire" => this. atomic_load ( args, dest, AtomicReadOrd :: Acquire ) ?,
27-
28- "store_seqcst" => this. atomic_store ( args, AtomicWriteOrd :: SeqCst ) ?,
29- "store_relaxed" => this. atomic_store ( args, AtomicWriteOrd :: Relaxed ) ?,
30- "store_release" => this. atomic_store ( args, AtomicWriteOrd :: Release ) ?,
31-
32- "fence_acquire" => this. atomic_fence ( args, AtomicFenceOrd :: Acquire ) ?,
33- "fence_release" => this. atomic_fence ( args, AtomicFenceOrd :: Release ) ?,
34- "fence_acqrel" => this. atomic_fence ( args, AtomicFenceOrd :: AcqRel ) ?,
35- "fence_seqcst" => this. atomic_fence ( args, AtomicFenceOrd :: SeqCst ) ?,
36-
37- "singlethreadfence_acquire" => this. compiler_fence ( args, AtomicFenceOrd :: Acquire ) ?,
38- "singlethreadfence_release" => this. compiler_fence ( args, AtomicFenceOrd :: Release ) ?,
39- "singlethreadfence_acqrel" => this. compiler_fence ( args, AtomicFenceOrd :: AcqRel ) ?,
40- "singlethreadfence_seqcst" => this. compiler_fence ( args, AtomicFenceOrd :: SeqCst ) ?,
41-
42- "xchg_seqcst" => this. atomic_exchange ( args, dest, AtomicRwOrd :: SeqCst ) ?,
43- "xchg_acquire" => this. atomic_exchange ( args, dest, AtomicRwOrd :: Acquire ) ?,
44- "xchg_release" => this. atomic_exchange ( args, dest, AtomicRwOrd :: Release ) ?,
45- "xchg_acqrel" => this. atomic_exchange ( args, dest, AtomicRwOrd :: AcqRel ) ?,
46- "xchg_relaxed" => this. atomic_exchange ( args, dest, AtomicRwOrd :: Relaxed ) ?,
47-
48- #[ rustfmt:: skip]
49- "cxchg_seqcst_seqcst" =>
50- this. atomic_compare_exchange ( args, dest, AtomicRwOrd :: SeqCst , AtomicReadOrd :: SeqCst ) ?,
51- #[ rustfmt:: skip]
52- "cxchg_seqcst_acquire" =>
53- this. atomic_compare_exchange ( args, dest, AtomicRwOrd :: SeqCst , AtomicReadOrd :: Acquire ) ?,
54- #[ rustfmt:: skip]
55- "cxchg_seqcst_relaxed" =>
56- this. atomic_compare_exchange ( args, dest, AtomicRwOrd :: SeqCst , AtomicReadOrd :: Relaxed ) ?,
57- #[ rustfmt:: skip]
58- "cxchg_acqrel_seqcst" =>
59- this. atomic_compare_exchange ( args, dest, AtomicRwOrd :: AcqRel , AtomicReadOrd :: SeqCst ) ?,
60- #[ rustfmt:: skip]
61- "cxchg_acqrel_acquire" =>
62- this. atomic_compare_exchange ( args, dest, AtomicRwOrd :: AcqRel , AtomicReadOrd :: Acquire ) ?,
63- #[ rustfmt:: skip]
64- "cxchg_acqrel_relaxed" =>
65- this. atomic_compare_exchange ( args, dest, AtomicRwOrd :: AcqRel , AtomicReadOrd :: Relaxed ) ?,
66- #[ rustfmt:: skip]
67- "cxchg_acquire_seqcst" =>
68- this. atomic_compare_exchange ( args, dest, AtomicRwOrd :: Acquire , AtomicReadOrd :: SeqCst ) ?,
69- #[ rustfmt:: skip]
70- "cxchg_acquire_acquire" =>
71- this. atomic_compare_exchange ( args, dest, AtomicRwOrd :: Acquire , AtomicReadOrd :: Acquire ) ?,
72- #[ rustfmt:: skip]
73- "cxchg_acquire_relaxed" =>
74- this. atomic_compare_exchange ( args, dest, AtomicRwOrd :: Acquire , AtomicReadOrd :: Relaxed ) ?,
75- #[ rustfmt:: skip]
76- "cxchg_release_seqcst" =>
77- this. atomic_compare_exchange ( args, dest, AtomicRwOrd :: Release , AtomicReadOrd :: SeqCst ) ?,
78- #[ rustfmt:: skip]
79- "cxchg_release_acquire" =>
80- this. atomic_compare_exchange ( args, dest, AtomicRwOrd :: Release , AtomicReadOrd :: Acquire ) ?,
81- #[ rustfmt:: skip]
82- "cxchg_release_relaxed" =>
83- this. atomic_compare_exchange ( args, dest, AtomicRwOrd :: Release , AtomicReadOrd :: Relaxed ) ?,
84- #[ rustfmt:: skip]
85- "cxchg_relaxed_seqcst" =>
86- this. atomic_compare_exchange ( args, dest, AtomicRwOrd :: Relaxed , AtomicReadOrd :: SeqCst ) ?,
87- #[ rustfmt:: skip]
88- "cxchg_relaxed_acquire" =>
89- this. atomic_compare_exchange ( args, dest, AtomicRwOrd :: Relaxed , AtomicReadOrd :: Acquire ) ?,
90- #[ rustfmt:: skip]
91- "cxchg_relaxed_relaxed" =>
92- this. atomic_compare_exchange ( args, dest, AtomicRwOrd :: Relaxed , AtomicReadOrd :: Relaxed ) ?,
93-
94- #[ rustfmt:: skip]
95- "cxchgweak_seqcst_seqcst" =>
96- this. atomic_compare_exchange_weak ( args, dest, AtomicRwOrd :: SeqCst , AtomicReadOrd :: SeqCst ) ?,
97- #[ rustfmt:: skip]
98- "cxchgweak_seqcst_acquire" =>
99- this. atomic_compare_exchange_weak ( args, dest, AtomicRwOrd :: SeqCst , AtomicReadOrd :: Acquire ) ?,
100- #[ rustfmt:: skip]
101- "cxchgweak_seqcst_relaxed" =>
102- this. atomic_compare_exchange_weak ( args, dest, AtomicRwOrd :: SeqCst , AtomicReadOrd :: Relaxed ) ?,
103- #[ rustfmt:: skip]
104- "cxchgweak_acqrel_seqcst" =>
105- this. atomic_compare_exchange_weak ( args, dest, AtomicRwOrd :: AcqRel , AtomicReadOrd :: SeqCst ) ?,
106- #[ rustfmt:: skip]
107- "cxchgweak_acqrel_acquire" =>
108- this. atomic_compare_exchange_weak ( args, dest, AtomicRwOrd :: AcqRel , AtomicReadOrd :: Acquire ) ?,
109- #[ rustfmt:: skip]
110- "cxchgweak_acqrel_relaxed" =>
111- this. atomic_compare_exchange_weak ( args, dest, AtomicRwOrd :: AcqRel , AtomicReadOrd :: Relaxed ) ?,
112- #[ rustfmt:: skip]
113- "cxchgweak_acquire_seqcst" =>
114- this. atomic_compare_exchange_weak ( args, dest, AtomicRwOrd :: Acquire , AtomicReadOrd :: SeqCst ) ?,
115- #[ rustfmt:: skip]
116- "cxchgweak_acquire_acquire" =>
117- this. atomic_compare_exchange_weak ( args, dest, AtomicRwOrd :: Acquire , AtomicReadOrd :: Acquire ) ?,
118- #[ rustfmt:: skip]
119- "cxchgweak_acquire_relaxed" =>
120- this. atomic_compare_exchange_weak ( args, dest, AtomicRwOrd :: Acquire , AtomicReadOrd :: Relaxed ) ?,
121- #[ rustfmt:: skip]
122- "cxchgweak_release_seqcst" =>
123- this. atomic_compare_exchange_weak ( args, dest, AtomicRwOrd :: Release , AtomicReadOrd :: SeqCst ) ?,
124- #[ rustfmt:: skip]
125- "cxchgweak_release_acquire" =>
126- this. atomic_compare_exchange_weak ( args, dest, AtomicRwOrd :: Release , AtomicReadOrd :: Acquire ) ?,
127- #[ rustfmt:: skip]
128- "cxchgweak_release_relaxed" =>
129- this. atomic_compare_exchange_weak ( args, dest, AtomicRwOrd :: Release , AtomicReadOrd :: Relaxed ) ?,
130- #[ rustfmt:: skip]
131- "cxchgweak_relaxed_seqcst" =>
132- this. atomic_compare_exchange_weak ( args, dest, AtomicRwOrd :: Relaxed , AtomicReadOrd :: SeqCst ) ?,
133- #[ rustfmt:: skip]
134- "cxchgweak_relaxed_acquire" =>
135- this. atomic_compare_exchange_weak ( args, dest, AtomicRwOrd :: Relaxed , AtomicReadOrd :: Acquire ) ?,
136- #[ rustfmt:: skip]
137- "cxchgweak_relaxed_relaxed" =>
138- this. atomic_compare_exchange_weak ( args, dest, AtomicRwOrd :: Relaxed , AtomicReadOrd :: Relaxed ) ?,
139-
140- #[ rustfmt:: skip]
141- "or_seqcst" =>
142- this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: BitOr , false ) , AtomicRwOrd :: SeqCst ) ?,
143- #[ rustfmt:: skip]
144- "or_acquire" =>
145- this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: BitOr , false ) , AtomicRwOrd :: Acquire ) ?,
146- #[ rustfmt:: skip]
147- "or_release" =>
148- this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: BitOr , false ) , AtomicRwOrd :: Release ) ?,
149- #[ rustfmt:: skip]
150- "or_acqrel" =>
151- this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: BitOr , false ) , AtomicRwOrd :: AcqRel ) ?,
152- #[ rustfmt:: skip]
153- "or_relaxed" =>
154- this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: BitOr , false ) , AtomicRwOrd :: Relaxed ) ?,
155- #[ rustfmt:: skip]
156- "xor_seqcst" =>
157- this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: BitXor , false ) , AtomicRwOrd :: SeqCst ) ?,
158- #[ rustfmt:: skip]
159- "xor_acquire" =>
160- this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: BitXor , false ) , AtomicRwOrd :: Acquire ) ?,
161- #[ rustfmt:: skip]
162- "xor_release" =>
163- this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: BitXor , false ) , AtomicRwOrd :: Release ) ?,
164- #[ rustfmt:: skip]
165- "xor_acqrel" =>
166- this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: BitXor , false ) , AtomicRwOrd :: AcqRel ) ?,
167- #[ rustfmt:: skip]
168- "xor_relaxed" =>
169- this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: BitXor , false ) , AtomicRwOrd :: Relaxed ) ?,
170- #[ rustfmt:: skip]
171- "and_seqcst" =>
172- this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: BitAnd , false ) , AtomicRwOrd :: SeqCst ) ?,
173- #[ rustfmt:: skip]
174- "and_acquire" =>
175- this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: BitAnd , false ) , AtomicRwOrd :: Acquire ) ?,
176- #[ rustfmt:: skip]
177- "and_release" =>
178- this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: BitAnd , false ) , AtomicRwOrd :: Release ) ?,
179- #[ rustfmt:: skip]
180- "and_acqrel" =>
181- this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: BitAnd , false ) , AtomicRwOrd :: AcqRel ) ?,
182- #[ rustfmt:: skip]
183- "and_relaxed" =>
184- this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: BitAnd , false ) , AtomicRwOrd :: Relaxed ) ?,
185- #[ rustfmt:: skip]
186- "nand_seqcst" =>
187- this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: BitAnd , true ) , AtomicRwOrd :: SeqCst ) ?,
188- #[ rustfmt:: skip]
189- "nand_acquire" =>
190- this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: BitAnd , true ) , AtomicRwOrd :: Acquire ) ?,
191- #[ rustfmt:: skip]
192- "nand_release" =>
193- this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: BitAnd , true ) , AtomicRwOrd :: Release ) ?,
194- #[ rustfmt:: skip]
195- "nand_acqrel" =>
196- this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: BitAnd , true ) , AtomicRwOrd :: AcqRel ) ?,
197- #[ rustfmt:: skip]
198- "nand_relaxed" =>
199- this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: BitAnd , true ) , AtomicRwOrd :: Relaxed ) ?,
200- #[ rustfmt:: skip]
201- "xadd_seqcst" =>
202- this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: Add , false ) , AtomicRwOrd :: SeqCst ) ?,
203- #[ rustfmt:: skip]
204- "xadd_acquire" =>
205- this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: Add , false ) , AtomicRwOrd :: Acquire ) ?,
206- #[ rustfmt:: skip]
207- "xadd_release" =>
208- this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: Add , false ) , AtomicRwOrd :: Release ) ?,
209- #[ rustfmt:: skip]
210- "xadd_acqrel" =>
211- this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: Add , false ) , AtomicRwOrd :: AcqRel ) ?,
212- #[ rustfmt:: skip]
213- "xadd_relaxed" =>
214- this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: Add , false ) , AtomicRwOrd :: Relaxed ) ?,
215- #[ rustfmt:: skip]
216- "xsub_seqcst" =>
217- this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: Sub , false ) , AtomicRwOrd :: SeqCst ) ?,
218- #[ rustfmt:: skip]
219- "xsub_acquire" =>
220- this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: Sub , false ) , AtomicRwOrd :: Acquire ) ?,
221- #[ rustfmt:: skip]
222- "xsub_release" =>
223- this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: Sub , false ) , AtomicRwOrd :: Release ) ?,
224- #[ rustfmt:: skip]
225- "xsub_acqrel" =>
226- this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: Sub , false ) , AtomicRwOrd :: AcqRel ) ?,
227- #[ rustfmt:: skip]
228- "xsub_relaxed" =>
229- this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: Sub , false ) , AtomicRwOrd :: Relaxed ) ?,
230-
231- "min_seqcst" => this. atomic_op ( args, dest, AtomicOp :: Min , AtomicRwOrd :: SeqCst ) ?,
232- "min_acquire" => this. atomic_op ( args, dest, AtomicOp :: Min , AtomicRwOrd :: Acquire ) ?,
233- "min_release" => this. atomic_op ( args, dest, AtomicOp :: Min , AtomicRwOrd :: Release ) ?,
234- "min_acqrel" => this. atomic_op ( args, dest, AtomicOp :: Min , AtomicRwOrd :: AcqRel ) ?,
235- "min_relaxed" => this. atomic_op ( args, dest, AtomicOp :: Min , AtomicRwOrd :: Relaxed ) ?,
236- "max_seqcst" => this. atomic_op ( args, dest, AtomicOp :: Max , AtomicRwOrd :: SeqCst ) ?,
237- "max_acquire" => this. atomic_op ( args, dest, AtomicOp :: Max , AtomicRwOrd :: Acquire ) ?,
238- "max_release" => this. atomic_op ( args, dest, AtomicOp :: Max , AtomicRwOrd :: Release ) ?,
239- "max_acqrel" => this. atomic_op ( args, dest, AtomicOp :: Max , AtomicRwOrd :: AcqRel ) ?,
240- "max_relaxed" => this. atomic_op ( args, dest, AtomicOp :: Max , AtomicRwOrd :: Relaxed ) ?,
241- "umin_seqcst" => this. atomic_op ( args, dest, AtomicOp :: Min , AtomicRwOrd :: SeqCst ) ?,
242- "umin_acquire" => this. atomic_op ( args, dest, AtomicOp :: Min , AtomicRwOrd :: Acquire ) ?,
243- "umin_release" => this. atomic_op ( args, dest, AtomicOp :: Min , AtomicRwOrd :: Release ) ?,
244- "umin_acqrel" => this. atomic_op ( args, dest, AtomicOp :: Min , AtomicRwOrd :: AcqRel ) ?,
245- "umin_relaxed" => this. atomic_op ( args, dest, AtomicOp :: Min , AtomicRwOrd :: Relaxed ) ?,
246- "umax_seqcst" => this. atomic_op ( args, dest, AtomicOp :: Max , AtomicRwOrd :: SeqCst ) ?,
247- "umax_acquire" => this. atomic_op ( args, dest, AtomicOp :: Max , AtomicRwOrd :: Acquire ) ?,
248- "umax_release" => this. atomic_op ( args, dest, AtomicOp :: Max , AtomicRwOrd :: Release ) ?,
249- "umax_acqrel" => this. atomic_op ( args, dest, AtomicOp :: Max , AtomicRwOrd :: AcqRel ) ?,
250- "umax_relaxed" => this. atomic_op ( args, dest, AtomicOp :: Max , AtomicRwOrd :: Relaxed ) ?,
251-
252- name => throw_unsup_format ! ( "unimplemented intrinsic: `atomic_{name}`" ) ,
25+
26+ let intrinsic_structure: Vec < _ > = intrinsic_name. split ( '_' ) . collect ( ) ;
27+
28+ fn read_ord < ' tcx > ( ord : & str ) -> InterpResult < ' tcx , AtomicReadOrd > {
29+ Ok ( match ord {
30+ "seqcst" => AtomicReadOrd :: SeqCst ,
31+ "acquire" => AtomicReadOrd :: Acquire ,
32+ "relaxed" => AtomicReadOrd :: Relaxed ,
33+ _ => throw_unsup_format ! ( "unsupported read ordering `{ord}`" ) ,
34+ } )
35+ }
36+
37+ fn write_ord < ' tcx > ( ord : & str ) -> InterpResult < ' tcx , AtomicWriteOrd > {
38+ Ok ( match ord {
39+ "seqcst" => AtomicWriteOrd :: SeqCst ,
40+ "release" => AtomicWriteOrd :: Release ,
41+ "relaxed" => AtomicWriteOrd :: Relaxed ,
42+ _ => throw_unsup_format ! ( "unsupported write ordering `{ord}`" ) ,
43+ } )
44+ }
45+
46+ fn rw_ord < ' tcx > ( ord : & str ) -> InterpResult < ' tcx , AtomicRwOrd > {
47+ Ok ( match ord {
48+ "seqcst" => AtomicRwOrd :: SeqCst ,
49+ "acqrel" => AtomicRwOrd :: AcqRel ,
50+ "acquire" => AtomicRwOrd :: Acquire ,
51+ "release" => AtomicRwOrd :: Release ,
52+ "relaxed" => AtomicRwOrd :: Relaxed ,
53+ _ => throw_unsup_format ! ( "unsupported read-write ordering `{ord}`" ) ,
54+ } )
55+ }
56+
57+ fn fence_ord < ' tcx > ( ord : & str ) -> InterpResult < ' tcx , AtomicFenceOrd > {
58+ Ok ( match ord {
59+ "seqcst" => AtomicFenceOrd :: SeqCst ,
60+ "acqrel" => AtomicFenceOrd :: AcqRel ,
61+ "acquire" => AtomicFenceOrd :: Acquire ,
62+ "release" => AtomicFenceOrd :: Release ,
63+ _ => throw_unsup_format ! ( "unsupported fence ordering `{ord}`" ) ,
64+ } )
65+ }
66+
67+ match & * intrinsic_structure {
68+ [ "load" , ord] => this. atomic_load ( args, dest, read_ord ( ord) ?) ?,
69+ [ "store" , ord] => this. atomic_store ( args, write_ord ( ord) ?) ?,
70+
71+ [ "fence" , ord] => this. atomic_fence ( args, fence_ord ( ord) ?) ?,
72+ [ "singlethreadfence" , ord] => this. compiler_fence ( args, fence_ord ( ord) ?) ?,
73+
74+ [ "xchg" , ord] => this. atomic_exchange ( args, dest, rw_ord ( ord) ?) ?,
75+ [ "cxchg" , ord1, ord2] =>
76+ this. atomic_compare_exchange ( args, dest, rw_ord ( ord1) ?, read_ord ( ord2) ?) ?,
77+ [ "cxchgweak" , ord1, ord2] =>
78+ this. atomic_compare_exchange_weak ( args, dest, rw_ord ( ord1) ?, read_ord ( ord2) ?) ?,
79+
80+ [ "or" , ord] =>
81+ this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: BitOr , false ) , rw_ord ( ord) ?) ?,
82+ [ "xor" , ord] =>
83+ this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: BitXor , false ) , rw_ord ( ord) ?) ?,
84+ [ "and" , ord] =>
85+ this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: BitAnd , false ) , rw_ord ( ord) ?) ?,
86+ [ "nand" , ord] =>
87+ this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: BitAnd , true ) , rw_ord ( ord) ?) ?,
88+ [ "xadd" , ord] =>
89+ this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: Add , false ) , rw_ord ( ord) ?) ?,
90+ [ "xsub" , ord] =>
91+ this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: Sub , false ) , rw_ord ( ord) ?) ?,
92+ [ "min" , ord] => {
93+ // Later we will use the type to indicate signed vs unsigned,
94+ // so make sure it matches the intrinsic name.
95+ assert ! ( matches!( args[ 1 ] . layout. ty. kind( ) , ty:: Int ( _) ) ) ;
96+ this. atomic_op ( args, dest, AtomicOp :: Min , rw_ord ( ord) ?) ?;
97+ }
98+ [ "umin" , ord] => {
99+ // Later we will use the type to indicate signed vs unsigned,
100+ // so make sure it matches the intrinsic name.
101+ assert ! ( matches!( args[ 1 ] . layout. ty. kind( ) , ty:: Uint ( _) ) ) ;
102+ this. atomic_op ( args, dest, AtomicOp :: Min , rw_ord ( ord) ?) ?;
103+ }
104+ [ "max" , ord] => {
105+ // Later we will use the type to indicate signed vs unsigned,
106+ // so make sure it matches the intrinsic name.
107+ assert ! ( matches!( args[ 1 ] . layout. ty. kind( ) , ty:: Int ( _) ) ) ;
108+ this. atomic_op ( args, dest, AtomicOp :: Max , rw_ord ( ord) ?) ?;
109+ }
110+ [ "umax" , ord] => {
111+ // Later we will use the type to indicate signed vs unsigned,
112+ // so make sure it matches the intrinsic name.
113+ assert ! ( matches!( args[ 1 ] . layout. ty. kind( ) , ty:: Uint ( _) ) ) ;
114+ this. atomic_op ( args, dest, AtomicOp :: Max , rw_ord ( ord) ?) ?;
115+ }
116+
117+ _ => throw_unsup_format ! ( "unimplemented intrinsic: `atomic_{intrinsic_name}`" ) ,
253118 }
254119 Ok ( ( ) )
255120 }
@@ -343,14 +208,17 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
343208
344209 let [ place, rhs] = check_arg_count ( args) ?;
345210 let place = this. deref_operand ( place) ?;
211+ let rhs = this. read_immediate ( rhs) ?;
346212
347213 if !place. layout . ty . is_integral ( ) && !place. layout . ty . is_unsafe_ptr ( ) {
348214 span_bug ! (
349215 this. cur_span( ) ,
350216 "atomic arithmetic operations only work on integer and raw pointer types" ,
351217 ) ;
352218 }
353- let rhs = this. read_immediate ( rhs) ?;
219+ if rhs. layout . ty != place. layout . ty {
220+ span_bug ! ( this. cur_span( ) , "atomic arithmetic operation type mismatch" ) ;
221+ }
354222
355223 // Check alignment requirements. Atomics must always be aligned to their size,
356224 // even if the type they wrap would be less aligned (e.g. AtomicU64 on 32bit must
0 commit comments