Skip to content

Commit c850ffe

Browse files
committed
add support for new RMW orders
1 parent 1174cda commit c850ffe

File tree

2 files changed

+79
-50
lines changed

2 files changed

+79
-50
lines changed

src/shims/intrinsics/atomic.rs

Lines changed: 60 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -49,57 +49,93 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
4949
"cxchg_seqcst_seqcst" =>
5050
this.atomic_compare_exchange(args, dest, AtomicRwOrd::SeqCst, AtomicReadOrd::SeqCst)?,
5151
#[rustfmt::skip]
52-
"cxchg_acquire_acquire" =>
53-
this.atomic_compare_exchange(args, dest, AtomicRwOrd::Acquire, AtomicReadOrd::Acquire)?,
52+
"cxchg_seqcst_acquire" =>
53+
this.atomic_compare_exchange(args, dest, AtomicRwOrd::SeqCst, AtomicReadOrd::Acquire)?,
5454
#[rustfmt::skip]
55-
"cxchg_release_relaxed" =>
56-
this.atomic_compare_exchange(args, dest, AtomicRwOrd::Release, AtomicReadOrd::Relaxed)?,
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)?,
5760
#[rustfmt::skip]
5861
"cxchg_acqrel_acquire" =>
5962
this.atomic_compare_exchange(args, dest, AtomicRwOrd::AcqRel, AtomicReadOrd::Acquire)?,
6063
#[rustfmt::skip]
61-
"cxchg_relaxed_relaxed" =>
62-
this.atomic_compare_exchange(args, dest, AtomicRwOrd::Relaxed, AtomicReadOrd::Relaxed)?,
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)?,
6372
#[rustfmt::skip]
6473
"cxchg_acquire_relaxed" =>
6574
this.atomic_compare_exchange(args, dest, AtomicRwOrd::Acquire, AtomicReadOrd::Relaxed)?,
6675
#[rustfmt::skip]
67-
"cxchg_acqrel_relaxed" =>
68-
this.atomic_compare_exchange(args, dest, AtomicRwOrd::AcqRel, AtomicReadOrd::Relaxed)?,
76+
"cxchg_release_seqcst" =>
77+
this.atomic_compare_exchange(args, dest, AtomicRwOrd::Release, AtomicReadOrd::SeqCst)?,
6978
#[rustfmt::skip]
70-
"cxchg_seqcst_relaxed" =>
71-
this.atomic_compare_exchange(args, dest, AtomicRwOrd::SeqCst, AtomicReadOrd::Relaxed)?,
79+
"cxchg_release_acquire" =>
80+
this.atomic_compare_exchange(args, dest, AtomicRwOrd::Release, AtomicReadOrd::Acquire)?,
7281
#[rustfmt::skip]
73-
"cxchg_seqcst_acquire" =>
74-
this.atomic_compare_exchange(args, dest, AtomicRwOrd::SeqCst, AtomicReadOrd::Acquire)?,
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)?,
7593

7694
#[rustfmt::skip]
7795
"cxchgweak_seqcst_seqcst" =>
7896
this.atomic_compare_exchange_weak(args, dest, AtomicRwOrd::SeqCst, AtomicReadOrd::SeqCst)?,
7997
#[rustfmt::skip]
80-
"cxchgweak_acquire_acquire" =>
81-
this.atomic_compare_exchange_weak(args, dest, AtomicRwOrd::Acquire, AtomicReadOrd::Acquire)?,
98+
"cxchgweak_seqcst_acquire" =>
99+
this.atomic_compare_exchange_weak(args, dest, AtomicRwOrd::SeqCst, AtomicReadOrd::Acquire)?,
82100
#[rustfmt::skip]
83-
"cxchgweak_release_relaxed" =>
84-
this.atomic_compare_exchange_weak(args, dest, AtomicRwOrd::Release, AtomicReadOrd::Relaxed)?,
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)?,
85106
#[rustfmt::skip]
86107
"cxchgweak_acqrel_acquire" =>
87108
this.atomic_compare_exchange_weak(args, dest, AtomicRwOrd::AcqRel, AtomicReadOrd::Acquire)?,
88109
#[rustfmt::skip]
89-
"cxchgweak_relaxed_relaxed" =>
90-
this.atomic_compare_exchange_weak(args, dest, AtomicRwOrd::Relaxed, AtomicReadOrd::Relaxed)?,
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)?,
91118
#[rustfmt::skip]
92119
"cxchgweak_acquire_relaxed" =>
93120
this.atomic_compare_exchange_weak(args, dest, AtomicRwOrd::Acquire, AtomicReadOrd::Relaxed)?,
94121
#[rustfmt::skip]
95-
"cxchgweak_acqrel_relaxed" =>
96-
this.atomic_compare_exchange_weak(args, dest, AtomicRwOrd::AcqRel, AtomicReadOrd::Relaxed)?,
122+
"cxchgweak_release_seqcst" =>
123+
this.atomic_compare_exchange_weak(args, dest, AtomicRwOrd::Release, AtomicReadOrd::SeqCst)?,
97124
#[rustfmt::skip]
98-
"cxchgweak_seqcst_relaxed" =>
99-
this.atomic_compare_exchange_weak(args, dest, AtomicRwOrd::SeqCst, AtomicReadOrd::Relaxed)?,
125+
"cxchgweak_release_acquire" =>
126+
this.atomic_compare_exchange_weak(args, dest, AtomicRwOrd::Release, AtomicReadOrd::Acquire)?,
100127
#[rustfmt::skip]
101-
"cxchgweak_seqcst_acquire" =>
102-
this.atomic_compare_exchange_weak(args, dest, AtomicRwOrd::SeqCst, AtomicReadOrd::Acquire)?,
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)?,
103139

104140
#[rustfmt::skip]
105141
"or_seqcst" =>

tests/pass/atomic.rs

Lines changed: 19 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -51,18 +51,22 @@ fn atomic_all_ops() {
5151
static ATOMIC: AtomicIsize = AtomicIsize::new(0);
5252
static ATOMIC_UNSIGNED: AtomicU64 = AtomicU64::new(0);
5353

54+
let load_orders = [Relaxed, Acquire, SeqCst];
55+
let stored_orders = [Relaxed, Release, SeqCst];
56+
let rmw_orders = [Relaxed, Release, Acquire, AcqRel, SeqCst];
57+
5458
// loads
55-
for o in [Relaxed, Acquire, SeqCst] {
59+
for o in load_orders {
5660
ATOMIC.load(o);
5761
}
5862

5963
// stores
60-
for o in [Relaxed, Release, SeqCst] {
64+
for o in stored_orders {
6165
ATOMIC.store(1, o);
6266
}
6367

6468
// most RMWs
65-
for o in [Relaxed, Release, Acquire, AcqRel, SeqCst] {
69+
for o in rmw_orders {
6670
ATOMIC.swap(0, o);
6771
ATOMIC.fetch_or(0, o);
6872
ATOMIC.fetch_xor(0, o);
@@ -76,37 +80,26 @@ fn atomic_all_ops() {
7680
ATOMIC_UNSIGNED.fetch_max(0, o);
7781
}
7882

79-
// RMWs with deparate failure ordering
80-
ATOMIC.store(0, SeqCst);
81-
assert_eq!(ATOMIC.compare_exchange(0, 1, Relaxed, Relaxed), Ok(0));
82-
assert_eq!(ATOMIC.compare_exchange(0, 2, Acquire, Relaxed), Err(1));
83-
assert_eq!(ATOMIC.compare_exchange(0, 1, Release, Relaxed), Err(1));
84-
assert_eq!(ATOMIC.compare_exchange(1, 0, AcqRel, Relaxed), Ok(1));
85-
ATOMIC.compare_exchange(0, 1, SeqCst, Relaxed).ok();
86-
ATOMIC.compare_exchange(0, 1, Acquire, Acquire).ok();
87-
ATOMIC.compare_exchange(0, 1, AcqRel, Acquire).ok();
88-
ATOMIC.compare_exchange(0, 1, SeqCst, Acquire).ok();
89-
ATOMIC.compare_exchange(0, 1, SeqCst, SeqCst).ok();
90-
91-
ATOMIC.store(0, SeqCst);
92-
compare_exchange_weak_loop!(ATOMIC, 0, 1, Relaxed, Relaxed);
93-
assert_eq!(ATOMIC.compare_exchange_weak(0, 2, Acquire, Relaxed), Err(1));
94-
assert_eq!(ATOMIC.compare_exchange_weak(0, 1, Release, Relaxed), Err(1));
95-
compare_exchange_weak_loop!(ATOMIC, 1, 0, AcqRel, Relaxed);
96-
assert_eq!(ATOMIC.load(Relaxed), 0);
97-
ATOMIC.compare_exchange_weak(0, 1, SeqCst, Relaxed).ok();
98-
ATOMIC.compare_exchange_weak(0, 1, Acquire, Acquire).ok();
99-
ATOMIC.compare_exchange_weak(0, 1, AcqRel, Acquire).ok();
100-
ATOMIC.compare_exchange_weak(0, 1, SeqCst, Acquire).ok();
101-
ATOMIC.compare_exchange_weak(0, 1, SeqCst, SeqCst).ok();
83+
// RMWs with separate failure ordering
84+
for o1 in rmw_orders {
85+
for o2 in load_orders {
86+
let _res = ATOMIC.compare_exchange(0, 0, o1, o2);
87+
let _res = ATOMIC.compare_exchange_weak(0, 0, o1, o2);
88+
}
89+
}
10290
}
10391

10492
fn atomic_u64() {
10593
static ATOMIC: AtomicU64 = AtomicU64::new(0);
10694

10795
ATOMIC.store(1, SeqCst);
10896
assert_eq!(ATOMIC.compare_exchange(0, 0x100, AcqRel, Acquire), Err(1));
97+
assert_eq!(ATOMIC.compare_exchange(0, 1, Release, Relaxed), Err(1));
98+
assert_eq!(ATOMIC.compare_exchange(1, 0, AcqRel, Relaxed), Ok(1));
99+
assert_eq!(ATOMIC.compare_exchange(0, 1, Relaxed, Relaxed), Ok(0));
109100
compare_exchange_weak_loop!(ATOMIC, 1, 0x100, AcqRel, Acquire);
101+
assert_eq!(ATOMIC.compare_exchange_weak(0, 2, Acquire, Relaxed), Err(0x100));
102+
assert_eq!(ATOMIC.compare_exchange_weak(0, 1, Release, Relaxed), Err(0x100));
110103
assert_eq!(ATOMIC.load(Relaxed), 0x100);
111104

112105
assert_eq!(ATOMIC.fetch_max(0x10, SeqCst), 0x100);

0 commit comments

Comments
 (0)