Skip to content

Commit

Permalink
x86_64: Remove needless test in CAS
Browse files Browse the repository at this point in the history
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).
  • Loading branch information
taiki-e committed Mar 21, 2024
1 parent 9ef916d commit 573e025
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 1 deletion.
3 changes: 2 additions & 1 deletion src/imp/atomic128/x86_64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
// - atomic-maybe-uninit https://github.com/taiki-e/atomic-maybe-uninit
//
// Generated asm:
// - x86_64 (+cmpxchg16b) https://godbolt.org/z/YnYE9qT6b
// - x86_64 (+cmpxchg16b) https://godbolt.org/z/r5x9M8PdK

include!("macros.rs");

Expand Down Expand Up @@ -124,6 +124,7 @@ unsafe fn cmpxchg16b(dst: *mut u128, old: u128, new: u128) -> (u128, bool) {
cmpxchg16b!("edi");
#[cfg(target_pointer_width = "64")]
cmpxchg16b!("rdi");
crate::utils::assert_unchecked(r == 0 || r == 1); // needed to remove extra test
(U128 { pair: Pair { lo: prev_lo, hi: prev_hi } }.whole, r != 0)
}
}
Expand Down
3 changes: 3 additions & 0 deletions src/imp/x86.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ macro_rules! atomic_bit_opts {
// Do not use `preserves_flags` because BTS modifies the CF flag.
options(nostack),
);
crate::utils::assert_unchecked(r == 0 || r == 1); // may help remove extra test
r != 0
}
}
Expand All @@ -172,6 +173,7 @@ macro_rules! atomic_bit_opts {
// Do not use `preserves_flags` because BTR modifies the CF flag.
options(nostack),
);
crate::utils::assert_unchecked(r == 0 || r == 1); // may help remove extra test
r != 0
}
}
Expand All @@ -196,6 +198,7 @@ macro_rules! atomic_bit_opts {
// Do not use `preserves_flags` because BTC modifies the CF flag.
options(nostack),
);
crate::utils::assert_unchecked(r == 0 || r == 1); // may help remove extra test
r != 0
}
}
Expand Down
16 changes: 16 additions & 0 deletions src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,22 @@ macro_rules! items {
};
}

#[allow(dead_code)]
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
// Stable version of https://doc.rust-lang.org/nightly/std/hint/fn.assert_unchecked.html.
#[inline(always)]
#[cfg_attr(all(debug_assertions, not(portable_atomic_no_track_caller)), track_caller)]
pub(crate) unsafe fn assert_unchecked(cond: bool) {
if !cond {
if cfg!(debug_assertions) {
unreachable!()
} else {
// SAFETY: the caller promised `cond` is true.
unsafe { core::hint::unreachable_unchecked() }
}
}
}

// https://github.com/rust-lang/rust/blob/1.70.0/library/core/src/sync/atomic.rs#L3155
#[inline]
#[cfg_attr(all(debug_assertions, not(portable_atomic_no_track_caller)), track_caller)]
Expand Down

0 comments on commit 573e025

Please sign in to comment.