https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102221
--- Comment #2 from Giuseppe D'Angelo <dangelog at gmail dot com> --- Hi, Thanks for the analysis! That basically allows me to reduce the testcase to something as simple as a swap: #include <memory> #include <utility> #if defined(SMART) using ptr = std::unique_ptr<int>; #else using ptr = int *; #endif auto swap1(ptr &a, ptr &b) { if (&a == &b) __builtin_unreachable(); // ptr tmp(std::move(a)); a = std::move(b); b = std::move(tmp); } auto swap2(ptr &a, ptr &b) { // deliberate std::swap<ptr>(a, b); } https://gcc.godbolt.org/z/Tqzz5eqrW In both cases there's basically a call to "delete nullptr" that doesn't get removed. I don't think this falls on libstdc++, rather than on the optimizer?