Skip to content

Commit d18b380

Browse files
committed
Auto merge of #141700 - RalfJung:atomic-intrinsics-part2, r=bjorn3
Atomic intrinsics : use const generic ordering, part 2 This completes what got started in rust-lang/rust#141507 by using a const generic for the ordering for all intrinsics. It is based on that PR; only the last commit is new. Blocked on: - rust-lang/rust#141507 - rust-lang/rust#141687 - rust-lang/stdarch#1811 - rust-lang/rust#141964 r? `@bjorn3`
2 parents a65be07 + c6e2cab commit d18b380

File tree

1 file changed

+88
-65
lines changed

1 file changed

+88
-65
lines changed

src/intrinsics/atomic.rs

Lines changed: 88 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -26,108 +26,131 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
2626
) -> InterpResult<'tcx, EmulateItemResult> {
2727
let this = self.eval_context_mut();
2828

29-
let intrinsic_structure: Vec<_> = intrinsic_name.split('_').collect();
29+
let get_ord_at = |i: usize| {
30+
let ordering = generic_args.const_at(i).to_value();
31+
ordering.valtree.unwrap_branch()[0].unwrap_leaf().to_atomic_ordering()
32+
};
3033

31-
fn read_ord(ord: &str) -> AtomicReadOrd {
34+
fn read_ord(ord: AtomicOrdering) -> AtomicReadOrd {
3235
match ord {
33-
"seqcst" => AtomicReadOrd::SeqCst,
34-
"acquire" => AtomicReadOrd::Acquire,
35-
"relaxed" => AtomicReadOrd::Relaxed,
36-
_ => panic!("invalid read ordering `{ord}`"),
37-
}
38-
}
39-
40-
fn read_ord_const_generic(o: AtomicOrdering) -> AtomicReadOrd {
41-
match o {
4236
AtomicOrdering::SeqCst => AtomicReadOrd::SeqCst,
4337
AtomicOrdering::Acquire => AtomicReadOrd::Acquire,
4438
AtomicOrdering::Relaxed => AtomicReadOrd::Relaxed,
45-
_ => panic!("invalid read ordering `{o:?}`"),
39+
_ => panic!("invalid read ordering `{ord:?}`"),
4640
}
4741
}
4842

49-
fn write_ord(ord: &str) -> AtomicWriteOrd {
43+
fn write_ord(ord: AtomicOrdering) -> AtomicWriteOrd {
5044
match ord {
51-
"seqcst" => AtomicWriteOrd::SeqCst,
52-
"release" => AtomicWriteOrd::Release,
53-
"relaxed" => AtomicWriteOrd::Relaxed,
54-
_ => panic!("invalid write ordering `{ord}`"),
45+
AtomicOrdering::SeqCst => AtomicWriteOrd::SeqCst,
46+
AtomicOrdering::Release => AtomicWriteOrd::Release,
47+
AtomicOrdering::Relaxed => AtomicWriteOrd::Relaxed,
48+
_ => panic!("invalid write ordering `{ord:?}`"),
5549
}
5650
}
5751

58-
fn rw_ord(ord: &str) -> AtomicRwOrd {
52+
fn rw_ord(ord: AtomicOrdering) -> AtomicRwOrd {
5953
match ord {
60-
"seqcst" => AtomicRwOrd::SeqCst,
61-
"acqrel" => AtomicRwOrd::AcqRel,
62-
"acquire" => AtomicRwOrd::Acquire,
63-
"release" => AtomicRwOrd::Release,
64-
"relaxed" => AtomicRwOrd::Relaxed,
65-
_ => panic!("invalid read-write ordering `{ord}`"),
54+
AtomicOrdering::SeqCst => AtomicRwOrd::SeqCst,
55+
AtomicOrdering::AcqRel => AtomicRwOrd::AcqRel,
56+
AtomicOrdering::Acquire => AtomicRwOrd::Acquire,
57+
AtomicOrdering::Release => AtomicRwOrd::Release,
58+
AtomicOrdering::Relaxed => AtomicRwOrd::Relaxed,
6659
}
6760
}
6861

69-
fn fence_ord(ord: &str) -> AtomicFenceOrd {
62+
fn fence_ord(ord: AtomicOrdering) -> AtomicFenceOrd {
7063
match ord {
71-
"seqcst" => AtomicFenceOrd::SeqCst,
72-
"acqrel" => AtomicFenceOrd::AcqRel,
73-
"acquire" => AtomicFenceOrd::Acquire,
74-
"release" => AtomicFenceOrd::Release,
75-
_ => panic!("invalid fence ordering `{ord}`"),
64+
AtomicOrdering::SeqCst => AtomicFenceOrd::SeqCst,
65+
AtomicOrdering::AcqRel => AtomicFenceOrd::AcqRel,
66+
AtomicOrdering::Acquire => AtomicFenceOrd::Acquire,
67+
AtomicOrdering::Release => AtomicFenceOrd::Release,
68+
_ => panic!("invalid fence ordering `{ord:?}`"),
7669
}
7770
}
7871

79-
match &*intrinsic_structure {
80-
// New-style intrinsics that use const generics
81-
["load"] => {
82-
let ordering = generic_args.const_at(1).to_value();
83-
let ordering =
84-
ordering.valtree.unwrap_branch()[0].unwrap_leaf().to_atomic_ordering();
85-
this.atomic_load(args, dest, read_ord_const_generic(ordering))?;
72+
match intrinsic_name {
73+
"load" => {
74+
let ord = get_ord_at(1);
75+
this.atomic_load(args, dest, read_ord(ord))?;
76+
}
77+
78+
"store" => {
79+
let ord = get_ord_at(1);
80+
this.atomic_store(args, write_ord(ord))?
8681
}
8782

88-
// Old-style intrinsics that have the ordering in the intrinsic name
89-
["store", ord] => this.atomic_store(args, write_ord(ord))?,
90-
91-
["fence", ord] => this.atomic_fence_intrinsic(args, fence_ord(ord))?,
92-
["singlethreadfence", ord] => this.compiler_fence_intrinsic(args, fence_ord(ord))?,
93-
94-
["xchg", ord] => this.atomic_exchange(args, dest, rw_ord(ord))?,
95-
["cxchg", ord1, ord2] =>
96-
this.atomic_compare_exchange(args, dest, rw_ord(ord1), read_ord(ord2))?,
97-
["cxchgweak", ord1, ord2] =>
98-
this.atomic_compare_exchange_weak(args, dest, rw_ord(ord1), read_ord(ord2))?,
99-
100-
["or", ord] =>
101-
this.atomic_rmw_op(args, dest, AtomicOp::MirOp(BinOp::BitOr, false), rw_ord(ord))?,
102-
["xor", ord] =>
103-
this.atomic_rmw_op(args, dest, AtomicOp::MirOp(BinOp::BitXor, false), rw_ord(ord))?,
104-
["and", ord] =>
105-
this.atomic_rmw_op(args, dest, AtomicOp::MirOp(BinOp::BitAnd, false), rw_ord(ord))?,
106-
["nand", ord] =>
107-
this.atomic_rmw_op(args, dest, AtomicOp::MirOp(BinOp::BitAnd, true), rw_ord(ord))?,
108-
["xadd", ord] =>
109-
this.atomic_rmw_op(args, dest, AtomicOp::MirOp(BinOp::Add, false), rw_ord(ord))?,
110-
["xsub", ord] =>
111-
this.atomic_rmw_op(args, dest, AtomicOp::MirOp(BinOp::Sub, false), rw_ord(ord))?,
112-
["min", ord] => {
83+
"fence" => {
84+
let ord = get_ord_at(0);
85+
this.atomic_fence_intrinsic(args, fence_ord(ord))?
86+
}
87+
"singlethreadfence" => {
88+
let ord = get_ord_at(0);
89+
this.compiler_fence_intrinsic(args, fence_ord(ord))?;
90+
}
91+
92+
"xchg" => {
93+
let ord = get_ord_at(1);
94+
this.atomic_exchange(args, dest, rw_ord(ord))?;
95+
}
96+
"cxchg" => {
97+
let ord1 = get_ord_at(1);
98+
let ord2 = get_ord_at(2);
99+
this.atomic_compare_exchange(args, dest, rw_ord(ord1), read_ord(ord2))?;
100+
}
101+
"cxchgweak" => {
102+
let ord1 = get_ord_at(1);
103+
let ord2 = get_ord_at(2);
104+
this.atomic_compare_exchange_weak(args, dest, rw_ord(ord1), read_ord(ord2))?;
105+
}
106+
107+
"or" => {
108+
let ord = get_ord_at(1);
109+
this.atomic_rmw_op(args, dest, AtomicOp::MirOp(BinOp::BitOr, false), rw_ord(ord))?;
110+
}
111+
"xor" => {
112+
let ord = get_ord_at(1);
113+
this.atomic_rmw_op(args, dest, AtomicOp::MirOp(BinOp::BitXor, false), rw_ord(ord))?;
114+
}
115+
"and" => {
116+
let ord = get_ord_at(1);
117+
this.atomic_rmw_op(args, dest, AtomicOp::MirOp(BinOp::BitAnd, false), rw_ord(ord))?;
118+
}
119+
"nand" => {
120+
let ord = get_ord_at(1);
121+
this.atomic_rmw_op(args, dest, AtomicOp::MirOp(BinOp::BitAnd, true), rw_ord(ord))?;
122+
}
123+
"xadd" => {
124+
let ord = get_ord_at(1);
125+
this.atomic_rmw_op(args, dest, AtomicOp::MirOp(BinOp::Add, false), rw_ord(ord))?;
126+
}
127+
"xsub" => {
128+
let ord = get_ord_at(1);
129+
this.atomic_rmw_op(args, dest, AtomicOp::MirOp(BinOp::Sub, false), rw_ord(ord))?;
130+
}
131+
"min" => {
132+
let ord = get_ord_at(1);
113133
// Later we will use the type to indicate signed vs unsigned,
114134
// so make sure it matches the intrinsic name.
115135
assert!(matches!(args[1].layout.ty.kind(), ty::Int(_)));
116136
this.atomic_rmw_op(args, dest, AtomicOp::Min, rw_ord(ord))?;
117137
}
118-
["umin", ord] => {
138+
"umin" => {
139+
let ord = get_ord_at(1);
119140
// Later we will use the type to indicate signed vs unsigned,
120141
// so make sure it matches the intrinsic name.
121142
assert!(matches!(args[1].layout.ty.kind(), ty::Uint(_)));
122143
this.atomic_rmw_op(args, dest, AtomicOp::Min, rw_ord(ord))?;
123144
}
124-
["max", ord] => {
145+
"max" => {
146+
let ord = get_ord_at(1);
125147
// Later we will use the type to indicate signed vs unsigned,
126148
// so make sure it matches the intrinsic name.
127149
assert!(matches!(args[1].layout.ty.kind(), ty::Int(_)));
128150
this.atomic_rmw_op(args, dest, AtomicOp::Max, rw_ord(ord))?;
129151
}
130-
["umax", ord] => {
152+
"umax" => {
153+
let ord = get_ord_at(1);
131154
// Later we will use the type to indicate signed vs unsigned,
132155
// so make sure it matches the intrinsic name.
133156
assert!(matches!(args[1].layout.ty.kind(), ty::Uint(_)));

0 commit comments

Comments
 (0)