llvm / llvm/llvm-project

inefficient passing of `nullptr` to parameter of type `nullptr_t`

Open
#167,613 8 comments 0 reactions 0 assignees View on GitHub
c++ diverges-from:gcc missed-optimization
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.