Turns out that when you compile with a debug version of LLVM, a lot of errors surface

This commit is contained in:
2022-05-26 19:58:53 +02:00
parent 86d317f3ba
commit bac33a2a14

View File

@@ -276,6 +276,7 @@ static spv_result_t impl_parse_insn(
#pragma ide diagnostic ignored "cppcoreguidelines-pro-type-member-init"
struct Constant {
enum class Type {
Bool,
U32, U64, I32, I64,
F32, F64,
Subclass,
@@ -292,19 +293,21 @@ protected:
}
public:
Constant(uint32_t val): type(Type::U32), ival(val) {}
Constant(uint64_t val): type(Type::U64), ival(val) {}
Constant(int32_t val): type(Type::I32), ival(val) {}
Constant(int64_t val): type(Type::I64), ival(val) {}
Constant(float val): type(Type::F32), fval(val) {}
Constant(double val): type(Type::F64), fval(val) {}
Constant(Type type, uint64_t val): type(type), ival(val) {}
Constant(Type type, double val): type(type), fval(val) {}
Constant(): type(Type::I32), ival(0) {}
explicit Constant(bool val): type(Type::Bool), ival(val ? 1 : 0) {}
explicit Constant(uint32_t val): type(Type::U32), ival(val) {}
explicit Constant(uint64_t val): type(Type::U64), ival(val) {}
explicit Constant(int32_t val): type(Type::I32), ival(val) {}
explicit Constant(int64_t val): type(Type::I64), ival(val) {}
explicit Constant(float val): type(Type::F32), fval(val) {}
explicit Constant(double val): type(Type::F64), fval(val) {}
explicit Constant(Type type, uint64_t val): type(type), ival(val) {}
explicit Constant(Type type, double val): type(type), fval(val) {}
explicit Constant(): type(Type::I32), ival(0) {}
virtual ~Constant() = default;
virtual llvm::Constant *get_llvm_const(llvm::LLVMContext &ctx) {
switch (type) {
case Type::Bool:return llvm::ConstantInt::get(llvm::Type::getInt1Ty(ctx), ival);
case Type::U32:return llvm::ConstantInt::get(llvm::Type::getInt32Ty(ctx), ival, false);
case Type::U64:return llvm::ConstantInt::get(llvm::Type::getInt64Ty(ctx), ival, false);
case Type::I32:return llvm::ConstantInt::get(llvm::Type::getInt32Ty(ctx), ival, true);
@@ -373,6 +376,7 @@ struct CompilerImpl {
llvm::StructType* global_type;
std::shared_ptr<SpirvType> global_type_spv;
std::shared_ptr<FunctionContext> cur_function;
bool tgv_finished = false;
// decorations
std::map<uint32_t, std::string> value_names;
@@ -413,6 +417,10 @@ public:
}
void finish_tgv() {
if (tgv_finished) {
return;
}
tgv_finished = true;
for (auto &type: types) {
type.second->build_llvm_type(*ctx);
}
@@ -696,10 +704,12 @@ public:
auto v = OP_VALUE(4);
llvm::Value* res;
if (v->getType()->isVectorTy()) {
auto sty = v->getType()->getScalarType();
auto vty = llvm::dyn_cast<llvm::VectorType>(v->getType());
auto sty = vty->getScalarType();
auto vsq = builder->CreateFMul(v, v);
auto vsum = builder->CreateFAddReduce(llvm::ConstantFP::get(sty, 0), vsq);
res = builder->CreateIntrinsic(llvm::Intrinsic::sqrt, sty, vsum);
res = builder->CreateVectorSplat(vty->getElementCount(), res);
} else {
res = builder->CreateUnaryIntrinsic(llvm::Intrinsic::sqrt, v);
}
@@ -727,11 +737,11 @@ public:
//endregion
//region 3.42.7 Constant-creation instructions
case Op::OpConstantTrue: {
constants[rid] = std::make_shared<Constant>(uint32_t(1));
constants[rid] = std::make_shared<Constant>(true);
break;
}
case Op::OpConstantFalse:
constants[rid] = std::make_shared<Constant>(uint32_t(0));
constants[rid] = std::make_shared<Constant>(false);
break;
case Op::OpConstant: {
auto &type = types[rty];
@@ -819,7 +829,7 @@ public:
break;
}
case Op::OpStore: {
builder->CreateStore(cur_function->values[OP_WORD(1)], cur_function->values[OP_WORD(0)]);
builder->CreateStore(OP_VALUE(1), OP_VALUE(0));
break;
}
case Op::OpAccessChain: {
@@ -893,13 +903,25 @@ public:
// region 3.42.12 Composite instructions
case Op::OpVectorShuffle: {
std::vector<int> mask(OP_BYTES(4), OP_BYTES(insn->num_operands));
auto value = builder->CreateShuffleVector(
cur_function->values[OP_WORD(2)],
cur_function->values[OP_WORD(3)],
mask,
value_names[rid]
);
put_value(rid, value);
// We'd ordnarily use a shufflevector insn, but the types may not be the same
// So, we bodge it.
auto rty_llvm = llvm::dyn_cast<llvm::VectorType>(types[rty]->get_llvm_type());
llvm::Value* result = llvm::ConstantVector::getSplat(rty_llvm->getElementCount(), llvm::ConstantFP::get(rty_llvm->getElementType(), 0));
auto v1 = OP_VALUE(2);
auto v2 = OP_VALUE(3);
auto v1_len = llvm::dyn_cast<llvm::VectorType>(v1->getType())->getElementCount().getFixedValue();
for (int i = 4; i < insn->num_operands; i++) {
auto idx = OP_WORD(i);
auto didx = idx - 4;
auto el = idx > v1_len
? builder->CreateExtractElement(v1, idx)
: builder->CreateExtractElement(v2, idx-v1_len);
builder->CreateInsertElement(result, el, didx);
}
put_value(rid, result);
break;
}
case Op::OpCompositeConstruct: {