Switch SPIRV-Tools to use spirv.hpp11 internally (#4981)

Fixes #4960

* Switches to using enum classes with an underlying type to avoid
  undefined behaviour
This commit is contained in:
alan-baker 2022-11-04 17:27:10 -04:00 committed by GitHub
parent c8e1588cfa
commit d35a78db57
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
523 changed files with 16054 additions and 14867 deletions

View File

@ -220,7 +220,8 @@ $(1)/opencl.std.insts.inc \
--core-insts-output=$(1)/core.insts-unified1.inc \
--glsl-insts-output=$(1)/glsl.std.450.insts.inc \
--opencl-insts-output=$(1)/opencl.std.insts.inc \
--operand-kinds-output=$(1)/operand.kinds-unified1.inc
--operand-kinds-output=$(1)/operand.kinds-unified1.inc \
--output-language=c++
@echo "[$(TARGET_ARCH_ABI)] Grammar (from unified1) : instructions & operands <= grammar JSON files"
$(LOCAL_PATH)/source/opcode.cpp: $(1)/core.insts-unified1.inc
$(LOCAL_PATH)/source/operand.cpp: $(1)/operand.kinds-unified1.inc
@ -294,7 +295,8 @@ $(1)/extension_enum.inc $(1)/enum_string_mapping.inc: \
--extinst-debuginfo-grammar=$(SPV_DEBUGINFO_GRAMMAR) \
--extinst-cldebuginfo100-grammar=$(SPV_CLDEBUGINFO100_GRAMMAR) \
--extension-enum-output=$(1)/extension_enum.inc \
--enum-string-mapping-output=$(1)/enum_string_mapping.inc
--enum-string-mapping-output=$(1)/enum_string_mapping.inc \
--output-language=c++
@echo "[$(TARGET_ARCH_ABI)] Generate enum<->string mapping <= grammar JSON files"
# Generated header extension_enum.inc is transitively included by table.h, which is
# used pervasively. Capture the pervasive dependency.

View File

@ -137,7 +137,7 @@ cc_library(
copts = COMMON_COPTS,
includes = ["source"],
deps = [
"@spirv_headers//:spirv_c_headers",
"@spirv_headers//:spirv_cpp11_headers",
],
)
@ -162,7 +162,7 @@ cc_library(
deps = [
":generated_headers",
":spirv_tools_headers",
"@spirv_headers//:spirv_c_headers",
"@spirv_headers//:spirv_cpp11_headers",
"@spirv_headers//:spirv_common_headers",
],
)

View File

@ -69,6 +69,8 @@ template("spvtools_core_tables") {
rebase_path(cldebuginfo100_insts_file, root_build_dir),
"--operand-kinds-output",
rebase_path(operand_kinds_file, root_build_dir),
"--output-language",
"c++"
]
}
}
@ -101,6 +103,8 @@ template("spvtools_core_enums") {
rebase_path(extension_enum_file, root_build_dir),
"--enum-string-mapping-output",
rebase_path(extension_map_file, root_build_dir),
"--output-language",
"c++"
]
inputs = [
core_json_file,
@ -142,6 +146,8 @@ template("spvtools_glsl_tables") {
rebase_path(glsl_json_file, root_build_dir),
"--glsl-insts-output",
rebase_path(glsl_insts_file, root_build_dir),
"--output-language",
"c++"
]
inputs = [
core_json_file,

View File

@ -200,7 +200,7 @@ function(spvtools_default_compile_options TARGET)
if(NOT "${SPIRV_PERF}" STREQUAL "")
target_compile_options(${TARGET} PRIVATE -fno-omit-frame-pointer)
endif()
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang")
set(SPIRV_USE_SANITIZER "" CACHE STRING
"Use the clang sanitizer [address|memory|thread|...]")
if(NOT "${SPIRV_USE_SANITIZER}" STREQUAL "")

2
DEPS
View File

@ -6,7 +6,7 @@ vars = {
'effcee_revision': '35912e1b7778ec2ddcff7e7188177761539e59e0',
'googletest_revision': 'd9bb8412d60b993365abb53f00b6dad9b2c01b62',
're2_revision': 'd2836d1b1c34c4e330a85a1006201db474bf2c8a',
'spirv_headers_revision': '85a1ed200d50660786c1a88d9166e871123cce39',
'spirv_headers_revision': '47f2465ee3e78ec5ec38f00b2c405d9475797228',
}
deps = {

View File

@ -66,7 +66,8 @@ def generate_core_tables(version = None):
"--extinst-debuginfo-grammar=$(location {1}) " +
"--extinst-cldebuginfo100-grammar=$(location {2}) " +
"--core-insts-output=$(location {3}) " +
"--operand-kinds-output=$(location {4})"
"--operand-kinds-output=$(location {4}) " +
"--output-language=c++"
).format(*fmtargs),
cmd_bat = (
"$(location :generate_grammar_tables) " +
@ -74,7 +75,8 @@ def generate_core_tables(version = None):
"--extinst-debuginfo-grammar=$(location {1}) " +
"--extinst-cldebuginfo100-grammar=$(location {2}) " +
"--core-insts-output=$(location {3}) " +
"--operand-kinds-output=$(location {4})"
"--operand-kinds-output=$(location {4}) " +
"--output-language=c++"
).format(*fmtargs),
exec_tools = [":generate_grammar_tables"],
visibility = ["//visibility:private"],
@ -103,7 +105,8 @@ def generate_enum_string_mapping(version = None):
"--extinst-debuginfo-grammar=$(location {1}) " +
"--extinst-cldebuginfo100-grammar=$(location {2}) " +
"--extension-enum-output=$(location {3}) " +
"--enum-string-mapping-output=$(location {4})"
"--enum-string-mapping-output=$(location {4}) " +
"--output-language=c++"
).format(*fmtargs),
cmd_bat = (
"$(location :generate_grammar_tables) " +
@ -111,7 +114,8 @@ def generate_enum_string_mapping(version = None):
"--extinst-debuginfo-grammar=$(location {1}) " +
"--extinst-cldebuginfo100-grammar=$(location {2}) " +
"--extension-enum-output=$(location {3}) " +
"--enum-string-mapping-output=$(location {4})"
"--enum-string-mapping-output=$(location {4}) " +
"--output-language=c++"
).format(*fmtargs),
exec_tools = [":generate_grammar_tables"],
visibility = ["//visibility:private"],
@ -158,12 +162,14 @@ def generate_glsl_tables(version = None):
cmd = (
"$(location :generate_grammar_tables) " +
"--extinst-glsl-grammar=$(location {0}) " +
"--glsl-insts-output=$(location {1})"
"--glsl-insts-output=$(location {1}) " +
"--output-language=c++"
).format(*fmtargs),
cmd_bat = (
"$(location :generate_grammar_tables) " +
"--extinst-glsl-grammar=$(location {0}) " +
"--glsl-insts-output=$(location {1})"
"--glsl-insts-output=$(location {1}) " +
"--output-language=c++"
).format(*fmtargs),
exec_tools = [":generate_grammar_tables"],
visibility = ["//visibility:private"],

View File

@ -37,6 +37,7 @@ macro(spvtools_core_tables CONFIG_VERSION)
--extinst-cldebuginfo100-grammar=${CLDEBUGINFO100_GRAMMAR_JSON_FILE}
--core-insts-output=${GRAMMAR_INSTS_INC_FILE}
--operand-kinds-output=${GRAMMAR_KINDS_INC_FILE}
--output-language=c++
DEPENDS ${GRAMMAR_PROCESSING_SCRIPT}
${GRAMMAR_JSON_FILE}
${DEBUGINFO_GRAMMAR_JSON_FILE}
@ -58,6 +59,7 @@ macro(spvtools_enum_string_mapping CONFIG_VERSION)
--extinst-cldebuginfo100-grammar=${CLDEBUGINFO100_GRAMMAR_JSON_FILE}
--extension-enum-output=${GRAMMAR_EXTENSION_ENUM_INC_FILE}
--enum-string-mapping-output=${GRAMMAR_ENUM_STRING_MAPPING_INC_FILE}
--output-language=c++
DEPENDS ${GRAMMAR_PROCESSING_SCRIPT}
${GRAMMAR_JSON_FILE}
${DEBUGINFO_GRAMMAR_JSON_FILE}
@ -92,6 +94,7 @@ macro(spvtools_glsl_tables CONFIG_VERSION)
COMMAND ${PYTHON_EXECUTABLE} ${GRAMMAR_PROCESSING_SCRIPT}
--extinst-glsl-grammar=${GLSL_GRAMMAR_JSON_FILE}
--glsl-insts-output=${GRAMMAR_INC_FILE}
--output-language=c++
DEPENDS ${GRAMMAR_PROCESSING_SCRIPT} ${CORE_GRAMMAR_JSON_FILE} ${GLSL_GRAMMAR_JSON_FILE}
COMMENT "Generate info tables for GLSL extended instructions and operands v${CONFIG_VERSION}.")
list(APPEND EXTINST_CPP_DEPENDS ${GRAMMAR_INC_FILE})

View File

@ -78,16 +78,16 @@ spv_result_t spvTextParseMaskOperand(spv_target_env env,
// Associates an opcode with its name.
struct SpecConstantOpcodeEntry {
SpvOp opcode;
spv::Op opcode;
const char* name;
};
// All the opcodes allowed as the operation for OpSpecConstantOp.
// The name does not have the usual "Op" prefix. For example opcode SpvOpIAdd
// is associated with the name "IAdd".
// The name does not have the usual "Op" prefix. For example opcode
// spv::Op::IAdd is associated with the name "IAdd".
//
// clang-format off
#define CASE(NAME) { SpvOp##NAME, #NAME }
#define CASE(NAME) { spv::Op::Op##NAME, #NAME }
const SpecConstantOpcodeEntry kOpSpecConstantOpcodes[] = {
// Conversion
CASE(SConvert),
@ -173,7 +173,7 @@ bool AssemblyGrammar::isValid() const {
}
CapabilitySet AssemblyGrammar::filterCapsAgainstTargetEnv(
const SpvCapability* cap_array, uint32_t count) const {
const spv::Capability* cap_array, uint32_t count) const {
CapabilitySet cap_set;
for (uint32_t i = 0; i < count; ++i) {
spv_operand_desc cap_desc = {};
@ -194,7 +194,7 @@ spv_result_t AssemblyGrammar::lookupOpcode(const char* name,
return spvOpcodeTableNameLookup(target_env_, opcodeTable_, name, desc);
}
spv_result_t AssemblyGrammar::lookupOpcode(SpvOp opcode,
spv_result_t AssemblyGrammar::lookupOpcode(spv::Op opcode,
spv_opcode_desc* desc) const {
return spvOpcodeTableValueLookup(target_env_, opcodeTable_, opcode, desc);
}
@ -214,7 +214,7 @@ spv_result_t AssemblyGrammar::lookupOperand(spv_operand_type_t type,
}
spv_result_t AssemblyGrammar::lookupSpecConstantOpcode(const char* name,
SpvOp* opcode) const {
spv::Op* opcode) const {
const auto* last = kOpSpecConstantOpcodes + kNumOpSpecConstantOpcodes;
const auto* found =
std::find_if(kOpSpecConstantOpcodes, last,
@ -226,7 +226,7 @@ spv_result_t AssemblyGrammar::lookupSpecConstantOpcode(const char* name,
return SPV_SUCCESS;
}
spv_result_t AssemblyGrammar::lookupSpecConstantOpcode(SpvOp opcode) const {
spv_result_t AssemblyGrammar::lookupSpecConstantOpcode(spv::Op opcode) const {
const auto* last = kOpSpecConstantOpcodes + kNumOpSpecConstantOpcodes;
const auto* found =
std::find_if(kOpSpecConstantOpcodes, last,

View File

@ -41,7 +41,7 @@ class AssemblyGrammar {
// Removes capabilities not available in the current target environment and
// returns the rest.
CapabilitySet filterCapsAgainstTargetEnv(const SpvCapability* cap_array,
CapabilitySet filterCapsAgainstTargetEnv(const spv::Capability* cap_array,
uint32_t count) const;
// Fills in the desc parameter with the information about the opcode
@ -52,7 +52,7 @@ class AssemblyGrammar {
// Fills in the desc parameter with the information about the opcode
// of the valid. Returns SPV_SUCCESS if the opcode was found, and
// SPV_ERROR_INVALID_LOOKUP if the opcode does not exist.
spv_result_t lookupOpcode(SpvOp opcode, spv_opcode_desc* desc) const;
spv_result_t lookupOpcode(spv::Op opcode, spv_opcode_desc* desc) const;
// Fills in the desc parameter with the information about the given
// operand. Returns SPV_SUCCESS if the operand was found, and
@ -82,11 +82,12 @@ class AssemblyGrammar {
// the integer add opcode for OpSpecConstantOp. On success, returns
// SPV_SUCCESS and sends the discovered operation code through the opcode
// parameter. On failure, returns SPV_ERROR_INVALID_LOOKUP.
spv_result_t lookupSpecConstantOpcode(const char* name, SpvOp* opcode) const;
spv_result_t lookupSpecConstantOpcode(const char* name,
spv::Op* opcode) const;
// Returns SPV_SUCCESS if the given opcode is valid as the opcode operand
// to OpSpecConstantOp.
spv_result_t lookupSpecConstantOpcode(SpvOp opcode) const;
spv_result_t lookupSpecConstantOpcode(spv::Op opcode) const;
// Parses a mask expression string for the given operand type.
//

View File

@ -156,7 +156,7 @@ class Parser {
// Issues a diagnostic describing an exhaustion of input condition when
// trying to decode an instruction operand, and returns
// SPV_ERROR_INVALID_BINARY.
spv_result_t exhaustedInputDiagnostic(size_t inst_offset, SpvOp opcode,
spv_result_t exhaustedInputDiagnostic(size_t inst_offset, spv::Op opcode,
spv_operand_type_t type) {
return diagnostic() << "End of input reached while decoding Op"
<< spvOpcodeString(opcode) << " starting at word "
@ -318,7 +318,7 @@ spv_result_t Parser::parseInstruction() {
<< inst_word_count;
}
spv_opcode_desc opcode_desc;
if (grammar_.lookupOpcode(static_cast<SpvOp>(inst.opcode), &opcode_desc))
if (grammar_.lookupOpcode(static_cast<spv::Op>(inst.opcode), &opcode_desc))
return diagnostic() << "Invalid opcode: " << inst.opcode;
// Advance past the opcode word. But remember the of the start
@ -418,7 +418,7 @@ spv_result_t Parser::parseOperand(size_t inst_offset,
std::vector<uint32_t>* words,
std::vector<spv_parsed_operand_t>* operands,
spv_operand_pattern_t* expected_operands) {
const SpvOp opcode = static_cast<SpvOp>(inst->opcode);
const spv::Op opcode = static_cast<spv::Op>(inst->opcode);
// We'll fill in this result as we go along.
spv_parsed_operand_t parsed_operand;
parsed_operand.offset = uint16_t(_.word_index - inst_offset);
@ -473,7 +473,7 @@ spv_result_t Parser::parseOperand(size_t inst_offset,
if (!word) return diagnostic(SPV_ERROR_INVALID_ID) << "Id is 0";
parsed_operand.type = SPV_OPERAND_TYPE_ID;
if (opcode == SpvOpExtInst && parsed_operand.offset == 3) {
if (opcode == spv::Op::OpExtInst && parsed_operand.offset == 3) {
// The current word is the extended instruction set Id.
// Set the extended instruction set type for the current instruction.
auto ext_inst_type_iter = _.import_id_to_ext_inst_type.find(word);
@ -494,7 +494,7 @@ spv_result_t Parser::parseOperand(size_t inst_offset,
break;
case SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER: {
assert(SpvOpExtInst == opcode);
assert(spv::Op::OpExtInst == opcode);
assert(inst->ext_inst_type != SPV_EXT_INST_TYPE_NONE);
spv_ext_inst_desc ext_inst;
if (grammar_.lookupExtInst(inst->ext_inst_type, word, &ext_inst) ==
@ -516,14 +516,14 @@ spv_result_t Parser::parseOperand(size_t inst_offset,
} break;
case SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER: {
assert(SpvOpSpecConstantOp == opcode);
if (word > static_cast<uint32_t>(SpvOp::SpvOpMax) ||
grammar_.lookupSpecConstantOpcode(SpvOp(word))) {
assert(spv::Op::OpSpecConstantOp == opcode);
if (word > static_cast<uint32_t>(spv::Op::Max) ||
grammar_.lookupSpecConstantOpcode(spv::Op(word))) {
return diagnostic()
<< "Invalid " << spvOperandTypeStr(type) << ": " << word;
}
spv_opcode_desc opcode_entry = nullptr;
if (grammar_.lookupOpcode(SpvOp(word), &opcode_entry)) {
if (grammar_.lookupOpcode(spv::Op(word), &opcode_entry)) {
return diagnostic(SPV_ERROR_INTERNAL)
<< "OpSpecConstant opcode table out of sync";
}
@ -549,7 +549,7 @@ spv_result_t Parser::parseOperand(size_t inst_offset,
case SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER:
case SPV_OPERAND_TYPE_OPTIONAL_TYPED_LITERAL_INTEGER:
parsed_operand.type = SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER;
if (opcode == SpvOpSwitch) {
if (opcode == spv::Op::OpSwitch) {
// The literal operands have the same type as the value
// referenced by the selector Id.
const uint32_t selector_id = peekAt(inst_offset + 1);
@ -575,7 +575,8 @@ spv_result_t Parser::parseOperand(size_t inst_offset,
<< " is not a scalar integer";
}
} else {
assert(opcode == SpvOpConstant || opcode == SpvOpSpecConstant);
assert(opcode == spv::Op::OpConstant ||
opcode == spv::Op::OpSpecConstant);
// The literal number type is determined by the type Id for the
// constant.
assert(inst->type_id);
@ -607,7 +608,7 @@ spv_result_t Parser::parseOperand(size_t inst_offset,
parsed_operand.num_words = uint16_t(string_num_words);
parsed_operand.type = SPV_OPERAND_TYPE_LITERAL_STRING;
if (SpvOpExtInstImport == opcode) {
if (spv::Op::OpExtInstImport == opcode) {
// Record the extended instruction type for the ID for this import.
// There is only one string literal argument to OpExtInstImport,
// so it's sufficient to guard this just on the opcode.
@ -789,14 +790,14 @@ spv_result_t Parser::setNumericTypeInfoForType(
void Parser::recordNumberType(size_t inst_offset,
const spv_parsed_instruction_t* inst) {
const SpvOp opcode = static_cast<SpvOp>(inst->opcode);
const spv::Op opcode = static_cast<spv::Op>(inst->opcode);
if (spvOpcodeGeneratesType(opcode)) {
NumberType info = {SPV_NUMBER_NONE, 0};
if (SpvOpTypeInt == opcode) {
if (spv::Op::OpTypeInt == opcode) {
const bool is_signed = peekAt(inst_offset + 3) != 0;
info.type = is_signed ? SPV_NUMBER_SIGNED_INT : SPV_NUMBER_UNSIGNED_INT;
info.bit_width = peekAt(inst_offset + 2);
} else if (SpvOpTypeFloat == opcode) {
} else if (spv::Op::OpTypeFloat == opcode) {
info.type = SPV_NUMBER_FLOATING;
info.bit_width = peekAt(inst_offset + 2);
}

View File

@ -44,8 +44,8 @@ using IdGroup = std::vector<uint32_t>;
// different implementations produce identical results.
using IdGroupMapByName = std::map<std::string, IdGroup>;
using IdGroupMapByTypeId = std::map<uint32_t, IdGroup>;
using IdGroupMapByOp = std::map<SpvOp, IdGroup>;
using IdGroupMapByStorageClass = std::map<SpvStorageClass, IdGroup>;
using IdGroupMapByOp = std::map<spv::Op, IdGroup>;
using IdGroupMapByStorageClass = std::map<spv::StorageClass, IdGroup>;
// A set of potential id mappings that haven't been resolved yet. Any id in src
// may map in any id in dst. Note that ids are added in the same order as they
@ -301,10 +301,10 @@ class Differ {
// Get various properties from an id. These Helper functions are passed to
// `GroupIds` and `GroupIdsAndMatch` below (as the `get_group` argument).
uint32_t GroupIdsHelperGetTypeId(const IdInstructions& id_to, uint32_t id);
SpvStorageClass GroupIdsHelperGetTypePointerStorageClass(
spv::StorageClass GroupIdsHelperGetTypePointerStorageClass(
const IdInstructions& id_to, uint32_t id);
SpvOp GroupIdsHelperGetTypePointerTypeOp(const IdInstructions& id_to,
uint32_t id);
spv::Op GroupIdsHelperGetTypePointerTypeOp(const IdInstructions& id_to,
uint32_t id);
// Given a list of ids, groups them based on some value. The `get_group`
// function extracts a piece of information corresponding to each id, and the
@ -414,8 +414,8 @@ class Differ {
// Helper functions to retrieve information pertaining to an id
const opt::Instruction* GetInst(const IdInstructions& id_to, uint32_t id);
uint32_t GetConstantUint(const IdInstructions& id_to, uint32_t constant_id);
SpvExecutionModel GetExecutionModel(const opt::Module* module,
uint32_t entry_point_id);
spv::ExecutionModel GetExecutionModel(const opt::Module* module,
uint32_t entry_point_id);
bool HasName(const IdInstructions& id_to, uint32_t id);
// Get the OpName associated with an id
std::string GetName(const IdInstructions& id_to, uint32_t id, bool* has_name);
@ -424,20 +424,21 @@ class Differ {
// string, and this improves diff between SPIR-V from those tools and others.
std::string GetSanitizedName(const IdInstructions& id_to, uint32_t id);
uint32_t GetVarTypeId(const IdInstructions& id_to, uint32_t var_id,
SpvStorageClass* storage_class);
spv::StorageClass* storage_class);
bool GetDecorationValue(const IdInstructions& id_to, uint32_t id,
SpvDecoration decoration, uint32_t* decoration_value);
spv::Decoration decoration,
uint32_t* decoration_value);
const opt::Instruction* GetForwardPointerInst(const IdInstructions& id_to,
uint32_t id);
bool IsIntType(const IdInstructions& id_to, uint32_t type_id);
bool IsFloatType(const IdInstructions& id_to, uint32_t type_id);
bool IsConstantUint(const IdInstructions& id_to, uint32_t id);
bool IsVariable(const IdInstructions& id_to, uint32_t pointer_id);
bool IsOp(const IdInstructions& id_to, uint32_t id, SpvOp opcode);
bool IsOp(const IdInstructions& id_to, uint32_t id, spv::Op opcode);
bool IsPerVertexType(const IdInstructions& id_to, uint32_t type_id);
bool IsPerVertexVariable(const IdInstructions& id_to, uint32_t type_id);
SpvStorageClass GetPerVertexStorageClass(const opt::Module* module,
uint32_t type_id);
spv::StorageClass GetPerVertexStorageClass(const opt::Module* module,
uint32_t type_id);
spv_ext_inst_type_t GetExtInstType(const IdInstructions& id_to,
uint32_t set_id);
spv_number_kind_t GetNumberKind(const IdInstructions& id_to,
@ -561,19 +562,19 @@ void IdInstructions::MapIdsToInfos(
uint32_t id_operand = 0;
switch (inst.opcode()) {
case SpvOpName:
case spv::Op::OpName:
info_map = &name_map_;
break;
case SpvOpMemberName:
case spv::Op::OpMemberName:
info_map = &name_map_;
break;
case SpvOpDecorate:
case spv::Op::OpDecorate:
info_map = &decoration_map_;
break;
case SpvOpMemberDecorate:
case spv::Op::OpMemberDecorate:
info_map = &decoration_map_;
break;
case SpvOpTypeForwardPointer: {
case spv::Op::OpTypeForwardPointer: {
uint32_t id = inst.GetSingleWordOperand(0);
assert(id != 0);
@ -731,10 +732,10 @@ int Differ::ComparePreambleInstructions(const opt::Instruction* a,
// Instead of comparing OpExecutionMode entry point ids as ids, compare them
// through their corresponding execution model. This simplifies traversing
// the sorted list of instructions between src and dst modules.
if (a->opcode() == SpvOpExecutionMode) {
const SpvExecutionModel src_model =
if (a->opcode() == spv::Op::OpExecutionMode) {
const spv::ExecutionModel src_model =
GetExecutionModel(src_inst_module, a->GetSingleWordOperand(0));
const SpvExecutionModel dst_model =
const spv::ExecutionModel dst_model =
GetExecutionModel(dst_inst_module, b->GetSingleWordOperand(0));
if (src_model < dst_model) {
@ -818,17 +819,17 @@ uint32_t Differ::GroupIdsHelperGetTypeId(const IdInstructions& id_to,
return GetInst(id_to, id)->type_id();
}
SpvStorageClass Differ::GroupIdsHelperGetTypePointerStorageClass(
spv::StorageClass Differ::GroupIdsHelperGetTypePointerStorageClass(
const IdInstructions& id_to, uint32_t id) {
const opt::Instruction* inst = GetInst(id_to, id);
assert(inst && inst->opcode() == SpvOpTypePointer);
return SpvStorageClass(inst->GetSingleWordInOperand(0));
assert(inst && inst->opcode() == spv::Op::OpTypePointer);
return spv::StorageClass(inst->GetSingleWordInOperand(0));
}
SpvOp Differ::GroupIdsHelperGetTypePointerTypeOp(const IdInstructions& id_to,
uint32_t id) {
spv::Op Differ::GroupIdsHelperGetTypePointerTypeOp(const IdInstructions& id_to,
uint32_t id) {
const opt::Instruction* inst = GetInst(id_to, id);
assert(inst && inst->opcode() == SpvOpTypePointer);
assert(inst && inst->opcode() == spv::Op::OpTypePointer);
const uint32_t type_id = inst->GetSingleWordInOperand(1);
const opt::Instruction* type_inst = GetInst(id_to, type_id);
@ -1020,7 +1021,7 @@ bool Differ::DoInstructionsMatchFuzzy(const opt::Instruction* src_inst,
}
// For external instructions, make sure the set and opcode of the external
// instruction matches too.
if (src_inst->opcode() == SpvOpExtInst) {
if (src_inst->opcode() == spv::Op::OpExtInst) {
if (!DoOperandsMatch(src_inst, dst_inst, 0, 2)) {
return false;
}
@ -1064,26 +1065,26 @@ bool Differ::DoDebugAndAnnotationInstructionsMatch(
}
switch (src_inst->opcode()) {
case SpvOpString:
case SpvOpSourceExtension:
case SpvOpModuleProcessed:
case spv::Op::OpString:
case spv::Op::OpSourceExtension:
case spv::Op::OpModuleProcessed:
return DoesOperandMatch(src_inst->GetOperand(0), dst_inst->GetOperand(0));
case SpvOpSource:
case spv::Op::OpSource:
return DoOperandsMatch(src_inst, dst_inst, 0, 2);
case SpvOpSourceContinued:
case spv::Op::OpSourceContinued:
return true;
case SpvOpName:
case spv::Op::OpName:
return DoOperandsMatch(src_inst, dst_inst, 0, 1);
case SpvOpMemberName:
case spv::Op::OpMemberName:
return DoOperandsMatch(src_inst, dst_inst, 0, 2);
case SpvOpDecorate:
case spv::Op::OpDecorate:
return DoOperandsMatch(src_inst, dst_inst, 0, 2);
case SpvOpMemberDecorate:
case spv::Op::OpMemberDecorate:
return DoOperandsMatch(src_inst, dst_inst, 0, 3);
case SpvOpExtInst:
case SpvOpDecorationGroup:
case SpvOpGroupDecorate:
case SpvOpGroupMemberDecorate:
case spv::Op::OpExtInst:
case spv::Op::OpDecorationGroup:
case spv::Op::OpGroupDecorate:
case spv::Op::OpGroupMemberDecorate:
return false;
default:
return false;
@ -1095,9 +1096,9 @@ bool Differ::AreVariablesMatchable(uint32_t src_id, uint32_t dst_id,
// Variables must match by their built-in decorations.
uint32_t src_built_in_decoration = 0, dst_built_in_decoration = 0;
const bool src_is_built_in = GetDecorationValue(
src_id_to_, src_id, SpvDecorationBuiltIn, &src_built_in_decoration);
src_id_to_, src_id, spv::Decoration::BuiltIn, &src_built_in_decoration);
const bool dst_is_built_in = GetDecorationValue(
dst_id_to_, dst_id, SpvDecorationBuiltIn, &dst_built_in_decoration);
dst_id_to_, dst_id, spv::Decoration::BuiltIn, &dst_built_in_decoration);
if (src_is_built_in != dst_is_built_in) {
return false;
@ -1107,7 +1108,7 @@ bool Differ::AreVariablesMatchable(uint32_t src_id, uint32_t dst_id,
}
// Check their types and storage classes.
SpvStorageClass src_storage_class, dst_storage_class;
spv::StorageClass src_storage_class, dst_storage_class;
const uint32_t src_type_id =
GetVarTypeId(src_id_to_, src_id, &src_storage_class);
const uint32_t dst_type_id =
@ -1127,12 +1128,14 @@ bool Differ::AreVariablesMatchable(uint32_t src_id, uint32_t dst_id,
// Allow one of the two to be Private while the other is Input or
// Output, this allows matching in/out variables that have been turned
// global as part of linking two stages (as done in ANGLE).
const bool src_is_io = src_storage_class == SpvStorageClassInput ||
src_storage_class == SpvStorageClassOutput;
const bool dst_is_io = dst_storage_class == SpvStorageClassInput ||
dst_storage_class == SpvStorageClassOutput;
const bool src_is_private = src_storage_class == SpvStorageClassPrivate;
const bool dst_is_private = dst_storage_class == SpvStorageClassPrivate;
const bool src_is_io = src_storage_class == spv::StorageClass::Input ||
src_storage_class == spv::StorageClass::Output;
const bool dst_is_io = dst_storage_class == spv::StorageClass::Input ||
dst_storage_class == spv::StorageClass::Output;
const bool src_is_private =
src_storage_class == spv::StorageClass::Private;
const bool dst_is_private =
dst_storage_class == spv::StorageClass::Private;
if (!((src_is_io && dst_is_private) || (src_is_private && dst_is_io))) {
return false;
@ -1277,16 +1280,16 @@ bool Differ::MatchOpSpecConstant(const opt::Instruction* src_inst,
// Otherwise, match them by SpecId.
uint32_t src_spec_id, dst_spec_id;
if (GetDecorationValue(src_id_to_, src_id, SpvDecorationSpecId,
if (GetDecorationValue(src_id_to_, src_id, spv::Decoration::SpecId,
&src_spec_id) &&
GetDecorationValue(dst_id_to_, dst_id, SpvDecorationSpecId,
GetDecorationValue(dst_id_to_, dst_id, spv::Decoration::SpecId,
&dst_spec_id)) {
return src_spec_id == dst_spec_id;
}
// There is no SpecId decoration, while not practical, still valid.
// SpecConstantOp don't have SpecId and can be matched by operands
if (src_inst->opcode() == SpvOpSpecConstantOp) {
if (src_inst->opcode() == spv::Op::OpSpecConstantOp) {
if (src_inst->NumInOperandWords() == dst_inst->NumInOperandWords()) {
return DoOperandsMatch(src_inst, dst_inst, 0,
src_inst->NumInOperandWords());
@ -1327,13 +1330,13 @@ bool Differ::MatchOpVariable(const opt::Instruction* src_inst,
// built-in decorations.
uint32_t src_built_in_decoration;
const bool src_is_built_in = GetDecorationValue(
src_id_to_, src_id, SpvDecorationBuiltIn, &src_built_in_decoration);
src_id_to_, src_id, spv::Decoration::BuiltIn, &src_built_in_decoration);
if (src_is_built_in && AreVariablesMatchable(src_id, dst_id, flexibility)) {
return true;
}
SpvStorageClass src_storage_class, dst_storage_class;
spv::StorageClass src_storage_class, dst_storage_class;
GetVarTypeId(src_id_to_, src_id, &src_storage_class);
GetVarTypeId(dst_id_to_, dst_id, &dst_storage_class);
@ -1348,13 +1351,13 @@ bool Differ::MatchOpVariable(const opt::Instruction* src_inst,
uint32_t src_binding = 0, dst_binding = 0;
const bool src_has_set = GetDecorationValue(
src_id_to_, src_id, SpvDecorationDescriptorSet, &src_set);
src_id_to_, src_id, spv::Decoration::DescriptorSet, &src_set);
const bool dst_has_set = GetDecorationValue(
dst_id_to_, dst_id, SpvDecorationDescriptorSet, &dst_set);
const bool src_has_binding =
GetDecorationValue(src_id_to_, src_id, SpvDecorationBinding, &src_set);
const bool dst_has_binding =
GetDecorationValue(dst_id_to_, dst_id, SpvDecorationBinding, &dst_set);
dst_id_to_, dst_id, spv::Decoration::DescriptorSet, &dst_set);
const bool src_has_binding = GetDecorationValue(
src_id_to_, src_id, spv::Decoration::Binding, &src_set);
const bool dst_has_binding = GetDecorationValue(
dst_id_to_, dst_id, spv::Decoration::Binding, &dst_set);
if (src_has_set && dst_has_set && src_has_binding && dst_has_binding) {
return src_set == dst_set && src_binding == dst_binding;
@ -1367,9 +1370,9 @@ bool Differ::MatchOpVariable(const opt::Instruction* src_inst,
uint32_t src_location, dst_location;
const bool src_has_location = GetDecorationValue(
src_id_to_, src_id, SpvDecorationLocation, &src_location);
src_id_to_, src_id, spv::Decoration::Location, &src_location);
const bool dst_has_location = GetDecorationValue(
dst_id_to_, dst_id, SpvDecorationLocation, &dst_location);
dst_id_to_, dst_id, spv::Decoration::Location, &dst_location);
if (src_has_location && dst_has_location) {
return src_location == dst_location;
@ -1384,25 +1387,25 @@ bool Differ::MatchPerVertexType(uint32_t src_type_id, uint32_t dst_type_id) {
// For gl_PerVertex, find the type pointer of this type (array) and make sure
// the storage classes of src and dst match; geometry and tessellation shaders
// have two instances of gl_PerVertex.
SpvStorageClass src_storage_class =
spv::StorageClass src_storage_class =
GetPerVertexStorageClass(src_, src_type_id);
SpvStorageClass dst_storage_class =
spv::StorageClass dst_storage_class =
GetPerVertexStorageClass(dst_, dst_type_id);
assert(src_storage_class == SpvStorageClassInput ||
src_storage_class == SpvStorageClassOutput);
assert(dst_storage_class == SpvStorageClassInput ||
dst_storage_class == SpvStorageClassOutput);
assert(src_storage_class == spv::StorageClass::Input ||
src_storage_class == spv::StorageClass::Output);
assert(dst_storage_class == spv::StorageClass::Input ||
dst_storage_class == spv::StorageClass::Output);
return src_storage_class == dst_storage_class;
}
bool Differ::MatchPerVertexVariable(const opt::Instruction* src_inst,
const opt::Instruction* dst_inst) {
SpvStorageClass src_storage_class =
SpvStorageClass(src_inst->GetSingleWordInOperand(0));
SpvStorageClass dst_storage_class =
SpvStorageClass(dst_inst->GetSingleWordInOperand(0));
spv::StorageClass src_storage_class =
spv::StorageClass(src_inst->GetSingleWordInOperand(0));
spv::StorageClass dst_storage_class =
spv::StorageClass(dst_inst->GetSingleWordInOperand(0));
return src_storage_class == dst_storage_class;
}
@ -1479,7 +1482,7 @@ InstructionList Differ::GetFunctionHeader(const opt::Function& function) {
InstructionList body;
function.WhileEachInst(
[&body](const opt::Instruction* inst) {
if (inst->opcode() == SpvOpLabel) {
if (inst->opcode() == spv::Op::OpLabel) {
return false;
}
body.push_back(inst);
@ -1694,12 +1697,12 @@ void Differ::MatchVariablesUsedByMatchedInstructions(
default:
// TODO: match functions based on OpFunctionCall?
break;
case SpvOpAccessChain:
case SpvOpInBoundsAccessChain:
case SpvOpPtrAccessChain:
case SpvOpInBoundsPtrAccessChain:
case SpvOpLoad:
case SpvOpStore:
case spv::Op::OpAccessChain:
case spv::Op::OpInBoundsAccessChain:
case spv::Op::OpPtrAccessChain:
case spv::Op::OpInBoundsPtrAccessChain:
case spv::Op::OpLoad:
case spv::Op::OpStore:
const uint32_t src_pointer_id = src_inst->GetSingleWordInOperand(0);
const uint32_t dst_pointer_id = dst_inst->GetSingleWordInOperand(0);
if (IsVariable(src_id_to_, src_pointer_id) &&
@ -1727,23 +1730,24 @@ const opt::Instruction* Differ::GetInst(const IdInstructions& id_to,
uint32_t Differ::GetConstantUint(const IdInstructions& id_to,
uint32_t constant_id) {
const opt::Instruction* constant_inst = GetInst(id_to, constant_id);
assert(constant_inst->opcode() == SpvOpConstant);
assert(GetInst(id_to, constant_inst->type_id())->opcode() == SpvOpTypeInt);
assert(constant_inst->opcode() == spv::Op::OpConstant);
assert(GetInst(id_to, constant_inst->type_id())->opcode() ==
spv::Op::OpTypeInt);
return constant_inst->GetSingleWordInOperand(0);
}
SpvExecutionModel Differ::GetExecutionModel(const opt::Module* module,
uint32_t entry_point_id) {
spv::ExecutionModel Differ::GetExecutionModel(const opt::Module* module,
uint32_t entry_point_id) {
for (const opt::Instruction& inst : module->entry_points()) {
assert(inst.opcode() == SpvOpEntryPoint);
assert(inst.opcode() == spv::Op::OpEntryPoint);
if (inst.GetSingleWordOperand(1) == entry_point_id) {
return SpvExecutionModel(inst.GetSingleWordOperand(0));
return spv::ExecutionModel(inst.GetSingleWordOperand(0));
}
}
assert(false && "Unreachable");
return SpvExecutionModel(0xFFF);
return spv::ExecutionModel(0xFFF);
}
bool Differ::HasName(const IdInstructions& id_to, uint32_t id) {
@ -1751,7 +1755,7 @@ bool Differ::HasName(const IdInstructions& id_to, uint32_t id) {
assert(id < id_to.name_map_.size());
for (const opt::Instruction* inst : id_to.name_map_[id]) {
if (inst->opcode() == SpvOpName) {
if (inst->opcode() == spv::Op::OpName) {
return true;
}
}
@ -1765,7 +1769,7 @@ std::string Differ::GetName(const IdInstructions& id_to, uint32_t id,
assert(id < id_to.name_map_.size());
for (const opt::Instruction* inst : id_to.name_map_[id]) {
if (inst->opcode() == SpvOpName) {
if (inst->opcode() == spv::Op::OpName) {
*has_name = true;
return inst->GetOperand(1).AsString();
}
@ -1788,11 +1792,11 @@ std::string Differ::GetSanitizedName(const IdInstructions& id_to, uint32_t id) {
}
uint32_t Differ::GetVarTypeId(const IdInstructions& id_to, uint32_t var_id,
SpvStorageClass* storage_class) {
spv::StorageClass* storage_class) {
const opt::Instruction* var_inst = GetInst(id_to, var_id);
assert(var_inst->opcode() == SpvOpVariable);
assert(var_inst->opcode() == spv::Op::OpVariable);
*storage_class = SpvStorageClass(var_inst->GetSingleWordInOperand(0));
*storage_class = spv::StorageClass(var_inst->GetSingleWordInOperand(0));
// Get the type pointer from the variable.
const uint32_t type_pointer_id = var_inst->type_id();
@ -1803,15 +1807,15 @@ uint32_t Differ::GetVarTypeId(const IdInstructions& id_to, uint32_t var_id,
}
bool Differ::GetDecorationValue(const IdInstructions& id_to, uint32_t id,
SpvDecoration decoration,
spv::Decoration decoration,
uint32_t* decoration_value) {
assert(id != 0);
assert(id < id_to.decoration_map_.size());
for (const opt::Instruction* inst : id_to.decoration_map_[id]) {
if (inst->opcode() == SpvOpDecorate &&
if (inst->opcode() == spv::Op::OpDecorate &&
inst->GetSingleWordOperand(0) == id &&
inst->GetSingleWordOperand(1) == decoration) {
spv::Decoration(inst->GetSingleWordOperand(1)) == decoration) {
*decoration_value = inst->GetSingleWordOperand(2);
return true;
}
@ -1828,28 +1832,28 @@ const opt::Instruction* Differ::GetForwardPointerInst(
}
bool Differ::IsIntType(const IdInstructions& id_to, uint32_t type_id) {
return IsOp(id_to, type_id, SpvOpTypeInt);
return IsOp(id_to, type_id, spv::Op::OpTypeInt);
}
bool Differ::IsFloatType(const IdInstructions& id_to, uint32_t type_id) {
return IsOp(id_to, type_id, SpvOpTypeFloat);
return IsOp(id_to, type_id, spv::Op::OpTypeFloat);
}
bool Differ::IsConstantUint(const IdInstructions& id_to, uint32_t id) {
const opt::Instruction* constant_inst = GetInst(id_to, id);
if (constant_inst->opcode() != SpvOpConstant) {
if (constant_inst->opcode() != spv::Op::OpConstant) {
return false;
}
const opt::Instruction* type_inst = GetInst(id_to, constant_inst->type_id());
return type_inst->opcode() == SpvOpTypeInt;
return type_inst->opcode() == spv::Op::OpTypeInt;
}
bool Differ::IsVariable(const IdInstructions& id_to, uint32_t pointer_id) {
return IsOp(id_to, pointer_id, SpvOpVariable);
return IsOp(id_to, pointer_id, spv::Op::OpVariable);
}
bool Differ::IsOp(const IdInstructions& id_to, uint32_t id, SpvOp op) {
bool Differ::IsOp(const IdInstructions& id_to, uint32_t id, spv::Op op) {
return GetInst(id_to, id)->opcode() == op;
}
@ -1858,17 +1862,18 @@ bool Differ::IsPerVertexType(const IdInstructions& id_to, uint32_t type_id) {
assert(type_id < id_to.decoration_map_.size());
for (const opt::Instruction* inst : id_to.decoration_map_[type_id]) {
if (inst->opcode() == SpvOpMemberDecorate &&
if (inst->opcode() == spv::Op::OpMemberDecorate &&
inst->GetSingleWordOperand(0) == type_id &&
inst->GetSingleWordOperand(2) == SpvDecorationBuiltIn) {
SpvBuiltIn built_in = SpvBuiltIn(inst->GetSingleWordOperand(3));
spv::Decoration(inst->GetSingleWordOperand(2)) ==
spv::Decoration::BuiltIn) {
spv::BuiltIn built_in = spv::BuiltIn(inst->GetSingleWordOperand(3));
// Only gl_PerVertex can have, and it can only have, the following
// built-in decorations.
return built_in == SpvBuiltInPosition ||
built_in == SpvBuiltInPointSize ||
built_in == SpvBuiltInClipDistance ||
built_in == SpvBuiltInCullDistance;
return built_in == spv::BuiltIn::Position ||
built_in == spv::BuiltIn::PointSize ||
built_in == spv::BuiltIn::ClipDistance ||
built_in == spv::BuiltIn::CullDistance;
}
}
@ -1877,12 +1882,12 @@ bool Differ::IsPerVertexType(const IdInstructions& id_to, uint32_t type_id) {
bool Differ::IsPerVertexVariable(const IdInstructions& id_to, uint32_t var_id) {
// Get the type from the type pointer.
SpvStorageClass storage_class;
spv::StorageClass storage_class;
uint32_t type_id = GetVarTypeId(id_to, var_id, &storage_class);
const opt::Instruction* type_inst = GetInst(id_to, type_id);
// If array, get the element type.
if (type_inst->opcode() == SpvOpTypeArray) {
if (type_inst->opcode() == spv::Op::OpTypeArray) {
type_id = type_inst->GetSingleWordInOperand(0);
}
@ -1890,21 +1895,21 @@ bool Differ::IsPerVertexVariable(const IdInstructions& id_to, uint32_t var_id) {
return IsPerVertexType(id_to, type_id);
}
SpvStorageClass Differ::GetPerVertexStorageClass(const opt::Module* module,
uint32_t type_id) {
spv::StorageClass Differ::GetPerVertexStorageClass(const opt::Module* module,
uint32_t type_id) {
for (const opt::Instruction& inst : module->types_values()) {
switch (inst.opcode()) {
case SpvOpTypeArray:
case spv::Op::OpTypeArray:
// The gl_PerVertex instance could be an array, look for a variable of
// the array type instead.
if (inst.GetSingleWordInOperand(0) == type_id) {
type_id = inst.result_id();
}
break;
case SpvOpTypePointer:
case spv::Op::OpTypePointer:
// Find the storage class of the pointer to this type.
if (inst.GetSingleWordInOperand(1) == type_id) {
return SpvStorageClass(inst.GetSingleWordInOperand(0));
return spv::StorageClass(inst.GetSingleWordInOperand(0));
}
break;
default:
@ -1915,7 +1920,7 @@ SpvStorageClass Differ::GetPerVertexStorageClass(const opt::Module* module,
// gl_PerVertex is declared, but is unused. Return either of Input or Output
// classes just so it matches one in the other module. This should be highly
// unlikely, perhaps except for ancient GS-used-to-emulate-CS scenarios.
return SpvStorageClassOutput;
return spv::StorageClass::Output;
}
spv_ext_inst_type_t Differ::GetExtInstType(const IdInstructions& id_to,
@ -1941,9 +1946,9 @@ spv_number_kind_t Differ::GetNumberKind(const IdInstructions& id_to,
case SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER:
case SPV_OPERAND_TYPE_OPTIONAL_TYPED_LITERAL_INTEGER:
switch (inst.opcode()) {
case SpvOpSwitch:
case SpvOpConstant:
case SpvOpSpecConstant:
case spv::Op::OpSwitch:
case spv::Op::OpConstant:
case spv::Op::OpSpecConstant:
// Same kind of number as the selector (OpSwitch) or the type
// (Op*Constant).
return GetTypeNumberKind(id_to, inst.GetSingleWordOperand(0),
@ -1969,12 +1974,12 @@ spv_number_kind_t Differ::GetTypeNumberKind(const IdInstructions& id_to,
}
switch (type_inst->opcode()) {
case SpvOpTypeInt:
case spv::Op::OpTypeInt:
*number_bit_width = type_inst->GetSingleWordOperand(1);
return type_inst->GetSingleWordOperand(2) == 0 ? SPV_NUMBER_UNSIGNED_INT
: SPV_NUMBER_SIGNED_INT;
break;
case SpvOpTypeFloat:
case spv::Op::OpTypeFloat:
*number_bit_width = type_inst->GetSingleWordOperand(1);
return SPV_NUMBER_FLOATING;
default:
@ -2092,7 +2097,7 @@ void Differ::MatchTypeForwardPointers() {
return inst.GetSingleWordOperand(0);
};
auto accept_type_forward_pointer_ops = [](const opt::Instruction& inst) {
return inst.opcode() == SpvOpTypeForwardPointer;
return inst.opcode() == spv::Op::OpTypeForwardPointer;
};
PoolPotentialIds(src_->types_values(), potential_id_map.src_ids, true,
@ -2116,17 +2121,17 @@ void Differ::MatchTypeForwardPointers() {
// - If leftover is unique, match
// Group forwarded pointers by storage class first and loop over them.
GroupIdsAndMatch<SpvStorageClass>(
potential_id_map.src_ids, potential_id_map.dst_ids, SpvStorageClassMax,
&Differ::GroupIdsHelperGetTypePointerStorageClass,
GroupIdsAndMatch<spv::StorageClass>(
potential_id_map.src_ids, potential_id_map.dst_ids,
spv::StorageClass::Max, &Differ::GroupIdsHelperGetTypePointerStorageClass,
[this](const IdGroup& src_group_by_storage_class,
const IdGroup& dst_group_by_storage_class) {
// Group them further by the type they are pointing to and loop over
// them.
GroupIdsAndMatch<SpvOp>(
src_group_by_storage_class, dst_group_by_storage_class, SpvOpMax,
&Differ::GroupIdsHelperGetTypePointerTypeOp,
GroupIdsAndMatch<spv::Op>(
src_group_by_storage_class, dst_group_by_storage_class,
spv::Op::Max, &Differ::GroupIdsHelperGetTypePointerTypeOp,
[this](const IdGroup& src_group_by_type_op,
const IdGroup& dst_group_by_type_op) {
@ -2182,8 +2187,8 @@ void Differ::MatchTypeIds() {
MatchIds(potential_id_map, [this, flexibility](
const opt::Instruction* src_inst,
const opt::Instruction* dst_inst) {
const SpvOp src_op = src_inst->opcode();
const SpvOp dst_op = dst_inst->opcode();
const spv::Op src_op = src_inst->opcode();
const spv::Op dst_op = dst_inst->opcode();
// Don't match if the opcode is not the same.
if (src_op != dst_op) {
@ -2191,26 +2196,26 @@ void Differ::MatchTypeIds() {
}
switch (src_op) {
case SpvOpTypeVoid:
case SpvOpTypeBool:
case SpvOpTypeSampler:
case spv::Op::OpTypeVoid:
case spv::Op::OpTypeBool:
case spv::Op::OpTypeSampler:
// void, bool and sampler are unique, match them.
return true;
case SpvOpTypeInt:
case SpvOpTypeFloat:
case SpvOpTypeVector:
case SpvOpTypeMatrix:
case SpvOpTypeSampledImage:
case SpvOpTypeRuntimeArray:
case SpvOpTypePointer:
case spv::Op::OpTypeInt:
case spv::Op::OpTypeFloat:
case spv::Op::OpTypeVector:
case spv::Op::OpTypeMatrix:
case spv::Op::OpTypeSampledImage:
case spv::Op::OpTypeRuntimeArray:
case spv::Op::OpTypePointer:
// Match these instructions when all operands match.
assert(src_inst->NumInOperandWords() ==
dst_inst->NumInOperandWords());
return DoOperandsMatch(src_inst, dst_inst, 0,
src_inst->NumInOperandWords());
case SpvOpTypeFunction:
case SpvOpTypeImage:
case spv::Op::OpTypeFunction:
case spv::Op::OpTypeImage:
// Match function types only if they have the same number of operands,
// and they all match.
// Match image types similarly, expecting the optional final parameter
@ -2221,7 +2226,7 @@ void Differ::MatchTypeIds() {
return DoOperandsMatch(src_inst, dst_inst, 0,
src_inst->NumInOperandWords());
case SpvOpTypeArray:
case spv::Op::OpTypeArray:
// Match arrays only if the element type and length match. The length
// is an id of a constant, so the actual constant it's defining is
// compared instead.
@ -2238,7 +2243,7 @@ void Differ::MatchTypeIds() {
// example if a spec contant is used).
return DoOperandsMatch(src_inst, dst_inst, 1, 1);
case SpvOpTypeStruct:
case spv::Op::OpTypeStruct:
return MatchOpTypeStruct(src_inst, dst_inst, flexibility);
default:
@ -2270,8 +2275,8 @@ void Differ::MatchConstants() {
MatchIds(potential_id_map, [this, flexibility](
const opt::Instruction* src_inst,
const opt::Instruction* dst_inst) {
const SpvOp src_op = src_inst->opcode();
const SpvOp dst_op = dst_inst->opcode();
const spv::Op src_op = src_inst->opcode();
const spv::Op dst_op = dst_inst->opcode();
// Don't match if the opcode is not the same.
if (src_op != dst_op) {
@ -2279,14 +2284,14 @@ void Differ::MatchConstants() {
}
switch (src_op) {
case SpvOpConstantTrue:
case SpvOpConstantFalse:
case spv::Op::OpConstantTrue:
case spv::Op::OpConstantFalse:
// true and false are unique, match them.
return true;
case SpvOpConstant:
case spv::Op::OpConstant:
return MatchOpConstant(src_inst, dst_inst, flexibility);
case SpvOpConstantComposite:
case SpvOpSpecConstantComposite:
case spv::Op::OpConstantComposite:
case spv::Op::OpSpecConstantComposite:
// Composite constants must match in type and value.
//
// TODO: match OpConstantNull with OpConstantComposite with all zeros
@ -2299,7 +2304,7 @@ void Differ::MatchConstants() {
dst_inst->GetOperand(0)) &&
DoOperandsMatch(src_inst, dst_inst, 0,
src_inst->NumInOperandWords());
case SpvOpConstantSampler:
case spv::Op::OpConstantSampler:
// Match sampler constants exactly.
// TODO: Allow flexibility in parameters to better diff shaders where
// the sampler param has changed.
@ -2307,15 +2312,15 @@ void Differ::MatchConstants() {
dst_inst->NumInOperandWords());
return DoOperandsMatch(src_inst, dst_inst, 0,
src_inst->NumInOperandWords());
case SpvOpConstantNull:
case spv::Op::OpConstantNull:
// Match null constants as long as the type matches.
return DoesOperandMatch(src_inst->GetOperand(0),
dst_inst->GetOperand(0));
case SpvOpSpecConstantTrue:
case SpvOpSpecConstantFalse:
case SpvOpSpecConstant:
case SpvOpSpecConstantOp:
case spv::Op::OpSpecConstantTrue:
case spv::Op::OpSpecConstantFalse:
case spv::Op::OpSpecConstant:
case spv::Op::OpSpecConstantOp:
// Match spec constants by name if available, then by the SpecId
// decoration.
return MatchOpSpecConstant(src_inst, dst_inst);
@ -2334,7 +2339,7 @@ void Differ::MatchVariableIds() {
return inst.result_id();
};
auto accept_type_ops = [](const opt::Instruction& inst) {
return inst.opcode() == SpvOpVariable;
return inst.opcode() == spv::Op::OpVariable;
};
PoolPotentialIds(src_->types_values(), potential_id_map.src_ids, true,
@ -2350,8 +2355,8 @@ void Differ::MatchVariableIds() {
MatchIds(potential_id_map,
[this, flexibility](const opt::Instruction* src_inst,
const opt::Instruction* dst_inst) {
assert(src_inst->opcode() == SpvOpVariable);
assert(dst_inst->opcode() == SpvOpVariable);
assert(src_inst->opcode() == spv::Op::OpVariable);
assert(dst_inst->opcode() == spv::Op::OpVariable);
return MatchOpVariable(src_inst, dst_inst, flexibility);
});
@ -2597,7 +2602,7 @@ void Differ::ToParsedInstruction(
parsed_inst->num_words = static_cast<uint16_t>(inst_binary.size());
parsed_inst->opcode = static_cast<uint16_t>(inst.opcode());
parsed_inst->ext_inst_type =
inst.opcode() == SpvOpExtInst
inst.opcode() == spv::Op::OpExtInst
? GetExtInstType(id_to, original_inst.GetSingleWordInOperand(0))
: SPV_EXT_INST_TYPE_NONE;
parsed_inst->type_id =

View File

@ -244,7 +244,7 @@ void InstructionDisassembler::EmitHeaderSchema(uint32_t schema) {
void InstructionDisassembler::EmitInstruction(
const spv_parsed_instruction_t& inst, size_t inst_byte_offset) {
auto opcode = static_cast<SpvOp>(inst.opcode);
auto opcode = static_cast<spv::Op>(inst.opcode);
if (inst.result_id) {
SetBlue();
@ -268,7 +268,7 @@ void InstructionDisassembler::EmitInstruction(
EmitOperand(inst, i);
}
if (comment_ && opcode == SpvOpName) {
if (comment_ && opcode == spv::Op::OpName) {
const spv_parsed_operand_t& operand = inst.operands[0];
const uint32_t word = inst.words[operand.offset];
stream_ << " ; id %" << word;
@ -290,8 +290,8 @@ void InstructionDisassembler::EmitInstruction(
void InstructionDisassembler::EmitSectionComment(
const spv_parsed_instruction_t& inst, bool& inserted_decoration_space,
bool& inserted_debug_space, bool& inserted_type_space) {
auto opcode = static_cast<SpvOp>(inst.opcode);
if (comment_ && opcode == SpvOpFunction) {
auto opcode = static_cast<spv::Op>(inst.opcode);
if (comment_ && opcode == spv::Op::OpFunction) {
stream_ << std::endl;
stream_ << std::string(indent_, ' ');
stream_ << "; Function " << name_mapper_(inst.result_id) << std::endl;
@ -351,7 +351,7 @@ void InstructionDisassembler::EmitOperand(const spv_parsed_instruction_t& inst,
} break;
case SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER: {
spv_opcode_desc opcode_desc;
if (grammar_.lookupOpcode(SpvOp(word), &opcode_desc))
if (grammar_.lookupOpcode(spv::Op(word), &opcode_desc))
assert(false && "should have caught this earlier");
SetRed();
stream_ << opcode_desc->name;

View File

@ -200,8 +200,8 @@ class EnumSet {
std::unique_ptr<OverflowSetType> overflow_ = {};
};
// A set of SpvCapability, optimized for small capability values.
using CapabilitySet = EnumSet<SpvCapability>;
// A set of spv::Capability, optimized for small capability values.
using CapabilitySet = EnumSet<spv::Capability>;
} // namespace spvtools

View File

@ -29,7 +29,7 @@ bool GetExtensionFromString(const char* str, Extension* extension);
const char* ExtensionToString(Extension extension);
// Returns text string corresponding to |capability|.
const char* CapabilityToString(SpvCapability capability);
const char* CapabilityToString(spv::Capability capability);
} // namespace spvtools

View File

@ -24,7 +24,9 @@
namespace spvtools {
std::string GetExtensionString(const spv_parsed_instruction_t* inst) {
if (inst->opcode != SpvOpExtension) return "ERROR_not_op_extension";
if (inst->opcode != static_cast<uint16_t>(spv::Op::OpExtension)) {
return "ERROR_not_op_extension";
}
assert(inst->num_operands == 1);

View File

@ -130,7 +130,7 @@ bool AddedFunctionReducer::InterestingnessFunctionForReducingAddedFunction(
binary_under_reduction.size());
assert(ir_context != nullptr && "The binary should be parsable.");
for (auto& type_or_value : ir_context->module()->types_values()) {
if (type_or_value.opcode() != SpvOpVariable) {
if (type_or_value.opcode() != spv::Op::OpVariable) {
continue;
}
if (irrelevant_pointee_global_variables.count(type_or_value.result_id())) {
@ -202,7 +202,7 @@ void AddedFunctionReducer::ReplayPrefixAndAddFunction(
auto* ir_context = replay_result.transformed_module.get();
for (auto& type_or_value : ir_context->module()->types_values()) {
if (type_or_value.opcode() != SpvOpVariable) {
if (type_or_value.opcode() != spv::Op::OpVariable) {
continue;
}
if (replay_result.transformation_context->GetFactManager()

View File

@ -54,7 +54,7 @@ void CallGraph::BuildGraphAndGetDepthOfFunctionCalls(
// Consider every function call instruction in every block.
for (auto& block : function) {
for (auto& instruction : block) {
if (instruction.opcode() != SpvOpFunctionCall) {
if (instruction.opcode() != spv::Op::OpFunctionCall) {
continue;
}
// Get the id of the function being called.

View File

@ -63,7 +63,7 @@ std::vector<uint32_t> ConstantUniformFacts::GetConstantWords(
bool ConstantUniformFacts::DataMatches(
const opt::Instruction& constant_instruction,
const protobufs::FactConstantUniform& constant_uniform_fact) {
assert(constant_instruction.opcode() == SpvOpConstant);
assert(constant_instruction.opcode() == spv::Op::OpConstant);
std::vector<uint32_t> data_in_constant;
for (uint32_t i = 0; i < constant_instruction.NumInOperands(); i++) {
data_in_constant.push_back(constant_instruction.GetSingleWordInOperand(i));
@ -95,7 +95,7 @@ ConstantUniformFacts::GetUniformDescriptorsForConstant(
uint32_t constant_id) const {
std::vector<protobufs::UniformBufferElementDescriptor> result;
auto constant_inst = ir_context_->get_def_use_mgr()->GetDef(constant_id);
assert(constant_inst->opcode() == SpvOpConstant &&
assert(constant_inst->opcode() == spv::Op::OpConstant &&
"The given id must be that of a constant");
auto type_id = constant_inst->type_id();
for (auto& fact_and_type_id : facts_and_type_ids_) {
@ -175,8 +175,9 @@ bool ConstantUniformFacts::MaybeAddFact(
return false;
}
assert(SpvOpVariable == uniform_variable->opcode());
assert(SpvStorageClassUniform == uniform_variable->GetSingleWordInOperand(0));
assert(spv::Op::OpVariable == uniform_variable->opcode());
assert(spv::StorageClass::Uniform ==
spv::StorageClass(uniform_variable->GetSingleWordInOperand(0)));
auto should_be_uniform_pointer_type =
ir_context_->get_type_mgr()->GetType(uniform_variable->type_id());
@ -184,7 +185,7 @@ bool ConstantUniformFacts::MaybeAddFact(
return false;
}
if (should_be_uniform_pointer_type->AsPointer()->storage_class() !=
SpvStorageClassUniform) {
spv::StorageClass::Uniform) {
return false;
}
auto should_be_uniform_pointer_instruction =

View File

@ -23,7 +23,7 @@ namespace fact_manager {
size_t DataSynonymAndIdEquationFacts::OperationHash::operator()(
const Operation& operation) const {
std::u32string hash;
hash.push_back(operation.opcode);
hash.push_back(uint32_t(operation.opcode));
for (auto operand : operation.operands) {
hash.push_back(static_cast<uint32_t>(DataDescriptorHash()(operand)));
}
@ -104,7 +104,8 @@ bool DataSynonymAndIdEquationFacts::MaybeAddFact(
}
// Now add the fact.
AddEquationFactRecursive(lhs_dd, static_cast<SpvOp>(fact.opcode()), rhs_dds);
AddEquationFactRecursive(lhs_dd, static_cast<spv::Op>(fact.opcode()),
rhs_dds);
return true;
}
@ -119,7 +120,7 @@ DataSynonymAndIdEquationFacts::GetEquations(
}
void DataSynonymAndIdEquationFacts::AddEquationFactRecursive(
const protobufs::DataDescriptor& lhs_dd, SpvOp opcode,
const protobufs::DataDescriptor& lhs_dd, spv::Op opcode,
const std::vector<const protobufs::DataDescriptor*>& rhs_dds) {
assert(synonymous_.Exists(lhs_dd) &&
"The LHS must be known to the equivalence relation.");
@ -155,21 +156,21 @@ void DataSynonymAndIdEquationFacts::AddEquationFactRecursive(
// Now try to work out corollaries implied by the new equation and existing
// facts.
switch (opcode) {
case SpvOpConvertSToF:
case SpvOpConvertUToF:
case spv::Op::OpConvertSToF:
case spv::Op::OpConvertUToF:
ComputeConversionDataSynonymFacts(*rhs_dds[0]);
break;
case SpvOpBitcast: {
case spv::Op::OpBitcast: {
assert(DataDescriptorsAreWellFormedAndComparable(lhs_dd, *rhs_dds[0]) &&
"Operands of OpBitcast equation fact must have compatible types");
if (!synonymous_.IsEquivalent(lhs_dd, *rhs_dds[0])) {
AddDataSynonymFactRecursive(lhs_dd, *rhs_dds[0]);
}
} break;
case SpvOpIAdd: {
case spv::Op::OpIAdd: {
// Equation form: "a = b + c"
for (const auto& equation : GetEquations(rhs_dds[0])) {
if (equation.opcode == SpvOpISub) {
if (equation.opcode == spv::Op::OpISub) {
// Equation form: "a = (d - e) + c"
if (synonymous_.IsEquivalent(*equation.operands[1], *rhs_dds[1])) {
// Equation form: "a = (d - c) + c"
@ -179,7 +180,7 @@ void DataSynonymAndIdEquationFacts::AddEquationFactRecursive(
}
}
for (const auto& equation : GetEquations(rhs_dds[1])) {
if (equation.opcode == SpvOpISub) {
if (equation.opcode == spv::Op::OpISub) {
// Equation form: "a = b + (d - e)"
if (synonymous_.IsEquivalent(*equation.operands[1], *rhs_dds[0])) {
// Equation form: "a = b + (d - b)"
@ -190,10 +191,10 @@ void DataSynonymAndIdEquationFacts::AddEquationFactRecursive(
}
break;
}
case SpvOpISub: {
case spv::Op::OpISub: {
// Equation form: "a = b - c"
for (const auto& equation : GetEquations(rhs_dds[0])) {
if (equation.opcode == SpvOpIAdd) {
if (equation.opcode == spv::Op::OpIAdd) {
// Equation form: "a = (d + e) - c"
if (synonymous_.IsEquivalent(*equation.operands[0], *rhs_dds[1])) {
// Equation form: "a = (c + e) - c"
@ -207,34 +208,34 @@ void DataSynonymAndIdEquationFacts::AddEquationFactRecursive(
}
}
if (equation.opcode == SpvOpISub) {
if (equation.opcode == spv::Op::OpISub) {
// Equation form: "a = (d - e) - c"
if (synonymous_.IsEquivalent(*equation.operands[0], *rhs_dds[1])) {
// Equation form: "a = (c - e) - c"
// We can thus infer "a = -e"
AddEquationFactRecursive(lhs_dd, SpvOpSNegate,
AddEquationFactRecursive(lhs_dd, spv::Op::OpSNegate,
{equation.operands[1]});
}
}
}
for (const auto& equation : GetEquations(rhs_dds[1])) {
if (equation.opcode == SpvOpIAdd) {
if (equation.opcode == spv::Op::OpIAdd) {
// Equation form: "a = b - (d + e)"
if (synonymous_.IsEquivalent(*equation.operands[0], *rhs_dds[0])) {
// Equation form: "a = b - (b + e)"
// We can thus infer "a = -e"
AddEquationFactRecursive(lhs_dd, SpvOpSNegate,
AddEquationFactRecursive(lhs_dd, spv::Op::OpSNegate,
{equation.operands[1]});
}
if (synonymous_.IsEquivalent(*equation.operands[1], *rhs_dds[0])) {
// Equation form: "a = b - (d + b)"
// We can thus infer "a = -d"
AddEquationFactRecursive(lhs_dd, SpvOpSNegate,
AddEquationFactRecursive(lhs_dd, spv::Op::OpSNegate,
{equation.operands[0]});
}
}
if (equation.opcode == SpvOpISub) {
if (equation.opcode == spv::Op::OpISub) {
// Equation form: "a = b - (d - e)"
if (synonymous_.IsEquivalent(*equation.operands[0], *rhs_dds[0])) {
// Equation form: "a = b - (b - e)"
@ -245,8 +246,8 @@ void DataSynonymAndIdEquationFacts::AddEquationFactRecursive(
}
break;
}
case SpvOpLogicalNot:
case SpvOpSNegate: {
case spv::Op::OpLogicalNot:
case spv::Op::OpSNegate: {
// Equation form: "a = !b" or "a = -b"
for (const auto& equation : GetEquations(rhs_dds[0])) {
if (equation.opcode == opcode) {
@ -321,9 +322,9 @@ void DataSynonymAndIdEquationFacts::ComputeConversionDataSynonymFacts(
for (const auto& equation : fact.second) {
if (synonymous_.IsEquivalent(*equation.operands[0], dd)) {
if (equation.opcode == SpvOpConvertSToF) {
if (equation.opcode == spv::Op::OpConvertSToF) {
convert_s_to_f_lhs.push_back(*dd_it);
} else if (equation.opcode == SpvOpConvertUToF) {
} else if (equation.opcode == spv::Op::OpConvertUToF) {
convert_u_to_f_lhs.push_back(*dd_it);
}
}
@ -808,9 +809,9 @@ bool DataSynonymAndIdEquationFacts::DataDescriptorsAreWellFormedAndComparable(
}
// Neither end type is allowed to be void.
if (ir_context_->get_def_use_mgr()->GetDef(end_type_id_1)->opcode() ==
SpvOpTypeVoid ||
spv::Op::OpTypeVoid ||
ir_context_->get_def_use_mgr()->GetDef(end_type_id_2)->opcode() ==
SpvOpTypeVoid) {
spv::Op::OpTypeVoid) {
return false;
}
// If the end types are the same, the data descriptors are comparable.

View File

@ -79,7 +79,7 @@ class DataSynonymAndIdEquationFacts {
// This helper struct represents the right hand side of an equation as an
// operator applied to a number of data descriptor operands.
struct Operation {
SpvOp opcode;
spv::Op opcode;
std::vector<const protobufs::DataDescriptor*> operands;
};
@ -144,7 +144,7 @@ class DataSynonymAndIdEquationFacts {
// corollaries, in the form of data synonym or equation facts, that follow
// from this and other known facts.
void AddEquationFactRecursive(
const protobufs::DataDescriptor& lhs_dd, SpvOp opcode,
const protobufs::DataDescriptor& lhs_dd, spv::Op opcode,
const std::vector<const protobufs::DataDescriptor*>& rhs_dds);
// Returns true if and only if |dd.object()| still exists in the module.

View File

@ -64,7 +64,7 @@ std::string ToString(const protobufs::FactDataSynonym& fact) {
std::string ToString(const protobufs::FactIdEquation& fact) {
std::stringstream stream;
stream << fact.lhs_id();
stream << " " << static_cast<SpvOp>(fact.opcode());
stream << " " << fact.opcode();
for (auto rhs_id : fact.rhs_id()) {
stream << " " << rhs_id;
}
@ -255,11 +255,11 @@ void FactManager::AddFactIdIsIrrelevant(uint32_t result_id) {
assert(success && "|result_id| is invalid");
}
void FactManager::AddFactIdEquation(uint32_t lhs_id, SpvOp opcode,
void FactManager::AddFactIdEquation(uint32_t lhs_id, spv::Op opcode,
const std::vector<uint32_t>& rhs_id) {
protobufs::FactIdEquation fact;
fact.set_lhs_id(lhs_id);
fact.set_opcode(opcode);
fact.set_opcode(uint32_t(opcode));
for (auto an_rhs_id : rhs_id) {
fact.add_rhs_id(an_rhs_id);
}

View File

@ -83,7 +83,7 @@ class FactManager {
// |lhs_id| = |opcode| |rhs_id[0]| ... |rhs_id[N-1]|
//
// Neither |lhs_id| nor any of |rhs_id| may be irrelevant.
void AddFactIdEquation(uint32_t lhs_id, SpvOp opcode,
void AddFactIdEquation(uint32_t lhs_id, spv::Op opcode,
const std::vector<uint32_t>& rhs_id);
// Inspects all known facts and adds corollary facts; e.g. if we know that

View File

@ -36,8 +36,9 @@ opt::Function* FindFragmentShaderEntryPoint(opt::IRContext* ir_context,
// Check that this is a fragment shader
bool found_capability_shader = false;
for (auto& capability : ir_context->capabilities()) {
assert(capability.opcode() == SpvOpCapability);
if (capability.GetSingleWordInOperand(0) == SpvCapabilityShader) {
assert(capability.opcode() == spv::Op::OpCapability);
if (spv::Capability(capability.GetSingleWordInOperand(0)) ==
spv::Capability::Shader) {
found_capability_shader = true;
break;
}
@ -51,7 +52,8 @@ opt::Function* FindFragmentShaderEntryPoint(opt::IRContext* ir_context,
opt::Instruction* fragment_entry_point = nullptr;
for (auto& entry_point : ir_context->module()->entry_points()) {
if (entry_point.GetSingleWordInOperand(0) == SpvExecutionModelFragment) {
if (spv::ExecutionModel(entry_point.GetSingleWordInOperand(0)) ==
spv::ExecutionModel::Fragment) {
fragment_entry_point = &entry_point;
break;
}
@ -81,8 +83,9 @@ opt::Instruction* FindVec4OutputVariable(opt::IRContext* ir_context,
MessageConsumer message_consumer) {
opt::Instruction* output_variable = nullptr;
for (auto& inst : ir_context->types_values()) {
if (inst.opcode() == SpvOpVariable &&
inst.GetSingleWordInOperand(0) == SpvStorageClassOutput) {
if (inst.opcode() == spv::Op::OpVariable &&
spv::StorageClass(inst.GetSingleWordInOperand(0)) ==
spv::StorageClass::Output) {
if (output_variable != nullptr) {
message_consumer(SPV_MSG_ERROR, nullptr, {},
"Only one output variable can be handled at present; "
@ -144,10 +147,11 @@ MakeConstantUniformReplacement(opt::IRContext* ir_context,
uint32_t greater_than_instruction,
uint32_t in_operand_index) {
return MakeUnique<TransformationReplaceConstantWithUniform>(
MakeIdUseDescriptor(constant_id,
MakeInstructionDescriptor(greater_than_instruction,
SpvOpFOrdGreaterThan, 0),
in_operand_index),
MakeIdUseDescriptor(
constant_id,
MakeInstructionDescriptor(greater_than_instruction,
spv::Op::OpFOrdGreaterThan, 0),
in_operand_index),
fact_manager.GetUniformDescriptorsForConstant(constant_id)[0],
ir_context->TakeNextId(), ir_context->TakeNextId());
}
@ -204,20 +208,21 @@ bool ForceRenderRed(
// Make the new exit block
auto new_exit_block_id = ir_context->TakeNextId();
{
auto label = MakeUnique<opt::Instruction>(ir_context.get(), SpvOpLabel, 0,
new_exit_block_id,
opt::Instruction::OperandList());
auto label = MakeUnique<opt::Instruction>(
ir_context.get(), spv::Op::OpLabel, 0, new_exit_block_id,
opt::Instruction::OperandList());
auto new_exit_block = MakeUnique<opt::BasicBlock>(std::move(label));
new_exit_block->AddInstruction(MakeUnique<opt::Instruction>(
ir_context.get(), SpvOpReturn, 0, 0, opt::Instruction::OperandList()));
new_exit_block->AddInstruction(
MakeUnique<opt::Instruction>(ir_context.get(), spv::Op::OpReturn, 0, 0,
opt::Instruction::OperandList()));
entry_point_function->AddBasicBlock(std::move(new_exit_block));
}
// Make the new entry block
{
auto label = MakeUnique<opt::Instruction>(ir_context.get(), SpvOpLabel, 0,
ir_context->TakeNextId(),
opt::Instruction::OperandList());
auto label = MakeUnique<opt::Instruction>(
ir_context.get(), spv::Op::OpLabel, 0, ir_context->TakeNextId(),
opt::Instruction::OperandList());
auto new_entry_block = MakeUnique<opt::BasicBlock>(std::move(label));
// Make an instruction to construct vec4(1.0, 0.0, 0.0, 1.0), representing
@ -229,7 +234,7 @@ bool ForceRenderRed(
auto temp_vec4 = opt::analysis::Vector(float_type, 4);
auto vec4_id = ir_context->get_type_mgr()->GetId(&temp_vec4);
auto red = MakeUnique<opt::Instruction>(
ir_context.get(), SpvOpCompositeConstruct, vec4_id,
ir_context.get(), spv::Op::OpCompositeConstruct, vec4_id,
ir_context->TakeNextId(), op_composite_construct_operands);
auto red_id = red->result_id();
new_entry_block->AddInstruction(std::move(red));
@ -241,7 +246,7 @@ bool ForceRenderRed(
opt::Instruction::OperandList op_store_operands = {variable_to_store_into,
value_to_be_stored};
new_entry_block->AddInstruction(MakeUnique<opt::Instruction>(
ir_context.get(), SpvOpStore, 0, 0, op_store_operands));
ir_context.get(), spv::Op::OpStore, 0, 0, op_store_operands));
// We are going to attempt to construct 'false' as an expression of the form
// 'literal1 > literal2'. If we succeed, we will later replace each literal
@ -313,7 +318,7 @@ bool ForceRenderRed(
{SPV_OPERAND_TYPE_ID, {smaller_constant}},
{SPV_OPERAND_TYPE_ID, {larger_constant}}};
new_entry_block->AddInstruction(MakeUnique<opt::Instruction>(
ir_context.get(), SpvOpFOrdGreaterThan,
ir_context.get(), spv::Op::OpFOrdGreaterThan,
ir_context->get_type_mgr()->GetId(registered_bool_type),
id_guaranteed_to_be_false, greater_than_operands));
@ -344,9 +349,9 @@ bool ForceRenderRed(
opt::Operand else_block = {SPV_OPERAND_TYPE_ID, {new_exit_block_id}};
opt::Instruction::OperandList op_branch_conditional_operands = {
false_condition, then_block, else_block};
new_entry_block->AddInstruction(
MakeUnique<opt::Instruction>(ir_context.get(), SpvOpBranchConditional,
0, 0, op_branch_conditional_operands));
new_entry_block->AddInstruction(MakeUnique<opt::Instruction>(
ir_context.get(), spv::Op::OpBranchConditional, 0, 0,
op_branch_conditional_operands));
entry_point_function->InsertBasicBlockBefore(
std::move(new_entry_block), entry_point_function->entry().get());

View File

@ -131,14 +131,15 @@ void FuzzerPass::ForEachInstructionWithInstructionDescriptor(
// should skip when searching from 'base' for the desired instruction.
// (An instruction that has a result id is represented by its own opcode,
// itself as 'base', and a skip-count of 0.)
std::vector<std::tuple<uint32_t, SpvOp, uint32_t>> base_opcode_skip_triples;
std::vector<std::tuple<uint32_t, spv::Op, uint32_t>>
base_opcode_skip_triples;
// The initial base instruction is the block label.
uint32_t base = block->id();
// Counts the number of times we have seen each opcode since we reset the
// base instruction.
std::map<SpvOp, uint32_t> skip_count;
std::map<spv::Op, uint32_t> skip_count;
// Consider every instruction in the block. The label is excluded: it is
// only necessary to consider it as a base in case the first instruction
@ -151,7 +152,7 @@ void FuzzerPass::ForEachInstructionWithInstructionDescriptor(
base = inst_it->result_id();
skip_count.clear();
}
const SpvOp opcode = inst_it->opcode();
const spv::Op opcode = inst_it->opcode();
// Invoke the provided function, which might apply a transformation.
action(block, inst_it,
@ -330,7 +331,7 @@ uint32_t FuzzerPass::FindOrCreateStructType(
}
uint32_t FuzzerPass::FindOrCreatePointerType(uint32_t base_type_id,
SpvStorageClass storage_class) {
spv::StorageClass storage_class) {
// We do not use the type manager here, due to problems related to isomorphic
// but distinct structs not being regarded as different.
auto existing_id = fuzzerutil::MaybeGetPointerType(
@ -345,7 +346,7 @@ uint32_t FuzzerPass::FindOrCreatePointerType(uint32_t base_type_id,
}
uint32_t FuzzerPass::FindOrCreatePointerToIntegerType(
uint32_t width, bool is_signed, SpvStorageClass storage_class) {
uint32_t width, bool is_signed, spv::StorageClass storage_class) {
return FindOrCreatePointerType(FindOrCreateIntegerType(width, is_signed),
storage_class);
}
@ -432,7 +433,7 @@ uint32_t FuzzerPass::FindOrCreateCompositeConstant(
uint32_t FuzzerPass::FindOrCreateGlobalUndef(uint32_t type_id) {
for (auto& inst : GetIRContext()->types_values()) {
if (inst.opcode() == SpvOpUndef && inst.type_id() == type_id) {
if (inst.opcode() == spv::Op::OpUndef && inst.type_id() == type_id) {
return inst.result_id();
}
}
@ -464,7 +465,7 @@ uint32_t FuzzerPass::FindOrCreateNullConstant(uint32_t type_id) {
std::pair<std::vector<uint32_t>, std::map<uint32_t, std::vector<uint32_t>>>
FuzzerPass::GetAvailableBasicTypesAndPointers(
SpvStorageClass storage_class) const {
spv::StorageClass storage_class) const {
// Records all of the basic types available in the module.
std::set<uint32_t> basic_types;
@ -480,23 +481,23 @@ FuzzerPass::GetAvailableBasicTypesAndPointers(
// For pointer types with basic pointee types, associate the pointer type
// with the basic type.
switch (inst.opcode()) {
case SpvOpTypeBool:
case SpvOpTypeFloat:
case SpvOpTypeInt:
case SpvOpTypeMatrix:
case SpvOpTypeVector:
case spv::Op::OpTypeBool:
case spv::Op::OpTypeFloat:
case spv::Op::OpTypeInt:
case spv::Op::OpTypeMatrix:
case spv::Op::OpTypeVector:
// These are all basic types.
basic_types.insert(inst.result_id());
basic_type_to_pointers.insert({inst.result_id(), {}});
break;
case SpvOpTypeArray:
case spv::Op::OpTypeArray:
// An array type is basic if its base type is basic.
if (basic_types.count(inst.GetSingleWordInOperand(0))) {
basic_types.insert(inst.result_id());
basic_type_to_pointers.insert({inst.result_id(), {}});
}
break;
case SpvOpTypeStruct: {
case spv::Op::OpTypeStruct: {
// A struct type is basic if it does not have the Block/BufferBlock
// decoration, and if all of its members are basic.
if (!fuzzerutil::HasBlockOrBufferBlockDecoration(GetIRContext(),
@ -515,11 +516,12 @@ FuzzerPass::GetAvailableBasicTypesAndPointers(
}
break;
}
case SpvOpTypePointer: {
case spv::Op::OpTypePointer: {
// We are interested in the pointer if its pointee type is basic and it
// has the right storage class.
auto pointee_type = inst.GetSingleWordInOperand(1);
if (inst.GetSingleWordInOperand(0) == storage_class &&
if (spv::StorageClass(inst.GetSingleWordInOperand(0)) ==
storage_class &&
basic_types.count(pointee_type)) {
// The pointer has the desired storage class, and its pointee type is
// a basic type, so we are interested in it. Associate it with its
@ -541,22 +543,22 @@ uint32_t FuzzerPass::FindOrCreateZeroConstant(
GetIRContext()->get_def_use_mgr()->GetDef(scalar_or_composite_type_id);
assert(type_instruction && "The type instruction must exist.");
switch (type_instruction->opcode()) {
case SpvOpTypeBool:
case spv::Op::OpTypeBool:
return FindOrCreateBoolConstant(false, is_irrelevant);
case SpvOpTypeFloat: {
case spv::Op::OpTypeFloat: {
auto width = type_instruction->GetSingleWordInOperand(0);
auto num_words = (width + 32 - 1) / 32;
return FindOrCreateFloatConstant(std::vector<uint32_t>(num_words, 0),
width, is_irrelevant);
}
case SpvOpTypeInt: {
case spv::Op::OpTypeInt: {
auto width = type_instruction->GetSingleWordInOperand(0);
auto num_words = (width + 32 - 1) / 32;
return FindOrCreateIntegerConstant(
std::vector<uint32_t>(num_words, 0), width,
type_instruction->GetSingleWordInOperand(1), is_irrelevant);
}
case SpvOpTypeArray: {
case spv::Op::OpTypeArray: {
auto component_type_id = type_instruction->GetSingleWordInOperand(0);
auto num_components =
fuzzerutil::GetArraySize(*type_instruction, GetIRContext());
@ -566,8 +568,8 @@ uint32_t FuzzerPass::FindOrCreateZeroConstant(
FindOrCreateZeroConstant(component_type_id, is_irrelevant)),
scalar_or_composite_type_id, is_irrelevant);
}
case SpvOpTypeMatrix:
case SpvOpTypeVector: {
case spv::Op::OpTypeMatrix:
case spv::Op::OpTypeVector: {
auto component_type_id = type_instruction->GetSingleWordInOperand(0);
auto num_components = type_instruction->GetSingleWordInOperand(1);
return FindOrCreateCompositeConstant(
@ -576,7 +578,7 @@ uint32_t FuzzerPass::FindOrCreateZeroConstant(
FindOrCreateZeroConstant(component_type_id, is_irrelevant)),
scalar_or_composite_type_id, is_irrelevant);
}
case SpvOpTypeStruct: {
case spv::Op::OpTypeStruct: {
assert(!fuzzerutil::HasBlockOrBufferBlockDecoration(
GetIRContext(), scalar_or_composite_type_id) &&
"We do not construct constants of struct types decorated with "
@ -646,7 +648,7 @@ opt::BasicBlock* FuzzerPass::GetOrCreateSimpleLoopPreheader(
// |maybe_preheader| is a preheader if it branches unconditionally to
// the header. We also require it not to be a loop header.
if (maybe_preheader->terminator()->opcode() == SpvOpBranch &&
if (maybe_preheader->terminator()->opcode() == spv::Op::OpBranch &&
!maybe_preheader->IsLoopHeader()) {
return maybe_preheader;
}
@ -683,8 +685,8 @@ opt::BasicBlock* FuzzerPass::SplitBlockAfterOpPhiOrOpVariable(
// Find the first non-OpPhi and non-OpVariable instruction.
auto non_phi_or_var_inst = &*block->begin();
while (non_phi_or_var_inst->opcode() == SpvOpPhi ||
non_phi_or_var_inst->opcode() == SpvOpVariable) {
while (non_phi_or_var_inst->opcode() == spv::Op::OpPhi ||
non_phi_or_var_inst->opcode() == spv::Op::OpVariable) {
non_phi_or_var_inst = non_phi_or_var_inst->NextNode();
}
@ -706,7 +708,7 @@ uint32_t FuzzerPass::FindOrCreateLocalVariable(
(void)pointer_type;
assert(pointer_type && pointer_type->AsPointer() &&
pointer_type->AsPointer()->storage_class() ==
SpvStorageClassFunction &&
spv::StorageClass::Function &&
"The pointer_type_id must refer to a defined pointer type with "
"storage class Function");
auto function = fuzzerutil::FindFunction(GetIRContext(), function_id);
@ -715,7 +717,7 @@ uint32_t FuzzerPass::FindOrCreateLocalVariable(
// First we try to find a suitable existing variable.
// All of the local variable declarations are located in the first block.
for (auto& instruction : *function->begin()) {
if (instruction.opcode() != SpvOpVariable) {
if (instruction.opcode() != spv::Op::OpVariable) {
continue;
}
// The existing OpVariable must have type |pointer_type_id|.
@ -749,15 +751,16 @@ uint32_t FuzzerPass::FindOrCreateGlobalVariable(
(void)pointer_type;
assert(
pointer_type && pointer_type->AsPointer() &&
(pointer_type->AsPointer()->storage_class() == SpvStorageClassPrivate ||
(pointer_type->AsPointer()->storage_class() ==
spv::StorageClass::Private ||
pointer_type->AsPointer()->storage_class() ==
SpvStorageClassWorkgroup) &&
spv::StorageClass::Workgroup) &&
"The pointer_type_id must refer to a defined pointer type with storage "
"class Private or Workgroup");
// First we try to find a suitable existing variable.
for (auto& instruction : GetIRContext()->module()->types_values()) {
if (instruction.opcode() != SpvOpVariable) {
if (instruction.opcode() != spv::Op::OpVariable) {
continue;
}
// The existing OpVariable must have type |pointer_type_id|.
@ -781,13 +784,13 @@ uint32_t FuzzerPass::FindOrCreateGlobalVariable(
uint32_t result_id = GetFuzzerContext()->GetFreshId();
// A variable with storage class Workgroup shouldn't have an initializer.
if (storage_class == SpvStorageClassWorkgroup) {
if (storage_class == spv::StorageClass::Workgroup) {
ApplyTransformation(TransformationAddGlobalVariable(
result_id, pointer_type_id, SpvStorageClassWorkgroup, 0,
result_id, pointer_type_id, spv::StorageClass::Workgroup, 0,
pointee_value_is_irrelevant));
} else {
ApplyTransformation(TransformationAddGlobalVariable(
result_id, pointer_type_id, SpvStorageClassPrivate,
result_id, pointer_type_id, spv::StorageClass::Private,
FindOrCreateZeroConstant(pointee_type_id, pointee_value_is_irrelevant),
pointee_value_is_irrelevant));
}

View File

@ -159,14 +159,14 @@ class FuzzerPass {
// already exist) and storage class |storage_class|. A transformation is
// applied to add the pointer if it does not already exist.
uint32_t FindOrCreatePointerType(uint32_t base_type_id,
SpvStorageClass storage_class);
spv::StorageClass storage_class);
// Returns the id of an OpTypePointer instruction, with a integer base
// type of width and signedness specified by |width| and |is_signed|,
// respectively. If the pointer type or required integer base type do not
// exist, transformations are applied to add them.
uint32_t FindOrCreatePointerToIntegerType(uint32_t width, bool is_signed,
SpvStorageClass storage_class);
spv::StorageClass storage_class);
// Returns the id of an OpConstant instruction, with a integer type of
// width and signedness specified by |width| and |is_signed|, respectively,
@ -239,7 +239,7 @@ class FuzzerPass {
// storage class, and the sequence will have multiple elements if there are
// repeated pointer declarations for the same basic type and storage class.
std::pair<std::vector<uint32_t>, std::map<uint32_t, std::vector<uint32_t>>>
GetAvailableBasicTypesAndPointers(SpvStorageClass storage_class) const;
GetAvailableBasicTypesAndPointers(spv::StorageClass storage_class) const;
// Given a type id, |scalar_or_composite_type_id|, which must correspond to
// some scalar or composite type, returns the result id of an instruction

View File

@ -34,15 +34,16 @@ void FuzzerPassAddAccessChains::Apply() {
opt::BasicBlock::iterator inst_it,
const protobufs::InstructionDescriptor& instruction_descriptor)
-> void {
assert(inst_it->opcode() ==
instruction_descriptor.target_instruction_opcode() &&
"The opcode of the instruction we might insert before must be "
"the same as the opcode in the descriptor for the instruction");
assert(
inst_it->opcode() ==
spv::Op(instruction_descriptor.target_instruction_opcode()) &&
"The opcode of the instruction we might insert before must be "
"the same as the opcode in the descriptor for the instruction");
// Check whether it is legitimate to insert an access chain
// instruction before this instruction.
if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(SpvOpAccessChain,
inst_it)) {
if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(
spv::Op::OpAccessChain, inst_it)) {
return;
}
@ -64,8 +65,8 @@ void FuzzerPassAddAccessChains::Apply() {
return false;
}
switch (instruction->opcode()) {
case SpvOpConstantNull:
case SpvOpUndef:
case spv::Op::OpConstantNull:
case spv::Op::OpUndef:
// Do not allow making an access chain from a null or
// undefined pointer. (We can eliminate these cases
// before actually checking that the instruction is a
@ -78,7 +79,7 @@ void FuzzerPassAddAccessChains::Apply() {
// make an access chain from it.
return context->get_def_use_mgr()
->GetDef(instruction->type_id())
->opcode() == SpvOpTypePointer;
->opcode() == spv::Op::OpTypePointer;
});
// At this point, |relevant_instructions| contains all the pointers
@ -112,14 +113,14 @@ void FuzzerPassAddAccessChains::Apply() {
}
uint32_t bound;
switch (subobject_type->opcode()) {
case SpvOpTypeArray:
case spv::Op::OpTypeArray:
bound = fuzzerutil::GetArraySize(*subobject_type, GetIRContext());
break;
case SpvOpTypeMatrix:
case SpvOpTypeVector:
case spv::Op::OpTypeMatrix:
case spv::Op::OpTypeVector:
bound = subobject_type->GetSingleWordInOperand(1);
break;
case SpvOpTypeStruct:
case spv::Op::OpTypeStruct:
bound = fuzzerutil::GetNumberOfStructMembers(*subobject_type);
break;
default:
@ -140,9 +141,9 @@ void FuzzerPassAddAccessChains::Apply() {
GetFuzzerContext()->GetRandomIndexForAccessChain(bound);
switch (subobject_type->opcode()) {
case SpvOpTypeArray:
case SpvOpTypeMatrix:
case SpvOpTypeVector: {
case spv::Op::OpTypeArray:
case spv::Op::OpTypeMatrix:
case spv::Op::OpTypeVector: {
// The index will be clamped
bool is_signed = GetFuzzerContext()->ChooseEven();
@ -164,7 +165,7 @@ void FuzzerPassAddAccessChains::Apply() {
subobject_type_id = subobject_type->GetSingleWordInOperand(0);
} break;
case SpvOpTypeStruct:
case spv::Op::OpTypeStruct:
index_ids.push_back(FindOrCreateIntegerConstant(
{index_value}, 32, GetFuzzerContext()->ChooseEven(), false));
subobject_type_id =
@ -178,7 +179,7 @@ void FuzzerPassAddAccessChains::Apply() {
// pointer suitable for the access chain's result type exists, so we
// create one if it does not.
FindOrCreatePointerType(subobject_type_id,
static_cast<SpvStorageClass>(
static_cast<spv::StorageClass>(
pointer_type->GetSingleWordInOperand(0)));
// Apply the transformation to add an access chain.
ApplyTransformation(TransformationAccessChain(

View File

@ -53,8 +53,8 @@ void FuzzerPassAddCompositeExtract::Apply() {
opt::Function* /*unused*/, opt::BasicBlock* /*unused*/,
opt::BasicBlock::iterator inst_it,
const protobufs::InstructionDescriptor& instruction_descriptor) {
if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(SpvOpCompositeExtract,
inst_it)) {
if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(
spv::Op::OpCompositeExtract, inst_it)) {
return;
}
@ -97,15 +97,15 @@ void FuzzerPassAddCompositeExtract::Apply() {
assert(type_inst && "Composite instruction has invalid type id");
switch (type_inst->opcode()) {
case SpvOpTypeArray:
case spv::Op::OpTypeArray:
number_of_members =
fuzzerutil::GetArraySize(*type_inst, GetIRContext());
break;
case SpvOpTypeVector:
case SpvOpTypeMatrix:
case spv::Op::OpTypeVector:
case spv::Op::OpTypeMatrix:
number_of_members = type_inst->GetSingleWordInOperand(1);
break;
case SpvOpTypeStruct:
case spv::Op::OpTypeStruct:
number_of_members = type_inst->NumInOperands();
break;
default:
@ -122,12 +122,12 @@ void FuzzerPassAddCompositeExtract::Apply() {
number_of_members));
switch (type_inst->opcode()) {
case SpvOpTypeArray:
case SpvOpTypeVector:
case SpvOpTypeMatrix:
case spv::Op::OpTypeArray:
case spv::Op::OpTypeVector:
case spv::Op::OpTypeMatrix:
type_id = type_inst->GetSingleWordInOperand(0);
break;
case SpvOpTypeStruct:
case spv::Op::OpTypeStruct:
type_id = type_inst->GetSingleWordInOperand(indices.back());
break;
default:

View File

@ -36,10 +36,11 @@ void FuzzerPassAddCompositeInserts::Apply() {
opt::BasicBlock::iterator instruction_iterator,
const protobufs::InstructionDescriptor& instruction_descriptor)
-> void {
assert(instruction_iterator->opcode() ==
instruction_descriptor.target_instruction_opcode() &&
"The opcode of the instruction we might insert before must be "
"the same as the opcode in the descriptor for the instruction");
assert(
instruction_iterator->opcode() ==
spv::Op(instruction_descriptor.target_instruction_opcode()) &&
"The opcode of the instruction we might insert before must be "
"the same as the opcode in the descriptor for the instruction");
// Randomly decide whether to try adding an OpCompositeInsert
// instruction.
@ -51,7 +52,7 @@ void FuzzerPassAddCompositeInserts::Apply() {
// It must be possible to insert an OpCompositeInsert instruction
// before |instruction_iterator|.
if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(
SpvOpCompositeInsert, instruction_iterator)) {
spv::Op::OpCompositeInsert, instruction_iterator)) {
return;
}

View File

@ -114,15 +114,15 @@ uint32_t FuzzerPassAddCompositeTypes::ChooseScalarOrCompositeType() {
std::vector<uint32_t> candidates;
for (auto& inst : GetIRContext()->types_values()) {
switch (inst.opcode()) {
case SpvOpTypeArray:
case SpvOpTypeBool:
case SpvOpTypeFloat:
case SpvOpTypeInt:
case SpvOpTypeMatrix:
case SpvOpTypeVector:
case spv::Op::OpTypeArray:
case spv::Op::OpTypeBool:
case spv::Op::OpTypeFloat:
case spv::Op::OpTypeInt:
case spv::Op::OpTypeMatrix:
case spv::Op::OpTypeVector:
candidates.push_back(inst.result_id());
break;
case SpvOpTypeStruct: {
case spv::Op::OpTypeStruct: {
if (!fuzzerutil::MembersHaveBuiltInDecoration(GetIRContext(),
inst.result_id()) &&
!fuzzerutil::HasBlockOrBufferBlockDecoration(GetIRContext(),

View File

@ -36,7 +36,7 @@ void FuzzerPassAddCopyMemory::Apply() {
opt::BasicBlock::iterator inst_it,
const protobufs::InstructionDescriptor& instruction_descriptor) {
// Check that we can insert an OpCopyMemory before this instruction.
if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(SpvOpCopyMemory,
if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(spv::Op::OpCopyMemory,
inst_it)) {
return;
}
@ -61,8 +61,8 @@ void FuzzerPassAddCopyMemory::Apply() {
// Decide whether to create global or local variable.
auto storage_class = GetFuzzerContext()->ChooseEven()
? SpvStorageClassPrivate
: SpvStorageClassFunction;
? spv::StorageClass::Private
: spv::StorageClass::Function;
auto pointee_type_id = fuzzerutil::GetPointeeTypeIdFromPointerType(
GetIRContext(), inst->type_id());

View File

@ -29,12 +29,14 @@ bool IsBitWidthSupported(opt::IRContext* ir_context, uint32_t bit_width) {
return true;
case 64:
return ir_context->get_feature_mgr()->HasCapability(
SpvCapabilityFloat64) &&
ir_context->get_feature_mgr()->HasCapability(SpvCapabilityInt64);
spv::Capability::Float64) &&
ir_context->get_feature_mgr()->HasCapability(
spv::Capability::Int64);
case 16:
return ir_context->get_feature_mgr()->HasCapability(
SpvCapabilityFloat16) &&
ir_context->get_feature_mgr()->HasCapability(SpvCapabilityInt16);
spv::Capability::Float16) &&
ir_context->get_feature_mgr()->HasCapability(
spv::Capability::Int16);
default:
return false;
}
@ -66,7 +68,8 @@ void FuzzerPassAddEquationInstructions::Apply() {
// as an example opcode for this check, to be representative of *some*
// opcode that defines an equation, even though we may choose a
// different opcode below.
if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(SpvOpIAdd, inst_it)) {
if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(spv::Op::OpIAdd,
inst_it)) {
return;
}
@ -78,7 +81,7 @@ void FuzzerPassAddEquationInstructions::Apply() {
[this](opt::IRContext* /*unused*/,
opt::Instruction* instruction) -> bool {
return instruction->result_id() && instruction->type_id() &&
instruction->opcode() != SpvOpUndef &&
instruction->opcode() != spv::Op::OpUndef &&
!GetTransformationContext()
->GetFactManager()
->IdIsIrrelevant(instruction->result_id());
@ -86,15 +89,16 @@ void FuzzerPassAddEquationInstructions::Apply() {
// Try the opcodes for which we know how to make ids at random until
// something works.
std::vector<SpvOp> candidate_opcodes = {
SpvOpIAdd, SpvOpISub, SpvOpLogicalNot, SpvOpSNegate,
SpvOpConvertUToF, SpvOpConvertSToF, SpvOpBitcast};
std::vector<spv::Op> candidate_opcodes = {
spv::Op::OpIAdd, spv::Op::OpISub, spv::Op::OpLogicalNot,
spv::Op::OpSNegate, spv::Op::OpConvertUToF, spv::Op::OpConvertSToF,
spv::Op::OpBitcast};
do {
auto opcode =
GetFuzzerContext()->RemoveAtRandomIndex(&candidate_opcodes);
switch (opcode) {
case SpvOpConvertSToF:
case SpvOpConvertUToF: {
case spv::Op::OpConvertSToF:
case spv::Op::OpConvertUToF: {
std::vector<const opt::Instruction*> candidate_instructions;
for (const auto* inst :
GetIntegerInstructions(available_instructions)) {
@ -144,7 +148,7 @@ void FuzzerPassAddEquationInstructions::Apply() {
{operand->result_id()}, instruction_descriptor));
return;
}
case SpvOpBitcast: {
case spv::Op::OpBitcast: {
const auto candidate_instructions =
GetNumericalInstructions(available_instructions);
@ -197,8 +201,8 @@ void FuzzerPassAddEquationInstructions::Apply() {
return;
}
} break;
case SpvOpIAdd:
case SpvOpISub: {
case spv::Op::OpIAdd:
case spv::Op::OpISub: {
// Instructions of integer (scalar or vector) result type are
// suitable for these opcodes.
auto integer_instructions =
@ -251,7 +255,7 @@ void FuzzerPassAddEquationInstructions::Apply() {
}
break;
}
case SpvOpLogicalNot: {
case spv::Op::OpLogicalNot: {
// Choose any available instruction of boolean scalar/vector
// result type and equate its negation with a fresh id.
auto boolean_instructions =
@ -268,7 +272,7 @@ void FuzzerPassAddEquationInstructions::Apply() {
}
break;
}
case SpvOpSNegate: {
case spv::Op::OpSNegate: {
// Similar to OpLogicalNot, but for signed integer negation.
auto integer_instructions =
GetIntegerInstructions(available_instructions);

View File

@ -39,8 +39,8 @@ void FuzzerPassAddFunctionCalls::Apply() {
-> void {
// Check whether it is legitimate to insert a function call before the
// instruction.
if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(SpvOpFunctionCall,
inst_it)) {
if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(
spv::Op::OpFunctionCall, inst_it)) {
return;
}
@ -112,8 +112,8 @@ std::vector<uint32_t> FuzzerPassAddFunctionCalls::ChooseFunctionCallArguments(
auto available_pointers = FindAvailableInstructions(
caller_function, caller_block, caller_inst_it,
[this, caller_block](opt::IRContext* /*unused*/, opt::Instruction* inst) {
if (inst->opcode() != SpvOpVariable ||
inst->opcode() != SpvOpFunctionParameter) {
if (inst->opcode() != spv::Op::OpVariable ||
inst->opcode() != spv::Op::OpFunctionParameter) {
// Function parameters and variables are the only
// kinds of pointer that can be used as actual
// parameters.
@ -172,15 +172,15 @@ std::vector<uint32_t> FuzzerPassAddFunctionCalls::ChooseFunctionCallArguments(
auto storage_class = param_type->AsPointer()->storage_class();
auto pointee_type_id = fuzzerutil::GetPointeeTypeIdFromPointerType(
GetIRContext(), param->type_id());
if (storage_class == SpvStorageClassFunction) {
if (storage_class == spv::StorageClass::Function) {
// Add a new zero-initialized local variable to the current
// function, noting that its pointee value is irrelevant.
ApplyTransformation(TransformationAddLocalVariable(
fresh_variable_id, param->type_id(), caller_function->result_id(),
FindOrCreateZeroConstant(pointee_type_id, false), true));
} else {
assert((storage_class == SpvStorageClassPrivate ||
storage_class == SpvStorageClassWorkgroup) &&
assert((storage_class == spv::StorageClass::Private ||
storage_class == spv::StorageClass::Workgroup) &&
"Only Function, Private and Workgroup storage classes are "
"supported at present.");
// Add a new global variable to the module, zero-initializing it if
@ -188,7 +188,7 @@ std::vector<uint32_t> FuzzerPassAddFunctionCalls::ChooseFunctionCallArguments(
// irrelevant.
ApplyTransformation(TransformationAddGlobalVariable(
fresh_variable_id, param->type_id(), storage_class,
storage_class == SpvStorageClassPrivate
storage_class == spv::StorageClass::Private
? FindOrCreateZeroConstant(pointee_type_id, false)
: 0,
true));

View File

@ -29,16 +29,17 @@ FuzzerPassAddGlobalVariables::FuzzerPassAddGlobalVariables(
transformations, ignore_inapplicable_transformations) {}
void FuzzerPassAddGlobalVariables::Apply() {
SpvStorageClass variable_storage_class = SpvStorageClassPrivate;
spv::StorageClass variable_storage_class = spv::StorageClass::Private;
for (auto& entry_point : GetIRContext()->module()->entry_points()) {
// If the execution model of some entry point is GLCompute,
// then the variable storage class may be Workgroup.
if (entry_point.GetSingleWordInOperand(0) == SpvExecutionModelGLCompute) {
if (spv::ExecutionModel(entry_point.GetSingleWordInOperand(0)) ==
spv::ExecutionModel::GLCompute) {
variable_storage_class =
GetFuzzerContext()->ChoosePercentage(
GetFuzzerContext()->GetChanceOfChoosingWorkgroupStorageClass())
? SpvStorageClassWorkgroup
: SpvStorageClassPrivate;
? spv::StorageClass::Workgroup
: spv::StorageClass::Private;
break;
}
}
@ -87,7 +88,7 @@ void FuzzerPassAddGlobalVariables::Apply() {
ApplyTransformation(TransformationAddGlobalVariable(
GetFuzzerContext()->GetFreshId(), pointer_type_id,
variable_storage_class,
variable_storage_class == SpvStorageClassPrivate
variable_storage_class == spv::StorageClass::Private
? FindOrCreateZeroConstant(basic_type, false)
: 0,
true));

View File

@ -34,10 +34,11 @@ void FuzzerPassAddLoads::Apply() {
opt::BasicBlock::iterator inst_it,
const protobufs::InstructionDescriptor& instruction_descriptor)
-> void {
assert(inst_it->opcode() ==
instruction_descriptor.target_instruction_opcode() &&
"The opcode of the instruction we might insert before must be "
"the same as the opcode in the descriptor for the instruction");
assert(
inst_it->opcode() ==
spv::Op(instruction_descriptor.target_instruction_opcode()) &&
"The opcode of the instruction we might insert before must be "
"the same as the opcode in the descriptor for the instruction");
// Randomly decide whether to try inserting a load here.
if (!GetFuzzerContext()->ChoosePercentage(
@ -47,10 +48,11 @@ void FuzzerPassAddLoads::Apply() {
// Check whether it is legitimate to insert a load or atomic load before
// this instruction.
if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(SpvOpLoad, inst_it)) {
if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(spv::Op::OpLoad,
inst_it)) {
return;
}
if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(SpvOpAtomicLoad,
if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(spv::Op::OpAtomicLoad,
inst_it)) {
return;
}
@ -64,8 +66,8 @@ void FuzzerPassAddLoads::Apply() {
return false;
}
switch (instruction->opcode()) {
case SpvOpConstantNull:
case SpvOpUndef:
case spv::Op::OpConstantNull:
case spv::Op::OpUndef:
// Do not allow loading from a null or undefined pointer;
// this might be OK if the block is dead, but for now we
// conservatively avoid it.
@ -75,7 +77,7 @@ void FuzzerPassAddLoads::Apply() {
}
return context->get_def_use_mgr()
->GetDef(instruction->type_id())
->opcode() == SpvOpTypePointer;
->opcode() == spv::Op::OpTypePointer;
});
// At this point, |relevant_instructions| contains all the pointers
@ -92,25 +94,25 @@ void FuzzerPassAddLoads::Apply() {
uint32_t memory_scope_id = 0;
uint32_t memory_semantics_id = 0;
auto storage_class = static_cast<SpvStorageClass>(
auto storage_class = static_cast<spv::StorageClass>(
GetIRContext()
->get_def_use_mgr()
->GetDef(chosen_instruction->type_id())
->GetSingleWordInOperand(0));
switch (storage_class) {
case SpvStorageClassStorageBuffer:
case SpvStorageClassPhysicalStorageBuffer:
case SpvStorageClassWorkgroup:
case SpvStorageClassCrossWorkgroup:
case SpvStorageClassAtomicCounter:
case SpvStorageClassImage:
case spv::StorageClass::StorageBuffer:
case spv::StorageClass::PhysicalStorageBuffer:
case spv::StorageClass::Workgroup:
case spv::StorageClass::CrossWorkgroup:
case spv::StorageClass::AtomicCounter:
case spv::StorageClass::Image:
if (GetFuzzerContext()->ChoosePercentage(
GetFuzzerContext()->GetChanceOfAddingAtomicLoad())) {
is_atomic_load = true;
memory_scope_id = FindOrCreateConstant(
{SpvScopeInvocation},
{uint32_t(spv::Scope::Invocation)},
FindOrCreateIntegerType(32, GetFuzzerContext()->ChooseEven()),
false);

View File

@ -31,7 +31,7 @@ FuzzerPassAddLocalVariables::FuzzerPassAddLocalVariables(
void FuzzerPassAddLocalVariables::Apply() {
auto basic_type_ids_and_pointers =
GetAvailableBasicTypesAndPointers(SpvStorageClassFunction);
GetAvailableBasicTypesAndPointers(spv::StorageClass::Function);
// These are the basic types that are available to this fuzzer pass.
auto& basic_types = basic_type_ids_and_pointers.first;
@ -64,7 +64,7 @@ void FuzzerPassAddLocalVariables::Apply() {
// use it.
pointer_type = GetFuzzerContext()->GetFreshId();
ApplyTransformation(TransformationAddTypePointer(
pointer_type, SpvStorageClassFunction, basic_type));
pointer_type, spv::StorageClass::Function, basic_type));
available_pointers_to_basic_type.push_back(pointer_type);
} else {
// There is - grab one.

View File

@ -176,8 +176,8 @@ FuzzerPassAddOpPhiSynonyms::GetIdEquivalenceClasses() {
// - OpFunction does not yield a value;
// - OpUndef yields an undefined value at each use, so it should never be a
// synonym of another id.
if (pair.second->opcode() == SpvOpFunction ||
pair.second->opcode() == SpvOpUndef) {
if (pair.second->opcode() == spv::Op::OpFunction ||
pair.second->opcode() == spv::Op::OpUndef) {
continue;
}

View File

@ -79,7 +79,7 @@ void FuzzerPassAddParameters::Apply() {
auto storage_class = fuzzerutil::GetStorageClassFromPointerType(
GetIRContext(), current_type_id);
switch (storage_class) {
case SpvStorageClassFunction: {
case spv::StorageClass::Function: {
// In every caller find or create a local variable that has the
// selected type.
for (auto* instr :
@ -91,8 +91,8 @@ void FuzzerPassAddParameters::Apply() {
call_parameter_ids[instr->result_id()] = variable_id;
}
} break;
case SpvStorageClassPrivate:
case SpvStorageClassWorkgroup: {
case spv::StorageClass::Private:
case spv::StorageClass::Workgroup: {
// If there exists at least one caller, find or create a global
// variable that has the selected type.
std::vector<opt::Instruction*> callers =

View File

@ -34,10 +34,11 @@ void FuzzerPassAddStores::Apply() {
opt::BasicBlock::iterator inst_it,
const protobufs::InstructionDescriptor& instruction_descriptor)
-> void {
assert(inst_it->opcode() ==
instruction_descriptor.target_instruction_opcode() &&
"The opcode of the instruction we might insert before must be "
"the same as the opcode in the descriptor for the instruction");
assert(
inst_it->opcode() ==
spv::Op(instruction_descriptor.target_instruction_opcode()) &&
"The opcode of the instruction we might insert before must be "
"the same as the opcode in the descriptor for the instruction");
// Randomly decide whether to try inserting a store here.
if (!GetFuzzerContext()->ChoosePercentage(
@ -47,12 +48,12 @@ void FuzzerPassAddStores::Apply() {
// Check whether it is legitimate to insert a store before this
// instruction.
if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(SpvOpStore,
if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(spv::Op::OpStore,
inst_it)) {
return;
}
if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(SpvOpAtomicStore,
inst_it)) {
if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(
spv::Op::OpAtomicStore, inst_it)) {
return;
}
@ -67,7 +68,7 @@ void FuzzerPassAddStores::Apply() {
}
auto type_inst = context->get_def_use_mgr()->GetDef(
instruction->type_id());
if (type_inst->opcode() != SpvOpTypePointer) {
if (type_inst->opcode() != spv::Op::OpTypePointer) {
// Not a pointer.
return false;
}
@ -76,8 +77,8 @@ void FuzzerPassAddStores::Apply() {
return false;
}
switch (instruction->opcode()) {
case SpvOpConstantNull:
case SpvOpUndef:
case spv::Op::OpConstantNull:
case spv::Op::OpUndef:
// Do not allow storing to a null or undefined pointer;
// this might be OK if the block is dead, but for now we
// conservatively avoid it.
@ -126,24 +127,24 @@ void FuzzerPassAddStores::Apply() {
uint32_t memory_semantics_id = 0;
auto storage_class =
static_cast<SpvStorageClass>(GetIRContext()
->get_def_use_mgr()
->GetDef(pointer->type_id())
->GetSingleWordInOperand(0));
static_cast<spv::StorageClass>(GetIRContext()
->get_def_use_mgr()
->GetDef(pointer->type_id())
->GetSingleWordInOperand(0));
switch (storage_class) {
case SpvStorageClassStorageBuffer:
case SpvStorageClassPhysicalStorageBuffer:
case SpvStorageClassWorkgroup:
case SpvStorageClassCrossWorkgroup:
case SpvStorageClassAtomicCounter:
case SpvStorageClassImage:
case spv::StorageClass::StorageBuffer:
case spv::StorageClass::PhysicalStorageBuffer:
case spv::StorageClass::Workgroup:
case spv::StorageClass::CrossWorkgroup:
case spv::StorageClass::AtomicCounter:
case spv::StorageClass::Image:
if (GetFuzzerContext()->ChoosePercentage(
GetFuzzerContext()->GetChanceOfAddingAtomicStore())) {
is_atomic_store = true;
memory_scope_id = FindOrCreateConstant(
{SpvScopeInvocation},
{uint32_t(spv::Scope::Invocation)},
FindOrCreateIntegerType(32, GetFuzzerContext()->ChooseEven()),
false);

View File

@ -44,7 +44,8 @@ void FuzzerPassAddSynonyms::Apply() {
// Skip |inst_it| if we can't insert anything above it. OpIAdd is just
// a representative of some instruction that might be produced by the
// transformation.
if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(SpvOpIAdd, inst_it)) {
if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(spv::Op::OpIAdd,
inst_it)) {
return;
}

View File

@ -35,10 +35,11 @@ void FuzzerPassAddVectorShuffleInstructions::Apply() {
opt::BasicBlock::iterator instruction_iterator,
const protobufs::InstructionDescriptor& instruction_descriptor)
-> void {
assert(instruction_iterator->opcode() ==
instruction_descriptor.target_instruction_opcode() &&
"The opcode of the instruction we might insert before must be "
"the same as the opcode in the descriptor for the instruction");
assert(
instruction_iterator->opcode() ==
spv::Op(instruction_descriptor.target_instruction_opcode()) &&
"The opcode of the instruction we might insert before must be "
"the same as the opcode in the descriptor for the instruction");
// Randomly decide whether to try adding an OpVectorShuffle instruction.
if (!GetFuzzerContext()->ChoosePercentage(
@ -49,7 +50,7 @@ void FuzzerPassAddVectorShuffleInstructions::Apply() {
// It must be valid to insert an OpVectorShuffle instruction
// before |instruction_iterator|.
if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(
SpvOpVectorShuffle, instruction_iterator)) {
spv::Op::OpVectorShuffle, instruction_iterator)) {
return;
}

View File

@ -33,7 +33,7 @@ void FuzzerPassAdjustBranchWeights::Apply() {
// For all OpBranchConditional instructions,
// randomly applies the transformation.
GetIRContext()->module()->ForEachInst([this](opt::Instruction* instruction) {
if (instruction->opcode() == SpvOpBranchConditional &&
if (instruction->opcode() == spv::Op::OpBranchConditional &&
GetFuzzerContext()->ChoosePercentage(
GetFuzzerContext()->GetChanceOfAdjustingBranchWeights())) {
ApplyTransformation(TransformationAdjustBranchWeights(

View File

@ -40,21 +40,21 @@ void FuzzerPassAdjustFunctionControls::Apply() {
// For the new mask, we first randomly select one of three basic masks:
// None, Inline or DontInline. These are always valid (and are mutually
// exclusive).
std::vector<uint32_t> basic_function_control_masks = {
SpvFunctionControlMaskNone, SpvFunctionControlInlineMask,
SpvFunctionControlDontInlineMask};
std::vector<spv::FunctionControlMask> basic_function_control_masks = {
spv::FunctionControlMask::MaskNone, spv::FunctionControlMask::Inline,
spv::FunctionControlMask::DontInline};
uint32_t new_function_control_mask =
basic_function_control_masks[GetFuzzerContext()->RandomIndex(
basic_function_control_masks)];
uint32_t(basic_function_control_masks[GetFuzzerContext()->RandomIndex(
basic_function_control_masks)]);
// We now consider the Pure and Const mask bits. If these are already
// set on the function then it's OK to keep them, but also interesting
// to consider dropping them, so we decide randomly in each case.
for (auto mask_bit :
{SpvFunctionControlPureMask, SpvFunctionControlConstMask}) {
if ((existing_function_control_mask & mask_bit) &&
{spv::FunctionControlMask::Pure, spv::FunctionControlMask::Const}) {
if ((existing_function_control_mask & uint32_t(mask_bit)) &&
GetFuzzerContext()->ChooseEven()) {
new_function_control_mask |= mask_bit;
new_function_control_mask |= uint32_t(mask_bit);
}
}

View File

@ -34,7 +34,7 @@ void FuzzerPassAdjustLoopControls::Apply() {
for (auto& block : function) {
if (auto merge_inst = block.GetMergeInst()) {
// Ignore the instruction if it is not a loop merge.
if (merge_inst->opcode() != SpvOpLoopMerge) {
if (merge_inst->opcode() != spv::Op::OpLoopMerge) {
continue;
}
@ -48,9 +48,10 @@ void FuzzerPassAdjustLoopControls::Apply() {
TransformationSetLoopControl::kLoopControlMaskInOperandIndex);
// First, set the new mask to one of None, Unroll or DontUnroll.
std::vector<uint32_t> basic_masks = {SpvLoopControlMaskNone,
SpvLoopControlUnrollMask,
SpvLoopControlDontUnrollMask};
std::vector<uint32_t> basic_masks = {
uint32_t(spv::LoopControlMask::MaskNone),
uint32_t(spv::LoopControlMask::Unroll),
uint32_t(spv::LoopControlMask::DontUnroll)};
uint32_t new_mask =
basic_masks[GetFuzzerContext()->RandomIndex(basic_masks)];
@ -58,19 +59,20 @@ void FuzzerPassAdjustLoopControls::Apply() {
// does, check which of these were present in the existing mask and
// randomly decide whether to keep them. They are just hints, so
// removing them should not change the semantics of the module.
for (auto mask_bit :
{SpvLoopControlDependencyInfiniteMask,
SpvLoopControlDependencyLengthMask,
SpvLoopControlMinIterationsMask, SpvLoopControlMaxIterationsMask,
SpvLoopControlIterationMultipleMask}) {
if ((existing_mask & mask_bit) && GetFuzzerContext()->ChooseEven()) {
for (auto mask_bit : {spv::LoopControlMask::DependencyInfinite,
spv::LoopControlMask::DependencyLength,
spv::LoopControlMask::MinIterations,
spv::LoopControlMask::MaxIterations,
spv::LoopControlMask::IterationMultiple}) {
if ((existing_mask & uint32_t(mask_bit)) &&
GetFuzzerContext()->ChooseEven()) {
// The mask bits we are considering are not available in all SPIR-V
// versions. However, we only include a mask bit if it was present
// in the original loop control mask, and we work under the
// assumption that we are transforming a valid module, thus we don't
// need to actually check whether the SPIR-V version being used
// supports these loop control mask bits.
new_mask |= mask_bit;
new_mask |= uint32_t(mask_bit);
}
}
@ -81,14 +83,14 @@ void FuzzerPassAdjustLoopControls::Apply() {
// PeelCount and PartialCount are not compatible with DontUnroll, so
// we check whether DontUnroll is set.
if (!(new_mask & SpvLoopControlDontUnrollMask)) {
if (!(new_mask & uint32_t(spv::LoopControlMask::DontUnroll))) {
// If PeelCount is supported by this SPIR-V version, randomly choose
// whether to set it. If it was set in the original mask and is not
// selected for setting here, that amounts to dropping it.
if (TransformationSetLoopControl::PeelCountIsSupported(
GetIRContext()) &&
GetFuzzerContext()->ChooseEven()) {
new_mask |= SpvLoopControlPeelCountMask;
new_mask |= uint32_t(spv::LoopControlMask::PeelCount);
// The peel count is chosen randomly - if PeelCount was already set
// this will overwrite whatever peel count was previously used.
peel_count = GetFuzzerContext()->GetRandomLoopControlPeelCount();
@ -97,7 +99,7 @@ void FuzzerPassAdjustLoopControls::Apply() {
if (TransformationSetLoopControl::PartialCountIsSupported(
GetIRContext()) &&
GetFuzzerContext()->ChooseEven()) {
new_mask |= SpvLoopControlPartialCountMask;
new_mask |= uint32_t(spv::LoopControlMask::PartialCount);
partial_count =
GetFuzzerContext()->GetRandomLoopControlPartialCount();
}

View File

@ -47,8 +47,8 @@ void FuzzerPassAdjustMemoryOperandsMasks::Apply() {
// From SPIR-V 1.4 onwards, OpCopyMemory and OpCopyMemorySized have a
// second mask.
switch (inst_it->opcode()) {
case SpvOpCopyMemory:
case SpvOpCopyMemorySized:
case spv::Op::OpCopyMemory:
case spv::Op::OpCopyMemorySized:
if (TransformationSetMemoryOperandsMask::
MultipleMemoryOperandMasksAreSupported(GetIRContext())) {
indices_of_available_masks_to_adjust.push_back(1);
@ -75,24 +75,26 @@ void FuzzerPassAdjustMemoryOperandsMasks::Apply() {
existing_mask_in_operand_index < inst_it->NumInOperands()
? inst_it->GetSingleWordInOperand(
existing_mask_in_operand_index)
: static_cast<uint32_t>(SpvMemoryAccessMaskNone);
: static_cast<uint32_t>(spv::MemoryAccessMask::MaskNone);
// There are two things we can do to a mask:
// - add Volatile if not already present
// - toggle Nontemporal
// The following ensures that we do at least one of these
bool add_volatile = !(existing_mask & SpvMemoryAccessVolatileMask) &&
GetFuzzerContext()->ChooseEven();
bool add_volatile =
!(existing_mask & uint32_t(spv::MemoryAccessMask::Volatile)) &&
GetFuzzerContext()->ChooseEven();
bool toggle_nontemporal =
!add_volatile || GetFuzzerContext()->ChooseEven();
// These bitwise operations use '|' to add Volatile if desired, and
// '^' to toggle Nontemporal if desired.
uint32_t new_mask =
(existing_mask | (add_volatile ? SpvMemoryAccessVolatileMask
: SpvMemoryAccessMaskNone)) ^
(toggle_nontemporal ? SpvMemoryAccessNontemporalMask
: SpvMemoryAccessMaskNone);
(existing_mask |
(add_volatile ? uint32_t(spv::MemoryAccessMask::Volatile)
: uint32_t(spv::MemoryAccessMask::MaskNone))) ^
(toggle_nontemporal ? uint32_t(spv::MemoryAccessMask::Nontemporal)
: uint32_t(spv::MemoryAccessMask::MaskNone));
TransformationSetMemoryOperandsMask transformation(
MakeInstructionDescriptor(block, inst_it), new_mask, mask_index);

View File

@ -34,7 +34,7 @@ void FuzzerPassAdjustSelectionControls::Apply() {
for (auto& block : function) {
if (auto merge_inst = block.GetMergeInst()) {
// Ignore the instruction if it is not a selection merge.
if (merge_inst->opcode() != SpvOpSelectionMerge) {
if (merge_inst->opcode() != spv::Op::OpSelectionMerge) {
continue;
}
@ -48,13 +48,14 @@ void FuzzerPassAdjustSelectionControls::Apply() {
// The choices to change the selection control to are the set of valid
// controls, minus the current control.
std::vector<uint32_t> choices;
for (auto control :
{SpvSelectionControlMaskNone, SpvSelectionControlFlattenMask,
SpvSelectionControlDontFlattenMask}) {
if (control == merge_inst->GetSingleWordOperand(1)) {
for (auto control : {spv::SelectionControlMask::MaskNone,
spv::SelectionControlMask::Flatten,
spv::SelectionControlMask::DontFlatten}) {
if (control ==
spv::SelectionControlMask(merge_inst->GetSingleWordOperand(1))) {
continue;
}
choices.push_back(control);
choices.push_back(uint32_t(control));
}
// Apply the transformation and add it to the output transformation

View File

@ -107,9 +107,9 @@ void FuzzerPassApplyIdSynonyms::Apply() {
// which case we need to be able to add an extract instruction to get
// that element out.
if (synonym_to_try->index_size() > 0 &&
!fuzzerutil::CanInsertOpcodeBeforeInstruction(SpvOpCompositeExtract,
use_inst) &&
use_inst->opcode() != SpvOpPhi) {
!fuzzerutil::CanInsertOpcodeBeforeInstruction(
spv::Op::OpCompositeExtract, use_inst) &&
use_inst->opcode() != spv::Op::OpPhi) {
// We cannot insert an extract before this instruction, so this
// synonym is no good.
continue;
@ -132,7 +132,7 @@ void FuzzerPassApplyIdSynonyms::Apply() {
id_with_which_to_replace_use = GetFuzzerContext()->GetFreshId();
opt::Instruction* instruction_to_insert_before = nullptr;
if (use_inst->opcode() != SpvOpPhi) {
if (use_inst->opcode() != spv::Op::OpPhi) {
instruction_to_insert_before = use_inst;
} else {
auto parent_block_id =
@ -182,7 +182,7 @@ void FuzzerPassApplyIdSynonyms::Apply() {
}
bool FuzzerPassApplyIdSynonyms::DataDescriptorsHaveCompatibleTypes(
SpvOp opcode, uint32_t use_in_operand_index,
spv::Op opcode, uint32_t use_in_operand_index,
const protobufs::DataDescriptor& dd1,
const protobufs::DataDescriptor& dd2) {
auto base_object_type_id_1 =

View File

@ -38,7 +38,7 @@ class FuzzerPassApplyIdSynonyms : public FuzzerPass {
// with respect to the type. Concretely, returns true if |dd1| and |dd2| have
// the same type or both |dd1| and |dd2| are either a numerical or a vector
// type of integral components with possibly different signedness.
bool DataDescriptorsHaveCompatibleTypes(SpvOp opcode,
bool DataDescriptorsHaveCompatibleTypes(spv::Op opcode,
uint32_t use_in_operand_index,
const protobufs::DataDescriptor& dd1,
const protobufs::DataDescriptor& dd2);

View File

@ -81,7 +81,7 @@ void FuzzerPassConstructComposites::Apply() {
// Check whether it is legitimate to insert a composite construction
// before the instruction.
if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(
SpvOpCompositeConstruct, inst_it)) {
spv::Op::OpCompositeConstruct, inst_it)) {
return;
}
@ -121,19 +121,19 @@ void FuzzerPassConstructComposites::Apply() {
auto composite_type_inst =
GetIRContext()->get_def_use_mgr()->GetDef(chosen_composite_type);
switch (composite_type_inst->opcode()) {
case SpvOpTypeArray:
case spv::Op::OpTypeArray:
constructor_arguments = FindComponentsToConstructArray(
*composite_type_inst, type_id_to_available_instructions);
break;
case SpvOpTypeMatrix:
case spv::Op::OpTypeMatrix:
constructor_arguments = FindComponentsToConstructMatrix(
*composite_type_inst, type_id_to_available_instructions);
break;
case SpvOpTypeStruct:
case spv::Op::OpTypeStruct:
constructor_arguments = FindComponentsToConstructStruct(
*composite_type_inst, type_id_to_available_instructions);
break;
case SpvOpTypeVector:
case spv::Op::OpTypeVector:
constructor_arguments = FindComponentsToConstructVector(
*composite_type_inst, type_id_to_available_instructions);
break;
@ -156,7 +156,7 @@ std::vector<uint32_t>
FuzzerPassConstructComposites::FindComponentsToConstructArray(
const opt::Instruction& array_type_instruction,
const TypeIdToInstructions& type_id_to_available_instructions) {
assert(array_type_instruction.opcode() == SpvOpTypeArray &&
assert(array_type_instruction.opcode() == spv::Op::OpTypeArray &&
"Precondition: instruction must be an array type.");
// Get the element type for the array.
@ -191,7 +191,7 @@ std::vector<uint32_t>
FuzzerPassConstructComposites::FindComponentsToConstructMatrix(
const opt::Instruction& matrix_type_instruction,
const TypeIdToInstructions& type_id_to_available_instructions) {
assert(matrix_type_instruction.opcode() == SpvOpTypeMatrix &&
assert(matrix_type_instruction.opcode() == spv::Op::OpTypeMatrix &&
"Precondition: instruction must be a matrix type.");
// Get the element type for the matrix.
@ -221,7 +221,7 @@ std::vector<uint32_t>
FuzzerPassConstructComposites::FindComponentsToConstructStruct(
const opt::Instruction& struct_type_instruction,
const TypeIdToInstructions& type_id_to_available_instructions) {
assert(struct_type_instruction.opcode() == SpvOpTypeStruct &&
assert(struct_type_instruction.opcode() == spv::Op::OpTypeStruct &&
"Precondition: instruction must be a struct type.");
std::vector<uint32_t> result;
// Consider the type of each field of the struct.
@ -251,7 +251,7 @@ std::vector<uint32_t>
FuzzerPassConstructComposites::FindComponentsToConstructVector(
const opt::Instruction& vector_type_instruction,
const TypeIdToInstructions& type_id_to_available_instructions) {
assert(vector_type_instruction.opcode() == SpvOpTypeVector &&
assert(vector_type_instruction.opcode() == spv::Op::OpTypeVector &&
"Precondition: instruction must be a vector type.");
// Get details of the type underlying the vector, and the width of the vector,

View File

@ -35,10 +35,11 @@ void FuzzerPassCopyObjects::Apply() {
opt::BasicBlock::iterator inst_it,
const protobufs::InstructionDescriptor& instruction_descriptor)
-> void {
assert(inst_it->opcode() ==
instruction_descriptor.target_instruction_opcode() &&
"The opcode of the instruction we might insert before must be "
"the same as the opcode in the descriptor for the instruction");
assert(
inst_it->opcode() ==
spv::Op(instruction_descriptor.target_instruction_opcode()) &&
"The opcode of the instruction we might insert before must be "
"the same as the opcode in the descriptor for the instruction");
if (GetTransformationContext()->GetFactManager()->BlockIsDead(
block->id())) {
@ -48,7 +49,7 @@ void FuzzerPassCopyObjects::Apply() {
// Check whether it is legitimate to insert a copy before this
// instruction.
if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(SpvOpCopyObject,
if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(spv::Op::OpCopyObject,
inst_it)) {
return;
}

View File

@ -88,7 +88,7 @@ void FuzzerPassDonateModules::DonateSingleModule(
// module.
for (const auto& capability_inst : donor_ir_context->capabilities()) {
auto capability =
static_cast<SpvCapability>(capability_inst.GetSingleWordInOperand(0));
static_cast<spv::Capability>(capability_inst.GetSingleWordInOperand(0));
if (!GetIRContext()->get_feature_mgr()->HasCapability(capability)) {
return;
}
@ -122,27 +122,27 @@ void FuzzerPassDonateModules::DonateSingleModule(
// kinds of decoration.
}
SpvStorageClass FuzzerPassDonateModules::AdaptStorageClass(
SpvStorageClass donor_storage_class) {
spv::StorageClass FuzzerPassDonateModules::AdaptStorageClass(
spv::StorageClass donor_storage_class) {
switch (donor_storage_class) {
case SpvStorageClassFunction:
case SpvStorageClassPrivate:
case SpvStorageClassWorkgroup:
case spv::StorageClass::Function:
case spv::StorageClass::Private:
case spv::StorageClass::Workgroup:
// We leave these alone
return donor_storage_class;
case SpvStorageClassInput:
case SpvStorageClassOutput:
case SpvStorageClassUniform:
case SpvStorageClassUniformConstant:
case SpvStorageClassPushConstant:
case SpvStorageClassImage:
case SpvStorageClassStorageBuffer:
case spv::StorageClass::Input:
case spv::StorageClass::Output:
case spv::StorageClass::Uniform:
case spv::StorageClass::UniformConstant:
case spv::StorageClass::PushConstant:
case spv::StorageClass::Image:
case spv::StorageClass::StorageBuffer:
// We change these to Private
return SpvStorageClassPrivate;
return spv::StorageClass::Private;
default:
// Handle other cases on demand.
assert(false && "Currently unsupported storage class.");
return SpvStorageClassMax;
return spv::StorageClass::Max;
}
}
@ -200,14 +200,14 @@ void FuzzerPassDonateModules::HandleTypeOrValue(
// that its component types will have been considered previously, and that
// |original_id_to_donated_id| will already contain an entry for them.
switch (type_or_value.opcode()) {
case SpvOpTypeImage:
case SpvOpTypeSampledImage:
case SpvOpTypeSampler:
case spv::Op::OpTypeImage:
case spv::Op::OpTypeSampledImage:
case spv::Op::OpTypeSampler:
// We do not donate types and variables that relate to images and
// samplers, so we skip these types and subsequently skip anything that
// depends on them.
return;
case SpvOpTypeVoid: {
case spv::Op::OpTypeVoid: {
// Void has to exist already in order for us to have an entry point.
// Get the existing id of void.
opt::analysis::Void void_type;
@ -216,7 +216,7 @@ void FuzzerPassDonateModules::HandleTypeOrValue(
"The module being transformed will always have 'void' type "
"declared.");
} break;
case SpvOpTypeBool: {
case spv::Op::OpTypeBool: {
// Bool cannot be declared multiple times, so use its existing id if
// present, or add a declaration of Bool with a fresh id if not.
opt::analysis::Bool bool_type;
@ -228,7 +228,7 @@ void FuzzerPassDonateModules::HandleTypeOrValue(
ApplyTransformation(TransformationAddTypeBoolean(new_result_id));
}
} break;
case SpvOpTypeInt: {
case spv::Op::OpTypeInt: {
// Int cannot be declared multiple times with the same width and
// signedness, so check whether an existing identical Int type is
// present and use its id if so. Otherwise add a declaration of the
@ -246,8 +246,8 @@ void FuzzerPassDonateModules::HandleTypeOrValue(
TransformationAddTypeInt(new_result_id, width, is_signed));
}
} break;
case SpvOpTypeFloat: {
// Similar to SpvOpTypeInt.
case spv::Op::OpTypeFloat: {
// Similar to spv::Op::OpTypeInt.
const uint32_t width = type_or_value.GetSingleWordInOperand(0);
opt::analysis::Float float_type(width);
auto float_type_id = GetIRContext()->get_type_mgr()->GetId(&float_type);
@ -258,7 +258,7 @@ void FuzzerPassDonateModules::HandleTypeOrValue(
ApplyTransformation(TransformationAddTypeFloat(new_result_id, width));
}
} break;
case SpvOpTypeVector: {
case spv::Op::OpTypeVector: {
// It is not legal to have two Vector type declarations with identical
// element types and element counts, so check whether an existing
// identical Vector type is present and use its id if so. Otherwise add
@ -282,8 +282,8 @@ void FuzzerPassDonateModules::HandleTypeOrValue(
new_result_id, component_type_id, component_count));
}
} break;
case SpvOpTypeMatrix: {
// Similar to SpvOpTypeVector.
case spv::Op::OpTypeMatrix: {
// Similar to spv::Op::OpTypeVector.
uint32_t column_type_id = original_id_to_donated_id->at(
type_or_value.GetSingleWordInOperand(0));
auto column_type =
@ -302,7 +302,7 @@ void FuzzerPassDonateModules::HandleTypeOrValue(
}
} break;
case SpvOpTypeArray: {
case spv::Op::OpTypeArray: {
// It is OK to have multiple structurally identical array types, so
// we go ahead and add a remapped version of the type declared by the
// donor.
@ -318,7 +318,7 @@ void FuzzerPassDonateModules::HandleTypeOrValue(
original_id_to_donated_id->at(
type_or_value.GetSingleWordInOperand(1))));
} break;
case SpvOpTypeRuntimeArray: {
case spv::Op::OpTypeRuntimeArray: {
// A runtime array is allowed as the final member of an SSBO. During
// donation we turn runtime arrays into fixed-size arrays. For dead
// code donations this is OK because the array is never indexed into at
@ -341,8 +341,8 @@ void FuzzerPassDonateModules::HandleTypeOrValue(
{GetFuzzerContext()->GetRandomSizeForNewArray()}, 32, false,
false)));
} break;
case SpvOpTypeStruct: {
// Similar to SpvOpTypeArray.
case spv::Op::OpTypeStruct: {
// Similar to spv::Op::OpTypeArray.
std::vector<uint32_t> member_type_ids;
for (uint32_t i = 0; i < type_or_value.NumInOperands(); i++) {
auto component_type_id = type_or_value.GetSingleWordInOperand(i);
@ -358,8 +358,8 @@ void FuzzerPassDonateModules::HandleTypeOrValue(
ApplyTransformation(
TransformationAddTypeStruct(new_result_id, member_type_ids));
} break;
case SpvOpTypePointer: {
// Similar to SpvOpTypeArray.
case spv::Op::OpTypePointer: {
// Similar to spv::Op::OpTypeArray.
uint32_t pointee_type_id = type_or_value.GetSingleWordInOperand(1);
if (!original_id_to_donated_id->count(pointee_type_id)) {
// We did not donate the pointee type for this pointer type, so we
@ -369,11 +369,11 @@ void FuzzerPassDonateModules::HandleTypeOrValue(
new_result_id = GetFuzzerContext()->GetFreshId();
ApplyTransformation(TransformationAddTypePointer(
new_result_id,
AdaptStorageClass(static_cast<SpvStorageClass>(
AdaptStorageClass(static_cast<spv::StorageClass>(
type_or_value.GetSingleWordInOperand(0))),
original_id_to_donated_id->at(pointee_type_id)));
} break;
case SpvOpTypeFunction: {
case spv::Op::OpTypeFunction: {
// It is not OK to have multiple function types that use identical ids
// for their return and parameter types. We thus go through all
// existing function types to look for a match. We do not use the
@ -425,10 +425,11 @@ void FuzzerPassDonateModules::HandleTypeOrValue(
argument_type_ids));
}
} break;
case SpvOpSpecConstantOp: {
case spv::Op::OpSpecConstantOp: {
new_result_id = GetFuzzerContext()->GetFreshId();
auto type_id = original_id_to_donated_id->at(type_or_value.type_id());
auto opcode = static_cast<SpvOp>(type_or_value.GetSingleWordInOperand(0));
auto opcode =
static_cast<spv::Op>(type_or_value.GetSingleWordInOperand(0));
// Make sure we take into account |original_id_to_donated_id| when
// computing operands for OpSpecConstantOp.
@ -447,20 +448,20 @@ void FuzzerPassDonateModules::HandleTypeOrValue(
ApplyTransformation(TransformationAddSpecConstantOp(
new_result_id, type_id, opcode, std::move(operands)));
} break;
case SpvOpSpecConstantTrue:
case SpvOpSpecConstantFalse:
case SpvOpConstantTrue:
case SpvOpConstantFalse: {
case spv::Op::OpSpecConstantTrue:
case spv::Op::OpSpecConstantFalse:
case spv::Op::OpConstantTrue:
case spv::Op::OpConstantFalse: {
// It is OK to have duplicate definitions of True and False, so add
// these to the module, using a remapped Bool type.
new_result_id = GetFuzzerContext()->GetFreshId();
auto value = type_or_value.opcode() == SpvOpConstantTrue ||
type_or_value.opcode() == SpvOpSpecConstantTrue;
auto value = type_or_value.opcode() == spv::Op::OpConstantTrue ||
type_or_value.opcode() == spv::Op::OpSpecConstantTrue;
ApplyTransformation(
TransformationAddConstantBoolean(new_result_id, value, false));
} break;
case SpvOpSpecConstant:
case SpvOpConstant: {
case spv::Op::OpSpecConstant:
case spv::Op::OpConstant: {
// It is OK to have duplicate constant definitions, so add this to the
// module using a remapped result type.
new_result_id = GetFuzzerContext()->GetFreshId();
@ -472,8 +473,8 @@ void FuzzerPassDonateModules::HandleTypeOrValue(
new_result_id, original_id_to_donated_id->at(type_or_value.type_id()),
data_words, false));
} break;
case SpvOpSpecConstantComposite:
case SpvOpConstantComposite: {
case spv::Op::OpSpecConstantComposite:
case spv::Op::OpConstantComposite: {
assert(original_id_to_donated_id->count(type_or_value.type_id()) &&
"Composite types for which it is possible to create a constant "
"should have been donated.");
@ -495,7 +496,7 @@ void FuzzerPassDonateModules::HandleTypeOrValue(
new_result_id, original_id_to_donated_id->at(type_or_value.type_id()),
constituent_ids, false));
} break;
case SpvOpConstantNull: {
case spv::Op::OpConstantNull: {
if (!original_id_to_donated_id->count(type_or_value.type_id())) {
// We did not donate the type associated with this null constant, so
// we cannot donate the null constant.
@ -509,7 +510,7 @@ void FuzzerPassDonateModules::HandleTypeOrValue(
new_result_id,
original_id_to_donated_id->at(type_or_value.type_id())));
} break;
case SpvOpVariable: {
case spv::Op::OpVariable: {
if (!original_id_to_donated_id->count(type_or_value.type_id())) {
// We did not donate the pointer type associated with this variable,
// so we cannot donate the variable.
@ -536,11 +537,11 @@ void FuzzerPassDonateModules::HandleTypeOrValue(
uint32_t remapped_pointer_type =
original_id_to_donated_id->at(type_or_value.type_id());
uint32_t initializer_id;
SpvStorageClass storage_class =
static_cast<SpvStorageClass>(type_or_value.GetSingleWordInOperand(
0)) == SpvStorageClassWorkgroup
? SpvStorageClassWorkgroup
: SpvStorageClassPrivate;
spv::StorageClass storage_class =
static_cast<spv::StorageClass>(type_or_value.GetSingleWordInOperand(
0)) == spv::StorageClass::Workgroup
? spv::StorageClass::Workgroup
: spv::StorageClass::Private;
if (type_or_value.NumInOperands() == 1) {
// The variable did not have an initializer. Initialize it to zero
// if it has Private storage class (to limit problems associated with
@ -551,7 +552,7 @@ void FuzzerPassDonateModules::HandleTypeOrValue(
// could initialize Workgroup variables at the start of an entry
// point, and should do so if their uninitialized nature proves
// problematic.
initializer_id = storage_class == SpvStorageClassWorkgroup
initializer_id = storage_class == spv::StorageClass::Workgroup
? 0
: FindOrCreateZeroConstant(
fuzzerutil::GetPointeeTypeIdFromPointerType(
@ -566,7 +567,7 @@ void FuzzerPassDonateModules::HandleTypeOrValue(
TransformationAddGlobalVariable(new_result_id, remapped_pointer_type,
storage_class, initializer_id, true));
} break;
case SpvOpUndef: {
case spv::Op::OpUndef: {
if (!original_id_to_donated_id->count(type_or_value.type_id())) {
// We did not donate the type associated with this undef, so we cannot
// donate the undef.
@ -638,7 +639,7 @@ void FuzzerPassDonateModules::HandleFunctions(
[this, &donated_instructions, donor_ir_context,
&original_id_to_donated_id,
&skipped_instructions](const opt::Instruction* instruction) {
if (instruction->opcode() == SpvOpArrayLength) {
if (instruction->opcode() == spv::Op::OpArrayLength) {
// We treat OpArrayLength specially.
HandleOpArrayLength(*instruction, original_id_to_donated_id,
&donated_instructions);
@ -682,70 +683,70 @@ bool FuzzerPassDonateModules::CanDonateInstruction(
// Now consider instructions we specifically want to skip because we do not
// yet support them.
switch (instruction.opcode()) {
case SpvOpAtomicLoad:
case SpvOpAtomicStore:
case SpvOpAtomicExchange:
case SpvOpAtomicCompareExchange:
case SpvOpAtomicCompareExchangeWeak:
case SpvOpAtomicIIncrement:
case SpvOpAtomicIDecrement:
case SpvOpAtomicIAdd:
case SpvOpAtomicISub:
case SpvOpAtomicSMin:
case SpvOpAtomicUMin:
case SpvOpAtomicSMax:
case SpvOpAtomicUMax:
case SpvOpAtomicAnd:
case SpvOpAtomicOr:
case SpvOpAtomicXor:
case spv::Op::OpAtomicLoad:
case spv::Op::OpAtomicStore:
case spv::Op::OpAtomicExchange:
case spv::Op::OpAtomicCompareExchange:
case spv::Op::OpAtomicCompareExchangeWeak:
case spv::Op::OpAtomicIIncrement:
case spv::Op::OpAtomicIDecrement:
case spv::Op::OpAtomicIAdd:
case spv::Op::OpAtomicISub:
case spv::Op::OpAtomicSMin:
case spv::Op::OpAtomicUMin:
case spv::Op::OpAtomicSMax:
case spv::Op::OpAtomicUMax:
case spv::Op::OpAtomicAnd:
case spv::Op::OpAtomicOr:
case spv::Op::OpAtomicXor:
// We conservatively ignore all atomic instructions at present.
// TODO(https://github.com/KhronosGroup/SPIRV-Tools/issues/3276): Consider
// being less conservative here.
case SpvOpImageSampleImplicitLod:
case SpvOpImageSampleExplicitLod:
case SpvOpImageSampleDrefImplicitLod:
case SpvOpImageSampleDrefExplicitLod:
case SpvOpImageSampleProjImplicitLod:
case SpvOpImageSampleProjExplicitLod:
case SpvOpImageSampleProjDrefImplicitLod:
case SpvOpImageSampleProjDrefExplicitLod:
case SpvOpImageFetch:
case SpvOpImageGather:
case SpvOpImageDrefGather:
case SpvOpImageRead:
case SpvOpImageWrite:
case SpvOpImageSparseSampleImplicitLod:
case SpvOpImageSparseSampleExplicitLod:
case SpvOpImageSparseSampleDrefImplicitLod:
case SpvOpImageSparseSampleDrefExplicitLod:
case SpvOpImageSparseSampleProjImplicitLod:
case SpvOpImageSparseSampleProjExplicitLod:
case SpvOpImageSparseSampleProjDrefImplicitLod:
case SpvOpImageSparseSampleProjDrefExplicitLod:
case SpvOpImageSparseFetch:
case SpvOpImageSparseGather:
case SpvOpImageSparseDrefGather:
case SpvOpImageSparseRead:
case SpvOpImageSampleFootprintNV:
case SpvOpImage:
case SpvOpImageQueryFormat:
case SpvOpImageQueryLevels:
case SpvOpImageQueryLod:
case SpvOpImageQueryOrder:
case SpvOpImageQuerySamples:
case SpvOpImageQuerySize:
case SpvOpImageQuerySizeLod:
case SpvOpSampledImage:
case spv::Op::OpImageSampleImplicitLod:
case spv::Op::OpImageSampleExplicitLod:
case spv::Op::OpImageSampleDrefImplicitLod:
case spv::Op::OpImageSampleDrefExplicitLod:
case spv::Op::OpImageSampleProjImplicitLod:
case spv::Op::OpImageSampleProjExplicitLod:
case spv::Op::OpImageSampleProjDrefImplicitLod:
case spv::Op::OpImageSampleProjDrefExplicitLod:
case spv::Op::OpImageFetch:
case spv::Op::OpImageGather:
case spv::Op::OpImageDrefGather:
case spv::Op::OpImageRead:
case spv::Op::OpImageWrite:
case spv::Op::OpImageSparseSampleImplicitLod:
case spv::Op::OpImageSparseSampleExplicitLod:
case spv::Op::OpImageSparseSampleDrefImplicitLod:
case spv::Op::OpImageSparseSampleDrefExplicitLod:
case spv::Op::OpImageSparseSampleProjImplicitLod:
case spv::Op::OpImageSparseSampleProjExplicitLod:
case spv::Op::OpImageSparseSampleProjDrefImplicitLod:
case spv::Op::OpImageSparseSampleProjDrefExplicitLod:
case spv::Op::OpImageSparseFetch:
case spv::Op::OpImageSparseGather:
case spv::Op::OpImageSparseDrefGather:
case spv::Op::OpImageSparseRead:
case spv::Op::OpImageSampleFootprintNV:
case spv::Op::OpImage:
case spv::Op::OpImageQueryFormat:
case spv::Op::OpImageQueryLevels:
case spv::Op::OpImageQueryLod:
case spv::Op::OpImageQueryOrder:
case spv::Op::OpImageQuerySamples:
case spv::Op::OpImageQuerySize:
case spv::Op::OpImageQuerySizeLod:
case spv::Op::OpSampledImage:
// We ignore all instructions related to accessing images, since we do not
// donate images.
return false;
case SpvOpLoad:
case spv::Op::OpLoad:
switch (donor_ir_context->get_def_use_mgr()
->GetDef(instruction.type_id())
->opcode()) {
case SpvOpTypeImage:
case SpvOpTypeSampledImage:
case SpvOpTypeSampler:
case spv::Op::OpTypeImage:
case spv::Op::OpTypeSampledImage:
case spv::Op::OpTypeSampler:
// Again, we ignore instructions that relate to accessing images.
return false;
default:
@ -783,13 +784,13 @@ bool FuzzerPassDonateModules::CanDonateInstruction(
bool FuzzerPassDonateModules::IsBasicType(
const opt::Instruction& instruction) const {
switch (instruction.opcode()) {
case SpvOpTypeArray:
case SpvOpTypeBool:
case SpvOpTypeFloat:
case SpvOpTypeInt:
case SpvOpTypeMatrix:
case SpvOpTypeStruct:
case SpvOpTypeVector:
case spv::Op::OpTypeArray:
case spv::Op::OpTypeBool:
case spv::Op::OpTypeFloat:
case spv::Op::OpTypeInt:
case spv::Op::OpTypeMatrix:
case spv::Op::OpTypeStruct:
case spv::Op::OpTypeVector:
return true;
default:
return false;
@ -800,7 +801,7 @@ void FuzzerPassDonateModules::HandleOpArrayLength(
const opt::Instruction& instruction,
std::map<uint32_t, uint32_t>* original_id_to_donated_id,
std::vector<protobufs::Instruction>* donated_instructions) const {
assert(instruction.opcode() == SpvOpArrayLength &&
assert(instruction.opcode() == spv::Op::OpArrayLength &&
"Precondition: instruction must be OpArrayLength.");
uint32_t donated_variable_id =
original_id_to_donated_id->at(instruction.GetSingleWordInOperand(0));
@ -809,12 +810,12 @@ void FuzzerPassDonateModules::HandleOpArrayLength(
auto pointer_to_struct_instruction =
GetIRContext()->get_def_use_mgr()->GetDef(
donated_variable_instruction->type_id());
assert(pointer_to_struct_instruction->opcode() == SpvOpTypePointer &&
assert(pointer_to_struct_instruction->opcode() == spv::Op::OpTypePointer &&
"Type of variable must be pointer.");
auto donated_struct_type_instruction =
GetIRContext()->get_def_use_mgr()->GetDef(
pointer_to_struct_instruction->GetSingleWordInOperand(1));
assert(donated_struct_type_instruction->opcode() == SpvOpTypeStruct &&
assert(donated_struct_type_instruction->opcode() == spv::Op::OpTypeStruct &&
"Pointee type of pointer used by OpArrayLength must be struct.");
assert(donated_struct_type_instruction->NumInOperands() ==
instruction.GetSingleWordInOperand(1) + 1 &&
@ -825,7 +826,7 @@ void FuzzerPassDonateModules::HandleOpArrayLength(
donated_struct_type_instruction->NumInOperands() - 1);
auto fixed_size_array_type_instruction =
GetIRContext()->get_def_use_mgr()->GetDef(fixed_size_array_type_id);
assert(fixed_size_array_type_instruction->opcode() == SpvOpTypeArray &&
assert(fixed_size_array_type_instruction->opcode() == spv::Op::OpTypeArray &&
"The donated array type must be fixed-size.");
auto array_size_id =
fixed_size_array_type_instruction->GetSingleWordInOperand(1);
@ -837,7 +838,8 @@ void FuzzerPassDonateModules::HandleOpArrayLength(
}
donated_instructions->push_back(MakeInstructionMessage(
SpvOpCopyObject, original_id_to_donated_id->at(instruction.type_id()),
spv::Op::OpCopyObject,
original_id_to_donated_id->at(instruction.type_id()),
original_id_to_donated_id->at(instruction.result_id()),
opt::Instruction::OperandList({{SPV_OPERAND_TYPE_ID, {array_size_id}}})));
}
@ -892,7 +894,7 @@ void FuzzerPassDonateModules::HandleDifficultInstruction(
// more interesting value later.
auto zero_constant = FindOrCreateZeroConstant(remapped_type_id, true);
donated_instructions->push_back(MakeInstructionMessage(
SpvOpCopyObject, remapped_type_id,
spv::Op::OpCopyObject, remapped_type_id,
original_id_to_donated_id->at(instruction.result_id()),
opt::Instruction::OperandList({{SPV_OPERAND_TYPE_ID, {zero_constant}}})));
}
@ -926,8 +928,8 @@ void FuzzerPassDonateModules::PrepareInstructionForDonation(
(void)(donor_ir_context);
assert((donor_ir_context->get_def_use_mgr()
->GetDef(operand_id)
->opcode() == SpvOpLabel ||
instruction.opcode() == SpvOpPhi) &&
->opcode() == spv::Op::OpLabel ||
instruction.opcode() == spv::Op::OpPhi) &&
"Unsupported forward reference.");
original_id_to_donated_id->insert(
{operand_id, GetFuzzerContext()->GetFreshId()});
@ -942,7 +944,7 @@ void FuzzerPassDonateModules::PrepareInstructionForDonation(
input_operands.push_back({in_operand.type, operand_data});
}
if (instruction.opcode() == SpvOpVariable &&
if (instruction.opcode() == spv::Op::OpVariable &&
instruction.NumInOperands() == 1) {
// This is an uninitialized local variable. Initialize it to zero.
input_operands.push_back(
@ -1017,7 +1019,7 @@ bool FuzzerPassDonateModules::CreateLoopLimiterInfo(
// Adjust OpPhi instructions in the |merge_block|.
for (const auto& inst : *merge_block) {
if (inst.opcode() != SpvOpPhi) {
if (inst.opcode() != spv::Op::OpPhi) {
break;
}
@ -1070,7 +1072,8 @@ bool FuzzerPassDonateModules::MaybeAddLivesafeFunction(
// live-safe. Add them if not already present.
FindOrCreateBoolType(); // Needed for comparisons
FindOrCreatePointerToIntegerType(
32, false, SpvStorageClassFunction); // Needed for adding loop limiters
32, false,
spv::StorageClass::Function); // Needed for adding loop limiters
FindOrCreateIntegerConstant({0}, 32, false,
false); // Needed for initializing loop limiters
FindOrCreateIntegerConstant({1}, 32, false,
@ -1107,8 +1110,8 @@ bool FuzzerPassDonateModules::MaybeAddLivesafeFunction(
for (auto& block : function_to_donate) {
for (auto& inst : block) {
switch (inst.opcode()) {
case SpvOpAccessChain:
case SpvOpInBoundsAccessChain: {
case spv::Op::OpAccessChain:
case spv::Op::OpInBoundsAccessChain: {
protobufs::AccessChainClampingInfo clamping_info;
clamping_info.set_access_chain_id(
original_id_to_donated_id.at(inst.result_id()));
@ -1118,7 +1121,8 @@ bool FuzzerPassDonateModules::MaybeAddLivesafeFunction(
assert(base_object && "The base object must exist.");
auto pointer_type = donor_ir_context->get_def_use_mgr()->GetDef(
base_object->type_id());
assert(pointer_type && pointer_type->opcode() == SpvOpTypePointer &&
assert(pointer_type &&
pointer_type->opcode() == spv::Op::OpTypePointer &&
"The base object must have pointer type.");
auto should_be_composite_type =
@ -1138,7 +1142,8 @@ bool FuzzerPassDonateModules::MaybeAddLivesafeFunction(
// Get the bound for the component being indexed into.
uint32_t bound;
if (should_be_composite_type->opcode() == SpvOpTypeRuntimeArray) {
if (should_be_composite_type->opcode() ==
spv::Op::OpTypeRuntimeArray) {
// The donor is indexing into a runtime array. We do not
// donate runtime arrays. Instead, we donate a corresponding
// fixed-size array for every runtime array. We should thus
@ -1148,7 +1153,7 @@ bool FuzzerPassDonateModules::MaybeAddLivesafeFunction(
GetIRContext()->get_def_use_mgr()->GetDef(
original_id_to_donated_id.at(
should_be_composite_type->result_id()));
assert(fixed_size_array_type->opcode() == SpvOpTypeArray &&
assert(fixed_size_array_type->opcode() == spv::Op::OpTypeArray &&
"A runtime array type in the donor should have been "
"replaced by a fixed-sized array in the recipient.");
// The size of this fixed-size array is a suitable bound.
@ -1163,12 +1168,12 @@ bool FuzzerPassDonateModules::MaybeAddLivesafeFunction(
donor_ir_context->get_def_use_mgr()->GetDef(index_id);
auto index_type_inst = donor_ir_context->get_def_use_mgr()->GetDef(
index_inst->type_id());
assert(index_type_inst->opcode() == SpvOpTypeInt);
assert(index_type_inst->opcode() == spv::Op::OpTypeInt);
opt::analysis::Integer* index_int_type =
donor_ir_context->get_type_mgr()
->GetType(index_type_inst->result_id())
->AsInteger();
if (index_inst->opcode() != SpvOpConstant) {
if (index_inst->opcode() != spv::Op::OpConstant) {
// We will have to clamp this index, so we need a constant
// whose value is one less than the bound, to compare
// against and to use as the clamped value.
@ -1194,7 +1199,7 @@ bool FuzzerPassDonateModules::MaybeAddLivesafeFunction(
uint32_t kill_unreachable_return_value_id = 0;
auto function_return_type_inst =
donor_ir_context->get_def_use_mgr()->GetDef(function_to_donate.type_id());
if (function_return_type_inst->opcode() != SpvOpTypeVoid &&
if (function_return_type_inst->opcode() != spv::Op::OpTypeVoid &&
fuzzerutil::FunctionContainsOpKillOrUnreachable(function_to_donate)) {
kill_unreachable_return_value_id = FindOrCreateZeroConstant(
original_id_to_donated_id.at(function_return_type_inst->result_id()),

View File

@ -45,7 +45,8 @@ class FuzzerPassDonateModules : public FuzzerPass {
private:
// Adapts a storage class coming from a donor module so that it will work
// in a recipient module, e.g. by changing Uniform to Private.
static SpvStorageClass AdaptStorageClass(SpvStorageClass donor_storage_class);
static spv::StorageClass AdaptStorageClass(
spv::StorageClass donor_storage_class);
// Identifies all external instruction set imports in |donor_ir_context| and
// populates |original_id_to_donated_id| with a mapping from the donor's id

View File

@ -40,8 +40,8 @@ void FuzzerPassExpandVectorReductions::Apply() {
}
// |instruction| must be OpAny or OpAll.
if (instruction.opcode() != SpvOpAny &&
instruction.opcode() != SpvOpAll) {
if (instruction.opcode() != spv::Op::OpAny &&
instruction.opcode() != spv::Op::OpAll) {
continue;
}

View File

@ -48,8 +48,8 @@ void FuzzerPassFlattenConditionalBranches::Apply() {
// Only consider this block if it is the header of a conditional, with a
// non-irrelevant condition.
if (block.GetMergeInst() &&
block.GetMergeInst()->opcode() == SpvOpSelectionMerge &&
block.terminator()->opcode() == SpvOpBranchConditional &&
block.GetMergeInst()->opcode() == spv::Op::OpSelectionMerge &&
block.terminator()->opcode() == spv::Op::OpBranchConditional &&
!GetTransformationContext()->GetFactManager()->IdIsIrrelevant(
block.terminator()->GetSingleWordInOperand(0))) {
selection_headers.emplace_back(&block);
@ -94,11 +94,11 @@ void FuzzerPassFlattenConditionalBranches::Apply() {
->get_def_use_mgr()
->GetDef(phi_instruction->type_id())
->opcode()) {
case SpvOpTypeBool:
case SpvOpTypeInt:
case SpvOpTypeFloat:
case SpvOpTypePointer:
case SpvOpTypeVector:
case spv::Op::OpTypeBool:
case spv::Op::OpTypeInt:
case spv::Op::OpTypeFloat:
case spv::Op::OpTypePointer:
case spv::Op::OpTypeVector:
return true;
default:
return false;
@ -143,7 +143,7 @@ void FuzzerPassFlattenConditionalBranches::Apply() {
GetIRContext()->get_def_use_mgr()->GetDef(
phi_instruction->type_id());
switch (type_instruction->opcode()) {
case SpvOpTypeVector: {
case spv::Op::OpTypeVector: {
uint32_t dimension =
type_instruction->GetSingleWordInOperand(1);
switch (dimension) {

View File

@ -64,7 +64,7 @@ void FuzzerPassInlineFunctions::Apply() {
auto* function_call_block =
GetIRContext()->get_instr_block(function_call_instruction);
if ((function_call_instruction != &*--function_call_block->tail() ||
function_call_block->terminator()->opcode() != SpvOpBranch) &&
function_call_block->terminator()->opcode() != spv::Op::OpBranch) &&
!MaybeApplyTransformation(TransformationSplitBlock(
MakeInstructionDescriptor(GetIRContext(),
function_call_instruction->NextNode()),

View File

@ -47,18 +47,20 @@ void FuzzerPassMakeVectorOperationsDynamic::Apply() {
}
// Make sure |instruction| has only one indexing operand.
assert(instruction.NumInOperands() ==
(instruction.opcode() == SpvOpCompositeExtract ? 2 : 3) &&
"FuzzerPassMakeVectorOperationsDynamic: the composite "
"instruction must have "
"only one indexing operand.");
assert(
instruction.NumInOperands() ==
(instruction.opcode() == spv::Op::OpCompositeExtract ? 2 : 3) &&
"FuzzerPassMakeVectorOperationsDynamic: the composite "
"instruction must have "
"only one indexing operand.");
// Applies the make vector operation dynamic transformation.
ApplyTransformation(TransformationMakeVectorOperationDynamic(
instruction.result_id(),
FindOrCreateIntegerConstant(
{instruction.GetSingleWordInOperand(
instruction.opcode() == SpvOpCompositeExtract ? 1 : 2)},
instruction.opcode() == spv::Op::OpCompositeExtract ? 1
: 2)},
32, GetFuzzerContext()->ChooseEven(), false)));
}
}

View File

@ -64,11 +64,11 @@ void FuzzerPassMergeFunctionReturns::Apply() {
[this, function](
opt::BasicBlock* /*unused*/, opt::BasicBlock::iterator inst_it,
const protobufs::InstructionDescriptor& instruction_descriptor) {
const SpvOp opcode = inst_it->opcode();
const spv::Op opcode = inst_it->opcode();
switch (opcode) {
case SpvOpKill:
case SpvOpUnreachable:
case SpvOpTerminateInvocation: {
case spv::Op::OpKill:
case spv::Op::OpUnreachable:
case spv::Op::OpTerminateInvocation: {
// This is an early termination instruction - we need to wrap it
// so that it becomes a return.
if (TransformationWrapEarlyTerminatorInFunction::
@ -85,7 +85,7 @@ void FuzzerPassMergeFunctionReturns::Apply() {
GetIRContext()->get_def_use_mgr()->GetDef(
function->type_id());
uint32_t returned_value_id;
if (function_return_type->opcode() == SpvOpTypeVoid) {
if (function_return_type->opcode() == spv::Op::OpTypeVoid) {
// No value is needed.
returned_value_id = 0;
} else if (fuzzerutil::CanCreateConstant(
@ -130,7 +130,7 @@ void FuzzerPassMergeFunctionReturns::Apply() {
// If the entry block does not branch unconditionally to another block,
// split it.
if (function->entry()->terminator()->opcode() != SpvOpBranch) {
if (function->entry()->terminator()->opcode() != spv::Op::OpBranch) {
SplitBlockAfterOpPhiOrOpVariable(function->entry()->id());
}
@ -149,9 +149,9 @@ void FuzzerPassMergeFunctionReturns::Apply() {
if (GetIRContext()
->get_instr_block(merge_block)
->WhileEachInst([](opt::Instruction* inst) {
return inst->opcode() == SpvOpLabel ||
inst->opcode() == SpvOpPhi ||
inst->opcode() == SpvOpBranch;
return inst->opcode() == spv::Op::OpLabel ||
inst->opcode() == spv::Op::OpPhi ||
inst->opcode() == spv::Op::OpBranch;
})) {
actual_merge_blocks.emplace_back(merge_block);
continue;
@ -324,7 +324,8 @@ FuzzerPassMergeFunctionReturns::GetInfoNeededForMergeBlocks(
bool FuzzerPassMergeFunctionReturns::IsEarlyTerminatorWrapper(
const opt::Function& function) const {
for (SpvOp opcode : {SpvOpKill, SpvOpUnreachable, SpvOpTerminateInvocation}) {
for (spv::Op opcode : {spv::Op::OpKill, spv::Op::OpUnreachable,
spv::Op::OpTerminateInvocation}) {
if (TransformationWrapEarlyTerminatorInFunction::MaybeGetWrapperFunction(
GetIRContext(), opcode) == &function) {
return true;

View File

@ -39,7 +39,8 @@ void FuzzerPassMutatePointers::Apply() {
return;
}
if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(SpvOpLoad, inst_it)) {
if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(spv::Op::OpLoad,
inst_it)) {
return;
}

View File

@ -37,21 +37,21 @@ FuzzerPassObfuscateConstants::FuzzerPassObfuscateConstants(
void FuzzerPassObfuscateConstants::ObfuscateBoolConstantViaConstantPair(
uint32_t depth, const protobufs::IdUseDescriptor& bool_constant_use,
const std::vector<SpvOp>& greater_than_opcodes,
const std::vector<SpvOp>& less_than_opcodes, uint32_t constant_id_1,
const std::vector<spv::Op>& greater_than_opcodes,
const std::vector<spv::Op>& less_than_opcodes, uint32_t constant_id_1,
uint32_t constant_id_2, bool first_constant_is_larger) {
auto bool_constant_opcode = GetIRContext()
->get_def_use_mgr()
->GetDef(bool_constant_use.id_of_interest())
->opcode();
assert((bool_constant_opcode == SpvOpConstantFalse ||
bool_constant_opcode == SpvOpConstantTrue) &&
assert((bool_constant_opcode == spv::Op::OpConstantFalse ||
bool_constant_opcode == spv::Op::OpConstantTrue) &&
"Precondition: this must be a usage of a boolean constant.");
// Pick an opcode at random. First randomly decide whether to generate
// a 'greater than' or 'less than' kind of opcode, and then select a
// random opcode from the resulting subset.
SpvOp comparison_opcode;
spv::Op comparison_opcode;
if (GetFuzzerContext()->ChooseEven()) {
comparison_opcode = greater_than_opcodes[GetFuzzerContext()->RandomIndex(
greater_than_opcodes)];
@ -68,9 +68,9 @@ void FuzzerPassObfuscateConstants::ObfuscateBoolConstantViaConstantPair(
comparison_opcode) != greater_than_opcodes.end();
uint32_t lhs_id;
uint32_t rhs_id;
if ((bool_constant_opcode == SpvOpConstantTrue &&
if ((bool_constant_opcode == spv::Op::OpConstantTrue &&
first_constant_is_larger == is_greater_than_opcode) ||
(bool_constant_opcode == SpvOpConstantFalse &&
(bool_constant_opcode == spv::Op::OpConstantFalse &&
first_constant_is_larger != is_greater_than_opcode)) {
lhs_id = constant_id_1;
rhs_id = constant_id_2;
@ -147,12 +147,12 @@ void FuzzerPassObfuscateConstants::ObfuscateBoolConstantViaFloatConstantPair(
first_constant_is_larger =
float_constant_1->GetDouble() > float_constant_2->GetDouble();
}
std::vector<SpvOp> greater_than_opcodes{
SpvOpFOrdGreaterThan, SpvOpFOrdGreaterThanEqual, SpvOpFUnordGreaterThan,
SpvOpFUnordGreaterThanEqual};
std::vector<SpvOp> less_than_opcodes{
SpvOpFOrdGreaterThan, SpvOpFOrdGreaterThanEqual, SpvOpFUnordGreaterThan,
SpvOpFUnordGreaterThanEqual};
std::vector<spv::Op> greater_than_opcodes{
spv::Op::OpFOrdGreaterThan, spv::Op::OpFOrdGreaterThanEqual,
spv::Op::OpFUnordGreaterThan, spv::Op::OpFUnordGreaterThanEqual};
std::vector<spv::Op> less_than_opcodes{
spv::Op::OpFOrdGreaterThan, spv::Op::OpFOrdGreaterThanEqual,
spv::Op::OpFUnordGreaterThan, spv::Op::OpFUnordGreaterThanEqual};
ObfuscateBoolConstantViaConstantPair(
depth, bool_constant_use, greater_than_opcodes, less_than_opcodes,
@ -190,9 +190,10 @@ void FuzzerPassObfuscateConstants::
first_constant_is_larger =
signed_int_constant_1->GetS64() > signed_int_constant_2->GetS64();
}
std::vector<SpvOp> greater_than_opcodes{SpvOpSGreaterThan,
SpvOpSGreaterThanEqual};
std::vector<SpvOp> less_than_opcodes{SpvOpSLessThan, SpvOpSLessThanEqual};
std::vector<spv::Op> greater_than_opcodes{spv::Op::OpSGreaterThan,
spv::Op::OpSGreaterThanEqual};
std::vector<spv::Op> less_than_opcodes{spv::Op::OpSLessThan,
spv::Op::OpSLessThanEqual};
ObfuscateBoolConstantViaConstantPair(
depth, bool_constant_use, greater_than_opcodes, less_than_opcodes,
@ -232,9 +233,10 @@ void FuzzerPassObfuscateConstants::
first_constant_is_larger =
unsigned_int_constant_1->GetU64() > unsigned_int_constant_2->GetU64();
}
std::vector<SpvOp> greater_than_opcodes{SpvOpUGreaterThan,
SpvOpUGreaterThanEqual};
std::vector<SpvOp> less_than_opcodes{SpvOpULessThan, SpvOpULessThanEqual};
std::vector<spv::Op> greater_than_opcodes{spv::Op::OpUGreaterThan,
spv::Op::OpUGreaterThanEqual};
std::vector<spv::Op> less_than_opcodes{spv::Op::OpULessThan,
spv::Op::OpULessThanEqual};
ObfuscateBoolConstantViaConstantPair(
depth, bool_constant_use, greater_than_opcodes, less_than_opcodes,
@ -379,7 +381,7 @@ void FuzzerPassObfuscateConstants::ObfuscateScalarConstant(
uniform_descriptor.index());
assert(element_type_id && "Type of uniform variable is invalid");
FindOrCreatePointerType(element_type_id, SpvStorageClassUniform);
FindOrCreatePointerType(element_type_id, spv::StorageClass::Uniform);
// Create, apply and record a transformation to replace the constant use with
// the result of a load from the chosen uniform.
@ -394,11 +396,11 @@ void FuzzerPassObfuscateConstants::ObfuscateConstant(
->get_def_use_mgr()
->GetDef(constant_use.id_of_interest())
->opcode()) {
case SpvOpConstantTrue:
case SpvOpConstantFalse:
case spv::Op::OpConstantTrue:
case spv::Op::OpConstantFalse:
ObfuscateBoolConstant(depth, constant_use);
break;
case SpvOpConstant:
case spv::Op::OpConstant:
ObfuscateScalarConstant(depth, constant_use);
break;
default:
@ -410,7 +412,7 @@ void FuzzerPassObfuscateConstants::ObfuscateConstant(
void FuzzerPassObfuscateConstants::MaybeAddConstantIdUse(
const opt::Instruction& inst, uint32_t in_operand_index,
uint32_t base_instruction_result_id,
const std::map<SpvOp, uint32_t>& skipped_opcode_count,
const std::map<spv::Op, uint32_t>& skipped_opcode_count,
std::vector<protobufs::IdUseDescriptor>* constant_uses) {
if (inst.GetInOperand(in_operand_index).type != SPV_OPERAND_TYPE_ID) {
// The operand is not an id, so it cannot be a constant id.
@ -420,15 +422,15 @@ void FuzzerPassObfuscateConstants::MaybeAddConstantIdUse(
auto operand_definition =
GetIRContext()->get_def_use_mgr()->GetDef(operand_id);
switch (operand_definition->opcode()) {
case SpvOpConstantFalse:
case SpvOpConstantTrue:
case SpvOpConstant: {
case spv::Op::OpConstantFalse:
case spv::Op::OpConstantTrue:
case spv::Op::OpConstant: {
// The operand is a constant id, so make an id use descriptor and record
// it.
protobufs::IdUseDescriptor id_use_descriptor;
id_use_descriptor.set_id_of_interest(operand_id);
id_use_descriptor.mutable_enclosing_instruction()
->set_target_instruction_opcode(inst.opcode());
->set_target_instruction_opcode(uint32_t(inst.opcode()));
id_use_descriptor.mutable_enclosing_instruction()
->set_base_instruction_result_id(base_instruction_result_id);
id_use_descriptor.mutable_enclosing_instruction()
@ -461,7 +463,7 @@ void FuzzerPassObfuscateConstants::Apply() {
// opcode need to be skipped in order to find the instruction of interest
// from the base instruction. We maintain a mapping that records a skip
// count for each relevant opcode.
std::map<SpvOp, uint32_t> skipped_opcode_count;
std::map<spv::Op, uint32_t> skipped_opcode_count;
// Go through each instruction in the block.
for (auto& inst : block) {
@ -478,7 +480,7 @@ void FuzzerPassObfuscateConstants::Apply() {
// The instruction must not be an OpVariable, the only id that an
// OpVariable uses is an initializer id, which has to remain
// constant.
if (inst.opcode() != SpvOpVariable) {
if (inst.opcode() != spv::Op::OpVariable) {
// Consider each operand of the instruction, and add a constant id
// use for the operand if relevant.
for (uint32_t in_operand_index = 0;

View File

@ -85,8 +85,8 @@ class FuzzerPassObfuscateConstants : public FuzzerPass {
// (similar for |less_than_opcodes|).
void ObfuscateBoolConstantViaConstantPair(
uint32_t depth, const protobufs::IdUseDescriptor& bool_constant_use,
const std::vector<SpvOp>& greater_than_opcodes,
const std::vector<SpvOp>& less_than_opcodes, uint32_t constant_id_1,
const std::vector<spv::Op>& greater_than_opcodes,
const std::vector<spv::Op>& less_than_opcodes, uint32_t constant_id_1,
uint32_t constant_id_2, bool first_constant_is_larger);
// A helper method to determine whether input operand |in_operand_index| of
@ -96,7 +96,7 @@ class FuzzerPassObfuscateConstants : public FuzzerPass {
void MaybeAddConstantIdUse(
const opt::Instruction& inst, uint32_t in_operand_index,
uint32_t base_instruction_result_id,
const std::map<SpvOp, uint32_t>& skipped_opcode_count,
const std::map<spv::Op, uint32_t>& skipped_opcode_count,
std::vector<protobufs::IdUseDescriptor>* constant_uses);
// Returns a vector of unique words that denote constants. Every such constant

View File

@ -137,12 +137,12 @@ FuzzerPassOutlineFunctions::MaybeGetEntryBlockSuitableForOutlining(
"The entry block cannot be a loop header at this point.");
// If the entry block starts with OpPhi or OpVariable, try to split it.
if (entry_block->begin()->opcode() == SpvOpPhi ||
entry_block->begin()->opcode() == SpvOpVariable) {
if (entry_block->begin()->opcode() == spv::Op::OpPhi ||
entry_block->begin()->opcode() == spv::Op::OpVariable) {
// Find the first non-OpPhi and non-OpVariable instruction.
auto non_phi_or_var_inst = &*entry_block->begin();
while (non_phi_or_var_inst->opcode() == SpvOpPhi ||
non_phi_or_var_inst->opcode() == SpvOpVariable) {
while (non_phi_or_var_inst->opcode() == spv::Op::OpPhi ||
non_phi_or_var_inst->opcode() == spv::Op::OpVariable) {
non_phi_or_var_inst = non_phi_or_var_inst->NextNode();
}
@ -175,7 +175,7 @@ FuzzerPassOutlineFunctions::MaybeGetExitBlockSuitableForOutlining(
// Find the first non-OpPhi instruction, after which to split.
auto split_before = &*exit_block->begin();
while (split_before->opcode() == SpvOpPhi) {
while (split_before->opcode() == spv::Op::OpPhi) {
split_before = split_before->NextNode();
}

View File

@ -47,7 +47,7 @@ void FuzzerPassPermuteFunctionVariables::Apply() {
std::vector<opt::Instruction*> variables;
for (auto& instruction : *first_block) {
if (instruction.opcode() == SpvOpVariable) {
if (instruction.opcode() == spv::Op::OpVariable) {
variables.push_back(&instruction);
}
}

View File

@ -40,7 +40,7 @@ void FuzzerPassPermutePhiOperands::Apply() {
const protobufs::InstructionDescriptor& /*unused*/) {
const auto& inst = *inst_it;
if (inst.opcode() != SpvOpPhi) {
if (inst.opcode() != spv::Op::OpPhi) {
return;
}

View File

@ -35,10 +35,11 @@ void FuzzerPassPushIdsThroughVariables::Apply() {
opt::BasicBlock::iterator instruction_iterator,
const protobufs::InstructionDescriptor& instruction_descriptor)
-> void {
assert(instruction_iterator->opcode() ==
instruction_descriptor.target_instruction_opcode() &&
"The opcode of the instruction we might insert before must be "
"the same as the opcode in the descriptor for the instruction");
assert(
instruction_iterator->opcode() ==
spv::Op(instruction_descriptor.target_instruction_opcode()) &&
"The opcode of the instruction we might insert before must be "
"the same as the opcode in the descriptor for the instruction");
// Randomly decide whether to try pushing an id through a variable.
if (!GetFuzzerContext()->ChoosePercentage(
@ -55,16 +56,16 @@ void FuzzerPassPushIdsThroughVariables::Apply() {
// It must be valid to insert OpStore and OpLoad instructions
// before the instruction to insert before.
if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(
SpvOpStore, instruction_iterator) ||
spv::Op::OpStore, instruction_iterator) ||
!fuzzerutil::CanInsertOpcodeBeforeInstruction(
SpvOpLoad, instruction_iterator)) {
spv::Op::OpLoad, instruction_iterator)) {
return;
}
// Randomly decides whether a global or local variable will be added.
auto variable_storage_class = GetFuzzerContext()->ChooseEven()
? SpvStorageClassPrivate
: SpvStorageClassFunction;
? spv::StorageClass::Private
: spv::StorageClass::Function;
// Gets the available basic and pointer types.
auto basic_type_ids_and_pointers =
@ -127,13 +128,13 @@ void FuzzerPassPushIdsThroughVariables::Apply() {
GetIRContext()->get_def_use_mgr()->GetDef(basic_type_id);
assert(type_inst);
switch (type_inst->opcode()) {
case SpvOpTypeBool:
case SpvOpTypeFloat:
case SpvOpTypeInt:
case SpvOpTypeArray:
case SpvOpTypeMatrix:
case SpvOpTypeVector:
case SpvOpTypeStruct:
case spv::Op::OpTypeBool:
case spv::Op::OpTypeFloat:
case spv::Op::OpTypeInt:
case spv::Op::OpTypeArray:
case spv::Op::OpTypeMatrix:
case spv::Op::OpTypeVector:
case spv::Op::OpTypeStruct:
break;
default:
return;
@ -150,7 +151,8 @@ void FuzzerPassPushIdsThroughVariables::Apply() {
value_instructions)]
->result_id(),
GetFuzzerContext()->GetFreshId(), GetFuzzerContext()->GetFreshId(),
variable_storage_class, initializer_id, instruction_descriptor));
uint32_t(variable_storage_class), initializer_id,
instruction_descriptor));
});
}

View File

@ -38,13 +38,13 @@ void FuzzerPassReplaceBranchesFromDeadBlocksWithExits::Apply() {
// to be executed with the Fragment execution model. We conservatively only
// allow OpKill if every entry point in the module has the Fragment execution
// model.
auto fragment_execution_model_guaranteed =
std::all_of(GetIRContext()->module()->entry_points().begin(),
GetIRContext()->module()->entry_points().end(),
[](const opt::Instruction& entry_point) -> bool {
return entry_point.GetSingleWordInOperand(0) ==
SpvExecutionModelFragment;
});
auto fragment_execution_model_guaranteed = std::all_of(
GetIRContext()->module()->entry_points().begin(),
GetIRContext()->module()->entry_points().end(),
[](const opt::Instruction& entry_point) -> bool {
return spv::ExecutionModel(entry_point.GetSingleWordInOperand(0)) ==
spv::ExecutionModel::Fragment;
});
// Transformations of this type can disable one another. To avoid ordering
// bias, we therefore build a set of candidate transformations to apply, and
@ -71,20 +71,20 @@ void FuzzerPassReplaceBranchesFromDeadBlocksWithExits::Apply() {
// Whether we can use OpKill depends on the execution model, and which of
// OpReturn and OpReturnValue we can use depends on the return type of the
// enclosing function.
std::vector<SpvOp> opcodes = {SpvOpUnreachable};
std::vector<spv::Op> opcodes = {spv::Op::OpUnreachable};
if (fragment_execution_model_guaranteed) {
opcodes.emplace_back(SpvOpKill);
opcodes.emplace_back(spv::Op::OpKill);
}
auto function_return_type =
GetIRContext()->get_type_mgr()->GetType(function.type_id());
if (function_return_type->AsVoid()) {
opcodes.emplace_back(SpvOpReturn);
opcodes.emplace_back(spv::Op::OpReturn);
} else if (fuzzerutil::CanCreateConstant(GetIRContext(),
function.type_id())) {
// For simplicity we only allow OpReturnValue if the function return
// type is a type for which we can create a constant. This allows us a
// zero of the given type as a default return value.
opcodes.emplace_back(SpvOpReturnValue);
opcodes.emplace_back(spv::Op::OpReturnValue);
}
// Choose one of the available terminator opcodes at random and create a
// candidate transformation.
@ -92,7 +92,7 @@ void FuzzerPassReplaceBranchesFromDeadBlocksWithExits::Apply() {
candidate_transformations.emplace_back(
TransformationReplaceBranchFromDeadBlockWithExit(
block.id(), opcode,
opcode == SpvOpReturnValue
opcode == spv::Op::OpReturnValue
? FindOrCreateZeroConstant(function.type_id(), true)
: 0));
}

View File

@ -41,7 +41,7 @@ void FuzzerPassReplaceCopyMemoriesWithLoadsStores::Apply() {
}
// The instruction must be OpCopyMemory.
if (instruction->opcode() != SpvOpCopyMemory) {
if (instruction->opcode() != spv::Op::OpCopyMemory) {
return;
}

View File

@ -40,7 +40,7 @@ void FuzzerPassReplaceCopyObjectsWithStoresLoads::Apply() {
return;
}
// The instruction must be OpCopyObject.
if (instruction->opcode() != SpvOpCopyObject) {
if (instruction->opcode() != spv::Op::OpCopyObject) {
return;
}
// The opcode of the type_id instruction cannot be a OpTypePointer,
@ -48,21 +48,22 @@ void FuzzerPassReplaceCopyObjectsWithStoresLoads::Apply() {
if (GetIRContext()
->get_def_use_mgr()
->GetDef(instruction->type_id())
->opcode() == SpvOpTypePointer) {
->opcode() == spv::Op::OpTypePointer) {
return;
}
// It must be valid to insert OpStore and OpLoad instructions
// before the instruction OpCopyObject.
if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(SpvOpStore,
if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(spv::Op::OpStore,
instruction) ||
!fuzzerutil::CanInsertOpcodeBeforeInstruction(SpvOpLoad, instruction)) {
!fuzzerutil::CanInsertOpcodeBeforeInstruction(spv::Op::OpLoad,
instruction)) {
return;
}
// Randomly decides whether a global or local variable will be added.
auto variable_storage_class = GetFuzzerContext()->ChooseEven()
? SpvStorageClassPrivate
: SpvStorageClassFunction;
? spv::StorageClass::Private
: spv::StorageClass::Function;
// Find or create a constant to initialize the variable from. The type of
// |instruction| must be such that the function FindOrCreateConstant can be
@ -79,7 +80,7 @@ void FuzzerPassReplaceCopyObjectsWithStoresLoads::Apply() {
// Apply the transformation replacing OpCopyObject with Store and Load.
ApplyTransformation(TransformationReplaceCopyObjectWithStoreLoad(
instruction->result_id(), GetFuzzerContext()->GetFreshId(),
variable_storage_class, variable_initializer_id));
uint32_t(variable_storage_class), variable_initializer_id));
});
}

View File

@ -73,7 +73,7 @@ void FuzzerPassReplaceIrrelevantIds::Apply() {
// we cannot use these as replacements.
for (const auto& pair : GetIRContext()->get_def_use_mgr()->id_to_defs()) {
uint32_t type_id = pair.second->type_id();
if (pair.second->opcode() != SpvOpFunction && type_id &&
if (pair.second->opcode() != spv::Op::OpFunction && type_id &&
types_to_ids.count(type_id)) {
types_to_ids[type_id].push_back(pair.first);
}

View File

@ -50,9 +50,9 @@ void FuzzerPassReplaceLoadsStoresWithCopyMemories::Apply() {
std::unordered_map<uint32_t, opt::Instruction*> current_op_loads;
for (auto& instruction : block) {
// Add a potential OpLoad instruction.
if (instruction.opcode() == SpvOpLoad) {
if (instruction.opcode() == spv::Op::OpLoad) {
current_op_loads[instruction.result_id()] = &instruction;
} else if (instruction.opcode() == SpvOpStore) {
} else if (instruction.opcode() == spv::Op::OpStore) {
if (current_op_loads.find(instruction.GetSingleWordOperand(1)) !=
current_op_loads.end()) {
// We have found the matching OpLoad instruction to the current
@ -73,7 +73,7 @@ void FuzzerPassReplaceLoadsStoresWithCopyMemories::Apply() {
opt::Instruction* source_id =
GetIRContext()->get_def_use_mgr()->GetDef(
it->second->GetSingleWordOperand(2));
SpvStorageClass storage_class =
spv::StorageClass storage_class =
fuzzerutil::GetStorageClassFromPointerType(
GetIRContext(), source_id->type_id());
if (!TransformationReplaceLoadStoreWithCopyMemory::

View File

@ -50,7 +50,7 @@ void FuzzerPassReplaceOpPhiIdsFromDeadPredecessors::Apply() {
block->id(), [this, &function, block, &transformations](
opt::Instruction* instruction, uint32_t) {
// Only consider OpPhi instructions.
if (instruction->opcode() != SpvOpPhi) {
if (instruction->opcode() != spv::Op::OpPhi) {
return;
}

View File

@ -52,7 +52,7 @@ void FuzzerPassReplaceOpSelectsWithConditionalBranches::Apply() {
for (auto& instruction : block) {
// We only care about OpSelect instructions.
if (instruction.opcode() != SpvOpSelect) {
if (instruction.opcode() != spv::Op::OpSelect) {
continue;
}
@ -69,7 +69,7 @@ void FuzzerPassReplaceOpSelectsWithConditionalBranches::Apply() {
->get_def_use_mgr()
->GetDef(fuzzerutil::GetTypeId(
GetIRContext(), instruction.GetSingleWordInOperand(0)))
->opcode() != SpvOpTypeBool) {
->opcode() != spv::Op::OpTypeBool) {
continue;
}
@ -136,7 +136,7 @@ void FuzzerPassReplaceOpSelectsWithConditionalBranches::Apply() {
bool FuzzerPassReplaceOpSelectsWithConditionalBranches::
InstructionNeedsSplitBefore(opt::Instruction* instruction) {
assert(instruction && instruction->opcode() == SpvOpSelect &&
assert(instruction && instruction->opcode() == spv::Op::OpSelect &&
"The instruction must be OpSelect.");
auto block = GetIRContext()->get_instr_block(instruction);
@ -163,7 +163,7 @@ bool FuzzerPassReplaceOpSelectsWithConditionalBranches::
auto predecessor = GetIRContext()->get_instr_block(
GetIRContext()->cfg()->preds(block->id())[0]);
return predecessor->MergeBlockIdIfAny() ||
predecessor->terminator()->opcode() != SpvOpBranch;
predecessor->terminator()->opcode() != spv::Op::OpBranch;
}
} // namespace fuzz

View File

@ -72,7 +72,8 @@ void FuzzerPassReplaceParameterWithGlobal::Apply() {
assert(replaced_param && "Unable to find a parameter to replace");
// Make sure type id for the global variable exists in the module.
FindOrCreatePointerType(replaced_param->type_id(), SpvStorageClassPrivate);
FindOrCreatePointerType(replaced_param->type_id(),
spv::StorageClass::Private);
// Make sure initializer for the global variable exists in the module.
FindOrCreateZeroConstant(replaced_param->type_id(), false);

View File

@ -65,7 +65,7 @@ void FuzzerPassSplitBlocks::Apply() {
// Counts the number of times we have seen each opcode since we reset the
// base instruction.
std::map<SpvOp, uint32_t> skip_count;
std::map<spv::Op, uint32_t> skip_count;
// Consider every instruction in the block. The label is excluded: it is
// only necessary to consider it as a base in case the first instruction
@ -78,7 +78,7 @@ void FuzzerPassSplitBlocks::Apply() {
base = inst.result_id();
skip_count.clear();
}
const SpvOp opcode = inst.opcode();
const spv::Op opcode = inst.opcode();
instruction_descriptors.emplace_back(MakeInstructionDescriptor(
base, opcode, skip_count.count(opcode) ? skip_count.at(opcode) : 0));
if (!inst.HasResultId()) {

View File

@ -39,7 +39,7 @@ void FuzzerPassSwapBranchConditionalOperands::Apply() {
const protobufs::InstructionDescriptor& instruction_descriptor) {
const auto& inst = *inst_it;
if (inst.opcode() != SpvOpBranchConditional) {
if (inst.opcode() != spv::Op::OpBranchConditional) {
return;
}

View File

@ -36,8 +36,9 @@ void FuzzerPassToggleAccessChainInstruction::Apply() {
// probabilistically applied.
context->module()->ForEachInst([this,
context](opt::Instruction* instruction) {
SpvOp opcode = instruction->opcode();
if ((opcode == SpvOpAccessChain || opcode == SpvOpInBoundsAccessChain) &&
spv::Op opcode = instruction->opcode();
if ((opcode == spv::Op::OpAccessChain ||
opcode == spv::Op::OpInBoundsAccessChain) &&
GetFuzzerContext()->ChoosePercentage(
GetFuzzerContext()->GetChanceOfTogglingAccessChainInstruction())) {
auto instructionDescriptor =

View File

@ -52,7 +52,7 @@ void FuzzerPassWrapVectorSynonym::Apply() {
// It must be valid to insert an OpCompositeConstruct instruction
// before |instruction_iterator|.
if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(
SpvOpCompositeConstruct, instruction_iterator)) {
spv::Op::OpCompositeConstruct, instruction_iterator)) {
return;
}

File diff suppressed because it is too large Load Diff

View File

@ -111,7 +111,7 @@ opt::BasicBlock::iterator GetIteratorForInstruction(
// Determines whether it is OK to insert an instruction with opcode |opcode|
// before |instruction_in_block|.
bool CanInsertOpcodeBeforeInstruction(
SpvOp opcode, const opt::BasicBlock::iterator& instruction_in_block);
spv::Op opcode, const opt::BasicBlock::iterator& instruction_in_block);
// Determines whether it is OK to make a synonym of |inst|.
// |transformation_context| is used to verify that the result id of |inst|
@ -170,8 +170,8 @@ uint32_t GetBoundForCompositeIndex(const opt::Instruction& composite_type_inst,
opt::IRContext* ir_context);
// Returns memory semantics mask for specific storage class.
SpvMemorySemanticsMask GetMemorySemanticsForStorageClass(
SpvStorageClass storage_class);
spv::MemorySemanticsMask GetMemorySemanticsForStorageClass(
spv::StorageClass storage_class);
// Returns true if and only if |context| is valid, according to the validator
// instantiated with |validator_options|. |consumer| is used for error
@ -258,18 +258,18 @@ uint32_t GetPointeeTypeIdFromPointerType(opt::IRContext* context,
// Given |pointer_type_inst|, which must be an OpTypePointer instruction,
// returns the associated storage class.
SpvStorageClass GetStorageClassFromPointerType(
spv::StorageClass GetStorageClassFromPointerType(
opt::Instruction* pointer_type_inst);
// Given |pointer_type_id|, which must be the id of a pointer type, returns the
// associated storage class.
SpvStorageClass GetStorageClassFromPointerType(opt::IRContext* context,
uint32_t pointer_type_id);
spv::StorageClass GetStorageClassFromPointerType(opt::IRContext* context,
uint32_t pointer_type_id);
// Returns the id of a pointer with pointee type |pointee_type_id| and storage
// class |storage_class|, if it exists, and 0 otherwise.
uint32_t MaybeGetPointerType(opt::IRContext* context, uint32_t pointee_type_id,
SpvStorageClass storage_class);
spv::StorageClass storage_class);
// Given an instruction |inst| and an operand absolute index |absolute_index|,
// returns the index of the operand restricted to the input operands.
@ -309,7 +309,7 @@ void AddVariableIdToEntryPointInterfaces(opt::IRContext* context, uint32_t id);
// Returns a pointer to the new global variable instruction.
opt::Instruction* AddGlobalVariable(opt::IRContext* context, uint32_t result_id,
uint32_t type_id,
SpvStorageClass storage_class,
spv::StorageClass storage_class,
uint32_t initializer_id);
// Adds an instruction to the start of |function_id|, of the form:
@ -541,7 +541,7 @@ MapToRepeatedUInt32Pair(const std::map<uint32_t, uint32_t>& data);
// opcode |opcode| can be inserted, or nullptr if there is no such instruction.
opt::Instruction* GetLastInsertBeforeInstruction(opt::IRContext* ir_context,
uint32_t block_id,
SpvOp opcode);
spv::Op opcode);
// Checks whether various conditions hold related to the acceptability of
// replacing the id use at |use_in_operand_index| of |use_instruction| with a
@ -608,14 +608,14 @@ opt::Module::iterator GetFunctionIterator(opt::IRContext* ir_context,
// behaviour depending on the signedness of the operand at
// |use_in_operand_index|.
// Assumes that the operand must be the id of an integer scalar or vector.
bool IsAgnosticToSignednessOfOperand(SpvOp opcode,
bool IsAgnosticToSignednessOfOperand(spv::Op opcode,
uint32_t use_in_operand_index);
// Returns true if |type_id_1| and |type_id_2| represent compatible types
// given the context of the instruction with |opcode| (i.e. we can replace
// an operand of |opcode| of the first type with an id of the second type
// and vice-versa).
bool TypesAreCompatible(opt::IRContext* ir_context, SpvOp opcode,
bool TypesAreCompatible(opt::IRContext* ir_context, spv::Op opcode,
uint32_t use_in_operand_index, uint32_t type_id_1,
uint32_t type_id_2);

View File

@ -40,8 +40,9 @@ opt::Instruction* FindInstruction(
"The skipped instruction count should only be incremented "
"after the instruction base has been found.");
}
if (found_base && instruction.opcode() ==
instruction_descriptor.target_instruction_opcode()) {
if (found_base &&
instruction.opcode() ==
spv::Op(instruction_descriptor.target_instruction_opcode())) {
if (num_ignored == instruction_descriptor.num_opcodes_to_ignore()) {
return &instruction;
}
@ -52,11 +53,11 @@ opt::Instruction* FindInstruction(
}
protobufs::InstructionDescriptor MakeInstructionDescriptor(
uint32_t base_instruction_result_id, SpvOp target_instruction_opcode,
uint32_t base_instruction_result_id, spv::Op target_instruction_opcode,
uint32_t num_opcodes_to_ignore) {
protobufs::InstructionDescriptor result;
result.set_base_instruction_result_id(base_instruction_result_id);
result.set_target_instruction_opcode(target_instruction_opcode);
result.set_target_instruction_opcode(uint32_t(target_instruction_opcode));
result.set_num_opcodes_to_ignore(num_opcodes_to_ignore);
return result;
}
@ -64,7 +65,7 @@ protobufs::InstructionDescriptor MakeInstructionDescriptor(
protobufs::InstructionDescriptor MakeInstructionDescriptor(
const opt::BasicBlock& block,
const opt::BasicBlock::const_iterator& inst_it) {
const SpvOp opcode =
const spv::Op opcode =
inst_it->opcode(); // The opcode of the instruction being described.
uint32_t skip_count = 0; // The number of these opcodes we have skipped when
// searching backwards.

View File

@ -32,7 +32,7 @@ opt::Instruction* FindInstruction(
// components. See the protobuf definition for details of what these
// components mean.
protobufs::InstructionDescriptor MakeInstructionDescriptor(
uint32_t base_instruction_result_id, SpvOp target_instruction_opcode,
uint32_t base_instruction_result_id, spv::Op target_instruction_opcode,
uint32_t num_opcodes_to_ignore);
// Returns an instruction descriptor that describing the instruction at

View File

@ -20,10 +20,10 @@ namespace spvtools {
namespace fuzz {
protobufs::Instruction MakeInstructionMessage(
SpvOp opcode, uint32_t result_type_id, uint32_t result_id,
spv::Op opcode, uint32_t result_type_id, uint32_t result_id,
const opt::Instruction::OperandList& input_operands) {
protobufs::Instruction result;
result.set_opcode(opcode);
result.set_opcode(uint32_t(opcode));
result.set_result_type_id(result_type_id);
result.set_result_id(result_id);
for (auto& operand : input_operands) {
@ -71,7 +71,7 @@ std::unique_ptr<opt::Instruction> InstructionFromMessage(
}
// Create and return the instruction.
return MakeUnique<opt::Instruction>(
ir_context, static_cast<SpvOp>(instruction_message.opcode()),
ir_context, static_cast<spv::Op>(instruction_message.opcode()),
instruction_message.result_type_id(), instruction_message.result_id(),
in_operands);
}

View File

@ -26,7 +26,7 @@ namespace fuzz {
// Creates an Instruction protobuf message from its component parts.
protobufs::Instruction MakeInstructionMessage(
SpvOp opcode, uint32_t result_type_id, uint32_t result_id,
spv::Op opcode, uint32_t result_type_id, uint32_t result_id,
const opt::Instruction::OperandList& input_operands);
// Creates an Instruction protobuf message from a parsed instruction.

View File

@ -63,7 +63,7 @@ bool TransformationAccessChain::IsApplicable(
}
// The type must indeed be a pointer.
auto pointer_type = ir_context->get_def_use_mgr()->GetDef(pointer->type_id());
if (pointer_type->opcode() != SpvOpTypePointer) {
if (pointer_type->opcode() != spv::Op::OpTypePointer) {
return false;
}
@ -75,7 +75,7 @@ bool TransformationAccessChain::IsApplicable(
return false;
}
if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(
SpvOpAccessChain, instruction_to_insert_before)) {
spv::Op::OpAccessChain, instruction_to_insert_before)) {
return false;
}
@ -83,8 +83,8 @@ bool TransformationAccessChain::IsApplicable(
// we do not want to allow accessing such pointers. This might be acceptable
// in dead blocks, but we conservatively avoid it.
switch (pointer->opcode()) {
case SpvOpConstantNull:
case SpvOpUndef:
case spv::Op::OpConstantNull:
case spv::Op::OpUndef:
assert(
false &&
"Access chains should not be created from null/undefined pointers");
@ -117,7 +117,7 @@ bool TransformationAccessChain::IsApplicable(
// Check whether the object is a struct.
if (ir_context->get_def_use_mgr()->GetDef(subobject_type_id)->opcode() ==
SpvOpTypeStruct) {
spv::Op::OpTypeStruct) {
// It is a struct: we need to retrieve the integer value.
bool successful;
@ -202,7 +202,7 @@ bool TransformationAccessChain::IsApplicable(
// associated with pointers to isomorphic structs being regarded as the same.
return fuzzerutil::MaybeGetPointerType(
ir_context, subobject_type_id,
static_cast<SpvStorageClass>(
static_cast<spv::StorageClass>(
pointer_type->GetSingleWordInOperand(0))) != 0;
}
@ -243,7 +243,7 @@ void TransformationAccessChain::Apply(
// Check whether the object is a struct.
if (ir_context->get_def_use_mgr()->GetDef(subobject_type_id)->opcode() ==
SpvOpTypeStruct) {
spv::Op::OpTypeStruct) {
// It is a struct: we need to retrieve the integer value.
index_value =
@ -290,7 +290,8 @@ void TransformationAccessChain::Apply(
// %fresh_ids.first = OpULessThanEqual %bool %int_id %bound_minus_one.
fuzzerutil::UpdateModuleIdBound(ir_context, fresh_ids.first());
auto comparison_instruction = MakeUnique<opt::Instruction>(
ir_context, SpvOpULessThanEqual, bool_type_id, fresh_ids.first(),
ir_context, spv::Op::OpULessThanEqual, bool_type_id,
fresh_ids.first(),
opt::Instruction::OperandList(
{{SPV_OPERAND_TYPE_ID, {index_instruction->result_id()}},
{SPV_OPERAND_TYPE_ID, {bound_minus_one_id}}}));
@ -306,7 +307,7 @@ void TransformationAccessChain::Apply(
// %bound_minus_one
fuzzerutil::UpdateModuleIdBound(ir_context, fresh_ids.second());
auto select_instruction = MakeUnique<opt::Instruction>(
ir_context, SpvOpSelect, int_type_inst->result_id(),
ir_context, spv::Op::OpSelect, int_type_inst->result_id(),
fresh_ids.second(),
opt::Instruction::OperandList(
{{SPV_OPERAND_TYPE_ID, {fresh_ids.first()}},
@ -334,13 +335,14 @@ void TransformationAccessChain::Apply(
// of the original pointer.
uint32_t result_type = fuzzerutil::MaybeGetPointerType(
ir_context, subobject_type_id,
static_cast<SpvStorageClass>(pointer_type->GetSingleWordInOperand(0)));
static_cast<spv::StorageClass>(pointer_type->GetSingleWordInOperand(0)));
// Add the access chain instruction to the module, and update the module's
// id bound.
fuzzerutil::UpdateModuleIdBound(ir_context, message_.fresh_id());
auto access_chain_instruction = MakeUnique<opt::Instruction>(
ir_context, SpvOpAccessChain, result_type, message_.fresh_id(), operands);
auto access_chain_instruction =
MakeUnique<opt::Instruction>(ir_context, spv::Op::OpAccessChain,
result_type, message_.fresh_id(), operands);
auto access_chain_instruction_ptr = access_chain_instruction.get();
instruction_to_insert_before->InsertBefore(
std::move(access_chain_instruction));
@ -367,7 +369,7 @@ std::pair<bool, uint32_t> TransformationAccessChain::GetStructIndexValue(
opt::IRContext* ir_context, uint32_t index_id,
uint32_t object_type_id) const {
assert(ir_context->get_def_use_mgr()->GetDef(object_type_id)->opcode() ==
SpvOpTypeStruct &&
spv::Op::OpTypeStruct &&
"Precondition: the type must be a struct type.");
if (!ValidIndexToComposite(ir_context, index_id, object_type_id)) {
return {false, 0};
@ -408,14 +410,14 @@ bool TransformationAccessChain::ValidIndexToComposite(
// The index type must be 32-bit integer.
auto index_type =
ir_context->get_def_use_mgr()->GetDef(index_instruction->type_id());
if (index_type->opcode() != SpvOpTypeInt ||
if (index_type->opcode() != spv::Op::OpTypeInt ||
index_type->GetSingleWordInOperand(0) != 32) {
return false;
}
// If the object being traversed is a struct, the id must correspond to an
// in-bound constant.
if (object_type_def->opcode() == SpvOpTypeStruct) {
if (object_type_def->opcode() == spv::Op::OpTypeStruct) {
if (!spvOpcodeIsConstant(index_instruction->opcode())) {
return false;
}

View File

@ -87,10 +87,10 @@ void TransformationAddBitInstructionSynonym::Apply(
// synonym fact. The helper function should take care of invalidating
// analyses before adding facts.
switch (bit_instruction->opcode()) {
case SpvOpBitwiseOr:
case SpvOpBitwiseXor:
case SpvOpBitwiseAnd:
case SpvOpNot:
case spv::Op::OpBitwiseOr:
case spv::Op::OpBitwiseXor:
case spv::Op::OpBitwiseAnd:
case spv::Op::OpNot:
AddOpBitwiseOrOpNotSynonym(ir_context, transformation_context,
bit_instruction);
break;
@ -106,10 +106,10 @@ bool TransformationAddBitInstructionSynonym::IsInstructionSupported(
// Right now we only support certain operations. When this issue is addressed
// the following conditional can use the function |spvOpcodeIsBit|.
// |instruction| must be defined and must be a supported bit instruction.
if (!instruction || (instruction->opcode() != SpvOpBitwiseOr &&
instruction->opcode() != SpvOpBitwiseXor &&
instruction->opcode() != SpvOpBitwiseAnd &&
instruction->opcode() != SpvOpNot)) {
if (!instruction || (instruction->opcode() != spv::Op::OpBitwiseOr &&
instruction->opcode() != spv::Op::OpBitwiseXor &&
instruction->opcode() != spv::Op::OpBitwiseAnd &&
instruction->opcode() != spv::Op::OpNot)) {
return false;
}
@ -119,7 +119,7 @@ bool TransformationAddBitInstructionSynonym::IsInstructionSupported(
return false;
}
if (instruction->opcode() == SpvOpNot) {
if (instruction->opcode() == spv::Op::OpNot) {
auto operand = instruction->GetInOperand(0).words[0];
auto operand_inst = ir_context->get_def_use_mgr()->GetDef(operand);
auto operand_type =
@ -171,10 +171,10 @@ uint32_t TransformationAddBitInstructionSynonym::GetRequiredFreshIdCount(
// TODO(https://github.com/KhronosGroup/SPIRV-Tools/issues/3557):
// Right now, only certain operations are supported.
switch (bit_instruction->opcode()) {
case SpvOpBitwiseOr:
case SpvOpBitwiseXor:
case SpvOpBitwiseAnd:
case SpvOpNot:
case spv::Op::OpBitwiseOr:
case spv::Op::OpBitwiseXor:
case spv::Op::OpBitwiseAnd:
case spv::Op::OpNot:
return (2 + bit_instruction->NumInOperands()) *
ir_context->get_type_mgr()
->GetType(bit_instruction->type_id())
@ -220,7 +220,7 @@ void TransformationAddBitInstructionSynonym::AddOpBitwiseOrOpNotSynonym(
for (auto operand = bit_instruction->begin() + 2;
operand != bit_instruction->end(); operand++) {
auto bit_extract =
opt::Instruction(ir_context, SpvOpBitFieldUExtract,
opt::Instruction(ir_context, spv::Op::OpBitFieldUExtract,
bit_instruction->type_id(), *fresh_id++,
{{SPV_OPERAND_TYPE_ID, operand->words},
{SPV_OPERAND_TYPE_ID, {offset}},
@ -246,12 +246,13 @@ void TransformationAddBitInstructionSynonym::AddOpBitwiseOrOpNotSynonym(
// first two bits of the result.
uint32_t offset = fuzzerutil::MaybeGetIntegerConstant(
ir_context, *transformation_context, {1}, 32, false, false);
auto bit_insert = opt::Instruction(
ir_context, SpvOpBitFieldInsert, bit_instruction->type_id(), *fresh_id++,
{{SPV_OPERAND_TYPE_ID, {extracted_bit_instructions[0]}},
{SPV_OPERAND_TYPE_ID, {extracted_bit_instructions[1]}},
{SPV_OPERAND_TYPE_ID, {offset}},
{SPV_OPERAND_TYPE_ID, {count}}});
auto bit_insert =
opt::Instruction(ir_context, spv::Op::OpBitFieldInsert,
bit_instruction->type_id(), *fresh_id++,
{{SPV_OPERAND_TYPE_ID, {extracted_bit_instructions[0]}},
{SPV_OPERAND_TYPE_ID, {extracted_bit_instructions[1]}},
{SPV_OPERAND_TYPE_ID, {offset}},
{SPV_OPERAND_TYPE_ID, {count}}});
bit_instruction->InsertBefore(MakeUnique<opt::Instruction>(bit_insert));
fuzzerutil::UpdateModuleIdBound(ir_context, bit_insert.result_id());
@ -260,7 +261,7 @@ void TransformationAddBitInstructionSynonym::AddOpBitwiseOrOpNotSynonym(
offset = fuzzerutil::MaybeGetIntegerConstant(
ir_context, *transformation_context, {i}, 32, false, false);
bit_insert = opt::Instruction(
ir_context, SpvOpBitFieldInsert, bit_instruction->type_id(),
ir_context, spv::Op::OpBitFieldInsert, bit_instruction->type_id(),
*fresh_id++,
{{SPV_OPERAND_TYPE_ID, {bit_insert.result_id()}},
{SPV_OPERAND_TYPE_ID, {extracted_bit_instructions[i]}},

View File

@ -43,7 +43,8 @@ void TransformationAddConstantBoolean::Apply(
// Add the boolean constant to the module, ensuring the module's id bound is
// high enough.
auto new_instruction = MakeUnique<opt::Instruction>(
ir_context, message_.is_true() ? SpvOpConstantTrue : SpvOpConstantFalse,
ir_context,
message_.is_true() ? spv::Op::OpConstantTrue : spv::Op::OpConstantFalse,
fuzzerutil::MaybeGetBoolType(ir_context), message_.fresh_id(),
opt::Instruction::OperandList());
auto new_instruction_ptr = new_instruction.get();

View File

@ -53,7 +53,7 @@ bool TransformationAddConstantComposite::IsApplicable(
// struct - whether its decorations are OK.
std::vector<uint32_t> constituent_type_ids;
switch (composite_type_instruction->opcode()) {
case SpvOpTypeArray:
case spv::Op::OpTypeArray:
for (uint32_t index = 0;
index <
fuzzerutil::GetArraySize(*composite_type_instruction, ir_context);
@ -62,8 +62,8 @@ bool TransformationAddConstantComposite::IsApplicable(
composite_type_instruction->GetSingleWordInOperand(0));
}
break;
case SpvOpTypeMatrix:
case SpvOpTypeVector:
case spv::Op::OpTypeMatrix:
case spv::Op::OpTypeVector:
for (uint32_t index = 0;
index < composite_type_instruction->GetSingleWordInOperand(1);
index++) {
@ -71,7 +71,7 @@ bool TransformationAddConstantComposite::IsApplicable(
composite_type_instruction->GetSingleWordInOperand(0));
}
break;
case SpvOpTypeStruct:
case spv::Op::OpTypeStruct:
// We do not create constants of structs decorated with Block nor
// BufferBlock. The SPIR-V spec does not explicitly disallow this, but it
// seems like a strange thing to do, so we disallow it to avoid triggering
@ -120,7 +120,7 @@ void TransformationAddConstantComposite::Apply(
in_operands.push_back({SPV_OPERAND_TYPE_ID, {constituent_id}});
}
auto new_instruction = MakeUnique<opt::Instruction>(
ir_context, SpvOpConstantComposite, message_.type_id(),
ir_context, spv::Op::OpConstantComposite, message_.type_id(),
message_.fresh_id(), in_operands);
auto new_instruction_ptr = new_instruction.get();
ir_context->module()->AddGlobalValue(std::move(new_instruction));

View File

@ -48,8 +48,8 @@ bool TransformationAddConstantNull::IsApplicable(
void TransformationAddConstantNull::Apply(
opt::IRContext* ir_context, TransformationContext* /*unused*/) const {
auto new_instruction = MakeUnique<opt::Instruction>(
ir_context, SpvOpConstantNull, message_.type_id(), message_.fresh_id(),
opt::Instruction::OperandList());
ir_context, spv::Op::OpConstantNull, message_.type_id(),
message_.fresh_id(), opt::Instruction::OperandList());
auto new_instruction_ptr = new_instruction.get();
ir_context->module()->AddGlobalValue(std::move(new_instruction));
fuzzerutil::UpdateModuleIdBound(ir_context, message_.fresh_id());

View File

@ -65,7 +65,7 @@ void TransformationAddConstantScalar::Apply(
opt::IRContext* ir_context,
TransformationContext* transformation_context) const {
auto new_instruction = MakeUnique<opt::Instruction>(
ir_context, SpvOpConstant, message_.type_id(), message_.fresh_id(),
ir_context, spv::Op::OpConstant, message_.type_id(), message_.fresh_id(),
opt::Instruction::OperandList(
{{SPV_OPERAND_TYPE_LITERAL_INTEGER,
std::vector<uint32_t>(message_.word().begin(),

View File

@ -27,12 +27,12 @@ TransformationAddCopyMemory::TransformationAddCopyMemory(
TransformationAddCopyMemory::TransformationAddCopyMemory(
const protobufs::InstructionDescriptor& instruction_descriptor,
uint32_t fresh_id, uint32_t source_id, SpvStorageClass storage_class,
uint32_t fresh_id, uint32_t source_id, spv::StorageClass storage_class,
uint32_t initializer_id) {
*message_.mutable_instruction_descriptor() = instruction_descriptor;
message_.set_fresh_id(fresh_id);
message_.set_source_id(source_id);
message_.set_storage_class(storage_class);
message_.set_storage_class(uint32_t(storage_class));
message_.set_initializer_id(initializer_id);
}
@ -53,7 +53,8 @@ bool TransformationAddCopyMemory::IsApplicable(
// Check that we can insert OpCopyMemory before |instruction_descriptor|.
auto iter = fuzzerutil::GetIteratorForInstruction(
ir_context->get_instr_block(inst), inst);
if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(SpvOpCopyMemory, iter)) {
if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(spv::Op::OpCopyMemory,
iter)) {
return false;
}
@ -65,8 +66,10 @@ bool TransformationAddCopyMemory::IsApplicable(
}
// |storage_class| is either Function or Private.
if (message_.storage_class() != SpvStorageClassFunction &&
message_.storage_class() != SpvStorageClassPrivate) {
if (spv::StorageClass(message_.storage_class()) !=
spv::StorageClass::Function &&
spv::StorageClass(message_.storage_class()) !=
spv::StorageClass::Private) {
return false;
}
@ -76,7 +79,7 @@ bool TransformationAddCopyMemory::IsApplicable(
// OpTypePointer with |message_.storage_class| exists.
if (!fuzzerutil::MaybeGetPointerType(
ir_context, pointee_type_id,
static_cast<SpvStorageClass>(message_.storage_class()))) {
static_cast<spv::StorageClass>(message_.storage_class()))) {
return false;
}
@ -103,20 +106,20 @@ void TransformationAddCopyMemory::Apply(
ir_context->get_instr_block(insert_before_inst);
// Add global or local variable to copy memory into.
auto storage_class = static_cast<SpvStorageClass>(message_.storage_class());
auto storage_class = static_cast<spv::StorageClass>(message_.storage_class());
auto type_id = fuzzerutil::MaybeGetPointerType(
ir_context,
fuzzerutil::GetPointeeTypeIdFromPointerType(
ir_context, fuzzerutil::GetTypeId(ir_context, message_.source_id())),
storage_class);
if (storage_class == SpvStorageClassPrivate) {
if (storage_class == spv::StorageClass::Private) {
opt::Instruction* new_global =
fuzzerutil::AddGlobalVariable(ir_context, message_.fresh_id(), type_id,
storage_class, message_.initializer_id());
ir_context->get_def_use_mgr()->AnalyzeInstDefUse(new_global);
} else {
assert(storage_class == SpvStorageClassFunction &&
assert(storage_class == spv::StorageClass::Function &&
"Storage class can be either Private or Function");
opt::Function* enclosing_function = enclosing_block->GetParent();
opt::Instruction* new_local = fuzzerutil::AddLocalVariable(
@ -130,7 +133,7 @@ void TransformationAddCopyMemory::Apply(
enclosing_block, insert_before_inst);
auto new_instruction = MakeUnique<opt::Instruction>(
ir_context, SpvOpCopyMemory, 0, 0,
ir_context, spv::Op::OpCopyMemory, 0, 0,
opt::Instruction::OperandList{
{SPV_OPERAND_TYPE_ID, {message_.fresh_id()}},
{SPV_OPERAND_TYPE_ID, {message_.source_id()}}});
@ -160,7 +163,8 @@ protobufs::Transformation TransformationAddCopyMemory::ToMessage() const {
bool TransformationAddCopyMemory::IsInstructionSupported(
opt::IRContext* ir_context, opt::Instruction* inst) {
if (!inst->result_id() || !inst->type_id() ||
inst->opcode() == SpvOpConstantNull || inst->opcode() == SpvOpUndef) {
inst->opcode() == spv::Op::OpConstantNull ||
inst->opcode() == spv::Op::OpUndef) {
return false;
}

View File

@ -30,7 +30,7 @@ class TransformationAddCopyMemory : public Transformation {
TransformationAddCopyMemory(
const protobufs::InstructionDescriptor& instruction_descriptor,
uint32_t fresh_id, uint32_t source_id, SpvStorageClass storage_class,
uint32_t fresh_id, uint32_t source_id, spv::StorageClass storage_class,
uint32_t initializer_id);
// - |instruction_descriptor| must point to a valid instruction in the module.

View File

@ -61,7 +61,7 @@ bool TransformationAddDeadBlock::IsApplicable(
}
// It must end with OpBranch.
if (existing_block->terminator()->opcode() != SpvOpBranch) {
if (existing_block->terminator()->opcode() != spv::Op::OpBranch) {
return false;
}
@ -122,27 +122,27 @@ void TransformationAddDeadBlock::Apply(
auto enclosing_function = existing_block->GetParent();
std::unique_ptr<opt::BasicBlock> new_block =
MakeUnique<opt::BasicBlock>(MakeUnique<opt::Instruction>(
ir_context, SpvOpLabel, 0, message_.fresh_id(),
ir_context, spv::Op::OpLabel, 0, message_.fresh_id(),
opt::Instruction::OperandList()));
new_block->AddInstruction(MakeUnique<opt::Instruction>(
ir_context, SpvOpBranch, 0, 0,
ir_context, spv::Op::OpBranch, 0, 0,
opt::Instruction::OperandList(
{{SPV_OPERAND_TYPE_ID, {successor_block_id}}})));
// Turn the original block into a selection merge, with its original successor
// as the merge block.
existing_block->terminator()->InsertBefore(MakeUnique<opt::Instruction>(
ir_context, SpvOpSelectionMerge, 0, 0,
ir_context, spv::Op::OpSelectionMerge, 0, 0,
opt::Instruction::OperandList(
{{SPV_OPERAND_TYPE_ID, {successor_block_id}},
{SPV_OPERAND_TYPE_SELECTION_CONTROL,
{SpvSelectionControlMaskNone}}})));
{uint32_t(spv::SelectionControlMask::MaskNone)}}})));
// Change the original block's terminator to be a conditional branch on the
// given boolean, with the original successor and the new successor as branch
// targets, and such that at runtime control will always transfer to the
// original successor.
existing_block->terminator()->SetOpcode(SpvOpBranchConditional);
existing_block->terminator()->SetOpcode(spv::Op::OpBranchConditional);
existing_block->terminator()->SetInOperands(
{{SPV_OPERAND_TYPE_ID, {bool_id}},
{SPV_OPERAND_TYPE_ID,

View File

@ -142,7 +142,7 @@ bool TransformationAddDeadBreak::IsApplicable(
}
// Check that |message_.from_block| ends with an unconditional branch.
if (bb_from->terminator()->opcode() != SpvOpBranch) {
if (bb_from->terminator()->opcode() != spv::Op::OpBranch) {
// The block associated with the id does not end with an unconditional
// branch.
return false;

View File

@ -55,7 +55,7 @@ bool TransformationAddDeadContinue::IsApplicable(
}
// Check that |message_.from_block| ends with an unconditional branch.
if (bb_from->terminator()->opcode() != SpvOpBranch) {
if (bb_from->terminator()->opcode() != spv::Op::OpBranch) {
// The block associated with the id does not end with an unconditional
// branch.
return false;

View File

@ -28,17 +28,17 @@ TransformationAddEarlyTerminatorWrapper::
TransformationAddEarlyTerminatorWrapper::
TransformationAddEarlyTerminatorWrapper(uint32_t function_fresh_id,
uint32_t label_fresh_id,
SpvOp opcode) {
spv::Op opcode) {
message_.set_function_fresh_id(function_fresh_id);
message_.set_label_fresh_id(label_fresh_id);
message_.set_opcode(opcode);
message_.set_opcode(uint32_t(opcode));
}
bool TransformationAddEarlyTerminatorWrapper::IsApplicable(
opt::IRContext* ir_context, const TransformationContext& /*unused*/) const {
assert((message_.opcode() == SpvOpKill ||
message_.opcode() == SpvOpUnreachable ||
message_.opcode() == SpvOpTerminateInvocation) &&
assert((spv::Op(message_.opcode()) == spv::Op::OpKill ||
spv::Op(message_.opcode()) == spv::Op::OpUnreachable ||
spv::Op(message_.opcode()) == spv::Op::OpTerminateInvocation) &&
"Invalid opcode.");
if (!fuzzerutil::IsFreshId(ir_context, message_.function_fresh_id())) {
@ -66,26 +66,29 @@ void TransformationAddEarlyTerminatorWrapper::Apply(
// %label_fresh_id = OpLabel
// OpKill|Unreachable|TerminateInvocation
auto basic_block = MakeUnique<opt::BasicBlock>(MakeUnique<opt::Instruction>(
ir_context, SpvOpLabel, 0, message_.label_fresh_id(),
ir_context, spv::Op::OpLabel, 0, message_.label_fresh_id(),
opt::Instruction::OperandList()));
basic_block->AddInstruction(MakeUnique<opt::Instruction>(
ir_context, static_cast<SpvOp>(message_.opcode()), 0, 0,
ir_context, static_cast<spv::Op>(message_.opcode()), 0, 0,
opt::Instruction::OperandList()));
// Create a zero-argument void function.
auto void_type_id = fuzzerutil::MaybeGetVoidType(ir_context);
auto function = MakeUnique<opt::Function>(MakeUnique<opt::Instruction>(
ir_context, SpvOpFunction, void_type_id, message_.function_fresh_id(),
ir_context, spv::Op::OpFunction, void_type_id,
message_.function_fresh_id(),
opt::Instruction::OperandList(
{{SPV_OPERAND_TYPE_FUNCTION_CONTROL, {SpvFunctionControlMaskNone}},
{{SPV_OPERAND_TYPE_FUNCTION_CONTROL,
{uint32_t(spv::FunctionControlMask::MaskNone)}},
{SPV_OPERAND_TYPE_TYPE_ID,
{fuzzerutil::FindFunctionType(ir_context, {void_type_id})}}})));
// Add the basic block to the function as the sole block, and add the function
// to the module.
function->AddBasicBlock(std::move(basic_block));
function->SetFunctionEnd(MakeUnique<opt::Instruction>(
ir_context, SpvOpFunctionEnd, 0, 0, opt::Instruction::OperandList()));
function->SetFunctionEnd(
MakeUnique<opt::Instruction>(ir_context, spv::Op::OpFunctionEnd, 0, 0,
opt::Instruction::OperandList()));
ir_context->module()->AddFunction(std::move(function));
ir_context->InvalidateAnalysesExceptFor(opt::IRContext::kAnalysisNone);

View File

@ -30,7 +30,7 @@ class TransformationAddEarlyTerminatorWrapper : public Transformation {
TransformationAddEarlyTerminatorWrapper(uint32_t function_fresh_id,
uint32_t label_fresh_id,
SpvOp opcode);
spv::Op opcode);
// - |message_.function_fresh_id| and |message_.label_fresh_id| must be fresh
// and distinct.

View File

@ -178,7 +178,7 @@ void TransformationAddFunction::Apply(
}
ir_context->InvalidateAnalysesExceptFor(opt::IRContext::kAnalysisNone);
assert(message_.instruction(0).opcode() == SpvOpFunction &&
assert(spv::Op(message_.instruction(0).opcode()) == spv::Op::OpFunction &&
"The first instruction of an 'add function' transformation must be "
"OpFunction.");
@ -189,7 +189,7 @@ void TransformationAddFunction::Apply(
} else {
// Inform the fact manager that all blocks in the function are dead.
for (auto& inst : message_.instruction()) {
if (inst.opcode() == SpvOpLabel) {
if (spv::Op(inst.opcode()) == spv::Op::OpLabel) {
transformation_context->GetFactManager()->AddFactBlockIsDead(
inst.result_id());
}
@ -202,16 +202,16 @@ void TransformationAddFunction::Apply(
// parameters to other functions knowing that it is OK if they get
// over-written.
for (auto& instruction : message_.instruction()) {
switch (instruction.opcode()) {
case SpvOpFunctionParameter:
switch (spv::Op(instruction.opcode())) {
case spv::Op::OpFunctionParameter:
if (ir_context->get_def_use_mgr()
->GetDef(instruction.result_type_id())
->opcode() == SpvOpTypePointer) {
->opcode() == spv::Op::OpTypePointer) {
transformation_context->GetFactManager()
->AddFactValueOfPointeeIsIrrelevant(instruction.result_id());
}
break;
case SpvOpVariable:
case spv::Op::OpVariable:
transformation_context->GetFactManager()
->AddFactValueOfPointeeIsIrrelevant(instruction.result_id());
break;
@ -239,7 +239,7 @@ bool TransformationAddFunction::TryToAddFunction(
// A function must start with OpFunction.
auto function_begin = message_.instruction(0);
if (function_begin.opcode() != SpvOpFunction) {
if (spv::Op(function_begin.opcode()) != spv::Op::OpFunction) {
return false;
}
@ -256,8 +256,8 @@ bool TransformationAddFunction::TryToAddFunction(
// Iterate through all function parameter instructions, adding parameters to
// the new function.
while (instruction_index < num_instructions &&
message_.instruction(instruction_index).opcode() ==
SpvOpFunctionParameter) {
spv::Op(message_.instruction(instruction_index).opcode()) ==
spv::Op::OpFunctionParameter) {
new_function->AddParameter(InstructionFromMessage(
ir_context, message_.instruction(instruction_index)));
instruction_index++;
@ -265,16 +265,19 @@ bool TransformationAddFunction::TryToAddFunction(
// After the parameters, there needs to be a label.
if (instruction_index == num_instructions ||
message_.instruction(instruction_index).opcode() != SpvOpLabel) {
spv::Op(message_.instruction(instruction_index).opcode()) !=
spv::Op::OpLabel) {
return false;
}
// Iterate through the instructions block by block until the end of the
// function is reached.
while (instruction_index < num_instructions &&
message_.instruction(instruction_index).opcode() != SpvOpFunctionEnd) {
spv::Op(message_.instruction(instruction_index).opcode()) !=
spv::Op::OpFunctionEnd) {
// Invariant: we should always be at a label instruction at this point.
assert(message_.instruction(instruction_index).opcode() == SpvOpLabel);
assert(spv::Op(message_.instruction(instruction_index).opcode()) ==
spv::Op::OpLabel);
// Make a basic block using the label instruction.
std::unique_ptr<opt::BasicBlock> block =
@ -285,9 +288,10 @@ bool TransformationAddFunction::TryToAddFunction(
// of the function, adding each such instruction to the block.
instruction_index++;
while (instruction_index < num_instructions &&
message_.instruction(instruction_index).opcode() !=
SpvOpFunctionEnd &&
message_.instruction(instruction_index).opcode() != SpvOpLabel) {
spv::Op(message_.instruction(instruction_index).opcode()) !=
spv::Op::OpFunctionEnd &&
spv::Op(message_.instruction(instruction_index).opcode()) !=
spv::Op::OpLabel) {
block->AddInstruction(InstructionFromMessage(
ir_context, message_.instruction(instruction_index)));
instruction_index++;
@ -298,7 +302,8 @@ bool TransformationAddFunction::TryToAddFunction(
// Having considered all the blocks, we should be at the last instruction and
// it needs to be OpFunctionEnd.
if (instruction_index != num_instructions - 1 ||
message_.instruction(instruction_index).opcode() != SpvOpFunctionEnd) {
spv::Op(message_.instruction(instruction_index).opcode()) !=
spv::Op::OpFunctionEnd) {
return false;
}
// Set the function's final instruction, add the function to the module and
@ -339,20 +344,20 @@ bool TransformationAddFunction::TryToMakeFunctionLivesafe(
for (auto& block : *added_function) {
for (auto& inst : block) {
switch (inst.opcode()) {
case SpvOpKill:
case SpvOpUnreachable:
case spv::Op::OpKill:
case spv::Op::OpUnreachable:
if (!TryToTurnKillOrUnreachableIntoReturn(ir_context, added_function,
&inst)) {
return false;
}
break;
case SpvOpAccessChain:
case SpvOpInBoundsAccessChain:
case spv::Op::OpAccessChain:
case spv::Op::OpInBoundsAccessChain:
if (!TryToClampAccessChainIndices(ir_context, &inst)) {
return false;
}
break;
case SpvOpFunctionCall:
case spv::Op::OpFunctionCall:
// A livesafe function my only call other livesafe functions.
if (!transformation_context.GetFactManager()->FunctionIsLivesafe(
inst.GetSingleWordInOperand(0))) {
@ -404,7 +409,7 @@ bool TransformationAddFunction::TryToAddLoopLimiters(
auto loop_limit_constant_id_instr =
ir_context->get_def_use_mgr()->GetDef(message_.loop_limit_constant_id());
if (!loop_limit_constant_id_instr ||
loop_limit_constant_id_instr->opcode() != SpvOpConstant) {
loop_limit_constant_id_instr->opcode() != spv::Op::OpConstant) {
// The loop limit constant id instruction must exist and have an
// appropriate opcode.
return false;
@ -412,7 +417,7 @@ bool TransformationAddFunction::TryToAddLoopLimiters(
auto loop_limit_type = ir_context->get_def_use_mgr()->GetDef(
loop_limit_constant_id_instr->type_id());
if (loop_limit_type->opcode() != SpvOpTypeInt ||
if (loop_limit_type->opcode() != spv::Op::OpTypeInt ||
loop_limit_type->GetSingleWordInOperand(0) != 32) {
// The type of the loop limit constant must be 32-bit integer. It
// doesn't actually matter whether the integer is signed or not.
@ -457,7 +462,7 @@ bool TransformationAddFunction::TryToAddLoopLimiters(
// Look for pointer-to-unsigned int type.
opt::analysis::Pointer pointer_to_unsigned_int_type(
registered_unsigned_int_type, SpvStorageClassFunction);
registered_unsigned_int_type, spv::StorageClass::Function);
uint32_t pointer_to_unsigned_int_type_id =
ir_context->get_type_mgr()->GetId(&pointer_to_unsigned_int_type);
if (!pointer_to_unsigned_int_type_id) {
@ -477,13 +482,13 @@ bool TransformationAddFunction::TryToAddLoopLimiters(
// Declare the loop limiter variable at the start of the function's entry
// block, via an instruction of the form:
// %loop_limiter_var = SpvOpVariable %ptr_to_uint Function %zero
// %loop_limiter_var = spv::Op::OpVariable %ptr_to_uint Function %zero
added_function->begin()->begin()->InsertBefore(MakeUnique<opt::Instruction>(
ir_context, SpvOpVariable, pointer_to_unsigned_int_type_id,
ir_context, spv::Op::OpVariable, pointer_to_unsigned_int_type_id,
message_.loop_limiter_variable_id(),
opt::Instruction::OperandList(
{{SPV_OPERAND_TYPE_STORAGE_CLASS, {SpvStorageClassFunction}},
{SPV_OPERAND_TYPE_ID, {zero_id}}})));
opt::Instruction::OperandList({{SPV_OPERAND_TYPE_STORAGE_CLASS,
{uint32_t(spv::StorageClass::Function)}},
{SPV_OPERAND_TYPE_ID, {zero_id}}})));
// Update the module's id bound since we have added the loop limiter
// variable id.
fuzzerutil::UpdateModuleIdBound(ir_context,
@ -589,10 +594,11 @@ bool TransformationAddFunction::TryToAddLoopLimiters(
auto back_edge_block = ir_context->cfg()->block(back_edge_block_id);
auto back_edge_block_terminator = back_edge_block->terminator();
bool compare_using_greater_than_equal;
if (back_edge_block_terminator->opcode() == SpvOpBranch) {
if (back_edge_block_terminator->opcode() == spv::Op::OpBranch) {
compare_using_greater_than_equal = true;
} else {
assert(back_edge_block_terminator->opcode() == SpvOpBranchConditional);
assert(back_edge_block_terminator->opcode() ==
spv::Op::OpBranchConditional);
assert(((back_edge_block_terminator->GetSingleWordInOperand(1) ==
loop_header->id() &&
back_edge_block_terminator->GetSingleWordInOperand(2) ==
@ -613,7 +619,7 @@ bool TransformationAddFunction::TryToAddLoopLimiters(
// Add a load from the loop limiter variable, of the form:
// %t1 = OpLoad %uint32 %loop_limiter
new_instructions.push_back(MakeUnique<opt::Instruction>(
ir_context, SpvOpLoad, unsigned_int_type_id,
ir_context, spv::Op::OpLoad, unsigned_int_type_id,
loop_limiter_info.load_id(),
opt::Instruction::OperandList(
{{SPV_OPERAND_TYPE_ID, {message_.loop_limiter_variable_id()}}})));
@ -621,7 +627,7 @@ bool TransformationAddFunction::TryToAddLoopLimiters(
// Increment the loaded value:
// %t2 = OpIAdd %uint32 %t1 %one
new_instructions.push_back(MakeUnique<opt::Instruction>(
ir_context, SpvOpIAdd, unsigned_int_type_id,
ir_context, spv::Op::OpIAdd, unsigned_int_type_id,
loop_limiter_info.increment_id(),
opt::Instruction::OperandList(
{{SPV_OPERAND_TYPE_ID, {loop_limiter_info.load_id()}},
@ -630,7 +636,7 @@ bool TransformationAddFunction::TryToAddLoopLimiters(
// Store the incremented value back to the loop limiter variable:
// OpStore %loop_limiter %t2
new_instructions.push_back(MakeUnique<opt::Instruction>(
ir_context, SpvOpStore, 0, 0,
ir_context, spv::Op::OpStore, 0, 0,
opt::Instruction::OperandList(
{{SPV_OPERAND_TYPE_ID, {message_.loop_limiter_variable_id()}},
{SPV_OPERAND_TYPE_ID, {loop_limiter_info.increment_id()}}})));
@ -641,17 +647,18 @@ bool TransformationAddFunction::TryToAddLoopLimiters(
// %t3 = OpULessThan %bool %t1 %loop_limit
new_instructions.push_back(MakeUnique<opt::Instruction>(
ir_context,
compare_using_greater_than_equal ? SpvOpUGreaterThanEqual
: SpvOpULessThan,
compare_using_greater_than_equal ? spv::Op::OpUGreaterThanEqual
: spv::Op::OpULessThan,
bool_type_id, loop_limiter_info.compare_id(),
opt::Instruction::OperandList(
{{SPV_OPERAND_TYPE_ID, {loop_limiter_info.load_id()}},
{SPV_OPERAND_TYPE_ID, {message_.loop_limit_constant_id()}}})));
if (back_edge_block_terminator->opcode() == SpvOpBranchConditional) {
if (back_edge_block_terminator->opcode() == spv::Op::OpBranchConditional) {
new_instructions.push_back(MakeUnique<opt::Instruction>(
ir_context,
compare_using_greater_than_equal ? SpvOpLogicalOr : SpvOpLogicalAnd,
compare_using_greater_than_equal ? spv::Op::OpLogicalOr
: spv::Op::OpLogicalAnd,
bool_type_id, loop_limiter_info.logical_op_id(),
opt::Instruction::OperandList(
{{SPV_OPERAND_TYPE_ID,
@ -669,11 +676,11 @@ bool TransformationAddFunction::TryToAddLoopLimiters(
back_edge_block_terminator->InsertBefore(std::move(new_instructions));
}
if (back_edge_block_terminator->opcode() == SpvOpBranchConditional) {
if (back_edge_block_terminator->opcode() == spv::Op::OpBranchConditional) {
back_edge_block_terminator->SetInOperand(
0, {loop_limiter_info.logical_op_id()});
} else {
assert(back_edge_block_terminator->opcode() == SpvOpBranch &&
assert(back_edge_block_terminator->opcode() == spv::Op::OpBranch &&
"Back-edge terminator must be OpBranch or OpBranchConditional");
// Check that, if the merge block starts with OpPhi instructions, suitable
@ -689,7 +696,7 @@ bool TransformationAddFunction::TryToAddLoopLimiters(
// Augment OpPhi instructions at the loop merge with the given ids.
uint32_t phi_index = 0;
for (auto& inst : *merge_block) {
if (inst.opcode() != SpvOpPhi) {
if (inst.opcode() != spv::Op::OpPhi) {
break;
}
assert(phi_index <
@ -702,7 +709,7 @@ bool TransformationAddFunction::TryToAddLoopLimiters(
}
// Add the new edge, by changing OpBranch to OpBranchConditional.
back_edge_block_terminator->SetOpcode(SpvOpBranchConditional);
back_edge_block_terminator->SetOpcode(spv::Op::OpBranchConditional);
back_edge_block_terminator->SetInOperands(opt::Instruction::OperandList(
{{SPV_OPERAND_TYPE_ID, {loop_limiter_info.compare_id()}},
{SPV_OPERAND_TYPE_ID, {loop_header->MergeBlockId()}},
@ -724,18 +731,18 @@ bool TransformationAddFunction::TryToAddLoopLimiters(
bool TransformationAddFunction::TryToTurnKillOrUnreachableIntoReturn(
opt::IRContext* ir_context, opt::Function* added_function,
opt::Instruction* kill_or_unreachable_inst) const {
assert((kill_or_unreachable_inst->opcode() == SpvOpKill ||
kill_or_unreachable_inst->opcode() == SpvOpUnreachable) &&
assert((kill_or_unreachable_inst->opcode() == spv::Op::OpKill ||
kill_or_unreachable_inst->opcode() == spv::Op::OpUnreachable) &&
"Precondition: instruction must be OpKill or OpUnreachable.");
// Get the function's return type.
auto function_return_type_inst =
ir_context->get_def_use_mgr()->GetDef(added_function->type_id());
if (function_return_type_inst->opcode() == SpvOpTypeVoid) {
if (function_return_type_inst->opcode() == spv::Op::OpTypeVoid) {
// The function has void return type, so change this instruction to
// OpReturn.
kill_or_unreachable_inst->SetOpcode(SpvOpReturn);
kill_or_unreachable_inst->SetOpcode(spv::Op::OpReturn);
} else {
// The function has non-void return type, so change this instruction
// to OpReturnValue, using the value id provided with the
@ -749,7 +756,7 @@ bool TransformationAddFunction::TryToTurnKillOrUnreachableIntoReturn(
->type_id() != function_return_type_inst->result_id()) {
return false;
}
kill_or_unreachable_inst->SetOpcode(SpvOpReturnValue);
kill_or_unreachable_inst->SetOpcode(spv::Op::OpReturnValue);
kill_or_unreachable_inst->SetInOperands(
{{SPV_OPERAND_TYPE_ID, {message_.kill_unreachable_return_value_id()}}});
}
@ -758,8 +765,8 @@ bool TransformationAddFunction::TryToTurnKillOrUnreachableIntoReturn(
bool TransformationAddFunction::TryToClampAccessChainIndices(
opt::IRContext* ir_context, opt::Instruction* access_chain_inst) const {
assert((access_chain_inst->opcode() == SpvOpAccessChain ||
access_chain_inst->opcode() == SpvOpInBoundsAccessChain) &&
assert((access_chain_inst->opcode() == spv::Op::OpAccessChain ||
access_chain_inst->opcode() == spv::Op::OpInBoundsAccessChain) &&
"Precondition: instruction must be OpAccessChain or "
"OpInBoundsAccessChain.");
@ -793,7 +800,7 @@ bool TransformationAddFunction::TryToClampAccessChainIndices(
assert(base_object && "The base object must exist.");
auto pointer_type =
ir_context->get_def_use_mgr()->GetDef(base_object->type_id());
assert(pointer_type && pointer_type->opcode() == SpvOpTypePointer &&
assert(pointer_type && pointer_type->opcode() == spv::Op::OpTypePointer &&
"The base object must have pointer type.");
auto should_be_composite_type = ir_context->get_def_use_mgr()->GetDef(
pointer_type->GetSingleWordInOperand(1));
@ -824,18 +831,18 @@ bool TransformationAddFunction::TryToClampAccessChainIndices(
auto index_inst = ir_context->get_def_use_mgr()->GetDef(index_id);
auto index_type_inst =
ir_context->get_def_use_mgr()->GetDef(index_inst->type_id());
assert(index_type_inst->opcode() == SpvOpTypeInt);
assert(index_type_inst->opcode() == spv::Op::OpTypeInt);
assert(index_type_inst->GetSingleWordInOperand(0) == 32);
opt::analysis::Integer* index_int_type =
ir_context->get_type_mgr()
->GetType(index_type_inst->result_id())
->AsInteger();
if (index_inst->opcode() != SpvOpConstant ||
if (index_inst->opcode() != spv::Op::OpConstant ||
index_inst->GetSingleWordInOperand(0) >= bound) {
// The index is either non-constant or an out-of-bounds constant, so we
// need to clamp it.
assert(should_be_composite_type->opcode() != SpvOpTypeStruct &&
assert(should_be_composite_type->opcode() != spv::Op::OpTypeStruct &&
"Access chain indices into structures are required to be "
"constants.");
opt::analysis::IntConstant bound_minus_one(index_int_type, {bound - 1});
@ -866,7 +873,7 @@ bool TransformationAddFunction::TryToClampAccessChainIndices(
// Compare the index with the bound via an instruction of the form:
// %t1 = OpULessThanEqual %bool %index %bound_minus_one
new_instructions.push_back(MakeUnique<opt::Instruction>(
ir_context, SpvOpULessThanEqual, bool_type_id, compare_id,
ir_context, spv::Op::OpULessThanEqual, bool_type_id, compare_id,
opt::Instruction::OperandList(
{{SPV_OPERAND_TYPE_ID, {index_inst->result_id()}},
{SPV_OPERAND_TYPE_ID, {bound_minus_one_id}}})));
@ -874,7 +881,8 @@ bool TransformationAddFunction::TryToClampAccessChainIndices(
// Select the index if in-bounds, otherwise one less than the bound:
// %t2 = OpSelect %int_type %t1 %index %bound_minus_one
new_instructions.push_back(MakeUnique<opt::Instruction>(
ir_context, SpvOpSelect, index_type_inst->result_id(), select_id,
ir_context, spv::Op::OpSelect, index_type_inst->result_id(),
select_id,
opt::Instruction::OperandList(
{{SPV_OPERAND_TYPE_ID, {compare_id}},
{SPV_OPERAND_TYPE_ID, {index_inst->result_id()}},
@ -899,20 +907,20 @@ opt::Instruction* TransformationAddFunction::FollowCompositeIndex(
uint32_t index_id) {
uint32_t sub_object_type_id;
switch (composite_type_inst.opcode()) {
case SpvOpTypeArray:
case SpvOpTypeRuntimeArray:
case spv::Op::OpTypeArray:
case spv::Op::OpTypeRuntimeArray:
sub_object_type_id = composite_type_inst.GetSingleWordInOperand(0);
break;
case SpvOpTypeMatrix:
case SpvOpTypeVector:
case spv::Op::OpTypeMatrix:
case spv::Op::OpTypeVector:
sub_object_type_id = composite_type_inst.GetSingleWordInOperand(0);
break;
case SpvOpTypeStruct: {
case spv::Op::OpTypeStruct: {
auto index_inst = ir_context->get_def_use_mgr()->GetDef(index_id);
assert(index_inst->opcode() == SpvOpConstant);
assert(index_inst->opcode() == spv::Op::OpConstant);
assert(ir_context->get_def_use_mgr()
->GetDef(index_inst->type_id())
->opcode() == SpvOpTypeInt);
->opcode() == spv::Op::OpTypeInt);
assert(ir_context->get_def_use_mgr()
->GetDef(index_inst->type_id())
->GetSingleWordInOperand(0) == 32);

View File

@ -39,14 +39,14 @@ bool TransformationAddGlobalUndef::IsApplicable(
auto type = ir_context->get_def_use_mgr()->GetDef(message_.type_id());
// The type must exist, and must not be a function or pointer type.
return type != nullptr && opt::IsTypeInst(type->opcode()) &&
type->opcode() != SpvOpTypeFunction &&
type->opcode() != SpvOpTypePointer;
type->opcode() != spv::Op::OpTypeFunction &&
type->opcode() != spv::Op::OpTypePointer;
}
void TransformationAddGlobalUndef::Apply(
opt::IRContext* ir_context, TransformationContext* /*unused*/) const {
auto new_instruction = MakeUnique<opt::Instruction>(
ir_context, SpvOpUndef, message_.type_id(), message_.fresh_id(),
ir_context, spv::Op::OpUndef, message_.type_id(), message_.fresh_id(),
opt::Instruction::OperandList());
auto new_instruction_ptr = new_instruction.get();
ir_context->module()->AddGlobalValue(std::move(new_instruction));

View File

@ -24,11 +24,11 @@ TransformationAddGlobalVariable::TransformationAddGlobalVariable(
: message_(std::move(message)) {}
TransformationAddGlobalVariable::TransformationAddGlobalVariable(
uint32_t fresh_id, uint32_t type_id, SpvStorageClass storage_class,
uint32_t fresh_id, uint32_t type_id, spv::StorageClass storage_class,
uint32_t initializer_id, bool value_is_irrelevant) {
message_.set_fresh_id(fresh_id);
message_.set_type_id(type_id);
message_.set_storage_class(storage_class);
message_.set_storage_class(uint32_t(storage_class));
message_.set_initializer_id(initializer_id);
message_.set_value_is_irrelevant(value_is_irrelevant);
}
@ -41,10 +41,10 @@ bool TransformationAddGlobalVariable::IsApplicable(
}
// The storage class must be Private or Workgroup.
auto storage_class = static_cast<SpvStorageClass>(message_.storage_class());
auto storage_class = static_cast<spv::StorageClass>(message_.storage_class());
switch (storage_class) {
case SpvStorageClassPrivate:
case SpvStorageClassWorkgroup:
case spv::StorageClass::Private:
case spv::StorageClass::Workgroup:
break;
default:
assert(false && "Unsupported storage class.");
@ -66,7 +66,7 @@ bool TransformationAddGlobalVariable::IsApplicable(
}
if (message_.initializer_id()) {
// An initializer is not allowed if the storage class is Workgroup.
if (storage_class == SpvStorageClassWorkgroup) {
if (storage_class == spv::StorageClass::Workgroup) {
assert(false &&
"By construction this transformation should not have an "
"initializer when Workgroup storage class is used.");
@ -95,7 +95,7 @@ void TransformationAddGlobalVariable::Apply(
TransformationContext* transformation_context) const {
opt::Instruction* new_instruction = fuzzerutil::AddGlobalVariable(
ir_context, message_.fresh_id(), message_.type_id(),
static_cast<SpvStorageClass>(message_.storage_class()),
static_cast<spv::StorageClass>(message_.storage_class()),
message_.initializer_id());
// Inform the def-use manager about the new instruction.

View File

@ -29,7 +29,7 @@ class TransformationAddGlobalVariable : public Transformation {
protobufs::TransformationAddGlobalVariable message);
TransformationAddGlobalVariable(uint32_t fresh_id, uint32_t type_id,
SpvStorageClass storage_class,
spv::StorageClass storage_class,
uint32_t initializer_id,
bool value_is_irrelevant);

View File

@ -73,7 +73,7 @@ bool TransformationAddImageSampleUnusedComponents::IsApplicable(
// It must be an OpCompositeConstruct instruction such that it can be checked
// that the original components are present.
if (coordinate_with_unused_components_instruction->opcode() !=
SpvOpCompositeConstruct) {
spv::Op::OpCompositeConstruct) {
return false;
}

View File

@ -43,8 +43,10 @@ bool TransformationAddLocalVariable::IsApplicable(
// function storage class.
auto type_instruction =
ir_context->get_def_use_mgr()->GetDef(message_.type_id());
if (!type_instruction || type_instruction->opcode() != SpvOpTypePointer ||
type_instruction->GetSingleWordInOperand(0) != SpvStorageClassFunction) {
if (!type_instruction ||
type_instruction->opcode() != spv::Op::OpTypePointer ||
spv::StorageClass(type_instruction->GetSingleWordInOperand(0)) !=
spv::StorageClass::Function) {
return false;
}
// The initializer must...

Some files were not shown because too many files have changed in this diff Show More