llvm / llvm/llvm-project

[clang] cmp,1 + je instead of tst, jne

Open
#191,705 3 comments 0 reactions 0 assignees View on GitHub
backend:X86
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

The following code

```c++
#include
#include

void asymmetric_thread_fence_light() { asm volatile("" : : : "memory"); }

struct Reader1 {
void exit();

void notify();

std::atomic rcu_count;
std::uint32_t nested_readers;
std::atomic waiting;
};

void Reader1::exit() {
if (nested_readers) [[unlikely]] {
--nested_readers;
return;
}

asymmetric_thread_fence_light();
rcu_count.store(0, std::memory_order_relaxed);
asymmetric_thread_fence_light();

if (waiting.load(std::memory_order_relaxed)) [[unlikely]] {
notify();
}
}
```

https://godbolt.org/z/7P46qfYY6

In the check
`if (waiting.load(std::memory_order_relaxed)) [[unlikely]] {`
generates `cmp al, 1`

If we invert the condition we get `test al, al`

gcc generates `tst al, al` in both cases.

While I don't know for a fact here, I thought `tst al, al` would be the preferrable codegen.

Contributor guide

Open the contributing guide

Research direction

Reproduce the C++ example from the issue in the linked Compiler Explorer and compare Clang's assembly for the original and inverted conditions with GCC's output. Start by determining why Clang emits cmp against 1 for the atomic bool load; done means establishing whether test-style code generation is correct and, if so, adding the relevant regression coverage.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.