[clang] [Clang] Implement P2280R4 Using unknown pointers and references in constant expressions (PR #95474)

Vlad Serebrennikov via cfe-commits cfe-commits at lists.llvm.org
Sat Jul 27 10:47:12 PDT 2024


Endilll wrote:

Shafik contacted me offline about a libc++ test failure this PR causes. The test in question is `mem.res.eq/not_equal_pass.cpp`.
I reduced it down to the following:
```cpp
struct memory_resource {
  virtual ~memory_resource();
  bool is_equal(const memory_resource &) const noexcept;
};

inline bool operator==(const memory_resource &__lhs, const memory_resource &__rhs) {
  return &__lhs == &__rhs || __lhs.is_equal(__rhs);
  //     ^^^^^^^^^^^^^^^^ frontend built from this branch believes that this is never true         
}

void __assert_fail();

struct TestResourceImp : memory_resource {
  memory_resource do_is_equal_other;

  virtual bool do_is_equal() noexcept {
    return dynamic_cast<TestResourceImp *>(&do_is_equal_other);
  }
};

int main() {
  memory_resource mr1, mr2;
  mr1 != mr2 ? void() : __assert_fail();
}
```
Clang built from this branch produces the following IR for `operator==`
```llvm
; Function Attrs: mustprogress noinline nounwind optnone uwtable
define linkonce_odr dso_local noundef zeroext i1 @_ZeqRK15memory_resourceS1_(ptr noundef nonnull align 8 dereferenceable(8) %__lhs, ptr noundef nonnull align 8 dereferenceable(8) %__rhs) #1 comdat {
entry:
  %__lhs.addr = alloca ptr, align 8
  %__rhs.addr = alloca ptr, align 8
  store ptr %__lhs, ptr %__lhs.addr, align 8
  store ptr %__rhs, ptr %__rhs.addr, align 8
  %0 = load ptr, ptr %__lhs.addr, align 8
  %1 = load ptr, ptr %__rhs.addr, align 8
  %call = call noundef zeroext i1 @_ZNK15memory_resource8is_equalERKS_(ptr noundef nonnull align 8 dereferenceable(8) %0, ptr noundef nonnull align 8 dereferenceable(8) %1) #4
  ret i1 %call
}
```
Whereas a recent nighly build (`++20240704100628+b298e2d2d225-1~exp1~20240704220819.2190`) properly lowers the LHS of the logical OR:
```llvm
; Function Attrs: mustprogress noinline nounwind optnone uwtable
define linkonce_odr dso_local noundef zeroext i1 @_ZeqRK15memory_resourceS1_(ptr noundef nonnull align 8 dereferenceable(8) %__lhs, ptr noundef nonnull align 8 dereferenceable(8) %__rhs) #1 comdat {
entry:
  %__lhs.addr = alloca ptr, align 8
  %__rhs.addr = alloca ptr, align 8
  store ptr %__lhs, ptr %__lhs.addr, align 8
  store ptr %__rhs, ptr %__rhs.addr, align 8
  %0 = load ptr, ptr %__lhs.addr, align 8
  %1 = load ptr, ptr %__rhs.addr, align 8
  %cmp = icmp eq ptr %0, %1
  br i1 %cmp, label %lor.end, label %lor.rhs

lor.rhs:                                          ; preds = %entry
  %2 = load ptr, ptr %__lhs.addr, align 8
  %3 = load ptr, ptr %__rhs.addr, align 8
  %call = call noundef zeroext i1 @_ZNK15memory_resource8is_equalERKS_(ptr noundef nonnull align 8 dereferenceable(8) %2, ptr noundef nonnull align 8 dereferenceable(8) %3) #4
  br label %lor.end

lor.end:                                          ; preds = %lor.rhs, %entry
  %4 = phi i1 [ true, %entry ], [ %call, %lor.rhs ]
  ret i1 %4
}
```

https://github.com/llvm/llvm-project/pull/95474


More information about the cfe-commits mailing list