mirror of
https://github.com/KhronosGroup/SPIRV-Tools
synced 2024-11-23 12:10:06 +00:00
Opt: HasOnlySupportedRefs should consider OpCopyObject
This fixes test failure after merging the previous pull request.
This commit is contained in:
parent
4a539d77ef
commit
9f6efc76c8
@ -225,11 +225,9 @@ bool LocalSingleBlockLoadStoreElimPass::HasOnlySupportedRefs(uint32_t ptrId) {
|
||||
assert(uses != nullptr);
|
||||
for (auto u : *uses) {
|
||||
SpvOp op = u.inst->opcode();
|
||||
if (IsNonPtrAccessChain(op)) {
|
||||
if (!HasOnlySupportedRefs(u.inst->result_id()))
|
||||
return false;
|
||||
}
|
||||
else if (op != SpvOpStore && op != SpvOpLoad && op != SpvOpName)
|
||||
if (IsNonPtrAccessChain(op) || op == SpvOpCopyObject) {
|
||||
if (!HasOnlySupportedRefs(u.inst->result_id())) return false;
|
||||
} else if (op != SpvOpStore && op != SpvOpLoad && op != SpvOpName)
|
||||
return false;
|
||||
}
|
||||
supported_ref_ptrs_.insert(ptrId);
|
||||
@ -424,4 +422,3 @@ void LocalSingleBlockLoadStoreElimPass::InitExtensions() {
|
||||
|
||||
} // namespace opt
|
||||
} // namespace spvtools
|
||||
|
||||
|
@ -132,11 +132,9 @@ bool LocalSingleStoreElimPass::HasOnlySupportedRefs(uint32_t ptrId) {
|
||||
assert(uses != nullptr);
|
||||
for (auto u : *uses) {
|
||||
SpvOp op = u.inst->opcode();
|
||||
if (IsNonPtrAccessChain(op)) {
|
||||
if (!HasOnlySupportedRefs(u.inst->result_id()))
|
||||
return false;
|
||||
}
|
||||
else if (op != SpvOpStore && op != SpvOpLoad && op != SpvOpName)
|
||||
if (IsNonPtrAccessChain(op) || op == SpvOpCopyObject) {
|
||||
if (!HasOnlySupportedRefs(u.inst->result_id())) return false;
|
||||
} else if (op != SpvOpStore && op != SpvOpLoad && op != SpvOpName)
|
||||
return false;
|
||||
}
|
||||
supported_ref_ptrs_.insert(ptrId);
|
||||
@ -527,4 +525,3 @@ void LocalSingleStoreElimPass::InitExtensions() {
|
||||
|
||||
} // namespace opt
|
||||
} // namespace spvtools
|
||||
|
||||
|
@ -16,11 +16,12 @@
|
||||
#include "pass_fixture.h"
|
||||
#include "pass_utils.h"
|
||||
|
||||
template <typename T> std::vector<T> concat(const std::vector<T> &a, const std::vector<T> &b) {
|
||||
std::vector<T> ret = std::vector<T>();
|
||||
std::copy(a.begin(), a.end(), back_inserter(ret));
|
||||
std::copy(b.begin(), b.end(), back_inserter(ret));
|
||||
return ret;
|
||||
template <typename T>
|
||||
std::vector<T> concat(const std::vector<T>& a, const std::vector<T>& b) {
|
||||
std::vector<T> ret;
|
||||
std::copy(a.begin(), a.end(), back_inserter(ret));
|
||||
std::copy(b.begin(), b.end(), back_inserter(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
namespace {
|
||||
@ -31,9 +32,9 @@ using LocalSingleBlockLoadStoreElimTest = PassTest<::testing::Test>;
|
||||
|
||||
TEST_F(LocalSingleBlockLoadStoreElimTest, SimpleStoreLoadElim) {
|
||||
// #version 140
|
||||
//
|
||||
//
|
||||
// in vec4 BaseColor;
|
||||
//
|
||||
//
|
||||
// void main()
|
||||
// {
|
||||
// vec4 v = BaseColor;
|
||||
@ -90,10 +91,10 @@ OpFunctionEnd
|
||||
|
||||
TEST_F(LocalSingleBlockLoadStoreElimTest, SimpleLoadLoadElim) {
|
||||
// #version 140
|
||||
//
|
||||
//
|
||||
// in vec4 BaseColor;
|
||||
// in float fi;
|
||||
//
|
||||
//
|
||||
// void main()
|
||||
// {
|
||||
// vec4 v = BaseColor;
|
||||
@ -190,16 +191,16 @@ OpFunctionEnd
|
||||
}
|
||||
|
||||
TEST_F(LocalSingleBlockLoadStoreElimTest,
|
||||
NoStoreElimIfInterveningAccessChainLoad) {
|
||||
NoStoreElimIfInterveningAccessChainLoad) {
|
||||
//
|
||||
// Note that even though the Load to %v is eliminated, the Store to %v
|
||||
// is not eliminated due to the following access chain reference.
|
||||
//
|
||||
// #version 140
|
||||
//
|
||||
//
|
||||
// in vec4 BaseColor;
|
||||
// flat in int Idx;
|
||||
//
|
||||
//
|
||||
// void main()
|
||||
// {
|
||||
// vec4 v = BaseColor;
|
||||
@ -279,10 +280,10 @@ OpFunctionEnd
|
||||
|
||||
TEST_F(LocalSingleBlockLoadStoreElimTest, NoElimIfInterveningAccessChainStore) {
|
||||
// #version 140
|
||||
//
|
||||
//
|
||||
// in vec4 BaseColor;
|
||||
// flat in int Idx;
|
||||
//
|
||||
//
|
||||
// void main()
|
||||
// {
|
||||
// vec4 v = BaseColor;
|
||||
@ -332,14 +333,14 @@ OpFunctionEnd
|
||||
)";
|
||||
|
||||
SinglePassRunAndCheck<opt::LocalSingleBlockLoadStoreElimPass>(
|
||||
assembly, assembly, false, true);
|
||||
assembly, assembly, false, true);
|
||||
}
|
||||
|
||||
TEST_F(LocalSingleBlockLoadStoreElimTest, NoElimIfInterveningFunctionCall) {
|
||||
// #version 140
|
||||
//
|
||||
//
|
||||
// in vec4 BaseColor;
|
||||
//
|
||||
//
|
||||
// void foo() {
|
||||
// }
|
||||
//
|
||||
@ -388,16 +389,16 @@ OpFunctionEnd
|
||||
)";
|
||||
|
||||
SinglePassRunAndCheck<opt::LocalSingleBlockLoadStoreElimPass>(
|
||||
assembly, assembly, false, true);
|
||||
assembly, assembly, false, true);
|
||||
}
|
||||
|
||||
TEST_F(LocalSingleBlockLoadStoreElimTest, ElimIfCopyObjectInFunction) {
|
||||
// Note: SPIR-V hand edited to insert CopyObject
|
||||
//
|
||||
// #version 140
|
||||
//
|
||||
//
|
||||
// in vec4 BaseColor;
|
||||
//
|
||||
//
|
||||
// void main()
|
||||
// {
|
||||
// vec4 v1 = BaseColor;
|
||||
|
@ -22,16 +22,15 @@ using namespace spvtools;
|
||||
|
||||
using LocalSingleStoreElimTest = PassTest<::testing::Test>;
|
||||
|
||||
|
||||
TEST_F(LocalSingleStoreElimTest, PositiveAndNegative) {
|
||||
// Single store to v is optimized. Multiple store to
|
||||
// f is not optimized.
|
||||
//
|
||||
// #version 140
|
||||
//
|
||||
//
|
||||
// in vec4 BaseColor;
|
||||
// in float fi;
|
||||
//
|
||||
//
|
||||
// void main()
|
||||
// {
|
||||
// vec4 v = BaseColor;
|
||||
@ -120,18 +119,18 @@ OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
|
||||
SinglePassRunAndCheck<opt::LocalSingleStoreElimPass>(predefs + before,
|
||||
predefs + after, true, true);
|
||||
SinglePassRunAndCheck<opt::LocalSingleStoreElimPass>(
|
||||
predefs + before, predefs + after, true, true);
|
||||
}
|
||||
|
||||
TEST_F(LocalSingleStoreElimTest, MultipleLoads) {
|
||||
// Single store to multiple loads of v is optimized.
|
||||
//
|
||||
// #version 140
|
||||
//
|
||||
//
|
||||
// in vec4 BaseColor;
|
||||
// in float fi;
|
||||
//
|
||||
//
|
||||
// void main()
|
||||
// {
|
||||
// vec4 v = BaseColor;
|
||||
@ -223,17 +222,17 @@ OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
|
||||
SinglePassRunAndCheck<opt::LocalSingleStoreElimPass>(predefs + before,
|
||||
predefs + after, true, true);
|
||||
SinglePassRunAndCheck<opt::LocalSingleStoreElimPass>(
|
||||
predefs + before, predefs + after, true, true);
|
||||
}
|
||||
|
||||
TEST_F(LocalSingleStoreElimTest, NoStoreElimWithInterveningAccessChainLoad) {
|
||||
// Last load of v is eliminated, but access chain load and store of v isn't
|
||||
//
|
||||
// #version 140
|
||||
//
|
||||
//
|
||||
// in vec4 BaseColor;
|
||||
//
|
||||
//
|
||||
// void main()
|
||||
// {
|
||||
// vec4 v = BaseColor;
|
||||
@ -300,17 +299,17 @@ OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
|
||||
SinglePassRunAndCheck<opt::LocalSingleStoreElimPass>(predefs + before,
|
||||
predefs + after, true, true);
|
||||
SinglePassRunAndCheck<opt::LocalSingleStoreElimPass>(
|
||||
predefs + before, predefs + after, true, true);
|
||||
}
|
||||
|
||||
TEST_F(LocalSingleStoreElimTest, NoReplaceOfDominatingPartialStore) {
|
||||
// Note: SPIR-V hand edited to initialize v to vec4(0.0)
|
||||
//
|
||||
// #version 140
|
||||
//
|
||||
//
|
||||
// in vec4 BaseColor;
|
||||
//
|
||||
//
|
||||
// void main()
|
||||
// {
|
||||
// vec4 v;
|
||||
@ -355,18 +354,18 @@ OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
|
||||
SinglePassRunAndCheck<opt::LocalSingleStoreElimPass>(
|
||||
assembly, assembly, true, true);
|
||||
SinglePassRunAndCheck<opt::LocalSingleStoreElimPass>(assembly, assembly, true,
|
||||
true);
|
||||
}
|
||||
|
||||
TEST_F(LocalSingleStoreElimTest, NoReplaceInPresenceOfUnsupportedInst) {
|
||||
// Note: PositiveNegative test hand edited to insert OpCopyObject
|
||||
TEST_F(LocalSingleStoreElimTest, ElimIfCopyObjectInFunction) {
|
||||
// Note: hand edited to insert OpCopyObject
|
||||
//
|
||||
// #version 140
|
||||
//
|
||||
//
|
||||
// in vec4 BaseColor;
|
||||
// in float fi;
|
||||
//
|
||||
//
|
||||
// void main()
|
||||
// {
|
||||
// vec4 v = BaseColor;
|
||||
@ -376,7 +375,7 @@ TEST_F(LocalSingleStoreElimTest, NoReplaceInPresenceOfUnsupportedInst) {
|
||||
// gl_FragColor = v + f;
|
||||
// }
|
||||
|
||||
const std::string assembly =
|
||||
const std::string predefs =
|
||||
R"(OpCapability Shader
|
||||
%1 = OpExtInstImport "GLSL.std.450"
|
||||
OpMemoryModel Logical GLSL450
|
||||
@ -403,7 +402,10 @@ OpName %gl_FragColor "gl_FragColor"
|
||||
%bool = OpTypeBool
|
||||
%_ptr_Output_v4float = OpTypePointer Output %v4float
|
||||
%gl_FragColor = OpVariable %_ptr_Output_v4float Output
|
||||
%main = OpFunction %void None %9
|
||||
)";
|
||||
|
||||
const std::string before =
|
||||
R"(%main = OpFunction %void None %9
|
||||
%19 = OpLabel
|
||||
%v = OpVariable %_ptr_Function_v4float Function
|
||||
%f = OpVariable %_ptr_Function_float Function
|
||||
@ -427,21 +429,45 @@ OpBranch %24
|
||||
OpStore %gl_FragColor %30
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
|
||||
const std::string after =
|
||||
R"(%main = OpFunction %void None %9
|
||||
%19 = OpLabel
|
||||
%v = OpVariable %_ptr_Function_v4float Function
|
||||
%f = OpVariable %_ptr_Function_float Function
|
||||
%20 = OpLoad %v4float %BaseColor
|
||||
%21 = OpLoad %float %fi
|
||||
OpStore %f %21
|
||||
%22 = OpLoad %float %f
|
||||
%23 = OpFOrdLessThan %bool %22 %float_0
|
||||
OpSelectionMerge %24 None
|
||||
OpBranchConditional %23 %25 %24
|
||||
%25 = OpLabel
|
||||
OpStore %f %float_0
|
||||
OpBranch %24
|
||||
%24 = OpLabel
|
||||
%28 = OpLoad %float %f
|
||||
%29 = OpCompositeConstruct %v4float %28 %28 %28 %28
|
||||
%30 = OpFAdd %v4float %20 %29
|
||||
OpStore %gl_FragColor %30
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
|
||||
SinglePassRunAndCheck<opt::LocalSingleStoreElimPass>(
|
||||
assembly, assembly, true, true);
|
||||
predefs + before, predefs + after, true, true);
|
||||
}
|
||||
|
||||
TEST_F(LocalSingleStoreElimTest, NoOptIfStoreNotDominating) {
|
||||
// Single store to f not optimized because it does not dominate
|
||||
// the load.
|
||||
//
|
||||
//
|
||||
// #version 140
|
||||
//
|
||||
//
|
||||
// in vec4 BaseColor;
|
||||
// in float fi;
|
||||
//
|
||||
//
|
||||
// void main()
|
||||
// {
|
||||
// float f;
|
||||
@ -509,8 +535,8 @@ OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
|
||||
SinglePassRunAndCheck<opt::LocalSingleStoreElimPass>(assembly, assembly,
|
||||
true, true);
|
||||
SinglePassRunAndCheck<opt::LocalSingleStoreElimPass>(assembly, assembly, true,
|
||||
true);
|
||||
}
|
||||
|
||||
// TODO(greg-lunarg): Add tests to verify handling of these cases:
|
||||
|
Loading…
Reference in New Issue
Block a user