mirror of
https://github.com/KhronosGroup/SPIRV-Tools
synced 2024-10-18 19:20:05 +00:00
Don't try to unroll loop with step count 0. (#4769)
These loop are infinite loop, so there is no reason to unroll the loop. Fixes #4711.
This commit is contained in:
parent
c1bb0b9415
commit
92c17edde7
@ -754,6 +754,10 @@ bool Loop::FindNumberOfIterations(const Instruction* induction,
|
|||||||
// |step_value| is NOT cleanly divisible then we add one to the sum.
|
// |step_value| is NOT cleanly divisible then we add one to the sum.
|
||||||
int64_t Loop::GetIterations(SpvOp condition, int64_t condition_value,
|
int64_t Loop::GetIterations(SpvOp condition, int64_t condition_value,
|
||||||
int64_t init_value, int64_t step_value) const {
|
int64_t init_value, int64_t step_value) const {
|
||||||
|
if (step_value == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int64_t diff = 0;
|
int64_t diff = 0;
|
||||||
|
|
||||||
switch (condition) {
|
switch (condition) {
|
||||||
|
@ -398,7 +398,8 @@ class Loop {
|
|||||||
// Each different loop |condition| affects how we calculate the number of
|
// Each different loop |condition| affects how we calculate the number of
|
||||||
// iterations using the |condition_value|, |init_value|, and |step_values| of
|
// iterations using the |condition_value|, |init_value|, and |step_values| of
|
||||||
// the induction variable. This method will return the number of iterations in
|
// the induction variable. This method will return the number of iterations in
|
||||||
// a loop with those values for a given |condition|.
|
// a loop with those values for a given |condition|. Returns 0 if the number
|
||||||
|
// of iterations could not be computed.
|
||||||
int64_t GetIterations(SpvOp condition, int64_t condition_value,
|
int64_t GetIterations(SpvOp condition, int64_t condition_value,
|
||||||
int64_t init_value, int64_t step_value) const;
|
int64_t init_value, int64_t step_value) const;
|
||||||
|
|
||||||
|
@ -3789,6 +3789,40 @@ TEST_F(PassClassTest, PartialUnrollWithPhiReferencesPhi) {
|
|||||||
SinglePassRunAndMatch<PartialUnrollerTestPass<2>>(text, true);
|
SinglePassRunAndMatch<PartialUnrollerTestPass<2>>(text, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(PassClassTest, DontUnrollInfiteLoop) {
|
||||||
|
// This is an infinite loop that because the step is 0. We want to make sure
|
||||||
|
// the unroller does not try to unroll it.
|
||||||
|
const std::string text = R"(OpCapability Shader
|
||||||
|
%1 = OpExtInstImport "GLSL.std.450"
|
||||||
|
OpMemoryModel Logical GLSL450
|
||||||
|
OpEntryPoint Fragment %2 "main"
|
||||||
|
OpExecutionMode %2 OriginUpperLeft
|
||||||
|
%void = OpTypeVoid
|
||||||
|
%4 = OpTypeFunction %void
|
||||||
|
%int = OpTypeInt 32 1
|
||||||
|
%int_0 = OpConstant %int 0
|
||||||
|
%int_50 = OpConstant %int 50
|
||||||
|
%bool = OpTypeBool
|
||||||
|
%int_0_0 = OpConstant %int 0
|
||||||
|
%2 = OpFunction %void None %4
|
||||||
|
%10 = OpLabel
|
||||||
|
OpBranch %11
|
||||||
|
%11 = OpLabel
|
||||||
|
%12 = OpPhi %int %int_0 %10 %13 %14
|
||||||
|
%15 = OpSLessThan %bool %12 %int_50
|
||||||
|
OpLoopMerge %16 %14 Unroll
|
||||||
|
OpBranchConditional %15 %14 %16
|
||||||
|
%14 = OpLabel
|
||||||
|
%13 = OpIAdd %int %12 %int_0_0
|
||||||
|
OpBranch %11
|
||||||
|
%16 = OpLabel
|
||||||
|
OpReturn
|
||||||
|
OpFunctionEnd
|
||||||
|
)";
|
||||||
|
|
||||||
|
SinglePassRunAndCheck<LoopUnroller>(text, text, false);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
} // namespace opt
|
} // namespace opt
|
||||||
} // namespace spvtools
|
} // namespace spvtools
|
||||||
|
Loading…
Reference in New Issue
Block a user