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