[llvm-bugs] [Bug 39889] New: Missed optimization: std::unique_ptr destructor emits check contradicting assume / unreachable

via llvm-bugs llvm-bugs at lists.llvm.org
Tue Dec 4 23:18:20 PST 2018


https://bugs.llvm.org/show_bug.cgi?id=39889

            Bug ID: 39889
           Summary: Missed optimization: std::unique_ptr destructor emits
                    check contradicting assume / unreachable
           Product: new-bugs
           Version: trunk
          Hardware: PC
                OS: All
            Status: NEW
          Severity: enhancement
          Priority: P
         Component: new bugs
          Assignee: unassignedbugs at nondot.org
          Reporter: costan at gmail.com
                CC: htmldeveloper at gmail.com, llvm-bugs at lists.llvm.org

I've been trying to find a way to tell Clang that a std::unique_ptr's pointer
cannot be null, so the emitted destructor code does not contain an unnecessary
check. GCC's optimizer seems to be able to figure this out. MSVC's optimizer
misses this opportunity.

https://godbolt.org/z/rywaj3 has my code and the compilers I've used. I will
also include the code at the end of the bug. In this example, the code
generated for Handle::~Handle(), which contains an inlined
unique_ptr<Handle>::~unique_ptr(), should not contain a test/je sequence. The
check contradicts the assumption that the unique_ptr is not null.

I tried expressing the assumption using the GCC-style __builtin_unreachable()
as well as Clang's __builtin_assume(). I tried to be more or less explicit in
the predicate -- tried ptr_, ptr_.get(), ptr_.get() != nullptr. I tried -O2,
-O3 and -Ofast.

Here is the code in the godbolt link above. The code can be simplified by
inlining the ASSUME(x) macro. I am submitting the current form so developers
can easily compare output across Clang, GCC and MSVC.

#include <memory>
#include <utility>

#if defined(__clang__)
// #define ASSUME(x) __builtin_assume(static_cast<bool>(x))
#define ASSUME(x) if(!static_cast<bool>(x)) __builtin_unreachable()
#elif defined(__GNUC__)
#define ASSUME(x) if(!static_cast<bool>(x)) __builtin_unreachable()
#elif defined(_MSC_VER)
#define ASSUME(x) __assume(static_cast<bool>(x))
#else
#error "No ASSUME definition"
#endif

struct Resource {
  ~Resource() noexcept;
};

class HandleBase {
  public:
   HandleBase() noexcept = default;
   virtual ~HandleBase();
};

class Handle : public HandleBase {
  const std::unique_ptr<Resource> ptr_;
 public:
  Handle();
  ~Handle() override;
};
Handle::Handle() : ptr_(std::make_unique<Resource>()) {}
Handle::~Handle() {
  ASSUME(ptr_.get() != nullptr);
}

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20181205/282b5564/attachment.html>


More information about the llvm-bugs mailing list