| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968 |
- // Copyright (c) 2019 Google LLC
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- #include "source/fuzz/transformation_set_loop_control.h"
- #include "test/fuzz/fuzz_test_util.h"
- namespace spvtools {
- namespace fuzz {
- namespace {
- TEST(TransformationSetLoopControlTest, VariousScenarios) {
- // This test features loops with various different controls, and goes through
- // a number of acceptable and unacceptable transformations to those controls.
- std::string shader = R"(
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %4 "main"
- OpExecutionMode %4 OriginUpperLeft
- OpSource ESSL 310
- OpName %4 "main"
- %2 = OpTypeVoid
- %3 = OpTypeFunction %2
- %6 = OpTypeInt 32 1
- %7 = OpTypePointer Function %6
- %9 = OpConstant %6 0
- %16 = OpConstant %6 100
- %17 = OpTypeBool
- %20 = OpConstant %6 1
- %4 = OpFunction %2 None %3
- %5 = OpLabel
- %8 = OpVariable %7 Function
- %22 = OpVariable %7 Function
- %32 = OpVariable %7 Function
- %42 = OpVariable %7 Function
- %52 = OpVariable %7 Function
- %62 = OpVariable %7 Function
- %72 = OpVariable %7 Function
- %82 = OpVariable %7 Function
- %92 = OpVariable %7 Function
- %102 = OpVariable %7 Function
- %112 = OpVariable %7 Function
- %122 = OpVariable %7 Function
- OpStore %8 %9
- OpBranch %10
- %10 = OpLabel
- %132 = OpPhi %6 %9 %5 %21 %13
- OpLoopMerge %12 %13 None
- OpBranch %14
- %14 = OpLabel
- %18 = OpSLessThan %17 %132 %16
- OpBranchConditional %18 %11 %12
- %11 = OpLabel
- OpBranch %13
- %13 = OpLabel
- %21 = OpIAdd %6 %132 %20
- OpStore %8 %21
- OpBranch %10
- %12 = OpLabel
- OpStore %22 %9
- OpBranch %23
- %23 = OpLabel
- %133 = OpPhi %6 %9 %12 %31 %26
- OpLoopMerge %25 %26 Unroll
- OpBranch %27
- %27 = OpLabel
- %29 = OpSLessThan %17 %133 %16
- OpBranchConditional %29 %24 %25
- %24 = OpLabel
- OpBranch %26
- %26 = OpLabel
- %31 = OpIAdd %6 %133 %20
- OpStore %22 %31
- OpBranch %23
- %25 = OpLabel
- OpStore %32 %9
- OpBranch %33
- %33 = OpLabel
- %134 = OpPhi %6 %9 %25 %41 %36
- OpLoopMerge %35 %36 DontUnroll
- OpBranch %37
- %37 = OpLabel
- %39 = OpSLessThan %17 %134 %16
- OpBranchConditional %39 %34 %35
- %34 = OpLabel
- OpBranch %36
- %36 = OpLabel
- %41 = OpIAdd %6 %134 %20
- OpStore %32 %41
- OpBranch %33
- %35 = OpLabel
- OpStore %42 %9
- OpBranch %43
- %43 = OpLabel
- %135 = OpPhi %6 %9 %35 %51 %46
- OpLoopMerge %45 %46 DependencyInfinite
- OpBranch %47
- %47 = OpLabel
- %49 = OpSLessThan %17 %135 %16
- OpBranchConditional %49 %44 %45
- %44 = OpLabel
- OpBranch %46
- %46 = OpLabel
- %51 = OpIAdd %6 %135 %20
- OpStore %42 %51
- OpBranch %43
- %45 = OpLabel
- OpStore %52 %9
- OpBranch %53
- %53 = OpLabel
- %136 = OpPhi %6 %9 %45 %61 %56
- OpLoopMerge %55 %56 DependencyLength 3
- OpBranch %57
- %57 = OpLabel
- %59 = OpSLessThan %17 %136 %16
- OpBranchConditional %59 %54 %55
- %54 = OpLabel
- OpBranch %56
- %56 = OpLabel
- %61 = OpIAdd %6 %136 %20
- OpStore %52 %61
- OpBranch %53
- %55 = OpLabel
- OpStore %62 %9
- OpBranch %63
- %63 = OpLabel
- %137 = OpPhi %6 %9 %55 %71 %66
- OpLoopMerge %65 %66 MinIterations 10
- OpBranch %67
- %67 = OpLabel
- %69 = OpSLessThan %17 %137 %16
- OpBranchConditional %69 %64 %65
- %64 = OpLabel
- OpBranch %66
- %66 = OpLabel
- %71 = OpIAdd %6 %137 %20
- OpStore %62 %71
- OpBranch %63
- %65 = OpLabel
- OpStore %72 %9
- OpBranch %73
- %73 = OpLabel
- %138 = OpPhi %6 %9 %65 %81 %76
- OpLoopMerge %75 %76 MaxIterations 50
- OpBranch %77
- %77 = OpLabel
- %79 = OpSLessThan %17 %138 %16
- OpBranchConditional %79 %74 %75
- %74 = OpLabel
- OpBranch %76
- %76 = OpLabel
- %81 = OpIAdd %6 %138 %20
- OpStore %72 %81
- OpBranch %73
- %75 = OpLabel
- OpStore %82 %9
- OpBranch %83
- %83 = OpLabel
- %139 = OpPhi %6 %9 %75 %91 %86
- OpLoopMerge %85 %86 IterationMultiple 4
- OpBranch %87
- %87 = OpLabel
- %89 = OpSLessThan %17 %139 %16
- OpBranchConditional %89 %84 %85
- %84 = OpLabel
- OpBranch %86
- %86 = OpLabel
- %91 = OpIAdd %6 %139 %20
- OpStore %82 %91
- OpBranch %83
- %85 = OpLabel
- OpStore %92 %9
- OpBranch %93
- %93 = OpLabel
- %140 = OpPhi %6 %9 %85 %101 %96
- OpLoopMerge %95 %96 PeelCount 2
- OpBranch %97
- %97 = OpLabel
- %99 = OpSLessThan %17 %140 %16
- OpBranchConditional %99 %94 %95
- %94 = OpLabel
- OpBranch %96
- %96 = OpLabel
- %101 = OpIAdd %6 %140 %20
- OpStore %92 %101
- OpBranch %93
- %95 = OpLabel
- OpStore %102 %9
- OpBranch %103
- %103 = OpLabel
- %141 = OpPhi %6 %9 %95 %111 %106
- OpLoopMerge %105 %106 PartialCount 3
- OpBranch %107
- %107 = OpLabel
- %109 = OpSLessThan %17 %141 %16
- OpBranchConditional %109 %104 %105
- %104 = OpLabel
- OpBranch %106
- %106 = OpLabel
- %111 = OpIAdd %6 %141 %20
- OpStore %102 %111
- OpBranch %103
- %105 = OpLabel
- OpStore %112 %9
- OpBranch %113
- %113 = OpLabel
- %142 = OpPhi %6 %9 %105 %121 %116
- OpLoopMerge %115 %116 Unroll|PeelCount|PartialCount 3 4
- OpBranch %117
- %117 = OpLabel
- %119 = OpSLessThan %17 %142 %16
- OpBranchConditional %119 %114 %115
- %114 = OpLabel
- OpBranch %116
- %116 = OpLabel
- %121 = OpIAdd %6 %142 %20
- OpStore %112 %121
- OpBranch %113
- %115 = OpLabel
- OpStore %122 %9
- OpBranch %123
- %123 = OpLabel
- %143 = OpPhi %6 %9 %115 %131 %126
- OpLoopMerge %125 %126 DependencyLength|MinIterations|MaxIterations|IterationMultiple|PeelCount|PartialCount 2 5 90 4 7 14
- OpBranch %127
- %127 = OpLabel
- %129 = OpSLessThan %17 %143 %16
- OpBranchConditional %129 %124 %125
- %124 = OpLabel
- OpBranch %126
- %126 = OpLabel
- %131 = OpIAdd %6 %143 %20
- OpStore %122 %131
- OpBranch %123
- %125 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- const auto env = SPV_ENV_UNIVERSAL_1_4;
- const auto consumer = nullptr;
- const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
- ASSERT_TRUE(IsValid(env, context.get()));
- FactManager fact_manager;
- // These are the loop headers together with the selection controls of their
- // merge instructions:
- // %10 None
- // %23 Unroll
- // %33 DontUnroll
- // %43 DependencyInfinite
- // %53 DependencyLength 3
- // %63 MinIterations 10
- // %73 MaxIterations 50
- // %83 IterationMultiple 4
- // %93 PeelCount 2
- // %103 PartialCount 3
- // %113 Unroll|PeelCount|PartialCount 3 4
- // %123
- // DependencyLength|MinIterations|MaxIterations|IterationMultiple|PeelCount|PartialCount
- // 2 5 90 4 7 14
- ASSERT_TRUE(TransformationSetLoopControl(10, SpvLoopControlMaskNone, 0, 0)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(TransformationSetLoopControl(10, SpvLoopControlUnrollMask, 0, 0)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(
- TransformationSetLoopControl(10, SpvLoopControlDontUnrollMask, 0, 0)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(TransformationSetLoopControl(
- 10, SpvLoopControlDependencyInfiniteMask, 0, 0)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(
- TransformationSetLoopControl(10, SpvLoopControlDependencyLengthMask, 0, 0)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(
- TransformationSetLoopControl(10, SpvLoopControlMinIterationsMask, 0, 0)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(
- TransformationSetLoopControl(10, SpvLoopControlMaxIterationsMask, 0, 0)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(TransformationSetLoopControl(
- 10, SpvLoopControlIterationMultipleMask, 0, 0)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(
- TransformationSetLoopControl(10, SpvLoopControlPeelCountMask, 3, 0)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(
- TransformationSetLoopControl(10, SpvLoopControlPeelCountMask, 3, 3)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(
- TransformationSetLoopControl(10, SpvLoopControlPartialCountMask, 0, 3)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(
- TransformationSetLoopControl(10, SpvLoopControlPartialCountMask, 3, 3)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(TransformationSetLoopControl(
- 10,
- SpvLoopControlPeelCountMask | SpvLoopControlPartialCountMask,
- 3, 3)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(TransformationSetLoopControl(10,
- SpvLoopControlUnrollMask |
- SpvLoopControlPeelCountMask |
- SpvLoopControlPartialCountMask,
- 3, 3)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(TransformationSetLoopControl(10,
- SpvLoopControlDontUnrollMask |
- SpvLoopControlPeelCountMask |
- SpvLoopControlPartialCountMask,
- 3, 3)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(TransformationSetLoopControl(23, SpvLoopControlMaskNone, 0, 0)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(TransformationSetLoopControl(23, SpvLoopControlUnrollMask, 0, 0)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(
- TransformationSetLoopControl(23, SpvLoopControlDontUnrollMask, 0, 0)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(TransformationSetLoopControl(
- 23,
- SpvLoopControlPeelCountMask | SpvLoopControlPartialCountMask,
- 3, 3)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(
- TransformationSetLoopControl(23, SpvLoopControlMaxIterationsMask, 2, 3)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(TransformationSetLoopControl(33, SpvLoopControlMaskNone, 0, 0)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(TransformationSetLoopControl(33, SpvLoopControlUnrollMask, 0, 0)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(
- TransformationSetLoopControl(33, SpvLoopControlDontUnrollMask, 0, 0)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(
- TransformationSetLoopControl(33, SpvLoopControlMinIterationsMask, 0, 0)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(
- TransformationSetLoopControl(
- 33, SpvLoopControlUnrollMask | SpvLoopControlPeelCountMask, 5, 0)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(TransformationSetLoopControl(33,
- SpvLoopControlDontUnrollMask |
- SpvLoopControlPartialCountMask,
- 0, 10)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(TransformationSetLoopControl(43, SpvLoopControlMaskNone, 0, 0)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(TransformationSetLoopControl(43, SpvLoopControlUnrollMask, 0, 0)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(
- TransformationSetLoopControl(43, SpvLoopControlDontUnrollMask, 0, 0)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(TransformationSetLoopControl(
- 43,
- SpvLoopControlMaskNone | SpvLoopControlDependencyInfiniteMask,
- 0, 0)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(
- TransformationSetLoopControl(
- 43, SpvLoopControlUnrollMask | SpvLoopControlDependencyInfiniteMask,
- 0, 0)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(
- TransformationSetLoopControl(
- 43,
- SpvLoopControlDontUnrollMask | SpvLoopControlDependencyInfiniteMask,
- 0, 0)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(
- TransformationSetLoopControl(43,
- SpvLoopControlDependencyInfiniteMask |
- SpvLoopControlDependencyLengthMask,
- 0, 0)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(
- TransformationSetLoopControl(
- 43, SpvLoopControlUnrollMask | SpvLoopControlPeelCountMask, 5, 0)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(TransformationSetLoopControl(53, SpvLoopControlMaskNone, 0, 0)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(TransformationSetLoopControl(53, SpvLoopControlUnrollMask, 0, 0)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(
- TransformationSetLoopControl(53, SpvLoopControlDontUnrollMask, 0, 0)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(
- TransformationSetLoopControl(53, SpvLoopControlMaxIterationsMask, 0, 0)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(
- TransformationSetLoopControl(
- 53, SpvLoopControlMaskNone | SpvLoopControlDependencyLengthMask, 0, 0)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(
- TransformationSetLoopControl(
- 53, SpvLoopControlUnrollMask | SpvLoopControlDependencyInfiniteMask,
- 0, 0)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(
- TransformationSetLoopControl(
- 53, SpvLoopControlDontUnrollMask | SpvLoopControlDependencyLengthMask,
- 0, 0)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(
- TransformationSetLoopControl(53,
- SpvLoopControlDependencyInfiniteMask |
- SpvLoopControlDependencyLengthMask,
- 0, 0)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(
- TransformationSetLoopControl(
- 53,
- SpvLoopControlUnrollMask | SpvLoopControlDependencyLengthMask |
- SpvLoopControlPeelCountMask | SpvLoopControlPartialCountMask,
- 5, 3)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(TransformationSetLoopControl(63, SpvLoopControlMaskNone, 0, 0)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(TransformationSetLoopControl(63, SpvLoopControlUnrollMask, 0, 0)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(
- TransformationSetLoopControl(63, SpvLoopControlDontUnrollMask, 0, 0)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(TransformationSetLoopControl(63,
- SpvLoopControlUnrollMask |
- SpvLoopControlMinIterationsMask |
- SpvLoopControlPeelCountMask |
- SpvLoopControlPartialCountMask,
- 5, 3)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(TransformationSetLoopControl(63,
- SpvLoopControlUnrollMask |
- SpvLoopControlMinIterationsMask |
- SpvLoopControlPeelCountMask,
- 23, 0)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(TransformationSetLoopControl(
- 63,
- SpvLoopControlUnrollMask | SpvLoopControlMinIterationsMask |
- SpvLoopControlPeelCountMask,
- 2, 23)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(TransformationSetLoopControl(73, SpvLoopControlMaskNone, 0, 0)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(TransformationSetLoopControl(73, SpvLoopControlUnrollMask, 0, 0)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(
- TransformationSetLoopControl(73, SpvLoopControlDontUnrollMask, 0, 0)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(TransformationSetLoopControl(
- 73,
- SpvLoopControlUnrollMask | SpvLoopControlMinIterationsMask |
- SpvLoopControlPeelCountMask |
- SpvLoopControlPartialCountMask,
- 5, 3)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(TransformationSetLoopControl(73,
- SpvLoopControlUnrollMask |
- SpvLoopControlMaxIterationsMask |
- SpvLoopControlPeelCountMask,
- 23, 0)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(TransformationSetLoopControl(
- 73,
- SpvLoopControlUnrollMask | SpvLoopControlMaxIterationsMask |
- SpvLoopControlPeelCountMask,
- 2, 23)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(TransformationSetLoopControl(83, SpvLoopControlMaskNone, 0, 0)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(TransformationSetLoopControl(83, SpvLoopControlUnrollMask, 0, 0)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(
- TransformationSetLoopControl(83, SpvLoopControlDontUnrollMask, 0, 0)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(TransformationSetLoopControl(
- 83,
- SpvLoopControlUnrollMask | SpvLoopControlMinIterationsMask |
- SpvLoopControlPeelCountMask |
- SpvLoopControlPartialCountMask,
- 5, 3)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(
- TransformationSetLoopControl(83,
- SpvLoopControlUnrollMask |
- SpvLoopControlIterationMultipleMask |
- SpvLoopControlPeelCountMask,
- 23, 0)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(
- TransformationSetLoopControl(83,
- SpvLoopControlUnrollMask |
- SpvLoopControlIterationMultipleMask |
- SpvLoopControlPeelCountMask,
- 2, 23)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(TransformationSetLoopControl(93, SpvLoopControlMaskNone, 0, 0)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(TransformationSetLoopControl(93, SpvLoopControlUnrollMask, 0, 0)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(
- TransformationSetLoopControl(93, SpvLoopControlDontUnrollMask, 0, 0)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(
- TransformationSetLoopControl(93, SpvLoopControlPeelCountMask, 8, 0)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(
- TransformationSetLoopControl(93, SpvLoopControlPeelCountMask, 8, 8)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(
- TransformationSetLoopControl(93, SpvLoopControlPartialCountMask, 0, 8)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(TransformationSetLoopControl(
- 93,
- SpvLoopControlPeelCountMask | SpvLoopControlPartialCountMask,
- 16, 8)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(TransformationSetLoopControl(103, SpvLoopControlMaskNone, 0, 0)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(TransformationSetLoopControl(103, SpvLoopControlUnrollMask, 0, 0)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(
- TransformationSetLoopControl(103, SpvLoopControlDontUnrollMask, 0, 0)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(
- TransformationSetLoopControl(103, SpvLoopControlPartialCountMask, 0, 60)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(TransformationSetLoopControl(103,
- SpvLoopControlDontUnrollMask |
- SpvLoopControlPartialCountMask,
- 0, 60)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(TransformationSetLoopControl(113, SpvLoopControlMaskNone, 0, 0)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(TransformationSetLoopControl(113, SpvLoopControlUnrollMask, 0, 0)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(
- TransformationSetLoopControl(113, SpvLoopControlDontUnrollMask, 0, 0)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(
- TransformationSetLoopControl(113, SpvLoopControlPeelCountMask, 12, 0)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(
- TransformationSetLoopControl(
- 113,
- SpvLoopControlIterationMultipleMask | SpvLoopControlPeelCountMask, 12,
- 0)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(TransformationSetLoopControl(123, SpvLoopControlMaskNone, 0, 0)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(TransformationSetLoopControl(123, SpvLoopControlUnrollMask, 0, 0)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(
- TransformationSetLoopControl(123, SpvLoopControlDontUnrollMask, 0, 0)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(
- TransformationSetLoopControl(
- 123,
- SpvLoopControlMinIterationsMask | SpvLoopControlMaxIterationsMask |
- SpvLoopControlIterationMultipleMask |
- SpvLoopControlPeelCountMask | SpvLoopControlPartialCountMask,
- 7, 8)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_TRUE(TransformationSetLoopControl(123,
- SpvLoopControlUnrollMask |
- SpvLoopControlMinIterationsMask |
- SpvLoopControlMaxIterationsMask |
- SpvLoopControlPartialCountMask,
- 0, 9)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(TransformationSetLoopControl(
- 123,
- SpvLoopControlUnrollMask | SpvLoopControlMinIterationsMask |
- SpvLoopControlMaxIterationsMask |
- SpvLoopControlPartialCountMask,
- 7, 9)
- .IsApplicable(context.get(), fact_manager));
- ASSERT_FALSE(
- TransformationSetLoopControl(
- 123,
- SpvLoopControlDontUnrollMask | SpvLoopControlMinIterationsMask |
- SpvLoopControlMaxIterationsMask | SpvLoopControlPartialCountMask,
- 7, 9)
- .IsApplicable(context.get(), fact_manager));
- TransformationSetLoopControl(10,
- SpvLoopControlUnrollMask |
- SpvLoopControlPeelCountMask |
- SpvLoopControlPartialCountMask,
- 3, 3)
- .Apply(context.get(), &fact_manager);
- TransformationSetLoopControl(23, SpvLoopControlDontUnrollMask, 0, 0)
- .Apply(context.get(), &fact_manager);
- TransformationSetLoopControl(33, SpvLoopControlUnrollMask, 0, 0)
- .Apply(context.get(), &fact_manager);
- TransformationSetLoopControl(
- 43, SpvLoopControlDontUnrollMask | SpvLoopControlDependencyInfiniteMask,
- 0, 0)
- .Apply(context.get(), &fact_manager);
- TransformationSetLoopControl(53, SpvLoopControlMaskNone, 0, 0)
- .Apply(context.get(), &fact_manager);
- TransformationSetLoopControl(63,
- SpvLoopControlUnrollMask |
- SpvLoopControlMinIterationsMask |
- SpvLoopControlPeelCountMask,
- 23, 0)
- .Apply(context.get(), &fact_manager);
- TransformationSetLoopControl(73,
- SpvLoopControlUnrollMask |
- SpvLoopControlMaxIterationsMask |
- SpvLoopControlPeelCountMask,
- 23, 0)
- .Apply(context.get(), &fact_manager);
- TransformationSetLoopControl(83, SpvLoopControlDontUnrollMask, 0, 0)
- .Apply(context.get(), &fact_manager);
- TransformationSetLoopControl(
- 93, SpvLoopControlPeelCountMask | SpvLoopControlPartialCountMask, 16, 8)
- .Apply(context.get(), &fact_manager);
- TransformationSetLoopControl(103, SpvLoopControlPartialCountMask, 0, 60)
- .Apply(context.get(), &fact_manager);
- TransformationSetLoopControl(113, SpvLoopControlPeelCountMask, 12, 0)
- .Apply(context.get(), &fact_manager);
- TransformationSetLoopControl(
- 123,
- SpvLoopControlUnrollMask | SpvLoopControlMinIterationsMask |
- SpvLoopControlMaxIterationsMask | SpvLoopControlPartialCountMask,
- 0, 9)
- .Apply(context.get(), &fact_manager);
- std::string after_transformation = R"(
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %4 "main"
- OpExecutionMode %4 OriginUpperLeft
- OpSource ESSL 310
- OpName %4 "main"
- %2 = OpTypeVoid
- %3 = OpTypeFunction %2
- %6 = OpTypeInt 32 1
- %7 = OpTypePointer Function %6
- %9 = OpConstant %6 0
- %16 = OpConstant %6 100
- %17 = OpTypeBool
- %20 = OpConstant %6 1
- %4 = OpFunction %2 None %3
- %5 = OpLabel
- %8 = OpVariable %7 Function
- %22 = OpVariable %7 Function
- %32 = OpVariable %7 Function
- %42 = OpVariable %7 Function
- %52 = OpVariable %7 Function
- %62 = OpVariable %7 Function
- %72 = OpVariable %7 Function
- %82 = OpVariable %7 Function
- %92 = OpVariable %7 Function
- %102 = OpVariable %7 Function
- %112 = OpVariable %7 Function
- %122 = OpVariable %7 Function
- OpStore %8 %9
- OpBranch %10
- %10 = OpLabel
- %132 = OpPhi %6 %9 %5 %21 %13
- OpLoopMerge %12 %13 Unroll|PeelCount|PartialCount 3 3
- OpBranch %14
- %14 = OpLabel
- %18 = OpSLessThan %17 %132 %16
- OpBranchConditional %18 %11 %12
- %11 = OpLabel
- OpBranch %13
- %13 = OpLabel
- %21 = OpIAdd %6 %132 %20
- OpStore %8 %21
- OpBranch %10
- %12 = OpLabel
- OpStore %22 %9
- OpBranch %23
- %23 = OpLabel
- %133 = OpPhi %6 %9 %12 %31 %26
- OpLoopMerge %25 %26 DontUnroll
- OpBranch %27
- %27 = OpLabel
- %29 = OpSLessThan %17 %133 %16
- OpBranchConditional %29 %24 %25
- %24 = OpLabel
- OpBranch %26
- %26 = OpLabel
- %31 = OpIAdd %6 %133 %20
- OpStore %22 %31
- OpBranch %23
- %25 = OpLabel
- OpStore %32 %9
- OpBranch %33
- %33 = OpLabel
- %134 = OpPhi %6 %9 %25 %41 %36
- OpLoopMerge %35 %36 Unroll
- OpBranch %37
- %37 = OpLabel
- %39 = OpSLessThan %17 %134 %16
- OpBranchConditional %39 %34 %35
- %34 = OpLabel
- OpBranch %36
- %36 = OpLabel
- %41 = OpIAdd %6 %134 %20
- OpStore %32 %41
- OpBranch %33
- %35 = OpLabel
- OpStore %42 %9
- OpBranch %43
- %43 = OpLabel
- %135 = OpPhi %6 %9 %35 %51 %46
- OpLoopMerge %45 %46 DontUnroll|DependencyInfinite
- OpBranch %47
- %47 = OpLabel
- %49 = OpSLessThan %17 %135 %16
- OpBranchConditional %49 %44 %45
- %44 = OpLabel
- OpBranch %46
- %46 = OpLabel
- %51 = OpIAdd %6 %135 %20
- OpStore %42 %51
- OpBranch %43
- %45 = OpLabel
- OpStore %52 %9
- OpBranch %53
- %53 = OpLabel
- %136 = OpPhi %6 %9 %45 %61 %56
- OpLoopMerge %55 %56 None
- OpBranch %57
- %57 = OpLabel
- %59 = OpSLessThan %17 %136 %16
- OpBranchConditional %59 %54 %55
- %54 = OpLabel
- OpBranch %56
- %56 = OpLabel
- %61 = OpIAdd %6 %136 %20
- OpStore %52 %61
- OpBranch %53
- %55 = OpLabel
- OpStore %62 %9
- OpBranch %63
- %63 = OpLabel
- %137 = OpPhi %6 %9 %55 %71 %66
- OpLoopMerge %65 %66 Unroll|MinIterations|PeelCount 10 23
- OpBranch %67
- %67 = OpLabel
- %69 = OpSLessThan %17 %137 %16
- OpBranchConditional %69 %64 %65
- %64 = OpLabel
- OpBranch %66
- %66 = OpLabel
- %71 = OpIAdd %6 %137 %20
- OpStore %62 %71
- OpBranch %63
- %65 = OpLabel
- OpStore %72 %9
- OpBranch %73
- %73 = OpLabel
- %138 = OpPhi %6 %9 %65 %81 %76
- OpLoopMerge %75 %76 Unroll|MaxIterations|PeelCount 50 23
- OpBranch %77
- %77 = OpLabel
- %79 = OpSLessThan %17 %138 %16
- OpBranchConditional %79 %74 %75
- %74 = OpLabel
- OpBranch %76
- %76 = OpLabel
- %81 = OpIAdd %6 %138 %20
- OpStore %72 %81
- OpBranch %73
- %75 = OpLabel
- OpStore %82 %9
- OpBranch %83
- %83 = OpLabel
- %139 = OpPhi %6 %9 %75 %91 %86
- OpLoopMerge %85 %86 DontUnroll
- OpBranch %87
- %87 = OpLabel
- %89 = OpSLessThan %17 %139 %16
- OpBranchConditional %89 %84 %85
- %84 = OpLabel
- OpBranch %86
- %86 = OpLabel
- %91 = OpIAdd %6 %139 %20
- OpStore %82 %91
- OpBranch %83
- %85 = OpLabel
- OpStore %92 %9
- OpBranch %93
- %93 = OpLabel
- %140 = OpPhi %6 %9 %85 %101 %96
- OpLoopMerge %95 %96 PeelCount|PartialCount 16 8
- OpBranch %97
- %97 = OpLabel
- %99 = OpSLessThan %17 %140 %16
- OpBranchConditional %99 %94 %95
- %94 = OpLabel
- OpBranch %96
- %96 = OpLabel
- %101 = OpIAdd %6 %140 %20
- OpStore %92 %101
- OpBranch %93
- %95 = OpLabel
- OpStore %102 %9
- OpBranch %103
- %103 = OpLabel
- %141 = OpPhi %6 %9 %95 %111 %106
- OpLoopMerge %105 %106 PartialCount 60
- OpBranch %107
- %107 = OpLabel
- %109 = OpSLessThan %17 %141 %16
- OpBranchConditional %109 %104 %105
- %104 = OpLabel
- OpBranch %106
- %106 = OpLabel
- %111 = OpIAdd %6 %141 %20
- OpStore %102 %111
- OpBranch %103
- %105 = OpLabel
- OpStore %112 %9
- OpBranch %113
- %113 = OpLabel
- %142 = OpPhi %6 %9 %105 %121 %116
- OpLoopMerge %115 %116 PeelCount 12
- OpBranch %117
- %117 = OpLabel
- %119 = OpSLessThan %17 %142 %16
- OpBranchConditional %119 %114 %115
- %114 = OpLabel
- OpBranch %116
- %116 = OpLabel
- %121 = OpIAdd %6 %142 %20
- OpStore %112 %121
- OpBranch %113
- %115 = OpLabel
- OpStore %122 %9
- OpBranch %123
- %123 = OpLabel
- %143 = OpPhi %6 %9 %115 %131 %126
- OpLoopMerge %125 %126 Unroll|MinIterations|MaxIterations|PartialCount 5 90 9
- OpBranch %127
- %127 = OpLabel
- %129 = OpSLessThan %17 %143 %16
- OpBranchConditional %129 %124 %125
- %124 = OpLabel
- OpBranch %126
- %126 = OpLabel
- %131 = OpIAdd %6 %143 %20
- OpStore %122 %131
- OpBranch %123
- %125 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- ASSERT_TRUE(IsEqual(env, after_transformation, context.get()));
- }
- TEST(TransformationSetLoopControlTest, CheckSPIRVVersionsRespected) {
- // This test checks that we do not allow introducing PeelCount and
- // PartialCount loop controls if the SPIR-V version being used does not
- // support them.
- std::string shader = R"(
- OpCapability Shader
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %4 "main"
- OpExecutionMode %4 OriginUpperLeft
- OpSource ESSL 310
- OpName %4 "main"
- OpName %8 "i"
- %2 = OpTypeVoid
- %3 = OpTypeFunction %2
- %6 = OpTypeInt 32 1
- %7 = OpTypePointer Function %6
- %9 = OpConstant %6 0
- %16 = OpConstant %6 10
- %17 = OpTypeBool
- %20 = OpConstant %6 1
- %4 = OpFunction %2 None %3
- %5 = OpLabel
- %8 = OpVariable %7 Function
- OpStore %8 %9
- OpBranch %10
- %10 = OpLabel
- OpLoopMerge %12 %13 None
- OpBranch %14
- %14 = OpLabel
- %15 = OpLoad %6 %8
- %18 = OpSLessThan %17 %15 %16
- OpBranchConditional %18 %11 %12
- %11 = OpLabel
- OpBranch %13
- %13 = OpLabel
- %19 = OpLoad %6 %8
- %21 = OpIAdd %6 %19 %20
- OpStore %8 %21
- OpBranch %10
- %12 = OpLabel
- OpReturn
- OpFunctionEnd
- )";
- const auto consumer = nullptr;
- const auto context_1_0 =
- BuildModule(SPV_ENV_UNIVERSAL_1_0, consumer, shader, kFuzzAssembleOption);
- const auto context_1_1 =
- BuildModule(SPV_ENV_UNIVERSAL_1_1, consumer, shader, kFuzzAssembleOption);
- const auto context_1_2 =
- BuildModule(SPV_ENV_UNIVERSAL_1_2, consumer, shader, kFuzzAssembleOption);
- const auto context_1_3 =
- BuildModule(SPV_ENV_UNIVERSAL_1_3, consumer, shader, kFuzzAssembleOption);
- const auto context_1_4 =
- BuildModule(SPV_ENV_UNIVERSAL_1_4, consumer, shader, kFuzzAssembleOption);
- const auto context_1_5 =
- BuildModule(SPV_ENV_UNIVERSAL_1_5, consumer, shader, kFuzzAssembleOption);
- FactManager fact_manager;
- TransformationSetLoopControl set_peel_and_partial(
- 10, SpvLoopControlPeelCountMask | SpvLoopControlPartialCountMask, 4, 4);
- // PeelCount and PartialCount were introduced in SPIRV 1.4, so are not valid
- // in the context of older versions.
- ASSERT_FALSE(
- set_peel_and_partial.IsApplicable(context_1_0.get(), fact_manager));
- ASSERT_FALSE(
- set_peel_and_partial.IsApplicable(context_1_1.get(), fact_manager));
- ASSERT_FALSE(
- set_peel_and_partial.IsApplicable(context_1_2.get(), fact_manager));
- ASSERT_FALSE(
- set_peel_and_partial.IsApplicable(context_1_3.get(), fact_manager));
- ASSERT_TRUE(
- set_peel_and_partial.IsApplicable(context_1_4.get(), fact_manager));
- ASSERT_TRUE(
- set_peel_and_partial.IsApplicable(context_1_5.get(), fact_manager));
- }
- } // namespace
- } // namespace fuzz
- } // namespace spvtools
|