Skip to content

Commit 573e025

Browse files
committed
x86_64: Remove needless test in CAS
Before: ``` xchg r10, rbx lock cmpxchg16b xmmword ptr [rdi] sete r8b mov rbx, r10 xor ecx, ecx test r8b, r8b sete cl ``` After: ``` xchg r10, rbx lock cmpxchg16b xmmword ptr [rdi] setne r8b mov rbx, r10 xor r8b, 1 movzx ecx, r8b ``` Note: There is xor in "After" because it is an assembly generated for a function that returns Result<u128, u128> (discriminant of Result: 0==Ok,1==Err, bool: 0==false,1=true).
1 parent 9ef916d commit 573e025

3 files changed

Lines changed: 21 additions & 1 deletion

File tree

src/imp/atomic128/x86_64.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
// - atomic-maybe-uninit https://github.com/taiki-e/atomic-maybe-uninit
1111
//
1212
// Generated asm:
13-
// - x86_64 (+cmpxchg16b) https://godbolt.org/z/YnYE9qT6b
13+
// - x86_64 (+cmpxchg16b) https://godbolt.org/z/r5x9M8PdK
1414

1515
include!("macros.rs");
1616

@@ -124,6 +124,7 @@ unsafe fn cmpxchg16b(dst: *mut u128, old: u128, new: u128) -> (u128, bool) {
124124
cmpxchg16b!("edi");
125125
#[cfg(target_pointer_width = "64")]
126126
cmpxchg16b!("rdi");
127+
crate::utils::assert_unchecked(r == 0 || r == 1); // needed to remove extra test
127128
(U128 { pair: Pair { lo: prev_lo, hi: prev_hi } }.whole, r != 0)
128129
}
129130
}

src/imp/x86.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ macro_rules! atomic_bit_opts {
148148
// Do not use `preserves_flags` because BTS modifies the CF flag.
149149
options(nostack),
150150
);
151+
crate::utils::assert_unchecked(r == 0 || r == 1); // may help remove extra test
151152
r != 0
152153
}
153154
}
@@ -172,6 +173,7 @@ macro_rules! atomic_bit_opts {
172173
// Do not use `preserves_flags` because BTR modifies the CF flag.
173174
options(nostack),
174175
);
176+
crate::utils::assert_unchecked(r == 0 || r == 1); // may help remove extra test
175177
r != 0
176178
}
177179
}
@@ -196,6 +198,7 @@ macro_rules! atomic_bit_opts {
196198
// Do not use `preserves_flags` because BTC modifies the CF flag.
197199
options(nostack),
198200
);
201+
crate::utils::assert_unchecked(r == 0 || r == 1); // may help remove extra test
199202
r != 0
200203
}
201204
}

src/utils.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,22 @@ macro_rules! items {
246246
};
247247
}
248248

249+
#[allow(dead_code)]
250+
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
251+
// Stable version of https://doc.rust-lang.org/nightly/std/hint/fn.assert_unchecked.html.
252+
#[inline(always)]
253+
#[cfg_attr(all(debug_assertions, not(portable_atomic_no_track_caller)), track_caller)]
254+
pub(crate) unsafe fn assert_unchecked(cond: bool) {
255+
if !cond {
256+
if cfg!(debug_assertions) {
257+
unreachable!()
258+
} else {
259+
// SAFETY: the caller promised `cond` is true.
260+
unsafe { core::hint::unreachable_unchecked() }
261+
}
262+
}
263+
}
264+
249265
// https://github.com/rust-lang/rust/blob/1.70.0/library/core/src/sync/atomic.rs#L3155
250266
#[inline]
251267
#[cfg_attr(all(debug_assertions, not(portable_atomic_no_track_caller)), track_caller)]

0 commit comments

Comments
 (0)