llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
28.59k stars 11.82k forks source link

consteval union constants result in IR containing incorrectly-typed stores #46711

Open llvmbot opened 4 years ago

llvmbot commented 4 years ago
Bugzilla Link 47367
Version trunk
OS Linux
Reporter LLVM Bugzilla Contributor
CC @zygoloid

Extended Description

Works in clang-10.0.1 but not in clang trunk.

code example: https://godbolt.org/z/j4bGxx

Furthermore this slight variation works: https://godbolt.org/z/beMvE9

ec04fc15-fa35-46f2-80e1-5d271f2ef708 commented 4 years ago

... actually, the store in comment#1 is clearly bogus: the type being stored is different from the type of the destination pointer. (I'm a little surprised that doesn't fail the verifier.)

ec04fc15-fa35-46f2-80e1-5d271f2ef708 commented 4 years ago

This version crashes in Clang's IR generation instead, but only when using libstdc++ (with libc++ it crashes in InstCombine like the other testcases): https://godbolt.org/z/xzK9Pr

ec04fc15-fa35-46f2-80e1-5d271f2ef708 commented 4 years ago

Reduced:

template<typename T, typename U>
struct variant {
    union { T t; U u; };
    constexpr variant(T t) : t(t) {}
    constexpr U &get() { return u; }
};

struct Sum {};
struct Value {
  int value;
};

consteval auto foo() {
  variant<Sum, Value> result = Sum{};
  return result;
}

int main() {
  auto result = foo();
  return result.get().value;
}

The generated IR (https://godbolt.org/z/vq4jhq) looks OK to me; the only slightly unusual thing here is an FCA store of undef:

  store { %struct.Sum, [3 x i8] } undef, %union.anon* %4, align 4