operand_to_undef_test.cpp 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. // Copyright (c) 2018 Google LLC
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #include "source/reduce/operand_to_undef_reduction_opportunity_finder.h"
  15. #include "source/opt/build_module.h"
  16. #include "source/reduce/reduction_opportunity.h"
  17. #include "test/reduce/reduce_test_util.h"
  18. namespace spvtools {
  19. namespace reduce {
  20. namespace {
  21. TEST(OperandToUndefReductionPassTest, BasicCheck) {
  22. // The following shader has 10 opportunities for replacing with undef.
  23. // #version 310 es
  24. //
  25. // precision highp float;
  26. //
  27. // layout(location=0) out vec4 _GLF_color;
  28. //
  29. // layout(set = 0, binding = 0) uniform buf0 {
  30. // vec2 uniform1;
  31. // };
  32. //
  33. // void main()
  34. // {
  35. // _GLF_color =
  36. // vec4( // opportunity
  37. // uniform1.x / 2.0, // opportunity x2 (2.0 is const)
  38. // uniform1.y / uniform1.x, // opportunity x3
  39. // uniform1.x + uniform1.x, // opportunity x3
  40. // uniform1.y); // opportunity
  41. // }
  42. std::string original = R"(
  43. OpCapability Shader
  44. %1 = OpExtInstImport "GLSL.std.450"
  45. OpMemoryModel Logical GLSL450
  46. OpEntryPoint Fragment %4 "main" %9
  47. OpExecutionMode %4 OriginUpperLeft
  48. OpSource ESSL 310
  49. OpName %4 "main"
  50. OpName %9 "_GLF_color"
  51. OpName %11 "buf0"
  52. OpMemberName %11 0 "uniform1"
  53. OpName %13 ""
  54. OpDecorate %9 Location 0
  55. OpMemberDecorate %11 0 Offset 0
  56. OpDecorate %11 Block
  57. OpDecorate %13 DescriptorSet 0
  58. OpDecorate %13 Binding 0
  59. %2 = OpTypeVoid
  60. %3 = OpTypeFunction %2
  61. %6 = OpTypeFloat 32
  62. %7 = OpTypeVector %6 4
  63. %8 = OpTypePointer Output %7
  64. %9 = OpVariable %8 Output
  65. %10 = OpTypeVector %6 2
  66. %11 = OpTypeStruct %10
  67. %12 = OpTypePointer Uniform %11
  68. %13 = OpVariable %12 Uniform
  69. %14 = OpTypeInt 32 1
  70. %15 = OpConstant %14 0
  71. %16 = OpTypeInt 32 0
  72. %17 = OpConstant %16 0
  73. %18 = OpTypePointer Uniform %6
  74. %21 = OpConstant %6 2
  75. %23 = OpConstant %16 1
  76. %4 = OpFunction %2 None %3
  77. %5 = OpLabel
  78. %19 = OpAccessChain %18 %13 %15 %17
  79. %20 = OpLoad %6 %19
  80. %22 = OpFDiv %6 %20 %21 ; opportunity %20 (%21 is const)
  81. %24 = OpAccessChain %18 %13 %15 %23
  82. %25 = OpLoad %6 %24
  83. %26 = OpAccessChain %18 %13 %15 %17
  84. %27 = OpLoad %6 %26
  85. %28 = OpFDiv %6 %25 %27 ; opportunity %25 %27
  86. %29 = OpAccessChain %18 %13 %15 %17
  87. %30 = OpLoad %6 %29
  88. %31 = OpAccessChain %18 %13 %15 %17
  89. %32 = OpLoad %6 %31
  90. %33 = OpFAdd %6 %30 %32 ; opportunity %30 %32
  91. %34 = OpAccessChain %18 %13 %15 %23
  92. %35 = OpLoad %6 %34
  93. %36 = OpCompositeConstruct %7 %22 %28 %33 %35 ; opportunity %22 %28 %33 %35
  94. OpStore %9 %36 ; opportunity %36
  95. OpReturn
  96. OpFunctionEnd
  97. )";
  98. // This is the same as original, except where noted.
  99. std::string expected = R"(
  100. OpCapability Shader
  101. %1 = OpExtInstImport "GLSL.std.450"
  102. OpMemoryModel Logical GLSL450
  103. OpEntryPoint Fragment %4 "main" %9
  104. OpExecutionMode %4 OriginUpperLeft
  105. OpSource ESSL 310
  106. OpName %4 "main"
  107. OpName %9 "_GLF_color"
  108. OpName %11 "buf0"
  109. OpMemberName %11 0 "uniform1"
  110. OpName %13 ""
  111. OpDecorate %9 Location 0
  112. OpMemberDecorate %11 0 Offset 0
  113. OpDecorate %11 Block
  114. OpDecorate %13 DescriptorSet 0
  115. OpDecorate %13 Binding 0
  116. %2 = OpTypeVoid
  117. %3 = OpTypeFunction %2
  118. %6 = OpTypeFloat 32
  119. %7 = OpTypeVector %6 4
  120. %8 = OpTypePointer Output %7
  121. %9 = OpVariable %8 Output
  122. %10 = OpTypeVector %6 2
  123. %11 = OpTypeStruct %10
  124. %12 = OpTypePointer Uniform %11
  125. %13 = OpVariable %12 Uniform
  126. %14 = OpTypeInt 32 1
  127. %15 = OpConstant %14 0
  128. %16 = OpTypeInt 32 0
  129. %17 = OpConstant %16 0
  130. %18 = OpTypePointer Uniform %6
  131. %21 = OpConstant %6 2
  132. %23 = OpConstant %16 1
  133. %37 = OpUndef %6 ; Added undef float as %37
  134. %4 = OpFunction %2 None %3
  135. %5 = OpLabel
  136. %19 = OpAccessChain %18 %13 %15 %17
  137. %20 = OpLoad %6 %19
  138. %22 = OpFDiv %6 %37 %21 ; Replaced with %37
  139. %24 = OpAccessChain %18 %13 %15 %23
  140. %25 = OpLoad %6 %24
  141. %26 = OpAccessChain %18 %13 %15 %17
  142. %27 = OpLoad %6 %26
  143. %28 = OpFDiv %6 %37 %37 ; Replaced with %37 twice
  144. %29 = OpAccessChain %18 %13 %15 %17
  145. %30 = OpLoad %6 %29
  146. %31 = OpAccessChain %18 %13 %15 %17
  147. %32 = OpLoad %6 %31
  148. %33 = OpFAdd %6 %30 %32
  149. %34 = OpAccessChain %18 %13 %15 %23
  150. %35 = OpLoad %6 %34
  151. %36 = OpCompositeConstruct %7 %22 %28 %33 %35
  152. OpStore %9 %36
  153. OpReturn
  154. OpFunctionEnd
  155. )";
  156. const auto env = SPV_ENV_UNIVERSAL_1_3;
  157. const auto consumer = nullptr;
  158. const auto context =
  159. BuildModule(env, consumer, original, kReduceAssembleOption);
  160. const auto ops =
  161. OperandToUndefReductionOpportunityFinder().GetAvailableOpportunities(
  162. context.get(), 0);
  163. ASSERT_EQ(10, ops.size());
  164. // Apply first three opportunities.
  165. ASSERT_TRUE(ops[0]->PreconditionHolds());
  166. ops[0]->TryToApply();
  167. ASSERT_TRUE(ops[1]->PreconditionHolds());
  168. ops[1]->TryToApply();
  169. ASSERT_TRUE(ops[2]->PreconditionHolds());
  170. ops[2]->TryToApply();
  171. CheckEqual(env, expected, context.get());
  172. }
  173. TEST(OperandToUndefReductionPassTest, WithCalledFunction) {
  174. // The following shader has no opportunities.
  175. // Most importantly, the noted function operand is not changed.
  176. std::string shader = R"(
  177. OpCapability Shader
  178. %1 = OpExtInstImport "GLSL.std.450"
  179. OpMemoryModel Logical GLSL450
  180. OpEntryPoint Fragment %4 "main" %10 %12
  181. OpExecutionMode %4 OriginUpperLeft
  182. OpSource ESSL 310
  183. %2 = OpTypeVoid
  184. %3 = OpTypeFunction %2
  185. %6 = OpTypeFloat 32
  186. %7 = OpTypeVector %6 4
  187. %8 = OpTypeFunction %7
  188. %9 = OpTypePointer Output %7
  189. %10 = OpVariable %9 Output
  190. %11 = OpTypePointer Input %7
  191. %12 = OpVariable %11 Input
  192. %13 = OpConstant %6 0
  193. %14 = OpConstantComposite %7 %13 %13 %13 %13
  194. %4 = OpFunction %2 None %3
  195. %5 = OpLabel
  196. %15 = OpFunctionCall %7 %16 ; do not replace %16 with undef
  197. OpReturn
  198. OpFunctionEnd
  199. %16 = OpFunction %7 None %8
  200. %17 = OpLabel
  201. OpReturnValue %14
  202. OpFunctionEnd
  203. )";
  204. const auto env = SPV_ENV_UNIVERSAL_1_3;
  205. const auto consumer = nullptr;
  206. const auto context =
  207. BuildModule(env, consumer, shader, kReduceAssembleOption);
  208. const auto ops =
  209. OperandToUndefReductionOpportunityFinder().GetAvailableOpportunities(
  210. context.get(), 0);
  211. ASSERT_EQ(0, ops.size());
  212. }
  213. } // namespace
  214. } // namespace reduce
  215. } // namespace spvtools