transformation_set_function_control_test.cpp 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. // Copyright (c) 2019 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/fuzz/transformation_set_function_control.h"
  15. #include "gtest/gtest.h"
  16. #include "source/fuzz/fuzzer_util.h"
  17. #include "test/fuzz/fuzz_test_util.h"
  18. namespace spvtools {
  19. namespace fuzz {
  20. namespace {
  21. TEST(TransformationSetFunctionControlTest, VariousScenarios) {
  22. // This is a simple transformation; this test captures the important things
  23. // to check for.
  24. std::string shader = R"(
  25. OpCapability Shader
  26. %1 = OpExtInstImport "GLSL.std.450"
  27. OpMemoryModel Logical GLSL450
  28. OpEntryPoint Fragment %4 "main" %54
  29. OpExecutionMode %4 OriginUpperLeft
  30. OpSource ESSL 310
  31. OpName %4 "main"
  32. OpName %11 "foo(i1;i1;"
  33. OpName %9 "a"
  34. OpName %10 "b"
  35. OpName %13 "bar("
  36. OpName %17 "baz(i1;"
  37. OpName %16 "x"
  38. OpName %21 "boo(i1;i1;"
  39. OpName %19 "a"
  40. OpName %20 "b"
  41. OpName %29 "g"
  42. OpName %42 "param"
  43. OpName %44 "param"
  44. OpName %45 "param"
  45. OpName %48 "param"
  46. OpName %49 "param"
  47. OpName %54 "color"
  48. OpDecorate %54 Location 0
  49. %2 = OpTypeVoid
  50. %3 = OpTypeFunction %2
  51. %6 = OpTypeInt 32 1
  52. %7 = OpTypePointer Function %6
  53. %8 = OpTypeFunction %6 %7 %7
  54. %15 = OpTypeFunction %6 %7
  55. %28 = OpTypePointer Private %6
  56. %29 = OpVariable %28 Private
  57. %30 = OpConstant %6 2
  58. %31 = OpConstant %6 5
  59. %51 = OpTypeFloat 32
  60. %52 = OpTypeVector %51 4
  61. %53 = OpTypePointer Output %52
  62. %54 = OpVariable %53 Output
  63. %4 = OpFunction %2 None %3
  64. %5 = OpLabel
  65. %42 = OpVariable %7 Function
  66. %44 = OpVariable %7 Function
  67. %45 = OpVariable %7 Function
  68. %48 = OpVariable %7 Function
  69. %49 = OpVariable %7 Function
  70. %41 = OpFunctionCall %2 %13
  71. OpStore %42 %30
  72. %43 = OpFunctionCall %6 %17 %42
  73. OpStore %44 %31
  74. %46 = OpLoad %6 %29
  75. OpStore %45 %46
  76. %47 = OpFunctionCall %6 %21 %44 %45
  77. OpStore %48 %43
  78. OpStore %49 %47
  79. %50 = OpFunctionCall %6 %11 %48 %49
  80. OpReturn
  81. OpFunctionEnd
  82. %11 = OpFunction %6 Const %8
  83. %9 = OpFunctionParameter %7
  84. %10 = OpFunctionParameter %7
  85. %12 = OpLabel
  86. %23 = OpLoad %6 %9
  87. %24 = OpLoad %6 %10
  88. %25 = OpIAdd %6 %23 %24
  89. OpReturnValue %25
  90. OpFunctionEnd
  91. %13 = OpFunction %2 Inline %3
  92. %14 = OpLabel
  93. OpStore %29 %30
  94. OpReturn
  95. OpFunctionEnd
  96. %17 = OpFunction %6 Pure|DontInline %15
  97. %16 = OpFunctionParameter %7
  98. %18 = OpLabel
  99. %32 = OpLoad %6 %16
  100. %33 = OpIAdd %6 %31 %32
  101. OpReturnValue %33
  102. OpFunctionEnd
  103. %21 = OpFunction %6 DontInline %8
  104. %19 = OpFunctionParameter %7
  105. %20 = OpFunctionParameter %7
  106. %22 = OpLabel
  107. %36 = OpLoad %6 %19
  108. %37 = OpLoad %6 %20
  109. %38 = OpIMul %6 %36 %37
  110. OpReturnValue %38
  111. OpFunctionEnd
  112. )";
  113. const auto env = SPV_ENV_UNIVERSAL_1_3;
  114. const auto consumer = nullptr;
  115. const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
  116. spvtools::ValidatorOptions validator_options;
  117. TransformationContext transformation_context(
  118. MakeUnique<FactManager>(context.get()), validator_options);
  119. // %36 is not a function
  120. ASSERT_FALSE(TransformationSetFunctionControl(
  121. 36, uint32_t(spv::FunctionControlMask::MaskNone))
  122. .IsApplicable(context.get(), transformation_context));
  123. // Cannot add the Pure function control to %4 as it did not already have it
  124. ASSERT_FALSE(TransformationSetFunctionControl(
  125. 4, uint32_t(spv::FunctionControlMask::Pure))
  126. .IsApplicable(context.get(), transformation_context));
  127. // Cannot add the Const function control to %21 as it did not already
  128. // have it
  129. ASSERT_FALSE(TransformationSetFunctionControl(
  130. 21, uint32_t(spv::FunctionControlMask::Const))
  131. .IsApplicable(context.get(), transformation_context));
  132. // Set to None, removing Const
  133. TransformationSetFunctionControl transformation1(
  134. 11, uint32_t(spv::FunctionControlMask::MaskNone));
  135. ASSERT_TRUE(
  136. transformation1.IsApplicable(context.get(), transformation_context));
  137. ApplyAndCheckFreshIds(transformation1, context.get(),
  138. &transformation_context);
  139. // Set to Inline; silly to do it on an entry point, but it is allowed
  140. TransformationSetFunctionControl transformation2(
  141. 4, uint32_t(spv::FunctionControlMask::Inline));
  142. ASSERT_TRUE(
  143. transformation2.IsApplicable(context.get(), transformation_context));
  144. ApplyAndCheckFreshIds(transformation2, context.get(),
  145. &transformation_context);
  146. // Set to Pure, removing DontInline
  147. TransformationSetFunctionControl transformation3(
  148. 17, uint32_t(spv::FunctionControlMask::Pure));
  149. ASSERT_TRUE(
  150. transformation3.IsApplicable(context.get(), transformation_context));
  151. ApplyAndCheckFreshIds(transformation3, context.get(),
  152. &transformation_context);
  153. // Change from Inline to DontInline
  154. TransformationSetFunctionControl transformation4(
  155. 13, uint32_t(spv::FunctionControlMask::DontInline));
  156. ASSERT_TRUE(
  157. transformation4.IsApplicable(context.get(), transformation_context));
  158. ApplyAndCheckFreshIds(transformation4, context.get(),
  159. &transformation_context);
  160. std::string after_transformation = R"(
  161. OpCapability Shader
  162. %1 = OpExtInstImport "GLSL.std.450"
  163. OpMemoryModel Logical GLSL450
  164. OpEntryPoint Fragment %4 "main" %54
  165. OpExecutionMode %4 OriginUpperLeft
  166. OpSource ESSL 310
  167. OpName %4 "main"
  168. OpName %11 "foo(i1;i1;"
  169. OpName %9 "a"
  170. OpName %10 "b"
  171. OpName %13 "bar("
  172. OpName %17 "baz(i1;"
  173. OpName %16 "x"
  174. OpName %21 "boo(i1;i1;"
  175. OpName %19 "a"
  176. OpName %20 "b"
  177. OpName %29 "g"
  178. OpName %42 "param"
  179. OpName %44 "param"
  180. OpName %45 "param"
  181. OpName %48 "param"
  182. OpName %49 "param"
  183. OpName %54 "color"
  184. OpDecorate %54 Location 0
  185. %2 = OpTypeVoid
  186. %3 = OpTypeFunction %2
  187. %6 = OpTypeInt 32 1
  188. %7 = OpTypePointer Function %6
  189. %8 = OpTypeFunction %6 %7 %7
  190. %15 = OpTypeFunction %6 %7
  191. %28 = OpTypePointer Private %6
  192. %29 = OpVariable %28 Private
  193. %30 = OpConstant %6 2
  194. %31 = OpConstant %6 5
  195. %51 = OpTypeFloat 32
  196. %52 = OpTypeVector %51 4
  197. %53 = OpTypePointer Output %52
  198. %54 = OpVariable %53 Output
  199. %4 = OpFunction %2 Inline %3
  200. %5 = OpLabel
  201. %42 = OpVariable %7 Function
  202. %44 = OpVariable %7 Function
  203. %45 = OpVariable %7 Function
  204. %48 = OpVariable %7 Function
  205. %49 = OpVariable %7 Function
  206. %41 = OpFunctionCall %2 %13
  207. OpStore %42 %30
  208. %43 = OpFunctionCall %6 %17 %42
  209. OpStore %44 %31
  210. %46 = OpLoad %6 %29
  211. OpStore %45 %46
  212. %47 = OpFunctionCall %6 %21 %44 %45
  213. OpStore %48 %43
  214. OpStore %49 %47
  215. %50 = OpFunctionCall %6 %11 %48 %49
  216. OpReturn
  217. OpFunctionEnd
  218. %11 = OpFunction %6 None %8
  219. %9 = OpFunctionParameter %7
  220. %10 = OpFunctionParameter %7
  221. %12 = OpLabel
  222. %23 = OpLoad %6 %9
  223. %24 = OpLoad %6 %10
  224. %25 = OpIAdd %6 %23 %24
  225. OpReturnValue %25
  226. OpFunctionEnd
  227. %13 = OpFunction %2 DontInline %3
  228. %14 = OpLabel
  229. OpStore %29 %30
  230. OpReturn
  231. OpFunctionEnd
  232. %17 = OpFunction %6 Pure %15
  233. %16 = OpFunctionParameter %7
  234. %18 = OpLabel
  235. %32 = OpLoad %6 %16
  236. %33 = OpIAdd %6 %31 %32
  237. OpReturnValue %33
  238. OpFunctionEnd
  239. %21 = OpFunction %6 DontInline %8
  240. %19 = OpFunctionParameter %7
  241. %20 = OpFunctionParameter %7
  242. %22 = OpLabel
  243. %36 = OpLoad %6 %19
  244. %37 = OpLoad %6 %20
  245. %38 = OpIMul %6 %36 %37
  246. OpReturnValue %38
  247. OpFunctionEnd
  248. )";
  249. ASSERT_TRUE(IsEqual(env, after_transformation, context.get()));
  250. }
  251. } // namespace
  252. } // namespace fuzz
  253. } // namespace spvtools