Skip to content

Commit 6ab6462

Browse files
committed
refactor atomic intrinsic handling to actually parse the intrinsic name
1 parent ad3010c commit 6ab6462

File tree

1 file changed

+100
-232
lines changed

1 file changed

+100
-232
lines changed

src/shims/intrinsics/atomic.rs

+100-232
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1-
use rustc_middle::{mir, mir::BinOp};
1+
use rustc_middle::{mir, mir::BinOp, ty};
22
use rustc_target::abi::Align;
33

44
use crate::*;
55
use helpers::check_arg_count;
66

77
pub 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

Comments
 (0)