Turns out that when you compile with a debug version of LLVM, a lot of errors surface
This commit is contained in:
@@ -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: {
|
||||
|
||||
Reference in New Issue
Block a user