Skip to content

inefficient passing of nullptr to parameter of type nullptr_t #167613

@zygoloid

Description

@zygoloid
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:

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 that there is no read from memory in this case, but each assignment does constitute a modification -- 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 when lowering a nullptr expression, we should instead produce ptr poison, given that the representation comprises only padding bits.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions