Convert validation to use libspriv::Instruction where possible. (#1663)
For the instructions which execute after the IdPass check we can provide
the Instruction instead of the spv_parsed_instruction_t. This
Instruction class provides a bit more context (like the source line)
that is not available from spv_parsed_instruction_t.
diff --git a/source/val/instruction.h b/source/val/instruction.h
index c47e6ba..72881d9 100644
--- a/source/val/instruction.h
+++ b/source/val/instruction.h
@@ -67,6 +67,11 @@
/// The words used to define the Instruction
const std::vector<uint32_t>& words() const { return words_; }
+ /// Returns the operand at |idx|.
+ const spv_parsed_operand_t& operand(size_t idx) const {
+ return operands_[idx];
+ }
+
/// The operands of the Instruction
const std::vector<spv_parsed_operand_t>& operands() const {
return operands_;
@@ -75,13 +80,18 @@
/// Provides direct access to the stored C instruction object.
const spv_parsed_instruction_t& c_inst() const { return inst_; }
+ /// Provides direct access to instructions spv_ext_inst_type_t object.
+ const spv_ext_inst_type_t& ext_inst_type() const {
+ return inst_.ext_inst_type;
+ }
+
// Casts the words belonging to the operand under |index| to |T| and returns.
template <typename T>
T GetOperandAs(size_t index) const {
- const spv_parsed_operand_t& operand = operands_.at(index);
- assert(operand.num_words * 4 >= sizeof(T));
- assert(operand.offset + operand.num_words <= inst_.num_words);
- return *reinterpret_cast<const T*>(&words_[operand.offset]);
+ const spv_parsed_operand_t& o = operands_.at(index);
+ assert(o.num_words * 4 >= sizeof(T));
+ assert(o.offset + o.num_words <= inst_.num_words);
+ return *reinterpret_cast<const T*>(&words_[o.offset]);
}
int InstructionPosition() const { return instruction_position_; }
diff --git a/source/val/validation_state.cpp b/source/val/validation_state.cpp
index afcc786..6907e59 100644
--- a/source/val/validation_state.cpp
+++ b/source/val/validation_state.cpp
@@ -487,20 +487,20 @@
void ValidationState_t::setIdBound(const uint32_t bound) { id_bound_ = bound; }
-bool ValidationState_t::RegisterUniqueTypeDeclaration(
- const spv_parsed_instruction_t& inst) {
+bool ValidationState_t::RegisterUniqueTypeDeclaration(const Instruction* inst) {
std::vector<uint32_t> key;
- key.push_back(static_cast<uint32_t>(inst.opcode));
- for (int index = 0; index < inst.num_operands; ++index) {
- const spv_parsed_operand_t& operand = inst.operands[index];
+ key.push_back(static_cast<uint32_t>(inst->opcode()));
+ for (size_t index = 0; index < inst->operands().size(); ++index) {
+ const spv_parsed_operand_t& operand = inst->operand(index);
if (operand.type == SPV_OPERAND_TYPE_RESULT_ID) continue;
const int words_begin = operand.offset;
const int words_end = words_begin + operand.num_words;
- assert(words_end <= static_cast<int>(inst.num_words));
+ assert(words_end <= static_cast<int>(inst->words().size()));
- key.insert(key.end(), inst.words + words_begin, inst.words + words_end);
+ key.insert(key.end(), inst->words().begin() + words_begin,
+ inst->words().begin() + words_end);
}
return unique_type_declarations_.insert(std::move(key)).second;
@@ -784,12 +784,9 @@
return true;
}
-uint32_t ValidationState_t::GetOperandTypeId(
- const spv_parsed_instruction_t* inst, size_t operand_index) const {
- assert(operand_index < inst->num_operands);
- const spv_parsed_operand_t& operand = inst->operands[operand_index];
- assert(operand.num_words == 1);
- return GetTypeId(inst->words[operand.offset]);
+uint32_t ValidationState_t::GetOperandTypeId(const Instruction* inst,
+ size_t operand_index) const {
+ return GetTypeId(inst->GetOperandAs<uint32_t>(operand_index));
}
bool ValidationState_t::GetConstantValUint64(uint32_t id, uint64_t* val) const {
diff --git a/source/val/validation_state.h b/source/val/validation_state.h
index 463cb23..d1b5281 100644
--- a/source/val/validation_state.h
+++ b/source/val/validation_state.h
@@ -400,7 +400,7 @@
/// Adds the instruction data to unique_type_declarations_.
/// Returns false if an identical type declaration already exists.
- bool RegisterUniqueTypeDeclaration(const spv_parsed_instruction_t& inst);
+ bool RegisterUniqueTypeDeclaration(const Instruction* inst);
// Returns type_id of the scalar component of |id|.
// |id| can be either
@@ -466,7 +466,7 @@
// Returns type_id for given id operand if it has a type or zero otherwise.
// |operand_index| is expected to be pointing towards an operand which is an
// id.
- uint32_t GetOperandTypeId(const spv_parsed_instruction_t* inst,
+ uint32_t GetOperandTypeId(const Instruction* inst,
size_t operand_index) const;
// Provides information on pointer type. Returns false iff not pointer type.
diff --git a/source/validate.cpp b/source/validate.cpp
index 76a81df..64321e6 100644
--- a/source/validate.cpp
+++ b/source/validate.cpp
@@ -174,24 +174,24 @@
const Instruction* instruction = &(_.ordered_instructions().back());
- if (auto error = DataRulesPass(_, inst)) return error;
- if (auto error = ModuleLayoutPass(_, inst)) return error;
+ if (auto error = DataRulesPass(_, instruction)) return error;
+ if (auto error = ModuleLayoutPass(_, instruction)) return error;
if (auto error = CfgPass(_, instruction)) return error;
- if (auto error = InstructionPass(_, inst)) return error;
- if (auto error = TypeUniquePass(_, inst)) return error;
- if (auto error = ArithmeticsPass(_, inst)) return error;
- if (auto error = CompositesPass(_, inst)) return error;
- if (auto error = ConversionPass(_, inst)) return error;
- if (auto error = DerivativesPass(_, inst)) return error;
- if (auto error = LogicalsPass(_, inst)) return error;
- if (auto error = BitwisePass(_, inst)) return error;
- if (auto error = ExtInstPass(_, inst)) return error;
- if (auto error = ImagePass(_, inst)) return error;
- if (auto error = AtomicsPass(_, inst)) return error;
- if (auto error = BarriersPass(_, inst)) return error;
- if (auto error = PrimitivesPass(_, inst)) return error;
- if (auto error = LiteralsPass(_, inst)) return error;
- if (auto error = NonUniformPass(_, inst)) return error;
+ if (auto error = InstructionPass(_, instruction)) return error;
+ if (auto error = TypeUniquePass(_, instruction)) return error;
+ if (auto error = ArithmeticsPass(_, instruction)) return error;
+ if (auto error = CompositesPass(_, instruction)) return error;
+ if (auto error = ConversionPass(_, instruction)) return error;
+ if (auto error = DerivativesPass(_, instruction)) return error;
+ if (auto error = LogicalsPass(_, instruction)) return error;
+ if (auto error = BitwisePass(_, instruction)) return error;
+ if (auto error = ExtInstPass(_, instruction)) return error;
+ if (auto error = ImagePass(_, instruction)) return error;
+ if (auto error = AtomicsPass(_, instruction)) return error;
+ if (auto error = BarriersPass(_, instruction)) return error;
+ if (auto error = PrimitivesPass(_, instruction)) return error;
+ if (auto error = LiteralsPass(_, instruction)) return error;
+ if (auto error = NonUniformPass(_, instruction)) return error;
return SPV_SUCCESS;
}
diff --git a/source/validate.h b/source/validate.h
index 5d84629..845ffa4 100644
--- a/source/validate.h
+++ b/source/validate.h
@@ -106,8 +106,7 @@
/// Performs logical layout validation as described in section 2.4 of the SPIR-V
/// spec.
-spv_result_t ModuleLayoutPass(ValidationState_t& _,
- const spv_parsed_instruction_t* inst);
+spv_result_t ModuleLayoutPass(ValidationState_t& _, const Instruction* inst);
/// Performs Control Flow Graph validation of a module
spv_result_t CfgPass(ValidationState_t& _, const Instruction* inst);
@@ -118,12 +117,10 @@
/// Performs validation of the Data Rules subsection of 2.16.1 Universal
/// Validation Rules.
/// TODO(ehsann): add more comments here as more validation code is added.
-spv_result_t DataRulesPass(ValidationState_t& _,
- const spv_parsed_instruction_t* inst);
+spv_result_t DataRulesPass(ValidationState_t& _, const Instruction* inst);
/// Performs instruction validation.
-spv_result_t InstructionPass(ValidationState_t& _,
- const spv_parsed_instruction_t* inst);
+spv_result_t InstructionPass(ValidationState_t& _, const Instruction* inst);
/// Performs decoration validation.
spv_result_t ValidateDecorations(ValidationState_t& _);
@@ -134,56 +131,43 @@
/// Validates that type declarations are unique, unless multiple declarations
/// of the same data type are allowed by the specification.
/// (see section 2.8 Types and Variables)
-spv_result_t TypeUniquePass(ValidationState_t& _,
- const spv_parsed_instruction_t* inst);
+spv_result_t TypeUniquePass(ValidationState_t& _, const Instruction* inst);
/// Validates correctness of arithmetic instructions.
-spv_result_t ArithmeticsPass(ValidationState_t& _,
- const spv_parsed_instruction_t* inst);
+spv_result_t ArithmeticsPass(ValidationState_t& _, const Instruction* inst);
/// Validates correctness of composite instructions.
-spv_result_t CompositesPass(ValidationState_t& _,
- const spv_parsed_instruction_t* inst);
+spv_result_t CompositesPass(ValidationState_t& _, const Instruction* inst);
/// Validates correctness of conversion instructions.
-spv_result_t ConversionPass(ValidationState_t& _,
- const spv_parsed_instruction_t* inst);
+spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst);
/// Validates correctness of derivative instructions.
-spv_result_t DerivativesPass(ValidationState_t& _,
- const spv_parsed_instruction_t* inst);
+spv_result_t DerivativesPass(ValidationState_t& _, const Instruction* inst);
/// Validates correctness of logical instructions.
-spv_result_t LogicalsPass(ValidationState_t& _,
- const spv_parsed_instruction_t* inst);
+spv_result_t LogicalsPass(ValidationState_t& _, const Instruction* inst);
/// Validates correctness of bitwise instructions.
-spv_result_t BitwisePass(ValidationState_t& _,
- const spv_parsed_instruction_t* inst);
+spv_result_t BitwisePass(ValidationState_t& _, const Instruction* inst);
/// Validates correctness of image instructions.
-spv_result_t ImagePass(ValidationState_t& _,
- const spv_parsed_instruction_t* inst);
+spv_result_t ImagePass(ValidationState_t& _, const Instruction* inst);
/// Validates correctness of atomic instructions.
-spv_result_t AtomicsPass(ValidationState_t& _,
- const spv_parsed_instruction_t* inst);
+spv_result_t AtomicsPass(ValidationState_t& _, const Instruction* inst);
/// Validates correctness of barrier instructions.
-spv_result_t BarriersPass(ValidationState_t& _,
- const spv_parsed_instruction_t* inst);
+spv_result_t BarriersPass(ValidationState_t& _, const Instruction* inst);
/// Validates correctness of literal numbers.
-spv_result_t LiteralsPass(ValidationState_t& _,
- const spv_parsed_instruction_t* inst);
+spv_result_t LiteralsPass(ValidationState_t& _, const Instruction* inst);
/// Validates correctness of ExtInst instructions.
-spv_result_t ExtInstPass(ValidationState_t& _,
- const spv_parsed_instruction_t* inst);
+spv_result_t ExtInstPass(ValidationState_t& _, const Instruction* inst);
/// Validates correctness of non-uniform group instructions.
-spv_result_t NonUniformPass(ValidationState_t& _,
- const spv_parsed_instruction_t* inst);
+spv_result_t NonUniformPass(ValidationState_t& _, const Instruction* inst);
// Validates that capability declarations use operands allowed in the current
// context.
@@ -191,8 +175,7 @@
const spv_parsed_instruction_t* inst);
/// Validates correctness of primitive instructions.
-spv_result_t PrimitivesPass(ValidationState_t& _,
- const spv_parsed_instruction_t* inst);
+spv_result_t PrimitivesPass(ValidationState_t& _, const Instruction* inst);
/// @brief Validate the ID usage of the instruction stream
///
diff --git a/source/validate_arithmetics.cpp b/source/validate_arithmetics.cpp
index 3460cde..d40c234 100644
--- a/source/validate_arithmetics.cpp
+++ b/source/validate_arithmetics.cpp
@@ -23,33 +23,11 @@
namespace spvtools {
namespace val {
-namespace {
-
-// Returns operand word for given instruction and operand index.
-// The operand is expected to only have one word.
-inline uint32_t GetOperandWord(const spv_parsed_instruction_t* inst,
- size_t operand_index) {
- assert(operand_index < inst->num_operands);
- const spv_parsed_operand_t& operand = inst->operands[operand_index];
- assert(operand.num_words == 1);
- return inst->words[operand.offset];
-}
-
-// Returns the type id of instruction operand at |operand_index|.
-// The operand is expected to be an id.
-inline uint32_t GetOperandTypeId(ValidationState_t& _,
- const spv_parsed_instruction_t* inst,
- size_t operand_index) {
- return _.GetTypeId(GetOperandWord(inst, operand_index));
-}
-
-} // namespace
// Validates correctness of arithmetic instructions.
-spv_result_t ArithmeticsPass(ValidationState_t& _,
- const spv_parsed_instruction_t* inst) {
- const SpvOp opcode = static_cast<SpvOp>(inst->opcode);
- const uint32_t result_type = inst->type_id;
+spv_result_t ArithmeticsPass(ValidationState_t& _, const Instruction* inst) {
+ const SpvOp opcode = inst->opcode();
+ const uint32_t result_type = inst->type_id();
switch (opcode) {
case SpvOpFAdd:
@@ -65,9 +43,9 @@
<< "Expected floating scalar or vector type as Result Type: "
<< spvOpcodeString(opcode);
- for (size_t operand_index = 2; operand_index < inst->num_operands;
+ for (size_t operand_index = 2; operand_index < inst->operands().size();
++operand_index) {
- if (GetOperandTypeId(_, inst, operand_index) != result_type)
+ if (_.GetOperandTypeId(inst, operand_index) != result_type)
return _.diag(SPV_ERROR_INVALID_DATA)
<< "Expected arithmetic operands to be of Result Type: "
<< spvOpcodeString(opcode) << " operand index "
@@ -84,9 +62,9 @@
<< "Expected unsigned int scalar or vector type as Result Type: "
<< spvOpcodeString(opcode);
- for (size_t operand_index = 2; operand_index < inst->num_operands;
+ for (size_t operand_index = 2; operand_index < inst->operands().size();
++operand_index) {
- if (GetOperandTypeId(_, inst, operand_index) != result_type)
+ if (_.GetOperandTypeId(inst, operand_index) != result_type)
return _.diag(SPV_ERROR_INVALID_DATA)
<< "Expected arithmetic operands to be of Result Type: "
<< spvOpcodeString(opcode) << " operand index "
@@ -110,9 +88,9 @@
const uint32_t dimension = _.GetDimension(result_type);
const uint32_t bit_width = _.GetBitWidth(result_type);
- for (size_t operand_index = 2; operand_index < inst->num_operands;
+ for (size_t operand_index = 2; operand_index < inst->operands().size();
++operand_index) {
- const uint32_t type_id = GetOperandTypeId(_, inst, operand_index);
+ const uint32_t type_id = _.GetOperandTypeId(inst, operand_index);
if (!type_id ||
(!_.IsIntScalarType(type_id) && !_.IsIntVectorType(type_id)))
return _.diag(SPV_ERROR_INVALID_DATA)
@@ -143,9 +121,9 @@
uint32_t first_vector_num_components = 0;
- for (size_t operand_index = 2; operand_index < inst->num_operands;
+ for (size_t operand_index = 2; operand_index < inst->operands().size();
++operand_index) {
- const uint32_t type_id = GetOperandTypeId(_, inst, operand_index);
+ const uint32_t type_id = _.GetOperandTypeId(inst, operand_index);
if (!type_id || !_.IsFloatVectorType(type_id))
return _.diag(SPV_ERROR_INVALID_DATA)
@@ -178,7 +156,7 @@
<< "Expected float vector type as Result Type: "
<< spvOpcodeString(opcode);
- const uint32_t vector_type_id = GetOperandTypeId(_, inst, 2);
+ const uint32_t vector_type_id = _.GetOperandTypeId(inst, 2);
if (result_type != vector_type_id)
return _.diag(SPV_ERROR_INVALID_DATA)
<< "Expected vector operand type to be equal to Result Type: "
@@ -186,7 +164,7 @@
const uint32_t component_type = _.GetComponentType(vector_type_id);
- const uint32_t scalar_type_id = GetOperandTypeId(_, inst, 3);
+ const uint32_t scalar_type_id = _.GetOperandTypeId(inst, 3);
if (component_type != scalar_type_id)
return _.diag(SPV_ERROR_INVALID_DATA)
<< "Expected scalar operand type to be equal to the component "
@@ -201,7 +179,7 @@
<< "Expected float matrix type as Result Type: "
<< spvOpcodeString(opcode);
- const uint32_t matrix_type_id = GetOperandTypeId(_, inst, 2);
+ const uint32_t matrix_type_id = _.GetOperandTypeId(inst, 2);
if (result_type != matrix_type_id)
return _.diag(SPV_ERROR_INVALID_DATA)
<< "Expected matrix operand type to be equal to Result Type: "
@@ -209,7 +187,7 @@
const uint32_t component_type = _.GetComponentType(matrix_type_id);
- const uint32_t scalar_type_id = GetOperandTypeId(_, inst, 3);
+ const uint32_t scalar_type_id = _.GetOperandTypeId(inst, 3);
if (component_type != scalar_type_id)
return _.diag(SPV_ERROR_INVALID_DATA)
<< "Expected scalar operand type to be equal to the component "
@@ -219,8 +197,8 @@
}
case SpvOpVectorTimesMatrix: {
- const uint32_t vector_type_id = GetOperandTypeId(_, inst, 2);
- const uint32_t matrix_type_id = GetOperandTypeId(_, inst, 3);
+ const uint32_t vector_type_id = _.GetOperandTypeId(inst, 2);
+ const uint32_t matrix_type_id = _.GetOperandTypeId(inst, 3);
if (!_.IsFloatVectorType(result_type))
return _.diag(SPV_ERROR_INVALID_DATA)
@@ -269,8 +247,8 @@
}
case SpvOpMatrixTimesVector: {
- const uint32_t matrix_type_id = GetOperandTypeId(_, inst, 2);
- const uint32_t vector_type_id = GetOperandTypeId(_, inst, 3);
+ const uint32_t matrix_type_id = _.GetOperandTypeId(inst, 2);
+ const uint32_t vector_type_id = _.GetOperandTypeId(inst, 3);
if (!_.IsFloatVectorType(result_type))
return _.diag(SPV_ERROR_INVALID_DATA)
@@ -313,8 +291,8 @@
}
case SpvOpMatrixTimesMatrix: {
- const uint32_t left_type_id = GetOperandTypeId(_, inst, 2);
- const uint32_t right_type_id = GetOperandTypeId(_, inst, 3);
+ const uint32_t left_type_id = _.GetOperandTypeId(inst, 2);
+ const uint32_t right_type_id = _.GetOperandTypeId(inst, 3);
uint32_t res_num_rows = 0;
uint32_t res_num_cols = 0;
@@ -379,8 +357,8 @@
}
case SpvOpOuterProduct: {
- const uint32_t left_type_id = GetOperandTypeId(_, inst, 2);
- const uint32_t right_type_id = GetOperandTypeId(_, inst, 3);
+ const uint32_t left_type_id = _.GetOperandTypeId(inst, 2);
+ const uint32_t right_type_id = _.GetOperandTypeId(inst, 3);
uint32_t res_num_rows = 0;
uint32_t res_num_cols = 0;
@@ -451,8 +429,8 @@
<< "Expected Result Type struct member types to be identical: "
<< spvOpcodeString(opcode);
- const uint32_t left_type_id = GetOperandTypeId(_, inst, 2);
- const uint32_t right_type_id = GetOperandTypeId(_, inst, 3);
+ const uint32_t left_type_id = _.GetOperandTypeId(inst, 2);
+ const uint32_t right_type_id = _.GetOperandTypeId(inst, 3);
if (left_type_id != result_types[0] || right_type_id != result_types[0])
return _.diag(SPV_ERROR_INVALID_DATA)
diff --git a/source/validate_atomics.cpp b/source/validate_atomics.cpp
index b4a196c..f4eaba4 100644
--- a/source/validate_atomics.cpp
+++ b/source/validate_atomics.cpp
@@ -27,10 +27,9 @@
namespace val {
// Validates Memory Scope operand.
-spv_result_t ValidateMemoryScope(ValidationState_t& _,
- const spv_parsed_instruction_t* inst,
+spv_result_t ValidateMemoryScope(ValidationState_t& _, const Instruction* inst,
uint32_t id) {
- const SpvOp opcode = static_cast<SpvOp>(inst->opcode);
+ const SpvOp opcode = inst->opcode();
bool is_int32 = false, is_const_int32 = false;
uint32_t value = 0;
std::tie(is_int32, is_const_int32, value) = _.EvalInt32IfConst(id);
@@ -64,13 +63,12 @@
// Validates a Memory Semantics operand.
spv_result_t ValidateMemorySemantics(ValidationState_t& _,
- const spv_parsed_instruction_t* inst,
+ const Instruction* inst,
uint32_t operand_index) {
- const SpvOp opcode = static_cast<SpvOp>(inst->opcode);
+ const SpvOp opcode = inst->opcode();
bool is_int32 = false, is_const_int32 = false;
uint32_t flags = 0;
- const uint32_t memory_semantics_id =
- inst->words[inst->operands[operand_index].offset];
+ auto memory_semantics_id = inst->GetOperandAs<const uint32_t>(operand_index);
std::tie(is_int32, is_const_int32, flags) =
_.EvalInt32IfConst(memory_semantics_id);
@@ -154,10 +152,9 @@
}
// Validates correctness of atomic instructions.
-spv_result_t AtomicsPass(ValidationState_t& _,
- const spv_parsed_instruction_t* inst) {
- const SpvOp opcode = static_cast<SpvOp>(inst->opcode);
- const uint32_t result_type = inst->type_id;
+spv_result_t AtomicsPass(ValidationState_t& _, const Instruction* inst) {
+ const SpvOp opcode = inst->opcode();
+ const uint32_t result_type = inst->type_id();
switch (opcode) {
case SpvOpAtomicLoad:
@@ -262,8 +259,7 @@
}
}
- const uint32_t memory_scope =
- inst->words[inst->operands[operand_index++].offset];
+ auto memory_scope = inst->GetOperandAs<const uint32_t>(operand_index++);
if (auto error = ValidateMemoryScope(_, inst, memory_scope)) {
return error;
}
diff --git a/source/validate_barriers.cpp b/source/validate_barriers.cpp
index 8985ada..0a49407 100644
--- a/source/validate_barriers.cpp
+++ b/source/validate_barriers.cpp
@@ -30,9 +30,8 @@
// Validates Execution Scope operand.
spv_result_t ValidateExecutionScope(ValidationState_t& _,
- const spv_parsed_instruction_t* inst,
- uint32_t id) {
- const SpvOp opcode = static_cast<SpvOp>(inst->opcode);
+ const Instruction* inst, uint32_t id) {
+ const SpvOp opcode = inst->opcode();
bool is_int32 = false, is_const_int32 = false;
uint32_t value = 0;
std::tie(is_int32, is_const_int32, value) = _.EvalInt32IfConst(id);
@@ -82,10 +81,9 @@
}
// Validates Memory Scope operand.
-spv_result_t ValidateMemoryScope(ValidationState_t& _,
- const spv_parsed_instruction_t* inst,
+spv_result_t ValidateMemoryScope(ValidationState_t& _, const Instruction* inst,
uint32_t id) {
- const SpvOp opcode = static_cast<SpvOp>(inst->opcode);
+ const SpvOp opcode = inst->opcode();
bool is_int32 = false, is_const_int32 = false;
uint32_t value = 0;
std::tie(is_int32, is_const_int32, value) = _.EvalInt32IfConst(id);
@@ -124,9 +122,8 @@
// Validates Memory Semantics operand.
spv_result_t ValidateMemorySemantics(ValidationState_t& _,
- const spv_parsed_instruction_t* inst,
- uint32_t id) {
- const SpvOp opcode = static_cast<SpvOp>(inst->opcode);
+ const Instruction* inst, uint32_t id) {
+ const SpvOp opcode = inst->opcode();
bool is_int32 = false, is_const_int32 = false;
uint32_t value = 0;
std::tie(is_int32, is_const_int32, value) = _.EvalInt32IfConst(id);
@@ -193,10 +190,9 @@
} // namespace
// Validates correctness of barrier instructions.
-spv_result_t BarriersPass(ValidationState_t& _,
- const spv_parsed_instruction_t* inst) {
- const SpvOp opcode = static_cast<SpvOp>(inst->opcode);
- const uint32_t result_type = inst->type_id;
+spv_result_t BarriersPass(ValidationState_t& _, const Instruction* inst) {
+ const SpvOp opcode = inst->opcode();
+ const uint32_t result_type = inst->type_id();
switch (opcode) {
case SpvOpControlBarrier: {
@@ -219,9 +215,9 @@
});
}
- const uint32_t execution_scope = inst->words[1];
- const uint32_t memory_scope = inst->words[2];
- const uint32_t memory_semantics = inst->words[3];
+ const uint32_t execution_scope = inst->word(1);
+ const uint32_t memory_scope = inst->word(2);
+ const uint32_t memory_semantics = inst->word(3);
if (auto error = ValidateExecutionScope(_, inst, execution_scope)) {
return error;
@@ -238,8 +234,8 @@
}
case SpvOpMemoryBarrier: {
- const uint32_t memory_scope = inst->words[1];
- const uint32_t memory_semantics = inst->words[2];
+ const uint32_t memory_scope = inst->word(1);
+ const uint32_t memory_semantics = inst->word(2);
if (auto error = ValidateMemoryScope(_, inst, memory_scope)) {
return error;
@@ -276,8 +272,8 @@
<< ": expected Named Barrier to be of type OpTypeNamedBarrier";
}
- const uint32_t memory_scope = inst->words[2];
- const uint32_t memory_semantics = inst->words[3];
+ const uint32_t memory_scope = inst->word(2);
+ const uint32_t memory_semantics = inst->word(3);
if (auto error = ValidateMemoryScope(_, inst, memory_scope)) {
return error;
diff --git a/source/validate_bitwise.cpp b/source/validate_bitwise.cpp
index cd00cd6..953fc46 100644
--- a/source/validate_bitwise.cpp
+++ b/source/validate_bitwise.cpp
@@ -23,33 +23,11 @@
namespace spvtools {
namespace val {
-namespace {
-
-// Returns operand word for given instruction and operand index.
-// The operand is expected to only have one word.
-inline uint32_t GetOperandWord(const spv_parsed_instruction_t* inst,
- size_t operand_index) {
- assert(operand_index < inst->num_operands);
- const spv_parsed_operand_t& operand = inst->operands[operand_index];
- assert(operand.num_words == 1);
- return inst->words[operand.offset];
-}
-
-// Returns the type id of instruction operand at |operand_index|.
-// The operand is expected to be an id.
-inline uint32_t GetOperandTypeId(ValidationState_t& _,
- const spv_parsed_instruction_t* inst,
- size_t operand_index) {
- return _.GetTypeId(GetOperandWord(inst, operand_index));
-}
-
-} // namespace
// Validates correctness of bitwise instructions.
-spv_result_t BitwisePass(ValidationState_t& _,
- const spv_parsed_instruction_t* inst) {
- const SpvOp opcode = static_cast<SpvOp>(inst->opcode);
- const uint32_t result_type = inst->type_id;
+spv_result_t BitwisePass(ValidationState_t& _, const Instruction* inst) {
+ const SpvOp opcode = inst->opcode();
+ const uint32_t result_type = inst->type_id();
switch (opcode) {
case SpvOpShiftRightLogical:
@@ -61,8 +39,8 @@
<< spvOpcodeString(opcode);
const uint32_t result_dimension = _.GetDimension(result_type);
- const uint32_t base_type = GetOperandTypeId(_, inst, 2);
- const uint32_t shift_type = GetOperandTypeId(_, inst, 3);
+ const uint32_t base_type = _.GetOperandTypeId(inst, 2);
+ const uint32_t shift_type = _.GetOperandTypeId(inst, 3);
if (!base_type ||
(!_.IsIntScalarType(base_type) && !_.IsIntVectorType(base_type)))
@@ -105,9 +83,9 @@
const uint32_t result_dimension = _.GetDimension(result_type);
const uint32_t result_bit_width = _.GetBitWidth(result_type);
- for (size_t operand_index = 2; operand_index < inst->num_operands;
+ for (size_t operand_index = 2; operand_index < inst->operands().size();
++operand_index) {
- const uint32_t type_id = GetOperandTypeId(_, inst, operand_index);
+ const uint32_t type_id = _.GetOperandTypeId(inst, operand_index);
if (!type_id ||
(!_.IsIntScalarType(type_id) && !_.IsIntVectorType(type_id)))
return _.diag(SPV_ERROR_INVALID_DATA)
@@ -136,10 +114,10 @@
<< "Expected int scalar or vector type as Result Type: "
<< spvOpcodeString(opcode);
- const uint32_t base_type = GetOperandTypeId(_, inst, 2);
- const uint32_t insert_type = GetOperandTypeId(_, inst, 3);
- const uint32_t offset_type = GetOperandTypeId(_, inst, 4);
- const uint32_t count_type = GetOperandTypeId(_, inst, 5);
+ const uint32_t base_type = _.GetOperandTypeId(inst, 2);
+ const uint32_t insert_type = _.GetOperandTypeId(inst, 3);
+ const uint32_t offset_type = _.GetOperandTypeId(inst, 4);
+ const uint32_t count_type = _.GetOperandTypeId(inst, 5);
if (base_type != result_type)
return _.diag(SPV_ERROR_INVALID_DATA)
@@ -170,9 +148,9 @@
<< "Expected int scalar or vector type as Result Type: "
<< spvOpcodeString(opcode);
- const uint32_t base_type = GetOperandTypeId(_, inst, 2);
- const uint32_t offset_type = GetOperandTypeId(_, inst, 3);
- const uint32_t count_type = GetOperandTypeId(_, inst, 4);
+ const uint32_t base_type = _.GetOperandTypeId(inst, 2);
+ const uint32_t offset_type = _.GetOperandTypeId(inst, 3);
+ const uint32_t count_type = _.GetOperandTypeId(inst, 4);
if (base_type != result_type)
return _.diag(SPV_ERROR_INVALID_DATA)
@@ -197,7 +175,7 @@
<< "Expected int scalar or vector type as Result Type: "
<< spvOpcodeString(opcode);
- const uint32_t base_type = GetOperandTypeId(_, inst, 2);
+ const uint32_t base_type = _.GetOperandTypeId(inst, 2);
if (base_type != result_type)
return _.diag(SPV_ERROR_INVALID_DATA)
@@ -212,7 +190,7 @@
<< "Expected int scalar or vector type as Result Type: "
<< spvOpcodeString(opcode);
- const uint32_t base_type = GetOperandTypeId(_, inst, 2);
+ const uint32_t base_type = _.GetOperandTypeId(inst, 2);
if (!base_type ||
(!_.IsIntScalarType(base_type) && !_.IsIntVectorType(base_type)))
return _.diag(SPV_ERROR_INVALID_DATA)
diff --git a/source/validate_cfg.cpp b/source/validate_cfg.cpp
index e09063a..ab3cd95 100644
--- a/source/validate_cfg.cpp
+++ b/source/validate_cfg.cpp
@@ -549,7 +549,7 @@
}
spv_result_t CfgPass(ValidationState_t& _, const Instruction* inst) {
- SpvOp opcode = static_cast<SpvOp>(inst->opcode());
+ SpvOp opcode = inst->opcode();
switch (opcode) {
case SpvOpLabel:
if (auto error = _.current_function().RegisterBlock(inst->id()))
diff --git a/source/validate_composites.cpp b/source/validate_composites.cpp
index f4ba74e..ce0a2df 100644
--- a/source/validate_composites.cpp
+++ b/source/validate_composites.cpp
@@ -32,12 +32,12 @@
// fails (encountered non-composite, out of bounds, nesting too deep).
// Returns the type of Composite operand if the instruction has no indices.
spv_result_t GetExtractInsertValueType(ValidationState_t& _,
- const spv_parsed_instruction_t& inst,
+ const Instruction* inst,
uint32_t* member_type) {
- const SpvOp opcode = static_cast<SpvOp>(inst.opcode);
+ const SpvOp opcode = inst->opcode();
assert(opcode == SpvOpCompositeExtract || opcode == SpvOpCompositeInsert);
uint32_t word_index = opcode == SpvOpCompositeExtract ? 4 : 5;
- const uint32_t num_words = static_cast<uint32_t>(inst.num_words);
+ const uint32_t num_words = static_cast<uint32_t>(inst->words().size());
const uint32_t composite_id_index = word_index - 1;
const uint32_t num_indices = num_words - word_index;
@@ -49,7 +49,7 @@
<< ". Found " << num_indices << " indexes.";
}
- *member_type = _.GetTypeId(inst.words[composite_id_index]);
+ *member_type = _.GetTypeId(inst->word(composite_id_index));
if (*member_type == 0) {
return _.diag(SPV_ERROR_INVALID_DATA)
<< spvOpcodeString(opcode)
@@ -57,7 +57,7 @@
}
for (; word_index < num_words; ++word_index) {
- const uint32_t component_index = inst.words[word_index];
+ const uint32_t component_index = inst->word(word_index);
const Instruction* const type_inst = _.FindDef(*member_type);
assert(type_inst);
switch (type_inst->opcode()) {
@@ -136,11 +136,10 @@
} // anonymous namespace
// Validates correctness of composite instructions.
-spv_result_t CompositesPass(ValidationState_t& _,
- const spv_parsed_instruction_t* inst) {
- const SpvOp opcode = static_cast<SpvOp>(inst->opcode);
- const uint32_t result_type = inst->type_id;
- const uint32_t num_operands = static_cast<uint32_t>(inst->num_operands);
+spv_result_t CompositesPass(ValidationState_t& _, const Instruction* inst) {
+ const SpvOp opcode = inst->opcode();
+ const uint32_t result_type = inst->type_id();
+ const uint32_t num_operands = static_cast<uint32_t>(inst->operands().size());
switch (opcode) {
case SpvOpVectorExtractDynamic: {
@@ -367,7 +366,7 @@
case SpvOpCompositeExtract: {
uint32_t member_type = 0;
if (spv_result_t error =
- GetExtractInsertValueType(_, *inst, &member_type)) {
+ GetExtractInsertValueType(_, inst, &member_type)) {
return error;
}
@@ -396,7 +395,7 @@
uint32_t member_type = 0;
if (spv_result_t error =
- GetExtractInsertValueType(_, *inst, &member_type)) {
+ GetExtractInsertValueType(_, inst, &member_type)) {
return error;
}
diff --git a/source/validate_conversion.cpp b/source/validate_conversion.cpp
index a4e75ed..ff2b774 100644
--- a/source/validate_conversion.cpp
+++ b/source/validate_conversion.cpp
@@ -25,10 +25,9 @@
namespace val {
// Validates correctness of conversion instructions.
-spv_result_t ConversionPass(ValidationState_t& _,
- const spv_parsed_instruction_t* inst) {
- const SpvOp opcode = static_cast<SpvOp>(inst->opcode);
- const uint32_t result_type = inst->type_id;
+spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) {
+ const SpvOp opcode = inst->opcode();
+ const uint32_t result_type = inst->type_id();
switch (opcode) {
case SpvOpConvertFToU: {
@@ -321,7 +320,7 @@
<< "Expected Result Type to be a pointer: "
<< spvOpcodeString(opcode);
- const uint32_t target_storage_class = inst->words[4];
+ const uint32_t target_storage_class = inst->word(4);
if (result_storage_class != target_storage_class)
return _.diag(SPV_ERROR_INVALID_DATA)
<< "Expected Result Type to be of target storage class: "
diff --git a/source/validate_datarules.cpp b/source/validate_datarules.cpp
index 59dba8b..7c78318 100644
--- a/source/validate_datarules.cpp
+++ b/source/validate_datarules.cpp
@@ -34,9 +34,9 @@
// Vector types can only be parameterized as having 2, 3, or 4 components.
// If the Vector16 capability is added, 8 and 16 components are also allowed.
spv_result_t ValidateVecNumComponents(ValidationState_t& _,
- const spv_parsed_instruction_t* inst) {
+ const Instruction* inst) {
// Operand 2 specifies the number of components in the vector.
- const uint32_t num_components = inst->words[inst->operands[2].offset];
+ auto num_components = inst->GetOperandAs<const uint32_t>(2);
if (num_components == 2 || num_components == 3 || num_components == 4) {
return SPV_SUCCESS;
}
@@ -46,12 +46,12 @@
}
return _.diag(SPV_ERROR_INVALID_DATA)
<< "Having " << num_components << " components for "
- << spvOpcodeString(static_cast<SpvOp>(inst->opcode))
+ << spvOpcodeString(inst->opcode())
<< " requires the Vector16 capability";
}
return _.diag(SPV_ERROR_INVALID_DATA)
<< "Illegal number of components (" << num_components << ") for "
- << spvOpcodeString(static_cast<SpvOp>(inst->opcode));
+ << spvOpcodeString(inst->opcode());
}
// Validates that the number of bits specifed for a float type is valid.
@@ -59,10 +59,9 @@
// Float16 capability allows using a 16-bit OpTypeFloat.
// Float16Buffer capability allows creation of a 16-bit OpTypeFloat.
// Float64 capability allows using a 64-bit OpTypeFloat.
-spv_result_t ValidateFloatSize(ValidationState_t& _,
- const spv_parsed_instruction_t* inst) {
+spv_result_t ValidateFloatSize(ValidationState_t& _, const Instruction* inst) {
// Operand 1 is the number of bits for this float
- const uint32_t num_bits = inst->words[inst->operands[1].offset];
+ auto num_bits = inst->GetOperandAs<const uint32_t>(1);
if (num_bits == 32) {
return SPV_SUCCESS;
}
@@ -91,10 +90,9 @@
// Scalar integer types can be parameterized only with 32-bits.
// Int8, Int16, and Int64 capabilities allow using 8-bit, 16-bit, and 64-bit
// integers, respectively.
-spv_result_t ValidateIntSize(ValidationState_t& _,
- const spv_parsed_instruction_t* inst) {
+spv_result_t ValidateIntSize(ValidationState_t& _, const Instruction* inst) {
// Operand 1 is the number of bits for this integer.
- const uint32_t num_bits = inst->words[inst->operands[1].offset];
+ auto num_bits = inst->GetOperandAs<const uint32_t>(1);
if (num_bits == 32) {
return SPV_SUCCESS;
}
@@ -127,10 +125,10 @@
// Validates that the matrix is parameterized with floating-point types.
spv_result_t ValidateMatrixColumnType(ValidationState_t& _,
- const spv_parsed_instruction_t* inst) {
+ const Instruction* inst) {
// Find the component type of matrix columns (must be vector).
// Operand 1 is the <id> of the type specified for matrix columns.
- auto type_id = inst->words[inst->operands[1].offset];
+ auto type_id = inst->GetOperandAs<const uint32_t>(1);
auto col_type_instr = _.FindDef(type_id);
if (col_type_instr->opcode() != SpvOpTypeVector) {
return _.diag(SPV_ERROR_INVALID_ID)
@@ -152,9 +150,9 @@
// Validates that the matrix has 2,3, or 4 columns.
spv_result_t ValidateMatrixNumCols(ValidationState_t& _,
- const spv_parsed_instruction_t* inst) {
+ const Instruction* inst) {
// Operand 2 is the number of columns in the matrix.
- const uint32_t num_cols = inst->words[inst->operands[2].offset];
+ auto num_cols = inst->GetOperandAs<const uint32_t>(2);
if (num_cols != 2 && num_cols != 3 && num_cols != 4) {
return _.diag(SPV_ERROR_INVALID_DATA) << "Matrix types can only be "
"parameterized as having only 2, "
@@ -165,9 +163,9 @@
// Validates that OpSpecConstant specializes to either int or float type.
spv_result_t ValidateSpecConstNumerical(ValidationState_t& _,
- const spv_parsed_instruction_t* inst) {
+ const Instruction* inst) {
// Operand 0 is the <id> of the type that we're specializing to.
- auto type_id = inst->words[inst->operands[0].offset];
+ auto type_id = inst->GetOperandAs<const uint32_t>(0);
auto type_instruction = _.FindDef(type_id);
auto type_opcode = type_instruction->opcode();
if (type_opcode != SpvOpTypeInt && type_opcode != SpvOpTypeFloat) {
@@ -180,9 +178,9 @@
// Validates that OpSpecConstantTrue and OpSpecConstantFalse specialize to bool.
spv_result_t ValidateSpecConstBoolean(ValidationState_t& _,
- const spv_parsed_instruction_t* inst) {
+ const Instruction* inst) {
// Find out the type that we're specializing to.
- auto type_instruction = _.FindDef(inst->type_id);
+ auto type_instruction = _.FindDef(inst->type_id());
if (type_instruction->opcode() != SpvOpTypeBool) {
return _.diag(SPV_ERROR_INVALID_ID) << "Specialization constant must be "
"a boolean type.";
@@ -192,21 +190,20 @@
// Records the <id> of the forward pointer to be used for validation.
spv_result_t ValidateForwardPointer(ValidationState_t& _,
- const spv_parsed_instruction_t* inst) {
+ const Instruction* inst) {
// Record the <id> (which is operand 0) to ensure it's used properly.
// OpTypeStruct can only include undefined pointers that are
// previously declared as a ForwardPointer
- return (_.RegisterForwardPointer(inst->words[inst->operands[0].offset]));
+ return (_.RegisterForwardPointer(inst->GetOperandAs<uint32_t>(0)));
}
// Validates that any undefined component of the struct is a forward pointer.
// It is valid to declare a forward pointer, and use its <id> as one of the
// components of a struct.
-spv_result_t ValidateStruct(ValidationState_t& _,
- const spv_parsed_instruction_t* inst) {
+spv_result_t ValidateStruct(ValidationState_t& _, const Instruction* inst) {
// Struct components are operands 1, 2, etc.
- for (unsigned i = 1; i < inst->num_operands; i++) {
- auto type_id = inst->words[inst->operands[i].offset];
+ for (unsigned i = 1; i < inst->operands().size(); i++) {
+ auto type_id = inst->GetOperandAs<const uint32_t>(i);
auto type_instruction = _.FindDef(type_id);
if (type_instruction == nullptr && !_.IsForwardPointer(type_id)) {
return _.diag(SPV_ERROR_INVALID_ID)
@@ -221,9 +218,8 @@
// Validates that Data Rules are followed according to the specifications.
// (Data Rules subsection of 2.16.1 Universal Validation Rules)
-spv_result_t DataRulesPass(ValidationState_t& _,
- const spv_parsed_instruction_t* inst) {
- switch (inst->opcode) {
+spv_result_t DataRulesPass(ValidationState_t& _, const Instruction* inst) {
+ switch (inst->opcode()) {
case SpvOpTypeVector: {
if (auto error = ValidateVecNumComponents(_, inst)) return error;
break;
diff --git a/source/validate_decorations.cpp b/source/validate_decorations.cpp
index 9b320a0..28a6865 100644
--- a/source/validate_decorations.cpp
+++ b/source/validate_decorations.cpp
@@ -408,7 +408,7 @@
}
// Check arrays.
if (SpvOpTypeArray == opcode) {
- const auto typeId = inst->words()[2];
+ const auto typeId = inst->word(2);
const auto arrayInst = vstate.FindDef(typeId);
if (SpvOpTypeStruct == arrayInst->opcode() &&
SPV_SUCCESS != (recursive_status = checkLayout(
@@ -549,8 +549,7 @@
return vstate.diag(SPV_ERROR_INVALID_ID)
<< "Interfaces passed to OpEntryPoint must be of type "
"OpTypeVariable. Found Op"
- << spvOpcodeString(static_cast<SpvOp>(var_instr->opcode()))
- << ".";
+ << spvOpcodeString(var_instr->opcode()) << ".";
}
const uint32_t ptr_id = var_instr->word(1);
Instruction* ptr_instr = vstate.FindDef(ptr_id);
@@ -622,19 +621,18 @@
}
if (!has_descriptor_set) continue;
- const auto& words = inst->words();
- const auto* ptrInst = vstate.FindDef(words[1]);
+ const auto* ptrInst = vstate.FindDef(inst->word(1));
assert(SpvOpTypePointer == ptrInst->opcode());
// Check for a first level array
- const auto typePtr = vstate.FindDef(ptrInst->words()[3]);
+ const auto typePtr = vstate.FindDef(ptrInst->word(3));
if (SpvOpTypeRuntimeArray != typePtr->opcode() &&
SpvOpTypeArray != typePtr->opcode()) {
continue;
}
// Check for a second level array
- const auto secondaryTypePtr = vstate.FindDef(typePtr->words()[2]);
+ const auto secondaryTypePtr = vstate.FindDef(typePtr->word(2));
if (SpvOpTypeRuntimeArray == secondaryTypePtr->opcode() ||
SpvOpTypeArray == secondaryTypePtr->opcode()) {
return vstate.diag(SPV_ERROR_INVALID_ID)
diff --git a/source/validate_derivatives.cpp b/source/validate_derivatives.cpp
index 5a794f3..df732fd 100644
--- a/source/validate_derivatives.cpp
+++ b/source/validate_derivatives.cpp
@@ -25,10 +25,9 @@
namespace val {
// Validates correctness of derivative instructions.
-spv_result_t DerivativesPass(ValidationState_t& _,
- const spv_parsed_instruction_t* inst) {
- const SpvOp opcode = static_cast<SpvOp>(inst->opcode);
- const uint32_t result_type = inst->type_id;
+spv_result_t DerivativesPass(ValidationState_t& _, const Instruction* inst) {
+ const SpvOp opcode = inst->opcode();
+ const uint32_t result_type = inst->type_id();
switch (opcode) {
case SpvOpDPdx:
diff --git a/source/validate_ext_inst.cpp b/source/validate_ext_inst.cpp
index 85e9dcf..6fb9451 100644
--- a/source/validate_ext_inst.cpp
+++ b/source/validate_ext_inst.cpp
@@ -41,18 +41,17 @@
} // anonymous namespace
// Validates correctness of ExtInst instructions.
-spv_result_t ExtInstPass(ValidationState_t& _,
- const spv_parsed_instruction_t* inst) {
- const SpvOp opcode = static_cast<SpvOp>(inst->opcode);
- const uint32_t result_type = inst->type_id;
- const uint32_t num_operands = inst->num_operands;
+spv_result_t ExtInstPass(ValidationState_t& _, const Instruction* inst) {
+ const SpvOp opcode = inst->opcode();
+ const uint32_t result_type = inst->type_id();
+ const uint32_t num_operands = static_cast<uint32_t>(inst->operands().size());
if (opcode != SpvOpExtInst) return SPV_SUCCESS;
- const uint32_t ext_inst_set = inst->words[3];
- const uint32_t ext_inst_index = inst->words[4];
+ const uint32_t ext_inst_set = inst->word(3);
+ const uint32_t ext_inst_index = inst->word(4);
const spv_ext_inst_type_t ext_inst_type =
- spv_ext_inst_type_t(inst->ext_inst_type);
+ spv_ext_inst_type_t(inst->ext_inst_type());
auto ext_inst_name = [&_, ext_inst_set, ext_inst_type, ext_inst_index]() {
spv_ext_inst_desc desc = nullptr;
@@ -1530,7 +1529,7 @@
"type of Result Type";
}
- const uint32_t n_value = inst->words[7];
+ const uint32_t n_value = inst->word(7);
if (num_components != n_value) {
return _.diag(SPV_ERROR_INVALID_DATA)
<< ext_inst_name() << ": "
@@ -1716,7 +1715,7 @@
<< "expected operand P data type to be 16-bit float scalar";
}
- const uint32_t n_value = inst->words[7];
+ const uint32_t n_value = inst->word(7);
if (num_components != n_value) {
return _.diag(SPV_ERROR_INVALID_DATA)
<< ext_inst_name() << ": "
diff --git a/source/validate_image.cpp b/source/validate_image.cpp
index e4dbe76..c7a5fca 100644
--- a/source/validate_image.cpp
+++ b/source/validate_image.cpp
@@ -199,14 +199,14 @@
// Checks ImageOperand bitfield and respective operands.
spv_result_t ValidateImageOperands(ValidationState_t& _,
- const spv_parsed_instruction_t& inst,
+ const Instruction* inst,
const ImageTypeInfo& info, uint32_t mask,
uint32_t word_index) {
static const bool kAllImageOperandsHandled = CheckAllImageOperandsHandled();
(void)kAllImageOperandsHandled;
- const SpvOp opcode = static_cast<SpvOp>(inst.opcode);
- const uint32_t num_words = inst.num_words;
+ const SpvOp opcode = inst->opcode();
+ const size_t num_words = inst->words().size();
size_t expected_num_image_operand_words = spvtools::utils::CountSetBits(mask);
if (mask & SpvImageOperandsGradMask) {
@@ -240,7 +240,7 @@
<< spvOpcodeString(opcode);
};
- const uint32_t type_id = _.GetTypeId(inst.words[word_index++]);
+ const uint32_t type_id = _.GetTypeId(inst->word(word_index++));
if (!_.IsFloatScalarType(type_id)) {
return _.diag(SPV_ERROR_INVALID_DATA)
<< "Expected Image Operand Bias to be float scalar: "
@@ -277,7 +277,7 @@
<< spvOpcodeString(opcode);
}
- const uint32_t type_id = _.GetTypeId(inst.words[word_index++]);
+ const uint32_t type_id = _.GetTypeId(inst->word(word_index++));
if (is_explicit_lod) {
if (!_.IsFloatScalarType(type_id)) {
return _.diag(SPV_ERROR_INVALID_DATA)
@@ -314,8 +314,8 @@
<< spvOpcodeString(opcode);
};
- const uint32_t dx_type_id = _.GetTypeId(inst.words[word_index++]);
- const uint32_t dy_type_id = _.GetTypeId(inst.words[word_index++]);
+ const uint32_t dx_type_id = _.GetTypeId(inst->word(word_index++));
+ const uint32_t dy_type_id = _.GetTypeId(inst->word(word_index++));
if (!_.IsFloatScalarOrVectorType(dx_type_id) ||
!_.IsFloatScalarOrVectorType(dy_type_id)) {
return _.diag(SPV_ERROR_INVALID_DATA)
@@ -355,7 +355,7 @@
<< spvOpcodeString(opcode);
}
- const uint32_t id = inst.words[word_index++];
+ const uint32_t id = inst->word(word_index++);
const uint32_t type_id = _.GetTypeId(id);
if (!_.IsIntScalarOrVectorType(type_id)) {
return _.diag(SPV_ERROR_INVALID_DATA)
@@ -386,7 +386,7 @@
<< spvOpcodeString(opcode);
}
- const uint32_t id = inst.words[word_index++];
+ const uint32_t id = inst->word(word_index++);
const uint32_t type_id = _.GetTypeId(id);
if (!_.IsIntScalarOrVectorType(type_id)) {
return _.diag(SPV_ERROR_INVALID_DATA)
@@ -421,7 +421,7 @@
<< spvOpcodeString(opcode);
}
- const uint32_t id = inst.words[word_index++];
+ const uint32_t id = inst->word(word_index++);
const uint32_t type_id = _.GetTypeId(id);
const Instruction* type_inst = _.FindDef(type_id);
assert(type_inst);
@@ -475,7 +475,7 @@
<< spvOpcodeString(opcode);
}
- const uint32_t type_id = _.GetTypeId(inst.words[word_index++]);
+ const uint32_t type_id = _.GetTypeId(inst->word(word_index++));
if (!_.IsIntScalarType(type_id)) {
return _.diag(SPV_ERROR_INVALID_DATA)
<< "Expected Image Operand Sample to be int scalar: "
@@ -491,7 +491,7 @@
<< spvOpcodeString(opcode);
};
- const uint32_t type_id = _.GetTypeId(inst.words[word_index++]);
+ const uint32_t type_id = _.GetTypeId(inst->word(word_index++));
if (!_.IsFloatScalarType(type_id)) {
return _.diag(SPV_ERROR_INVALID_DATA)
<< "Expected Image Operand MinLod to be float scalar: "
@@ -517,10 +517,9 @@
}
// Checks some of the validation rules which are common to multiple opcodes.
-spv_result_t ValidateImageCommon(ValidationState_t& _,
- const spv_parsed_instruction_t& inst,
+spv_result_t ValidateImageCommon(ValidationState_t& _, const Instruction* inst,
const ImageTypeInfo& info) {
- const SpvOp opcode = static_cast<SpvOp>(inst.opcode);
+ const SpvOp opcode = inst->opcode();
if (IsProj(opcode)) {
if (info.dim != SpvDim1D && info.dim != SpvDim2D && info.dim != SpvDim3D &&
info.dim != SpvDimRect) {
@@ -616,13 +615,12 @@
// Checks sparse image opcode result type and returns the second struct member.
// Returns inst.type_id for non-sparse image opcodes.
// Not valid for sparse image opcodes which do not return a struct.
-spv_result_t GetActualResultType(ValidationState_t& _,
- const spv_parsed_instruction_t& inst,
+spv_result_t GetActualResultType(ValidationState_t& _, const Instruction* inst,
uint32_t* actual_result_type) {
- const SpvOp opcode = static_cast<SpvOp>(inst.opcode);
+ const SpvOp opcode = inst->opcode();
if (IsSparse(opcode)) {
- const Instruction* const type_inst = _.FindDef(inst.type_id);
+ const Instruction* const type_inst = _.FindDef(inst->type_id());
assert(type_inst);
if (!type_inst || type_inst->opcode() != SpvOpTypeStruct) {
@@ -642,7 +640,7 @@
*actual_result_type = type_inst->word(3);
} else {
- *actual_result_type = inst.type_id;
+ *actual_result_type = inst->type_id();
}
return SPV_SUCCESS;
@@ -658,10 +656,9 @@
} // namespace
// Validates correctness of image instructions.
-spv_result_t ImagePass(ValidationState_t& _,
- const spv_parsed_instruction_t* inst) {
- const SpvOp opcode = static_cast<SpvOp>(inst->opcode);
- const uint32_t result_type = inst->type_id;
+spv_result_t ImagePass(ValidationState_t& _, const Instruction* inst) {
+ const SpvOp opcode = inst->opcode();
+ const uint32_t result_type = inst->type_id();
if (IsImplicitLod(opcode)) {
_.current_function().RegisterExecutionModelLimitation(
@@ -674,7 +671,7 @@
assert(result_type == 0);
ImageTypeInfo info;
- if (!GetImageTypeInfo(_, inst->words[1], &info)) {
+ if (!GetImageTypeInfo(_, inst->word(1), &info)) {
return _.diag(SPV_ERROR_INVALID_DATA)
<< "OpTypeImage: corrupt definition";
}
@@ -746,7 +743,7 @@
}
case SpvOpTypeSampledImage: {
- const uint32_t image_type = inst->words[2];
+ const uint32_t image_type = inst->word(2);
if (_.GetIdOpcode(image_type) != SpvOpTypeImage) {
return _.diag(SPV_ERROR_INVALID_DATA)
<< spvOpcodeString(opcode)
@@ -817,7 +814,7 @@
case SpvOpImageSparseSampleExplicitLod: {
uint32_t actual_result_type = 0;
if (spv_result_t error =
- GetActualResultType(_, *inst, &actual_result_type)) {
+ GetActualResultType(_, inst, &actual_result_type)) {
return error;
}
@@ -848,7 +845,7 @@
<< "Corrupt image type definition";
}
- if (spv_result_t result = ValidateImageCommon(_, *inst, info))
+ if (spv_result_t result = ValidateImageCommon(_, inst, info))
return result;
if (_.GetIdOpcode(info.sampled_type) != SpvOpTypeVoid) {
@@ -889,14 +886,14 @@
<< spvOpcodeString(opcode);
}
- if (inst->num_words <= 5) {
+ if (inst->words().size() <= 5) {
assert(IsImplicitLod(opcode));
break;
}
- const uint32_t mask = inst->words[5];
+ const uint32_t mask = inst->word(5);
if (spv_result_t result =
- ValidateImageOperands(_, *inst, info, mask, /* word_index = */ 6))
+ ValidateImageOperands(_, inst, info, mask, /* word_index = */ 6))
return result;
break;
@@ -910,7 +907,7 @@
case SpvOpImageSparseSampleDrefExplicitLod: {
uint32_t actual_result_type = 0;
if (spv_result_t error =
- GetActualResultType(_, *inst, &actual_result_type)) {
+ GetActualResultType(_, inst, &actual_result_type)) {
return error;
}
@@ -935,7 +932,7 @@
<< "Corrupt image type definition";
}
- if (spv_result_t result = ValidateImageCommon(_, *inst, info))
+ if (spv_result_t result = ValidateImageCommon(_, inst, info))
return result;
if (actual_result_type != info.sampled_type) {
@@ -968,14 +965,14 @@
<< ": Expected Dref to be of 32-bit float type";
}
- if (inst->num_words <= 6) {
+ if (inst->words().size() <= 6) {
assert(IsImplicitLod(opcode));
break;
}
- const uint32_t mask = inst->words[6];
+ const uint32_t mask = inst->word(6);
if (spv_result_t result =
- ValidateImageOperands(_, *inst, info, mask, /* word_index = */ 7))
+ ValidateImageOperands(_, inst, info, mask, /* word_index = */ 7))
return result;
break;
@@ -985,7 +982,7 @@
case SpvOpImageSparseFetch: {
uint32_t actual_result_type = 0;
if (spv_result_t error =
- GetActualResultType(_, *inst, &actual_result_type)) {
+ GetActualResultType(_, inst, &actual_result_type)) {
return error;
}
@@ -1054,11 +1051,11 @@
<< spvOpcodeString(opcode);
}
- if (inst->num_words <= 5) break;
+ if (inst->words().size() <= 5) break;
- const uint32_t mask = inst->words[5];
+ const uint32_t mask = inst->word(5);
if (spv_result_t result =
- ValidateImageOperands(_, *inst, info, mask, /* word_index = */ 6))
+ ValidateImageOperands(_, inst, info, mask, /* word_index = */ 6))
return result;
break;
@@ -1070,7 +1067,7 @@
case SpvOpImageSparseDrefGather: {
uint32_t actual_result_type = 0;
if (spv_result_t error =
- GetActualResultType(_, *inst, &actual_result_type)) {
+ GetActualResultType(_, inst, &actual_result_type)) {
return error;
}
@@ -1156,11 +1153,11 @@
}
}
- if (inst->num_words <= 6) break;
+ if (inst->words().size() <= 6) break;
- const uint32_t mask = inst->words[6];
+ const uint32_t mask = inst->word(6);
if (spv_result_t result =
- ValidateImageOperands(_, *inst, info, mask, /* word_index = */ 7))
+ ValidateImageOperands(_, inst, info, mask, /* word_index = */ 7))
return result;
break;
@@ -1170,7 +1167,7 @@
case SpvOpImageSparseRead: {
uint32_t actual_result_type = 0;
if (spv_result_t error =
- GetActualResultType(_, *inst, &actual_result_type)) {
+ GetActualResultType(_, inst, &actual_result_type)) {
return error;
}
@@ -1228,7 +1225,7 @@
}
}
- if (spv_result_t result = ValidateImageCommon(_, *inst, info))
+ if (spv_result_t result = ValidateImageCommon(_, inst, info))
return result;
const uint32_t coord_type = _.GetOperandTypeId(inst, 3);
@@ -1255,11 +1252,11 @@
<< "read storage image: " << spvOpcodeString(opcode);
}
- if (inst->num_words <= 5) break;
+ if (inst->words().size() <= 5) break;
- const uint32_t mask = inst->words[5];
+ const uint32_t mask = inst->word(5);
if (spv_result_t result =
- ValidateImageOperands(_, *inst, info, mask, /* word_index = */ 6))
+ ValidateImageOperands(_, inst, info, mask, /* word_index = */ 6))
return result;
break;
@@ -1285,7 +1282,7 @@
<< spvOpcodeString(opcode);
}
- if (spv_result_t result = ValidateImageCommon(_, *inst, info))
+ if (spv_result_t result = ValidateImageCommon(_, inst, info))
return result;
const uint32_t coord_type = _.GetOperandTypeId(inst, 1);
@@ -1341,11 +1338,11 @@
<< "to storage image: " << spvOpcodeString(opcode);
}
- if (inst->num_words <= 4) break;
+ if (inst->words().size() <= 4) break;
- const uint32_t mask = inst->words[4];
+ const uint32_t mask = inst->word(4);
if (spv_result_t result =
- ValidateImageOperands(_, *inst, info, mask, /* word_index = */ 5))
+ ValidateImageOperands(_, inst, info, mask, /* word_index = */ 5))
return result;
break;
diff --git a/source/validate_instruction.cpp b/source/validate_instruction.cpp
index 605ae3c..b71d6ba 100644
--- a/source/validate_instruction.cpp
+++ b/source/validate_instruction.cpp
@@ -57,7 +57,7 @@
// Reports a missing-capability error to _'s diagnostic stream and returns
// SPV_ERROR_INVALID_CAPABILITY.
-spv_result_t CapabilityError(const ValidationState_t& _, int which_operand,
+spv_result_t CapabilityError(const ValidationState_t& _, size_t which_operand,
SpvOp opcode,
const std::string& required_capabilities) {
return _.diag(SPV_ERROR_INVALID_CAPABILITY)
@@ -100,7 +100,7 @@
// in the module. Otherwise issues an error message and returns
// SPV_ERROR_INVALID_CAPABILITY.
spv_result_t CheckRequiredCapabilities(const ValidationState_t& state,
- SpvOp opcode, int which_operand,
+ SpvOp opcode, size_t which_operand,
spv_operand_type_t type,
uint32_t operand) {
// Mere mention of PointSize, ClipDistance, or CullDistance in a Builtin
@@ -181,9 +181,8 @@
// Returns SPV_ERROR_INVALID_BINARY and emits a diagnostic if the instruction
// is explicitly reserved in the SPIR-V core spec. Otherwise return
// SPV_SUCCESS.
-spv_result_t ReservedCheck(ValidationState_t& _,
- const spv_parsed_instruction_t* inst) {
- const SpvOp opcode = static_cast<SpvOp>(inst->opcode);
+spv_result_t ReservedCheck(ValidationState_t& _, const Instruction* inst) {
+ const SpvOp opcode = inst->opcode();
switch (opcode) {
// These instructions are enabled by a capability, but should never
// be used anyway.
@@ -204,9 +203,8 @@
// Returns SPV_ERROR_INVALID_BINARY and emits a diagnostic if the instruction
// is invalid because of an execution environment constraint.
-spv_result_t EnvironmentCheck(ValidationState_t& _,
- const spv_parsed_instruction_t* inst) {
- const SpvOp opcode = static_cast<SpvOp>(inst->opcode);
+spv_result_t EnvironmentCheck(ValidationState_t& _, const Instruction* inst) {
+ const SpvOp opcode = inst->opcode();
switch (opcode) {
case SpvOpUndef:
if (_.features().bans_op_undef) {
@@ -222,9 +220,8 @@
// Returns SPV_ERROR_INVALID_CAPABILITY and emits a diagnostic if the
// instruction is invalid because the required capability isn't declared
// in the module.
-spv_result_t CapabilityCheck(ValidationState_t& _,
- const spv_parsed_instruction_t* inst) {
- const SpvOp opcode = static_cast<SpvOp>(inst->opcode);
+spv_result_t CapabilityCheck(ValidationState_t& _, const Instruction* inst) {
+ const SpvOp opcode = inst->opcode();
CapabilitySet opcode_caps = EnablingCapabilitiesForOp(_, opcode);
if (!_.HasAnyOfCapabilities(opcode_caps)) {
return _.diag(SPV_ERROR_INVALID_CAPABILITY)
@@ -232,9 +229,9 @@
<< " requires one of these capabilities: "
<< ToString(opcode_caps, _.grammar());
}
- for (int i = 0; i < inst->num_operands; ++i) {
- const auto& operand = inst->operands[i];
- const auto word = inst->words[operand.offset];
+ for (size_t i = 0; i < inst->operands().size(); ++i) {
+ const auto& operand = inst->operand(i);
+ const auto word = inst->word(operand.offset);
if (spvOperandIsConcreteMask(operand.type)) {
// Check for required capabilities for each bit position of the mask.
for (uint32_t mask_bit = 0x80000000; mask_bit; mask_bit >>= 1) {
@@ -260,13 +257,12 @@
// Checks that all extensions required by the given instruction's operands were
// declared in the module.
-spv_result_t ExtensionCheck(ValidationState_t& _,
- const spv_parsed_instruction_t* inst) {
- const SpvOp opcode = static_cast<SpvOp>(inst->opcode);
- for (size_t operand_index = 0; operand_index < inst->num_operands;
+spv_result_t ExtensionCheck(ValidationState_t& _, const Instruction* inst) {
+ const SpvOp opcode = inst->opcode();
+ for (size_t operand_index = 0; operand_index < inst->operands().size();
++operand_index) {
- const auto& operand = inst->operands[operand_index];
- const uint32_t word = inst->words[operand.offset];
+ const auto& operand = inst->operand(operand_index);
+ const uint32_t word = inst->word(operand.offset);
const ExtensionSet required_extensions =
RequiredExtensions(_, operand.type, word);
if (!_.HasAnyOfExtensions(required_extensions)) {
@@ -283,9 +279,8 @@
// Checks that the instruction can be used in this target environment's base
// version. Assumes that CapabilityCheck has checked direct capability
// dependencies for the opcode.
-spv_result_t VersionCheck(ValidationState_t& _,
- const spv_parsed_instruction_t* inst) {
- const auto opcode = static_cast<SpvOp>(inst->opcode);
+spv_result_t VersionCheck(ValidationState_t& _, const Instruction* inst) {
+ const auto opcode = inst->opcode();
spv_opcode_desc inst_desc;
const bool r = _.grammar().lookupOpcode(opcode, &inst_desc);
assert(r == SPV_SUCCESS);
@@ -339,20 +334,18 @@
}
// Checks that the Resuld <id> is within the valid bound.
-spv_result_t LimitCheckIdBound(ValidationState_t& _,
- const spv_parsed_instruction_t* inst) {
- if (inst->result_id >= _.getIdBound()) {
+spv_result_t LimitCheckIdBound(ValidationState_t& _, const Instruction* inst) {
+ if (inst->id() >= _.getIdBound()) {
return _.diag(SPV_ERROR_INVALID_BINARY)
- << "Result <id> '" << inst->result_id
+ << "Result <id> '" << inst->id()
<< "' must be less than the ID bound '" << _.getIdBound() << "'.";
}
return SPV_SUCCESS;
}
// Checks that the number of OpTypeStruct members is within the limit.
-spv_result_t LimitCheckStruct(ValidationState_t& _,
- const spv_parsed_instruction_t* inst) {
- if (SpvOpTypeStruct != inst->opcode) {
+spv_result_t LimitCheckStruct(ValidationState_t& _, const Instruction* inst) {
+ if (SpvOpTypeStruct != inst->opcode()) {
return SPV_SUCCESS;
}
@@ -360,9 +353,9 @@
// One operand is the result ID.
const uint16_t limit =
static_cast<uint16_t>(_.options()->universal_limits_.max_struct_members);
- if (inst->num_operands - 1 > limit) {
+ if (inst->operands().size() - 1 > limit) {
return _.diag(SPV_ERROR_INVALID_BINARY)
- << "Number of OpTypeStruct members (" << inst->num_operands - 1
+ << "Number of OpTypeStruct members (" << inst->operands().size() - 1
<< ") has exceeded the limit (" << limit << ").";
}
@@ -375,8 +368,8 @@
// Scalars are at depth 0.
uint32_t max_member_depth = 0;
// Struct members start at word 2 of OpTypeStruct instruction.
- for (size_t word_i = 2; word_i < inst->num_words; ++word_i) {
- auto member = inst->words[word_i];
+ for (size_t word_i = 2; word_i < inst->words().size(); ++word_i) {
+ auto member = inst->word(word_i);
auto memberTypeInstr = _.FindDef(member);
if (memberTypeInstr && SpvOpTypeStruct == memberTypeInstr->opcode()) {
max_member_depth = std::max(
@@ -386,7 +379,7 @@
const uint32_t depth_limit = _.options()->universal_limits_.max_struct_depth;
const uint32_t cur_depth = 1 + max_member_depth;
- _.set_struct_nesting_depth(inst->result_id, cur_depth);
+ _.set_struct_nesting_depth(inst->id(), cur_depth);
if (cur_depth > depth_limit) {
return _.diag(SPV_ERROR_INVALID_BINARY)
<< "Structure Nesting Depth may not be larger than " << depth_limit
@@ -397,14 +390,13 @@
// Checks that the number of (literal, label) pairs in OpSwitch is within the
// limit.
-spv_result_t LimitCheckSwitch(ValidationState_t& _,
- const spv_parsed_instruction_t* inst) {
- if (SpvOpSwitch == inst->opcode) {
+spv_result_t LimitCheckSwitch(ValidationState_t& _, const Instruction* inst) {
+ if (SpvOpSwitch == inst->opcode()) {
// The instruction syntax is as follows:
// OpSwitch <selector ID> <Default ID> literal label literal label ...
// literal,label pairs come after the first 2 operands.
// It is guaranteed at this point that num_operands is an even numner.
- unsigned int num_pairs = (inst->num_operands - 2) / 2;
+ size_t num_pairs = (inst->operands().size() - 2) / 2;
const unsigned int num_pairs_limit =
_.options()->universal_limits_.max_switch_branches;
if (num_pairs > num_pairs_limit) {
@@ -446,27 +438,27 @@
// Registers necessary decoration(s) for the appropriate IDs based on the
// instruction.
spv_result_t RegisterDecorations(ValidationState_t& _,
- const spv_parsed_instruction_t* inst) {
- switch (inst->opcode) {
+ const Instruction* inst) {
+ switch (inst->opcode()) {
case SpvOpDecorate: {
- const uint32_t target_id = inst->words[1];
- const SpvDecoration dec_type = static_cast<SpvDecoration>(inst->words[2]);
+ const uint32_t target_id = inst->word(1);
+ const SpvDecoration dec_type = static_cast<SpvDecoration>(inst->word(2));
std::vector<uint32_t> dec_params;
- if (inst->num_words > 3) {
- dec_params.insert(dec_params.end(), inst->words + 3,
- inst->words + inst->num_words);
+ if (inst->words().size() > 3) {
+ dec_params.insert(dec_params.end(), inst->words().begin() + 3,
+ inst->words().end());
}
_.RegisterDecorationForId(target_id, Decoration(dec_type, dec_params));
break;
}
case SpvOpMemberDecorate: {
- const uint32_t struct_id = inst->words[1];
- const uint32_t index = inst->words[2];
- const SpvDecoration dec_type = static_cast<SpvDecoration>(inst->words[3]);
+ const uint32_t struct_id = inst->word(1);
+ const uint32_t index = inst->word(2);
+ const SpvDecoration dec_type = static_cast<SpvDecoration>(inst->word(3));
std::vector<uint32_t> dec_params;
- if (inst->num_words > 4) {
- dec_params.insert(dec_params.end(), inst->words + 4,
- inst->words + inst->num_words);
+ if (inst->words().size() > 4) {
+ dec_params.insert(dec_params.end(), inst->words().begin() + 4,
+ inst->words().end());
}
_.RegisterDecorationForId(struct_id,
Decoration(dec_type, dec_params, index));
@@ -480,11 +472,11 @@
case SpvOpGroupDecorate: {
// Word 1 is the group <id>. All subsequent words are target <id>s that
// are going to be decorated with the decorations.
- const uint32_t decoration_group_id = inst->words[1];
+ const uint32_t decoration_group_id = inst->word(1);
std::vector<Decoration>& group_decorations =
_.id_decorations(decoration_group_id);
- for (int i = 2; i < inst->num_words; ++i) {
- const uint32_t target_id = inst->words[i];
+ for (size_t i = 2; i < inst->words().size(); ++i) {
+ const uint32_t target_id = inst->word(i);
_.RegisterDecorationsForId(target_id, group_decorations.begin(),
group_decorations.end());
}
@@ -494,14 +486,14 @@
// Word 1 is the Decoration Group <id> followed by (struct<id>,literal)
// pairs. All decorations of the group should be applied to all the struct
// members that are specified in the instructions.
- const uint32_t decoration_group_id = inst->words[1];
+ const uint32_t decoration_group_id = inst->word(1);
std::vector<Decoration>& group_decorations =
_.id_decorations(decoration_group_id);
// Grammar checks ensures that the number of arguments to this instruction
// is an odd number: 1 decoration group + (id,literal) pairs.
- for (int i = 2; i + 1 < inst->num_words; i = i + 2) {
- const uint32_t struct_id = inst->words[i];
- const uint32_t index = inst->words[i + 1];
+ for (size_t i = 2; i + 1 < inst->words().size(); i = i + 2) {
+ const uint32_t struct_id = inst->word(i);
+ const uint32_t index = inst->word(i + 1);
// ID validation phase ensures this is in fact a struct instruction and
// that the index is not out of bound.
_.RegisterDecorationsForStructMember(struct_id, index,
@@ -517,9 +509,8 @@
}
// Parses OpExtension instruction and logs warnings if unsuccessful.
-void CheckIfKnownExtension(ValidationState_t& _,
- const spv_parsed_instruction_t* inst) {
- const std::string extension_str = GetExtensionString(inst);
+void CheckIfKnownExtension(ValidationState_t& _, const Instruction* inst) {
+ const std::string extension_str = GetExtensionString(&(inst->c_inst()));
Extension extension;
if (!GetExtensionFromString(extension_str.c_str(), &extension)) {
_.diag(SPV_SUCCESS) << "Found unrecognized extension " << extension_str;
@@ -529,31 +520,26 @@
} // namespace
-spv_result_t InstructionPass(ValidationState_t& _,
- const spv_parsed_instruction_t* inst) {
- const SpvOp opcode = static_cast<SpvOp>(inst->opcode);
+spv_result_t InstructionPass(ValidationState_t& _, const Instruction* inst) {
+ const SpvOp opcode = inst->opcode();
if (opcode == SpvOpExtension) {
CheckIfKnownExtension(_, inst);
} else if (opcode == SpvOpCapability) {
- _.RegisterCapability(
- static_cast<SpvCapability>(inst->words[inst->operands[0].offset]));
+ _.RegisterCapability(inst->GetOperandAs<SpvCapability>(0));
} else if (opcode == SpvOpMemoryModel) {
if (_.has_memory_model_specified()) {
return _.diag(SPV_ERROR_INVALID_LAYOUT)
<< "OpMemoryModel should only be provided once.";
}
- _.set_addressing_model(
- static_cast<SpvAddressingModel>(inst->words[inst->operands[0].offset]));
- _.set_memory_model(
- static_cast<SpvMemoryModel>(inst->words[inst->operands[1].offset]));
+ _.set_addressing_model(inst->GetOperandAs<SpvAddressingModel>(0));
+ _.set_memory_model(inst->GetOperandAs<SpvMemoryModel>(1));
} else if (opcode == SpvOpExecutionMode) {
- const uint32_t entry_point = inst->words[1];
+ const uint32_t entry_point = inst->word(1);
_.RegisterExecutionModeForEntryPoint(entry_point,
- SpvExecutionMode(inst->words[2]));
+ SpvExecutionMode(inst->word(2)));
} else if (opcode == SpvOpVariable) {
- const auto storage_class =
- static_cast<SpvStorageClass>(inst->words[inst->operands[2].offset]);
- if (auto error = LimitCheckNumVars(_, inst->result_id, storage_class)) {
+ const auto storage_class = inst->GetOperandAs<SpvStorageClass>(2);
+ if (auto error = LimitCheckNumVars(_, inst->id(), storage_class)) {
return error;
}
if (storage_class == SpvStorageClassGeneric)
@@ -582,8 +568,8 @@
// SPIR-V Spec 2.16.3: Validation Rules for Kernel Capabilities: The
// Signedness in OpTypeInt must always be 0.
- if (SpvOpTypeInt == inst->opcode && _.HasCapability(SpvCapabilityKernel) &&
- inst->words[inst->operands[2].offset] != 0u) {
+ if (SpvOpTypeInt == inst->opcode() && _.HasCapability(SpvCapabilityKernel) &&
+ inst->GetOperandAs<uint32_t>(2) != 0u) {
return _.diag(SPV_ERROR_INVALID_BINARY) << "The Signedness in OpTypeInt "
"must always be 0 when Kernel "
"capability is used.";
diff --git a/source/validate_layout.cpp b/source/validate_layout.cpp
index 287a49e..e45d4d4 100644
--- a/source/validate_layout.cpp
+++ b/source/validate_layout.cpp
@@ -23,6 +23,7 @@
#include "operand.h"
#include "spirv-tools/libspirv.h"
#include "val/function.h"
+#include "val/instruction.h"
#include "val/validation_state.h"
namespace spvtools {
@@ -33,8 +34,7 @@
// is part of the current layout section. If it is not then the next sections is
// checked.
spv_result_t ModuleScopedInstructions(ValidationState_t& _,
- const spv_parsed_instruction_t* inst,
- SpvOp opcode) {
+ const Instruction* inst, SpvOp opcode) {
while (_.IsOpcodeInCurrentLayoutSection(opcode) == false) {
_.ProgressToNextLayoutSectionOrder();
@@ -63,8 +63,7 @@
// inside of another function. This stage ends when the first label is
// encountered inside of a function.
spv_result_t FunctionScopedInstructions(ValidationState_t& _,
- const spv_parsed_instruction_t* inst,
- SpvOp opcode) {
+ const Instruction* inst, SpvOp opcode) {
if (_.IsOpcodeInCurrentLayoutSection(opcode)) {
switch (opcode) {
case SpvOpFunction: {
@@ -72,11 +71,10 @@
return _.diag(SPV_ERROR_INVALID_LAYOUT)
<< "Cannot declare a function in a function body";
}
- auto control_mask = static_cast<SpvFunctionControlMask>(
- inst->words[inst->operands[2].offset]);
+ auto control_mask = inst->GetOperandAs<SpvFunctionControlMask>(2);
if (auto error =
- _.RegisterFunction(inst->result_id, inst->type_id, control_mask,
- inst->words[inst->operands[3].offset]))
+ _.RegisterFunction(inst->id(), inst->type_id(), control_mask,
+ inst->GetOperandAs<uint32_t>(3)))
return error;
if (_.current_layout_section() == kLayoutFunctionDefinitions) {
if (auto error = _.current_function().RegisterSetFunctionDeclType(
@@ -97,7 +95,7 @@
"the function definition";
}
if (auto error = _.current_function().RegisterFunctionParameter(
- inst->result_id, inst->type_id))
+ inst->id(), inst->type_id()))
return error;
break;
@@ -174,9 +172,8 @@
// TODO(umar): Better error messages
// NOTE: This function does not handle CFG related validation
// Performs logical layout validation. See Section 2.4
-spv_result_t ModuleLayoutPass(ValidationState_t& _,
- const spv_parsed_instruction_t* inst) {
- const SpvOp opcode = static_cast<SpvOp>(inst->opcode);
+spv_result_t ModuleLayoutPass(ValidationState_t& _, const Instruction* inst) {
+ const SpvOp opcode = inst->opcode();
switch (_.current_layout_section()) {
case kLayoutCapabilities:
diff --git a/source/validate_literals.cpp b/source/validate_literals.cpp
index 3f8e55e..76ef467 100644
--- a/source/validate_literals.cpp
+++ b/source/validate_literals.cpp
@@ -28,8 +28,8 @@
namespace {
// Returns true if the operand holds a literal number
-bool IsLiteralNumber(const spv_parsed_operand_t* operand) {
- switch (operand->number_kind) {
+bool IsLiteralNumber(const spv_parsed_operand_t& operand) {
+ switch (operand.number_kind) {
case SPV_NUMBER_SIGNED_INT:
case SPV_NUMBER_UNSIGNED_INT:
case SPV_NUMBER_FLOATING:
@@ -64,31 +64,30 @@
} // namespace
// Validates that literal numbers are represented according to the spec
-spv_result_t LiteralsPass(ValidationState_t& _,
- const spv_parsed_instruction_t* inst) {
+spv_result_t LiteralsPass(ValidationState_t& _, const Instruction* inst) {
// For every operand that is a literal number
- for (uint16_t i = 0; i < inst->num_operands; i++) {
- const spv_parsed_operand_t* operand = inst->operands + i;
+ for (size_t i = 0; i < inst->operands().size(); i++) {
+ const spv_parsed_operand_t& operand = inst->operand(i);
if (!IsLiteralNumber(operand)) continue;
// The upper bits are always in the last word (little-endian)
- int last_index = operand->offset + operand->num_words - 1;
- const uint32_t upper_word = inst->words[last_index];
+ int last_index = operand.offset + operand.num_words - 1;
+ const uint32_t upper_word = inst->word(last_index);
// TODO(jcaraban): is the |word size| defined in some header?
const uint32_t word_size = 32;
- uint32_t bit_width = operand->number_bit_width;
+ uint32_t bit_width = operand.number_bit_width;
// Bit widths that are a multiple of the word size have no upper bits
const auto remaining_value_bits = bit_width % word_size;
if (remaining_value_bits == 0) continue;
- const bool signedness = operand->number_kind == SPV_NUMBER_SIGNED_INT;
+ const bool signedness = operand.number_kind == SPV_NUMBER_SIGNED_INT;
if (!VerifyUpperBits(upper_word, remaining_value_bits, signedness)) {
return _.diag(SPV_ERROR_INVALID_VALUE)
<< "The high-order bits of a literal number in instruction <id> "
- << inst->result_id << " must be 0 for a floating-point type, "
+ << inst->id() << " must be 0 for a floating-point type, "
<< "or 0 for an integer type with Signedness of 0, "
<< "or sign extended when Signedness is 1";
}
diff --git a/source/validate_logicals.cpp b/source/validate_logicals.cpp
index a893d3f..7239968 100644
--- a/source/validate_logicals.cpp
+++ b/source/validate_logicals.cpp
@@ -23,32 +23,11 @@
namespace spvtools {
namespace val {
-namespace {
-
-// Returns operand word for given instruction and operand index.
-// The operand is expected to only have one word.
-inline uint32_t GetOperandWord(const spv_parsed_instruction_t* inst,
- size_t operand_index) {
- assert(operand_index < inst->num_operands);
- const spv_parsed_operand_t& operand = inst->operands[operand_index];
- assert(operand.num_words == 1);
- return inst->words[operand.offset];
-}
-
-// Returns the type id of instruction operand at |operand_index|.
-// The operand is expected to be an id.
-inline uint32_t GetOperandTypeId(ValidationState_t& _,
- const spv_parsed_instruction_t* inst,
- size_t operand_index) {
- return _.GetTypeId(GetOperandWord(inst, operand_index));
-}
-} // namespace
// Validates correctness of logical instructions.
-spv_result_t LogicalsPass(ValidationState_t& _,
- const spv_parsed_instruction_t* inst) {
- const SpvOp opcode = static_cast<SpvOp>(inst->opcode);
- const uint32_t result_type = inst->type_id;
+spv_result_t LogicalsPass(ValidationState_t& _, const Instruction* inst) {
+ const SpvOp opcode = inst->opcode();
+ const uint32_t result_type = inst->type_id();
switch (opcode) {
case SpvOpAny:
@@ -58,7 +37,7 @@
<< "Expected bool scalar type as Result Type: "
<< spvOpcodeString(opcode);
- const uint32_t vector_type = GetOperandTypeId(_, inst, 2);
+ const uint32_t vector_type = _.GetOperandTypeId(inst, 2);
if (!vector_type || !_.IsBoolVectorType(vector_type))
return _.diag(SPV_ERROR_INVALID_DATA)
<< "Expected operand to be vector bool: "
@@ -77,7 +56,7 @@
<< "Expected bool scalar or vector type as Result Type: "
<< spvOpcodeString(opcode);
- const uint32_t operand_type = GetOperandTypeId(_, inst, 2);
+ const uint32_t operand_type = _.GetOperandTypeId(inst, 2);
if (!operand_type || (!_.IsFloatScalarType(operand_type) &&
!_.IsFloatVectorType(operand_type)))
return _.diag(SPV_ERROR_INVALID_DATA)
@@ -113,7 +92,7 @@
<< "Expected bool scalar or vector type as Result Type: "
<< spvOpcodeString(opcode);
- const uint32_t left_operand_type = GetOperandTypeId(_, inst, 2);
+ const uint32_t left_operand_type = _.GetOperandTypeId(inst, 2);
if (!left_operand_type || (!_.IsFloatScalarType(left_operand_type) &&
!_.IsFloatVectorType(left_operand_type)))
return _.diag(SPV_ERROR_INVALID_DATA)
@@ -126,7 +105,7 @@
"equal: "
<< spvOpcodeString(opcode);
- if (left_operand_type != GetOperandTypeId(_, inst, 3))
+ if (left_operand_type != _.GetOperandTypeId(inst, 3))
return _.diag(SPV_ERROR_INVALID_DATA)
<< "Expected left and right operands to have the same type: "
<< spvOpcodeString(opcode);
@@ -143,8 +122,8 @@
<< "Expected bool scalar or vector type as Result Type: "
<< spvOpcodeString(opcode);
- if (result_type != GetOperandTypeId(_, inst, 2) ||
- result_type != GetOperandTypeId(_, inst, 3))
+ if (result_type != _.GetOperandTypeId(inst, 2) ||
+ result_type != _.GetOperandTypeId(inst, 3))
return _.diag(SPV_ERROR_INVALID_DATA)
<< "Expected both operands to be of Result Type: "
<< spvOpcodeString(opcode);
@@ -158,7 +137,7 @@
<< "Expected bool scalar or vector type as Result Type: "
<< spvOpcodeString(opcode);
- if (result_type != GetOperandTypeId(_, inst, 2))
+ if (result_type != _.GetOperandTypeId(inst, 2))
return _.diag(SPV_ERROR_INVALID_DATA)
<< "Expected operand to be of Result Type: "
<< spvOpcodeString(opcode);
@@ -202,9 +181,9 @@
}
}
- const uint32_t condition_type = GetOperandTypeId(_, inst, 2);
- const uint32_t left_type = GetOperandTypeId(_, inst, 3);
- const uint32_t right_type = GetOperandTypeId(_, inst, 4);
+ const uint32_t condition_type = _.GetOperandTypeId(inst, 2);
+ const uint32_t left_type = _.GetOperandTypeId(inst, 3);
+ const uint32_t right_type = _.GetOperandTypeId(inst, 4);
if (!condition_type || (!_.IsBoolScalarType(condition_type) &&
!_.IsBoolVectorType(condition_type)))
@@ -240,8 +219,8 @@
<< "Expected bool scalar or vector type as Result Type: "
<< spvOpcodeString(opcode);
- const uint32_t left_type = GetOperandTypeId(_, inst, 2);
- const uint32_t right_type = GetOperandTypeId(_, inst, 3);
+ const uint32_t left_type = _.GetOperandTypeId(inst, 2);
+ const uint32_t right_type = _.GetOperandTypeId(inst, 3);
if (!left_type ||
(!_.IsIntScalarType(left_type) && !_.IsIntVectorType(left_type)))
diff --git a/source/validate_non_uniform.cpp b/source/validate_non_uniform.cpp
index de42dea..070c773 100644
--- a/source/validate_non_uniform.cpp
+++ b/source/validate_non_uniform.cpp
@@ -29,9 +29,8 @@
namespace {
spv_result_t ValidateExecutionScope(ValidationState_t& _,
- const spv_parsed_instruction_t* inst,
- uint32_t scope) {
- SpvOp opcode = static_cast<SpvOp>(inst->opcode);
+ const Instruction* inst, uint32_t scope) {
+ SpvOp opcode = inst->opcode();
bool is_int32 = false, is_const_int32 = false;
uint32_t value = 0;
std::tie(is_int32, is_const_int32, value) = _.EvalInt32IfConst(scope);
@@ -67,12 +66,11 @@
} // namespace
// Validates correctness of non-uniform group instructions.
-spv_result_t NonUniformPass(ValidationState_t& _,
- const spv_parsed_instruction_t* inst) {
- const SpvOp opcode = static_cast<SpvOp>(inst->opcode);
+spv_result_t NonUniformPass(ValidationState_t& _, const Instruction* inst) {
+ const SpvOp opcode = inst->opcode();
if (spvOpcodeIsNonUniformGroupOperation(opcode)) {
- const uint32_t execution_scope = inst->words[3];
+ const uint32_t execution_scope = inst->word(3);
if (auto error = ValidateExecutionScope(_, inst, execution_scope)) {
return error;
}
diff --git a/source/validate_primitives.cpp b/source/validate_primitives.cpp
index 4705496..289ac39 100644
--- a/source/validate_primitives.cpp
+++ b/source/validate_primitives.cpp
@@ -27,9 +27,8 @@
namespace val {
// Validates correctness of primitive instructions.
-spv_result_t PrimitivesPass(ValidationState_t& _,
- const spv_parsed_instruction_t* inst) {
- const SpvOp opcode = static_cast<SpvOp>(inst->opcode);
+spv_result_t PrimitivesPass(ValidationState_t& _, const Instruction* inst) {
+ const SpvOp opcode = inst->opcode();
switch (opcode) {
case SpvOpEmitVertex:
@@ -48,7 +47,7 @@
switch (opcode) {
case SpvOpEmitStreamVertex:
case SpvOpEndStreamPrimitive: {
- const uint32_t stream_id = inst->words[1];
+ const uint32_t stream_id = inst->word(1);
const uint32_t stream_type = _.GetTypeId(stream_id);
if (!_.IsIntScalarType(stream_type)) {
return _.diag(SPV_ERROR_INVALID_DATA)
diff --git a/source/validate_type_unique.cpp b/source/validate_type_unique.cpp
index c251f6c..643c1e1 100644
--- a/source/validate_type_unique.cpp
+++ b/source/validate_type_unique.cpp
@@ -29,12 +29,11 @@
// (see section 2.8 Types and Variables)
// Doesn't do anything if SPV_VAL_ignore_type_decl_unique was declared in the
// module.
-spv_result_t TypeUniquePass(ValidationState_t& _,
- const spv_parsed_instruction_t* inst) {
+spv_result_t TypeUniquePass(ValidationState_t& _, const Instruction* inst) {
if (_.HasExtension(Extension::kSPV_VALIDATOR_ignore_type_decl_unique))
return SPV_SUCCESS;
- const SpvOp opcode = static_cast<SpvOp>(inst->opcode);
+ const SpvOp opcode = inst->opcode();
if (spvOpcodeGeneratesType(opcode)) {
if (opcode == SpvOpTypeArray || opcode == SpvOpTypeRuntimeArray ||
@@ -43,11 +42,11 @@
return SPV_SUCCESS;
}
- if (!_.RegisterUniqueTypeDeclaration(*inst)) {
+ if (!_.RegisterUniqueTypeDeclaration(inst)) {
return _.diag(SPV_ERROR_INVALID_DATA)
<< "Duplicate non-aggregate type declarations are not allowed."
- << " Opcode: " << spvOpcodeString(SpvOp(inst->opcode))
- << " id: " << inst->result_id;
+ << " Opcode: " << spvOpcodeString(SpvOp(inst->opcode()))
+ << " id: " << inst->id();
}
}
diff --git a/test/opt/loop_optimizations/unroll_simple.cpp b/test/opt/loop_optimizations/unroll_simple.cpp
index 7f985de..d13520a 100644
--- a/test/opt/loop_optimizations/unroll_simple.cpp
+++ b/test/opt/loop_optimizations/unroll_simple.cpp
@@ -44,7 +44,6 @@
}
*/
TEST_F(PassClassTest, SimpleFullyUnrollTest) {
- // clang-format off
// With opt::LocalMultiStoreElimPass
const std::string text = R"(
OpCapability Shader
@@ -98,8 +97,7 @@
OpFunctionEnd
)";
-const std::string output =
-R"(OpCapability Shader
+ const std::string output = R"(OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %2 "main" %3
@@ -183,17 +181,17 @@
OpReturn
OpFunctionEnd
)";
- // clang-format on
-std::unique_ptr<opt::IRContext> context =
- BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
- SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-opt::Module* module = context->module();
-EXPECT_NE(nullptr, module) << "Assembling failed for ushader:\n"
- << text << std::endl;
-opt::LoopUnroller loop_unroller;
-SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
-SinglePassRunAndCheck<opt::LoopUnroller>(text, output, false);
+ std::unique_ptr<opt::IRContext> context =
+ BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
+ SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+ opt::Module* module = context->module();
+ EXPECT_NE(nullptr, module) << "Assembling failed for ushader:\n"
+ << text << std::endl;
+
+ opt::LoopUnroller loop_unroller;
+ SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
+ SinglePassRunAndCheck<opt::LoopUnroller>(text, output, false);
}
template <int factor>
@@ -228,7 +226,6 @@
}
*/
TEST_F(PassClassTest, SimplePartialUnroll) {
- // clang-format off
// With opt::LocalMultiStoreElimPass
const std::string text = R"(
OpCapability Shader
@@ -344,7 +341,7 @@
OpReturn
OpFunctionEnd
)";
- // clang-format on
+
std::unique_ptr<opt::IRContext> context =
BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
@@ -369,7 +366,6 @@
}
*/
TEST_F(PassClassTest, SimpleUnevenPartialUnroll) {
- // clang-format off
// With opt::LocalMultiStoreElimPass
const std::string text = R"(
OpCapability Shader
@@ -423,8 +419,7 @@
OpFunctionEnd
)";
-const std::string output =
-R"(OpCapability Shader
+ const std::string output = R"(OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %2 "main" %3
@@ -517,20 +512,20 @@
OpReturn
OpFunctionEnd
)";
- // clang-format on
-std::unique_ptr<opt::IRContext> context =
- BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
- SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-opt::Module* module = context->module();
-EXPECT_NE(nullptr, module) << "Assembling failed for ushader:\n"
- << text << std::endl;
-opt::LoopUnroller loop_unroller;
-SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
-// By unrolling by a factor that doesn't divide evenly into the number of loop
-// iterations we perfom an additional transform when partially unrolling to
-// account for the remainder.
-SinglePassRunAndCheck<PartialUnrollerTestPass<3>>(text, output, false);
+ std::unique_ptr<opt::IRContext> context =
+ BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
+ SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+ opt::Module* module = context->module();
+ EXPECT_NE(nullptr, module) << "Assembling failed for ushader:\n"
+ << text << std::endl;
+
+ opt::LoopUnroller loop_unroller;
+ SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
+ // By unrolling by a factor that doesn't divide evenly into the number of loop
+ // iterations we perfom an additional transform when partially unrolling to
+ // account for the remainder.
+ SinglePassRunAndCheck<PartialUnrollerTestPass<3>>(text, output, false);
}
/* Generated from
@@ -544,7 +539,6 @@
}
*/
TEST_F(PassClassTest, SimpleLoopIterationsCheck) {
- // clang-format off
// With opt::LocalMultiStoreElimPass
const std::string text = R"(
OpCapability Shader
@@ -596,7 +590,6 @@
OpReturn
OpFunctionEnd
)";
- // clang-format on
std::unique_ptr<opt::IRContext> context =
BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
@@ -639,7 +632,6 @@
}
*/
TEST_F(PassClassTest, SimpleLoopIterationsCheckSignedInit) {
- // clang-format off
// With opt::LocalMultiStoreElimPass
const std::string text = R"(
OpCapability Shader
@@ -692,7 +684,6 @@
OpReturn
OpFunctionEnd
)";
- // clang-format on
std::unique_ptr<opt::IRContext> context =
BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
@@ -739,7 +730,6 @@
}
*/
TEST_F(PassClassTest, UnrollNestedLoops) {
- // clang-format off
// With opt::LocalMultiStoreElimPass
const std::string text = R"(
OpCapability Shader
@@ -809,8 +799,7 @@
OpFunctionEnd
)";
-const std::string output =
-R"(OpCapability Shader
+ const std::string output = R"(OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %2 "main"
@@ -964,16 +953,16 @@
OpReturn
OpFunctionEnd
)";
- // clang-format on
-std::unique_ptr<opt::IRContext> context =
- BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
- SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-opt::Module* module = context->module();
-EXPECT_NE(nullptr, module) << "Assembling failed for ushader:\n"
- << text << std::endl;
-opt::LoopUnroller loop_unroller;
-SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
-SinglePassRunAndCheck<opt::LoopUnroller>(text, output, false);
+
+ std::unique_ptr<opt::IRContext> context =
+ BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
+ SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+ opt::Module* module = context->module();
+ EXPECT_NE(nullptr, module) << "Assembling failed for ushader:\n"
+ << text << std::endl;
+ opt::LoopUnroller loop_unroller;
+ SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
+ SinglePassRunAndCheck<opt::LoopUnroller>(text, output, false);
}
/*
@@ -987,9 +976,8 @@
}
*/
TEST_F(PassClassTest, NegativeConditionAndInit) {
- // clang-format off
// With opt::LocalMultiStoreElimPass
-const std::string text = R"(
+ const std::string text = R"(
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
@@ -1035,7 +1023,7 @@
OpFunctionEnd
)";
-const std::string expected = R"(OpCapability Shader
+ const std::string expected = R"(OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %2 "main"
@@ -1090,42 +1078,41 @@
OpReturn
OpFunctionEnd
)";
- // clang-format on
-std::unique_ptr<opt::IRContext> context =
- BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
- SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-opt::Module* module = context->module();
-EXPECT_NE(nullptr, module) << "Assembling failed for ushader:\n"
- << text << std::endl;
+ std::unique_ptr<opt::IRContext> context =
+ BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
+ SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+ opt::Module* module = context->module();
+ EXPECT_NE(nullptr, module) << "Assembling failed for ushader:\n"
+ << text << std::endl;
-opt::LoopUnroller loop_unroller;
-SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
-// SinglePassRunAndCheck<opt::LoopUnroller>(text, expected, false);
+ opt::LoopUnroller loop_unroller;
+ SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
+ // SinglePassRunAndCheck<opt::LoopUnroller>(text, expected, false);
-opt::Function* f = spvtest::GetFunction(module, 4);
+ opt::Function* f = spvtest::GetFunction(module, 4);
-opt::LoopDescriptor& loop_descriptor = *context->GetLoopDescriptor(f);
-EXPECT_EQ(loop_descriptor.NumLoops(), 1u);
+ opt::LoopDescriptor& loop_descriptor = *context->GetLoopDescriptor(f);
+ EXPECT_EQ(loop_descriptor.NumLoops(), 1u);
-opt::Loop& loop = loop_descriptor.GetLoopByIndex(0);
+ opt::Loop& loop = loop_descriptor.GetLoopByIndex(0);
-EXPECT_TRUE(loop.HasUnrollLoopControl());
+ EXPECT_TRUE(loop.HasUnrollLoopControl());
-opt::BasicBlock* condition = loop.FindConditionBlock();
-EXPECT_EQ(condition->id(), 14u);
+ opt::BasicBlock* condition = loop.FindConditionBlock();
+ EXPECT_EQ(condition->id(), 14u);
-opt::Instruction* induction = loop.FindConditionVariable(condition);
-EXPECT_EQ(induction->result_id(), 32u);
+ opt::Instruction* induction = loop.FindConditionVariable(condition);
+ EXPECT_EQ(induction->result_id(), 32u);
-opt::LoopUtils loop_utils{context.get(), &loop};
-EXPECT_TRUE(loop_utils.CanPerformUnroll());
+ opt::LoopUtils loop_utils{context.get(), &loop};
+ EXPECT_TRUE(loop_utils.CanPerformUnroll());
-size_t iterations = 0;
-EXPECT_TRUE(
- loop.FindNumberOfIterations(induction, &*condition->ctail(), &iterations));
-EXPECT_EQ(iterations, 2u);
-SinglePassRunAndCheck<opt::LoopUnroller>(text, expected, false);
+ size_t iterations = 0;
+ EXPECT_TRUE(loop.FindNumberOfIterations(induction, &*condition->ctail(),
+ &iterations));
+ EXPECT_EQ(iterations, 2u);
+ SinglePassRunAndCheck<opt::LoopUnroller>(text, expected, false);
}
/*
@@ -1139,9 +1126,8 @@
}
*/
TEST_F(PassClassTest, NegativeConditionAndInitResidualUnroll) {
- // clang-format off
// With opt::LocalMultiStoreElimPass
-const std::string text = R"(
+ const std::string text = R"(
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
@@ -1187,7 +1173,7 @@
OpFunctionEnd
)";
-const std::string expected = R"(OpCapability Shader
+ const std::string expected = R"(OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %2 "main"
@@ -1313,7 +1299,6 @@
}
*/
TEST_F(PassClassTest, UnrollNestedLoopsValidateDescriptor) {
- // clang-format off
// With opt::LocalMultiStoreElimPass
const std::string text = R"(
OpCapability Shader
@@ -1383,8 +1368,6 @@
OpFunctionEnd
)";
- // clang-format on
-
{ // Test fully unroll
std::unique_ptr<opt::IRContext> context =
BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
@@ -1479,7 +1462,6 @@
}
*/
TEST_F(PassClassTest, FullyUnrollNegativeStepLoopTest) {
- // clang-format off
// With opt::LocalMultiStoreElimPass
const std::string text = R"(
OpCapability Shader
@@ -1528,8 +1510,7 @@
OpFunctionEnd
)";
-const std::string output =
-R"(OpCapability Shader
+ const std::string output = R"(OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %2 "main"
@@ -1598,17 +1579,17 @@
OpReturn
OpFunctionEnd
)";
- // clang-format on
-std::unique_ptr<opt::IRContext> context =
- BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
- SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-opt::Module* module = context->module();
-EXPECT_NE(nullptr, module) << "Assembling failed for ushader:\n"
- << text << std::endl;
-opt::LoopUnroller loop_unroller;
-SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
-SinglePassRunAndCheck<opt::LoopUnroller>(text, output, false);
+ std::unique_ptr<opt::IRContext> context =
+ BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
+ SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+ opt::Module* module = context->module();
+ EXPECT_NE(nullptr, module) << "Assembling failed for ushader:\n"
+ << text << std::endl;
+
+ opt::LoopUnroller loop_unroller;
+ SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
+ SinglePassRunAndCheck<opt::LoopUnroller>(text, output, false);
}
/*
@@ -1622,7 +1603,6 @@
}
*/
TEST_F(PassClassTest, FullyUnrollNegativeNonOneStepLoop) {
- // clang-format off
// With opt::LocalMultiStoreElimPass
const std::string text = R"(
OpCapability Shader
@@ -1671,8 +1651,7 @@
OpFunctionEnd
)";
-const std::string output =
-R"(OpCapability Shader
+ const std::string output = R"(OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %2 "main"
@@ -1741,17 +1720,17 @@
OpReturn
OpFunctionEnd
)";
- // clang-format on
-std::unique_ptr<opt::IRContext> context =
- BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
- SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-opt::Module* module = context->module();
-EXPECT_NE(nullptr, module) << "Assembling failed for ushader:\n"
- << text << std::endl;
-opt::LoopUnroller loop_unroller;
-SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
-SinglePassRunAndCheck<opt::LoopUnroller>(text, output, false);
+ std::unique_ptr<opt::IRContext> context =
+ BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
+ SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+ opt::Module* module = context->module();
+ EXPECT_NE(nullptr, module) << "Assembling failed for ushader:\n"
+ << text << std::endl;
+
+ opt::LoopUnroller loop_unroller;
+ SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
+ SinglePassRunAndCheck<opt::LoopUnroller>(text, output, false);
}
/*
@@ -1765,7 +1744,6 @@
}
*/
TEST_F(PassClassTest, FullyUnrollNonDivisibleStepLoop) {
- // clang-format off
// With opt::LocalMultiStoreElimPass
const std::string text = R"(OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
@@ -1813,8 +1791,7 @@
OpFunctionEnd
)";
-const std::string output =
-R"(OpCapability Shader
+ const std::string output = R"(OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %2 "main"
@@ -1883,17 +1860,17 @@
OpReturn
OpFunctionEnd
)";
- // clang-format on
-std::unique_ptr<opt::IRContext> context =
- BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
- SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-opt::Module* module = context->module();
-EXPECT_NE(nullptr, module) << "Assembling failed for ushader:\n"
- << text << std::endl;
-opt::LoopUnroller loop_unroller;
-SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
-SinglePassRunAndCheck<opt::LoopUnroller>(text, output, false);
+ std::unique_ptr<opt::IRContext> context =
+ BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
+ SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+ opt::Module* module = context->module();
+ EXPECT_NE(nullptr, module) << "Assembling failed for ushader:\n"
+ << text << std::endl;
+
+ opt::LoopUnroller loop_unroller;
+ SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
+ SinglePassRunAndCheck<opt::LoopUnroller>(text, output, false);
}
/*
@@ -1907,7 +1884,6 @@
}
*/
TEST_F(PassClassTest, FullyUnrollNegativeNonDivisibleStepLoop) {
- // clang-format off
// With opt::LocalMultiStoreElimPass
const std::string text = R"(OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
@@ -1955,8 +1931,7 @@
OpFunctionEnd
)";
-const std::string output =
-R"(OpCapability Shader
+ const std::string output = R"(OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %2 "main"
@@ -2038,20 +2013,19 @@
OpReturn
OpFunctionEnd
)";
- // clang-format on
-std::unique_ptr<opt::IRContext> context =
- BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
- SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-opt::Module* module = context->module();
-EXPECT_NE(nullptr, module) << "Assembling failed for ushader:\n"
- << text << std::endl;
-opt::LoopUnroller loop_unroller;
-SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
-SinglePassRunAndCheck<opt::LoopUnroller>(text, output, false);
+ std::unique_ptr<opt::IRContext> context =
+ BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
+ SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+ opt::Module* module = context->module();
+ EXPECT_NE(nullptr, module) << "Assembling failed for ushader:\n"
+ << text << std::endl;
+
+ opt::LoopUnroller loop_unroller;
+ SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
+ SinglePassRunAndCheck<opt::LoopUnroller>(text, output, false);
}
-// clang-format off
// With opt::LocalMultiStoreElimPass
static const std::string multiple_phi_shader = R"(
OpCapability Shader
@@ -2102,12 +2076,9 @@
OpReturnValue %37
OpFunctionEnd
)";
-// clang-format on
TEST_F(PassClassTest, PartiallyUnrollResidualMultipleInductionVariables) {
- // clang-format off
-const std::string output =
-R"(OpCapability Shader
+ const std::string output = R"(OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %2 "main"
@@ -2218,24 +2189,22 @@
OpReturnValue %30
OpFunctionEnd
)";
- // clang-format on
-std::unique_ptr<opt::IRContext> context =
- BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, multiple_phi_shader,
- SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-opt::Module* module = context->module();
-EXPECT_NE(nullptr, module) << "Assembling failed for ushader:\n"
- << multiple_phi_shader << std::endl;
-opt::LoopUnroller loop_unroller;
-SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
-SinglePassRunAndCheck<PartialUnrollerTestPass<4>>(multiple_phi_shader, output,
- false);
+ std::unique_ptr<opt::IRContext> context =
+ BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, multiple_phi_shader,
+ SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+ opt::Module* module = context->module();
+ EXPECT_NE(nullptr, module) << "Assembling failed for ushader:\n"
+ << multiple_phi_shader << std::endl;
+
+ opt::LoopUnroller loop_unroller;
+ SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
+ SinglePassRunAndCheck<PartialUnrollerTestPass<4>>(multiple_phi_shader, output,
+ false);
}
TEST_F(PassClassTest, PartiallyUnrollMultipleInductionVariables) {
- // clang-format off
-const std::string output =
-R"(OpCapability Shader
+ const std::string output = R"(OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %2 "main"
@@ -2296,24 +2265,22 @@
OpReturnValue %30
OpFunctionEnd
)";
- // clang-format on
-std::unique_ptr<opt::IRContext> context =
- BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, multiple_phi_shader,
- SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-opt::Module* module = context->module();
-EXPECT_NE(nullptr, module) << "Assembling failed for ushader:\n"
- << multiple_phi_shader << std::endl;
-opt::LoopUnroller loop_unroller;
-SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
-SinglePassRunAndCheck<PartialUnrollerTestPass<2>>(multiple_phi_shader, output,
- false);
+ std::unique_ptr<opt::IRContext> context =
+ BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, multiple_phi_shader,
+ SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+ opt::Module* module = context->module();
+ EXPECT_NE(nullptr, module) << "Assembling failed for ushader:\n"
+ << multiple_phi_shader << std::endl;
+
+ opt::LoopUnroller loop_unroller;
+ SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
+ SinglePassRunAndCheck<PartialUnrollerTestPass<2>>(multiple_phi_shader, output,
+ false);
}
TEST_F(PassClassTest, FullyUnrollMultipleInductionVariables) {
- // clang-format off
-const std::string output =
-R"(OpCapability Shader
+ const std::string output = R"(OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %2 "main"
@@ -2422,17 +2389,17 @@
OpReturnValue %30
OpFunctionEnd
)";
- // clang-format on
-std::unique_ptr<opt::IRContext> context =
- BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, multiple_phi_shader,
- SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-opt::Module* module = context->module();
-EXPECT_NE(nullptr, module) << "Assembling failed for ushader:\n"
- << multiple_phi_shader << std::endl;
-opt::LoopUnroller loop_unroller;
-SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
-SinglePassRunAndCheck<opt::LoopUnroller>(multiple_phi_shader, output, false);
+ std::unique_ptr<opt::IRContext> context =
+ BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, multiple_phi_shader,
+ SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+ opt::Module* module = context->module();
+ EXPECT_NE(nullptr, module) << "Assembling failed for ushader:\n"
+ << multiple_phi_shader << std::endl;
+
+ opt::LoopUnroller loop_unroller;
+ SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
+ SinglePassRunAndCheck<opt::LoopUnroller>(multiple_phi_shader, output, false);
}
/*
@@ -2449,7 +2416,6 @@
}
*/
TEST_F(PassClassTest, FullyUnrollEqualToOperations) {
- // clang-format off
// With opt::LocalMultiStoreElimPass
const std::string text = R"(
OpCapability Shader
@@ -2505,8 +2471,7 @@
OpFunctionEnd
)";
-const std::string output =
-R"(OpCapability Shader
+ const std::string output = R"(OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %2 "main"
@@ -2585,22 +2550,21 @@
OpReturn
OpFunctionEnd
)";
- // clang-format on
-std::unique_ptr<opt::IRContext> context =
- BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
- SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-opt::Module* module = context->module();
-EXPECT_NE(nullptr, module) << "Assembling failed for ushader:\n"
- << text << std::endl;
-opt::LoopUnroller loop_unroller;
-SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
-SinglePassRunAndCheck<opt::LoopUnroller>(text, output, false);
+ std::unique_ptr<opt::IRContext> context =
+ BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
+ SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+ opt::Module* module = context->module();
+ EXPECT_NE(nullptr, module) << "Assembling failed for ushader:\n"
+ << text << std::endl;
+
+ opt::LoopUnroller loop_unroller;
+ SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
+ SinglePassRunAndCheck<opt::LoopUnroller>(text, output, false);
}
-// clang-format off
- // With opt::LocalMultiStoreElimPass
- const std::string condition_in_header = R"(
+// With opt::LocalMultiStoreElimPass
+const std::string condition_in_header = R"(
OpCapability Shader
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %main "main" %o
@@ -2637,14 +2601,9 @@
OpReturn
OpFunctionEnd
)";
-//clang-format on
-
TEST_F(PassClassTest, FullyUnrollConditionIsInHeaderBlock) {
-
-// clang-format off
-const std::string output =
-R"(OpCapability Shader
+ const std::string output = R"(OpCapability Shader
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %1 "main" %2
OpExecutionMode %1 OriginUpperLeft
@@ -2700,23 +2659,21 @@
OpReturn
OpFunctionEnd
)";
- // clang-format on
-std::unique_ptr<opt::IRContext> context =
- BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, condition_in_header,
- SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-opt::Module* module = context->module();
-EXPECT_NE(nullptr, module) << "Assembling failed for ushader:\n"
- << condition_in_header << std::endl;
-opt::LoopUnroller loop_unroller;
-SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
-SinglePassRunAndCheck<opt::LoopUnroller>(condition_in_header, output, false);
+ std::unique_ptr<opt::IRContext> context =
+ BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, condition_in_header,
+ SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+ opt::Module* module = context->module();
+ EXPECT_NE(nullptr, module) << "Assembling failed for ushader:\n"
+ << condition_in_header << std::endl;
+
+ opt::LoopUnroller loop_unroller;
+ SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
+ SinglePassRunAndCheck<opt::LoopUnroller>(condition_in_header, output, false);
}
TEST_F(PassClassTest, PartiallyUnrollResidualConditionIsInHeaderBlock) {
- // clang-format off
-const std::string output =
-R"(OpCapability Shader
+ const std::string output = R"(OpCapability Shader
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %1 "main" %2
OpExecutionMode %1 OriginUpperLeft
@@ -2782,18 +2739,18 @@
OpReturn
OpFunctionEnd
)";
- // clang-format on
-std::unique_ptr<opt::IRContext> context =
- BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, condition_in_header,
- SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
-opt::Module* module = context->module();
-EXPECT_NE(nullptr, module) << "Assembling failed for ushader:\n"
- << condition_in_header << std::endl;
-opt::LoopUnroller loop_unroller;
-SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
-SinglePassRunAndCheck<PartialUnrollerTestPass<2>>(condition_in_header, output,
- false);
+ std::unique_ptr<opt::IRContext> context =
+ BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, condition_in_header,
+ SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+ opt::Module* module = context->module();
+ EXPECT_NE(nullptr, module) << "Assembling failed for ushader:\n"
+ << condition_in_header << std::endl;
+
+ opt::LoopUnroller loop_unroller;
+ SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
+ SinglePassRunAndCheck<PartialUnrollerTestPass<2>>(condition_in_header, output,
+ false);
}
/*
@@ -2808,7 +2765,6 @@
}
*/
TEST_F(PassClassTest, PartiallyUnrollLatchNotContinue) {
- // clang-format off
const std::string text = R"(OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
@@ -2967,7 +2923,7 @@
OpReturn
OpFunctionEnd
)";
- // clang-format on
+
SetDisassembleOptions(SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
SinglePassRunAndCheck<PartialUnrollerTestPass<3>>(text, expected, true);