Updated spirv-tools.

This commit is contained in:
Бранимир Караџић
2020-12-13 13:12:15 -08:00
parent 0001c8067d
commit 6fe24f441e
16 changed files with 123 additions and 33 deletions

View File

@@ -1,14 +1,15 @@
Revision history for SPIRV-Tools
v2020.7-dev 2020-12-03
v2020.7-dev 2020-12-07
- Start v2020.7-dev
v2020.6 2020-12-02
v2020.6 2020-12-07
- General
CMake: Add SPIRV_TOOLS_BUILD_STATIC flag (#3910)
- Disassembler
Add some context comments to disassembly. (#3847)
- Optimizer
- Take new (raytracing) termination instructions into account. (#4050)
- Do run DCE if SPV_KHR_ray_query is used. (#4047)
- Handle 8-bit index in elim dead member (#4043)
- Add texel buffer out-of-bounds checking instrumentation (#4038)

View File

@@ -1 +1 @@
"v2020.7-dev", "SPIRV-Tools v2020.7-dev c73d8d8cf8076c3848338cc5a5f63d291afa2989"
"v2020.7-dev", "SPIRV-Tools v2020.7-dev 5a705a115f558ea53abd7ef08456551e6d9bd42f"

View File

@@ -444,15 +444,32 @@ bool spvOpcodeIsReturn(SpvOp opcode) {
}
}
bool spvOpcodeIsAbort(SpvOp opcode) {
switch (opcode) {
case SpvOpKill:
case SpvOpUnreachable:
case SpvOpTerminateInvocation:
case SpvOpTerminateRayKHR:
case SpvOpIgnoreIntersectionKHR:
return true;
default:
return false;
}
}
bool spvOpcodeIsReturnOrAbort(SpvOp opcode) {
return spvOpcodeIsReturn(opcode) || opcode == SpvOpKill ||
opcode == SpvOpUnreachable || opcode == SpvOpTerminateInvocation;
return spvOpcodeIsReturn(opcode) || spvOpcodeIsAbort(opcode);
}
bool spvOpcodeIsBlockTerminator(SpvOp opcode) {
return spvOpcodeIsBranch(opcode) || spvOpcodeIsReturnOrAbort(opcode);
}
bool spvOpcodeTerminatesExecution(SpvOp opcode) {
return opcode == SpvOpKill || opcode == SpvOpTerminateInvocation ||
opcode == SpvOpTerminateRayKHR || opcode == SpvOpIgnoreIntersectionKHR;
}
bool spvOpcodeIsBaseOpaqueType(SpvOp opcode) {
switch (opcode) {
case SpvOpTypeImage:

View File

@@ -110,10 +110,18 @@ bool spvOpcodeIsBranch(SpvOp opcode);
// Returns true if the given opcode is a return instruction.
bool spvOpcodeIsReturn(SpvOp opcode);
// Returns true if the given opcode aborts execution.
bool spvOpcodeIsAbort(SpvOp opcode);
// Returns true if the given opcode is a return instruction or it aborts
// execution.
bool spvOpcodeIsReturnOrAbort(SpvOp opcode);
// Returns true if the given opcode is a kill instruction or it terminates
// execution. Note that branches, returns, and unreachables do not terminate
// execution.
bool spvOpcodeTerminatesExecution(SpvOp opcode);
// Returns true if the given opcode is a basic block terminator.
bool spvOpcodeIsBlockTerminator(SpvOp opcode);

View File

@@ -24,6 +24,7 @@
#include "DebugInfo.h"
#include "OpenCLDebugInfo100.h"
#include "source/macro.h"
#include "source/opcode.h"
#include "source/spirv_constant.h"
#include "source/spirv_target_env.h"
@@ -491,6 +492,11 @@ bool spvIsInIdType(spv_operand_type_t type) {
std::function<bool(unsigned)> spvOperandCanBeForwardDeclaredFunction(
SpvOp opcode) {
std::function<bool(unsigned index)> out;
if (spvOpcodeGeneratesType(opcode)) {
// All types can use forward pointers.
out = [](unsigned) { return true; };
return out;
}
switch (opcode) {
case SpvOpExecutionMode:
case SpvOpExecutionModeId:
@@ -503,7 +509,6 @@ std::function<bool(unsigned)> spvOperandCanBeForwardDeclaredFunction(
case SpvOpDecorateId:
case SpvOpDecorateStringGOOGLE:
case SpvOpMemberDecorateStringGOOGLE:
case SpvOpTypeStruct:
case SpvOpBranch:
case SpvOpLoopMerge:
out = [](unsigned) { return true; };

View File

@@ -995,6 +995,7 @@ void AggressiveDCEPass::InitExtensions() {
"SPV_EXT_fragment_invocation_density",
"SPV_EXT_physical_storage_buffer",
"SPV_KHR_terminate_invocation",
"SPV_KHR_shader_clock",
});
}

View File

@@ -230,7 +230,7 @@ std::string BasicBlock::PrettyPrint(uint32_t options) const {
std::ostringstream str;
ForEachInst([&str, options](const Instruction* inst) {
str << inst->PrettyPrint(options);
if (!IsTerminatorInst(inst->opcode())) {
if (!spvOpcodeIsBlockTerminator(inst->opcode())) {
str << std::endl;
}
});

View File

@@ -383,9 +383,7 @@ std::unique_ptr<BasicBlock> InlinePass::InlineReturn(
uint32_t returnLabelId = 0;
for (auto callee_block_itr = calleeFn->begin();
callee_block_itr != calleeFn->end(); ++callee_block_itr) {
if (callee_block_itr->tail()->opcode() == SpvOpUnreachable ||
callee_block_itr->tail()->opcode() == SpvOpKill ||
callee_block_itr->tail()->opcode() == SpvOpTerminateInvocation) {
if (spvOpcodeIsAbort(callee_block_itr->tail()->opcode())) {
returnLabelId = context()->TakeNextId();
break;
}
@@ -759,8 +757,7 @@ bool InlinePass::IsInlinableFunction(Function* func) {
bool InlinePass::ContainsKillOrTerminateInvocation(Function* func) const {
return !func->WhileEachInst([](Instruction* inst) {
const auto opcode = inst->opcode();
return (opcode != SpvOpKill) && (opcode != SpvOpTerminateInvocation);
return !spvOpcodeTerminatesExecution(inst->opcode());
});
}

View File

@@ -137,7 +137,7 @@ bool IrLoader::AddInstruction(const spv_parsed_instruction_t* inst) {
return false;
}
block_ = MakeUnique<BasicBlock>(std::move(spv_inst));
} else if (IsTerminatorInst(opcode)) {
} else if (spvOpcodeIsBlockTerminator(opcode)) {
if (function_ == nullptr) {
Error(consumer_, src, loc, "terminator instruction outside function");
return false;

View File

@@ -188,7 +188,7 @@ void Module::ToBinary(std::vector<uint32_t>* binary, bool skip_nop) const {
i->ToBinaryWithoutAttachedDebugInsts(binary);
}
// Update the last line instruction.
if (IsTerminatorInst(opcode) || opcode == SpvOpNoLine) {
if (spvOpcodeIsBlockTerminator(opcode) || opcode == SpvOpNoLine) {
last_line_inst = nullptr;
} else if (opcode == SpvOpLoopMerge || opcode == SpvOpSelectionMerge) {
between_merge_and_branch = true;

View File

@@ -59,10 +59,6 @@ inline bool IsCompileTimeConstantInst(SpvOp opcode) {
inline bool IsSpecConstantInst(SpvOp opcode) {
return opcode >= SpvOpSpecConstantTrue && opcode <= SpvOpSpecConstantOp;
}
inline bool IsTerminatorInst(SpvOp opcode) {
return (opcode >= SpvOpBranch && opcode <= SpvOpUnreachable) ||
(opcode == SpvOpTerminateInvocation);
}
} // namespace opt
} // namespace spvtools

View File

@@ -1098,8 +1098,9 @@ spv_result_t BuiltInsValidator::ValidateClipOrCullDistanceAtReference(
if (storage_class != SpvStorageClassMax &&
storage_class != SpvStorageClassInput &&
storage_class != SpvStorageClassOutput) {
uint32_t vuid = (decoration.params()[0] == SpvBuiltInClipDistance) ? 4190 : 4199;
return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst)
<< "Vulkan spec allows BuiltIn "
<< _.VkErrorID(vuid) << "Vulkan spec allows BuiltIn "
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN,
operand)
<< " to be only used for variables with Input or Output storage "
@@ -1111,19 +1112,28 @@ spv_result_t BuiltInsValidator::ValidateClipOrCullDistanceAtReference(
if (storage_class == SpvStorageClassInput) {
assert(function_id_ == 0);
uint32_t vuid = (decoration.params()[0] == SpvBuiltInClipDistance) ? 4188 : 4197;
id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind(
&BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, -1,
&BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, vuid,
"Vulkan spec doesn't allow BuiltIn ClipDistance/CullDistance to be "
"used for variables with Input storage class if execution model is "
"Vertex.",
SpvExecutionModelVertex, decoration, built_in_inst,
referenced_from_inst, std::placeholders::_1));
id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind(
&BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, vuid,
"Vulkan spec doesn't allow BuiltIn ClipDistance/CullDistance to be "
"used for variables with Input storage class if execution model is "
"Vertex.",
SpvExecutionModelMeshNV, decoration, built_in_inst,
referenced_from_inst, std::placeholders::_1));
}
if (storage_class == SpvStorageClassOutput) {
assert(function_id_ == 0);
uint32_t vuid = (decoration.params()[0] == SpvBuiltInClipDistance) ? 4189 : 4198;
id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind(
&BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, -1,
&BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, vuid,
"Vulkan spec doesn't allow BuiltIn ClipDistance/CullDistance to be "
"used for variables with Output storage class if execution model is "
"Fragment.",
@@ -1869,7 +1879,7 @@ spv_result_t BuiltInsValidator::ValidatePositionAtReference(
storage_class != SpvStorageClassInput &&
storage_class != SpvStorageClassOutput) {
return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst)
<< "Vulkan spec allows BuiltIn Position to be only used for "
<< _.VkErrorID(4320) << "Vulkan spec allows BuiltIn Position to be only used for "
"variables with Input or Output storage class. "
<< GetReferenceDesc(decoration, built_in_inst, referenced_inst,
referenced_from_inst)
@@ -1879,12 +1889,19 @@ spv_result_t BuiltInsValidator::ValidatePositionAtReference(
if (storage_class == SpvStorageClassInput) {
assert(function_id_ == 0);
id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind(
&BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, 4320,
&BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, 4319,
"Vulkan spec doesn't allow BuiltIn Position to be used "
"for variables "
"with Input storage class if execution model is Vertex.",
SpvExecutionModelVertex, decoration, built_in_inst,
referenced_from_inst, std::placeholders::_1));
id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind(
&BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, 4319,
"Vulkan spec doesn't allow BuiltIn Position to be used "
"for variables "
"with Input storage class if execution model is MeshNV.",
SpvExecutionModelMeshNV, decoration, built_in_inst,
referenced_from_inst, std::placeholders::_1));
}
for (const SpvExecutionModel execution_model : execution_models_) {
@@ -2458,8 +2475,9 @@ spv_result_t BuiltInsValidator::ValidateTessLevelAtReference(
if (storage_class == SpvStorageClassInput) {
assert(function_id_ == 0);
uint32_t vuid = (decoration.params()[0] == SpvBuiltInTessLevelOuter) ? 4391 : 4395;
id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind(
&BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, -1,
&BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, vuid,
"Vulkan spec doesn't allow TessLevelOuter/TessLevelInner to be "
"used "
"for variables with Input storage class if execution model is "
@@ -2470,8 +2488,9 @@ spv_result_t BuiltInsValidator::ValidateTessLevelAtReference(
if (storage_class == SpvStorageClassOutput) {
assert(function_id_ == 0);
uint32_t vuid = (decoration.params()[0] == SpvBuiltInTessLevelOuter) ? 4392 : 4396;
id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind(
&BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, -1,
&BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, vuid,
"Vulkan spec doesn't allow TessLevelOuter/TessLevelInner to be "
"used "
"for variables with Output storage class if execution model is "
@@ -2768,8 +2787,9 @@ spv_result_t BuiltInsValidator::ValidateLayerOrViewportIndexAtReference(
if (operand == SpvBuiltInLayer)
capability = "ShaderViewportIndexLayerEXT or ShaderLayer";
uint32_t vuid = (operand == SpvBuiltInLayer) ? 4273 : 4405;
return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst)
<< "Using BuiltIn "
<< _.VkErrorID(vuid) << "Using BuiltIn "
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN,
operand)
<< " in Vertex or Tessellation execution model requires the "

View File

@@ -201,7 +201,7 @@ spv_result_t IdPass(ValidationState_t& _, Instruction* inst) {
ret = SPV_SUCCESS;
}
} else if (can_have_forward_declared_ids(i)) {
if (inst->opcode() == SpvOpTypeStruct &&
if (spvOpcodeGeneratesType(inst->opcode()) &&
!_.IsForwardPointer(operand_word)) {
ret = _.diag(SPV_ERROR_INVALID_ID, inst)
<< "Operand " << _.getIdName(operand_word)

View File

@@ -736,7 +736,8 @@ spv_result_t ValidateTypeImage(ValidationState_t& _, const Instruction* inst) {
<< "Corrupt image type definition";
}
if (spvIsVulkanEnv(_.context()->target_env)) {
const auto target_env = _.context()->target_env;
if (spvIsVulkanEnv(target_env)) {
if ((!_.IsFloatScalarType(info.sampled_type) &&
!_.IsIntScalarType(info.sampled_type)) ||
(32 != _.GetBitWidth(info.sampled_type) &&
@@ -746,7 +747,7 @@ spv_result_t ValidateTypeImage(ValidationState_t& _, const Instruction* inst) {
<< "Expected Sampled Type to be a 32-bit int or float "
"scalar type for Vulkan environment";
}
} else if (spvIsOpenCLEnv(_.context()->target_env)) {
} else if (spvIsOpenCLEnv(target_env)) {
if (!_.IsVoidType(info.sampled_type)) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Sampled Type must be OpTypeVoid in the OpenCL environment.";
@@ -774,7 +775,7 @@ spv_result_t ValidateTypeImage(ValidationState_t& _, const Instruction* inst) {
<< "Invalid Arrayed " << info.arrayed << " (must be 0 or 1)";
}
if (spvIsOpenCLEnv(_.context()->target_env)) {
if (spvIsOpenCLEnv(target_env)) {
if ((info.arrayed == 1) && (info.dim != SpvDim1D) &&
(info.dim != SpvDim2D)) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
@@ -788,10 +789,10 @@ spv_result_t ValidateTypeImage(ValidationState_t& _, const Instruction* inst) {
<< "Invalid MS " << info.multisampled << " (must be 0 or 1)";
}
if (spvIsOpenCLEnv(_.context()->target_env)) {
if (spvIsOpenCLEnv(target_env)) {
if (info.multisampled != 0) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "MS must be 0 in the OpenCL environement.";
<< "MS must be 0 in the OpenCL environment.";
}
}
@@ -800,6 +801,15 @@ spv_result_t ValidateTypeImage(ValidationState_t& _, const Instruction* inst) {
<< "Invalid Sampled " << info.sampled << " (must be 0, 1 or 2)";
}
if (spvIsVulkanEnv(target_env) || spvIsWebGPUEnv(target_env)) {
if (info.sampled == 0) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Sampled must be 1 or 2 in the "
<< (spvIsVulkanEnv(target_env) ? "Vulkan" : "WebGPU")
<< " environment.";
}
}
if (spvIsOpenCLEnv(_.context()->target_env)) {
if (info.sampled != 0) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
@@ -829,6 +839,15 @@ spv_result_t ValidateTypeImage(ValidationState_t& _, const Instruction* inst) {
}
}
if (info.multisampled && (info.sampled == 2) &&
(info.dim != SpvDimSubpassData)) {
if (!_.HasCapability(SpvCapabilityStorageImageMultisample)) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Capability StorageImageMultisample is required when using "
"multisampled storage image";
}
}
return SPV_SUCCESS;
}

View File

@@ -1315,10 +1315,22 @@ std::string ValidationState_t::VkErrorID(uint32_t id,
return VUID_WRAP(VUID-BaseVertex-BaseVertex-04186);
case 4187:
return VUID_WRAP(VUID-ClipDistance-ClipDistance-04187);
case 4188:
return VUID_WRAP(VUID-ClipDistance-ClipDistance-04188);
case 4189:
return VUID_WRAP(VUID-ClipDistance-ClipDistance-04189);
case 4190:
return VUID_WRAP(VUID-ClipDistance-ClipDistance-04190);
case 4191:
return VUID_WRAP(VUID-ClipDistance-ClipDistance-04191);
case 4196:
return VUID_WRAP(VUID-CullDistance-CullDistance-04196);
case 4197:
return VUID_WRAP(VUID-CullDistance-CullDistance-04197);
case 4198:
return VUID_WRAP(VUID-CullDistance-CullDistance-04198);
case 4199:
return VUID_WRAP(VUID-CullDistance-CullDistance-04199);
case 4200:
return VUID_WRAP(VUID-CullDistance-CullDistance-04200);
case 4205:
@@ -1419,6 +1431,8 @@ std::string ValidationState_t::VkErrorID(uint32_t id,
return VUID_WRAP(VUID-LaunchSizeKHR-LaunchSizeKHR-04271);
case 4272:
return VUID_WRAP(VUID-Layer-Layer-04272);
case 4273:
return VUID_WRAP(VUID-Layer-Layer-04273);
case 4274:
return VUID_WRAP(VUID-Layer-Layer-04274);
case 4275:
@@ -1477,6 +1491,8 @@ std::string ValidationState_t::VkErrorID(uint32_t id,
return VUID_WRAP(VUID-PointSize-PointSize-04317);
case 4318:
return VUID_WRAP(VUID-Position-Position-04318);
case 4319:
return VUID_WRAP(VUID-Position-Position-04319);
case 4320:
return VUID_WRAP(VUID-Position-Position-04320);
case 4321:
@@ -1531,10 +1547,18 @@ std::string ValidationState_t::VkErrorID(uint32_t id,
return VUID_WRAP(VUID-TessCoord-TessCoord-04389);
case 4390:
return VUID_WRAP(VUID-TessLevelOuter-TessLevelOuter-04390);
case 4391:
return VUID_WRAP(VUID-TessLevelOuter-TessLevelOuter-04391);
case 4392:
return VUID_WRAP(VUID-TessLevelOuter-TessLevelOuter-04392);
case 4393:
return VUID_WRAP(VUID-TessLevelOuter-TessLevelOuter-04393);
case 4394:
return VUID_WRAP(VUID-TessLevelInner-TessLevelInner-04394);
case 4395:
return VUID_WRAP(VUID-TessLevelInner-TessLevelInner-04395);
case 4396:
return VUID_WRAP(VUID-TessLevelInner-TessLevelInner-04396);
case 4397:
return VUID_WRAP(VUID-TessLevelInner-TessLevelInner-04397);
case 4398:
@@ -1551,6 +1575,8 @@ std::string ValidationState_t::VkErrorID(uint32_t id,
return VUID_WRAP(VUID-ViewIndex-ViewIndex-04403);
case 4404:
return VUID_WRAP(VUID-ViewportIndex-ViewportIndex-04404);
case 4405:
return VUID_WRAP(VUID-ViewportIndex-ViewportIndex-04405);
case 4406:
return VUID_WRAP(VUID-ViewportIndex-ViewportIndex-04406);
case 4407:

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
# Copyright 2014 Google Inc.
#
# Redistribution and use in source and binary forms, with or without