inefficient passing of `nullptr` to parameter of type `nullptr_t`
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
```c++
void f(decltype(nullptr) x);
void g() { f(nullptr); }
```
Clang (and GCC) generate an instruction to zero a register when making this call. That's unnecessary -- `nullptr_t` contains only padding bits, so there is no need to put any particular value in the parameter.
It's a little weird that the C++ standard requires it to have the same size and alignment as a pointer, but also says that lvalue-to-rvalue conversions don't touch memory. And it's unfortunate that our ABIs require a register to be allocated to (not) passing it. But it's too late to change any of that.
We also have divergence from GCC on this:
```c++
void h() {
volatile auto p = nullptr;
p = nullptr;
p = p;
}
```
Clang generates three volatile stores of `ptr null` here and zero volatile loads. GCC generates three volatile stores and one volatile load. To my reading, Clang is right and GCC is wrong: the standard [is clear](https://eel.is/c++draft/conv.lval#3.1) that there is no read from memory in this case, but each assignment [does constitute a modification](https://eel.is/c++draft/expr.assign#2) -- but we don't need to store `null` in particular, any bits would do here, so long as we perform a store. (Weirdly.)
I think instead of [producing `ptr null`](https://github.com/llvm/llvm-project/blob/ea10026b64f66b3b69c0545db20f9daa8579f5cb/clang/lib/CodeGen/CGExprScalar.cpp#L771) when lowering a `nullptr` expression, we should instead produce `ptr poison`, given that the representation comprises only padding bits.
Contributor guide
Assessment
This issue has not been assessed yet.