transformation_permute_function_parameters_test.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563
  1. // Copyright (c) 2020 Vasyl Teliman
  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_permute_function_parameters.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(TransformationPermuteFunctionParametersTest, BasicTest) {
  22. std::string shader = R"(
  23. OpCapability Shader
  24. %1 = OpExtInstImport "GLSL.std.450"
  25. OpMemoryModel Logical GLSL450
  26. OpEntryPoint Fragment %4 "main" %72 %74
  27. OpExecutionMode %4 OriginUpperLeft
  28. OpSource ESSL 310
  29. OpName %4 "main"
  30. OpName %12 "g(f1;f1;"
  31. OpName %10 "x"
  32. OpName %11 "y"
  33. OpName %22 "f(f1;i1;vf2;"
  34. OpName %19 "x"
  35. OpName %20 "y"
  36. OpName %21 "z"
  37. OpName %28 "cond(i1;f1;"
  38. OpName %26 "a"
  39. OpName %27 "b"
  40. OpName %53 "param"
  41. OpName %54 "param"
  42. OpName %66 "param"
  43. OpName %67 "param"
  44. OpName %72 "color"
  45. OpName %74 "gl_FragCoord"
  46. OpName %75 "param"
  47. OpName %79 "param"
  48. OpName %85 "param"
  49. OpName %86 "param"
  50. OpName %91 "param"
  51. OpName %92 "param"
  52. OpName %93 "param"
  53. OpName %99 "param"
  54. OpName %100 "param"
  55. OpName %101 "param"
  56. OpDecorate %20 RelaxedPrecision
  57. OpDecorate %26 RelaxedPrecision
  58. OpDecorate %47 RelaxedPrecision
  59. OpDecorate %58 RelaxedPrecision
  60. OpDecorate %72 Location 0
  61. OpDecorate %74 BuiltIn FragCoord
  62. %2 = OpTypeVoid
  63. %3 = OpTypeFunction %2
  64. %6 = OpTypeFloat 32
  65. %7 = OpTypePointer Function %6
  66. %8 = OpTypeVector %6 4
  67. %9 = OpTypeFunction %8 %7 %7
  68. %14 = OpTypeInt 32 1
  69. %15 = OpTypePointer Function %14
  70. %16 = OpTypeVector %6 2
  71. %17 = OpTypePointer Function %16
  72. %18 = OpTypeFunction %8 %7 %15 %17
  73. %24 = OpTypeBool
  74. %25 = OpTypeFunction %24 %15 %7
  75. %31 = OpConstant %6 255
  76. %33 = OpConstant %6 0
  77. %34 = OpConstant %6 1
  78. %42 = OpTypeInt 32 0
  79. %43 = OpConstant %42 0
  80. %49 = OpConstant %42 1
  81. %64 = OpConstant %14 4
  82. %65 = OpConstant %6 5
  83. %71 = OpTypePointer Output %8
  84. %72 = OpVariable %71 Output
  85. %73 = OpTypePointer Input %8
  86. %74 = OpVariable %73 Input
  87. %76 = OpTypePointer Input %6
  88. %84 = OpConstant %14 5
  89. %90 = OpConstant %6 3
  90. %98 = OpConstant %6 4
  91. %206 = OpTypeFunction %2 %14 %16
  92. %223 = OpTypeFunction %2 %6 %8
  93. %224 = OpTypeFunction %2 %8 %6
  94. %233 = OpTypeFunction %2 %42 %24
  95. %234 = OpTypeFunction %2 %24 %42
  96. %4 = OpFunction %2 None %3
  97. %5 = OpLabel
  98. %66 = OpVariable %15 Function
  99. %67 = OpVariable %7 Function
  100. %75 = OpVariable %7 Function
  101. %79 = OpVariable %7 Function
  102. %85 = OpVariable %15 Function
  103. %86 = OpVariable %7 Function
  104. %91 = OpVariable %7 Function
  105. %92 = OpVariable %15 Function
  106. %93 = OpVariable %17 Function
  107. %99 = OpVariable %7 Function
  108. %100 = OpVariable %15 Function
  109. %101 = OpVariable %17 Function
  110. OpStore %66 %64
  111. OpStore %67 %65
  112. %68 = OpFunctionCall %24 %28 %66 %67
  113. OpSelectionMerge %70 None
  114. OpBranchConditional %68 %69 %83
  115. %69 = OpLabel
  116. %77 = OpAccessChain %76 %74 %43
  117. %78 = OpLoad %6 %77
  118. OpStore %75 %78
  119. %80 = OpAccessChain %76 %74 %49
  120. %81 = OpLoad %6 %80
  121. OpStore %79 %81
  122. %82 = OpFunctionCall %8 %12 %75 %79
  123. OpStore %72 %82
  124. OpBranch %70
  125. %83 = OpLabel
  126. OpStore %85 %84
  127. OpStore %86 %65
  128. %87 = OpFunctionCall %24 %28 %85 %86
  129. OpSelectionMerge %89 None
  130. OpBranchConditional %87 %88 %97
  131. %88 = OpLabel
  132. OpStore %91 %90
  133. OpStore %92 %64
  134. %94 = OpLoad %8 %74
  135. %95 = OpVectorShuffle %16 %94 %94 0 1
  136. OpStore %93 %95
  137. %96 = OpFunctionCall %8 %22 %91 %92 %93
  138. OpStore %72 %96
  139. OpBranch %89
  140. %97 = OpLabel
  141. OpStore %99 %98
  142. OpStore %100 %84
  143. %102 = OpLoad %8 %74
  144. %103 = OpVectorShuffle %16 %102 %102 0 1
  145. OpStore %101 %103
  146. %104 = OpFunctionCall %8 %22 %99 %100 %101
  147. OpStore %72 %104
  148. OpBranch %89
  149. %89 = OpLabel
  150. OpBranch %70
  151. %70 = OpLabel
  152. OpReturn
  153. OpFunctionEnd
  154. ; adjust type of the function in-place
  155. %12 = OpFunction %8 None %9
  156. %10 = OpFunctionParameter %7
  157. %11 = OpFunctionParameter %7
  158. %13 = OpLabel
  159. %30 = OpLoad %6 %10
  160. %32 = OpFDiv %6 %30 %31
  161. %35 = OpLoad %6 %11
  162. %36 = OpFDiv %6 %35 %31
  163. %37 = OpFSub %6 %34 %36
  164. %38 = OpCompositeConstruct %8 %32 %33 %37 %34
  165. OpReturnValue %38
  166. OpFunctionEnd
  167. %22 = OpFunction %8 None %18
  168. %19 = OpFunctionParameter %7
  169. %20 = OpFunctionParameter %15
  170. %21 = OpFunctionParameter %17
  171. %23 = OpLabel
  172. %53 = OpVariable %7 Function
  173. %54 = OpVariable %7 Function
  174. %41 = OpLoad %6 %19
  175. %44 = OpAccessChain %7 %21 %43
  176. %45 = OpLoad %6 %44
  177. %46 = OpFAdd %6 %41 %45
  178. %47 = OpLoad %14 %20
  179. %48 = OpConvertSToF %6 %47
  180. %50 = OpAccessChain %7 %21 %49
  181. %51 = OpLoad %6 %50
  182. %52 = OpFAdd %6 %48 %51
  183. OpStore %53 %46
  184. OpStore %54 %52
  185. %55 = OpFunctionCall %8 %12 %53 %54
  186. OpReturnValue %55
  187. OpFunctionEnd
  188. %28 = OpFunction %24 None %25
  189. %26 = OpFunctionParameter %15
  190. %27 = OpFunctionParameter %7
  191. %29 = OpLabel
  192. %58 = OpLoad %14 %26
  193. %59 = OpConvertSToF %6 %58
  194. %60 = OpLoad %6 %27
  195. %61 = OpFOrdLessThan %24 %59 %60
  196. OpReturnValue %61
  197. OpFunctionEnd
  198. ; create a new function type
  199. %200 = OpFunction %2 None %206
  200. %207 = OpFunctionParameter %14
  201. %208 = OpFunctionParameter %16
  202. %202 = OpLabel
  203. OpReturn
  204. OpFunctionEnd
  205. %203 = OpFunction %2 None %206
  206. %209 = OpFunctionParameter %14
  207. %210 = OpFunctionParameter %16
  208. %205 = OpLabel
  209. OpReturn
  210. OpFunctionEnd
  211. ; reuse an existing function type
  212. %211 = OpFunction %2 None %223
  213. %212 = OpFunctionParameter %6
  214. %213 = OpFunctionParameter %8
  215. %214 = OpLabel
  216. OpReturn
  217. OpFunctionEnd
  218. %215 = OpFunction %2 None %224
  219. %216 = OpFunctionParameter %8
  220. %217 = OpFunctionParameter %6
  221. %218 = OpLabel
  222. OpReturn
  223. OpFunctionEnd
  224. %219 = OpFunction %2 None %224
  225. %220 = OpFunctionParameter %8
  226. %221 = OpFunctionParameter %6
  227. %222 = OpLabel
  228. OpReturn
  229. OpFunctionEnd
  230. ; don't adjust the type of the function if it creates a duplicate
  231. %225 = OpFunction %2 None %233
  232. %226 = OpFunctionParameter %42
  233. %227 = OpFunctionParameter %24
  234. %228 = OpLabel
  235. OpReturn
  236. OpFunctionEnd
  237. %229 = OpFunction %2 None %234
  238. %230 = OpFunctionParameter %24
  239. %231 = OpFunctionParameter %42
  240. %232 = OpLabel
  241. OpReturn
  242. OpFunctionEnd
  243. )";
  244. const auto env = SPV_ENV_UNIVERSAL_1_3;
  245. const auto consumer = nullptr;
  246. const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
  247. spvtools::ValidatorOptions validator_options;
  248. ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
  249. kConsoleMessageConsumer));
  250. TransformationContext transformation_context(
  251. MakeUnique<FactManager>(context.get()), validator_options);
  252. // Can't permute main function
  253. ASSERT_FALSE(TransformationPermuteFunctionParameters(4, 105, {})
  254. .IsApplicable(context.get(), transformation_context));
  255. // Can't permute invalid instruction
  256. ASSERT_FALSE(TransformationPermuteFunctionParameters(101, 105, {})
  257. .IsApplicable(context.get(), transformation_context));
  258. // Permutation has too many values
  259. ASSERT_FALSE(TransformationPermuteFunctionParameters(22, 105, {2, 1, 0, 3})
  260. .IsApplicable(context.get(), transformation_context));
  261. // Permutation has too few values
  262. ASSERT_FALSE(TransformationPermuteFunctionParameters(22, 105, {0, 1})
  263. .IsApplicable(context.get(), transformation_context));
  264. // Permutation has invalid values 1
  265. ASSERT_FALSE(TransformationPermuteFunctionParameters(22, 105, {3, 1, 0})
  266. .IsApplicable(context.get(), transformation_context));
  267. #ifndef NDEBUG
  268. // Permutation has invalid values 2
  269. ASSERT_DEATH(TransformationPermuteFunctionParameters(22, 105, {2, 2, 1})
  270. .IsApplicable(context.get(), transformation_context),
  271. "Permutation has duplicates");
  272. #endif
  273. // Result id for new function type is not fresh.
  274. ASSERT_FALSE(TransformationPermuteFunctionParameters(22, 42, {2, 1, 0})
  275. .IsApplicable(context.get(), transformation_context));
  276. // Successful transformations
  277. {
  278. TransformationPermuteFunctionParameters transformation(12, 105, {1, 0});
  279. ASSERT_TRUE(
  280. transformation.IsApplicable(context.get(), transformation_context));
  281. ApplyAndCheckFreshIds(transformation, context.get(),
  282. &transformation_context);
  283. ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(
  284. context.get(), validator_options, kConsoleMessageConsumer));
  285. }
  286. {
  287. TransformationPermuteFunctionParameters transformation(28, 106, {1, 0});
  288. ASSERT_TRUE(
  289. transformation.IsApplicable(context.get(), transformation_context));
  290. ApplyAndCheckFreshIds(transformation, context.get(),
  291. &transformation_context);
  292. ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(
  293. context.get(), validator_options, kConsoleMessageConsumer));
  294. }
  295. {
  296. TransformationPermuteFunctionParameters transformation(200, 107, {1, 0});
  297. ASSERT_TRUE(
  298. transformation.IsApplicable(context.get(), transformation_context));
  299. ApplyAndCheckFreshIds(transformation, context.get(),
  300. &transformation_context);
  301. ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(
  302. context.get(), validator_options, kConsoleMessageConsumer));
  303. }
  304. {
  305. TransformationPermuteFunctionParameters transformation(219, 108, {1, 0});
  306. ASSERT_TRUE(
  307. transformation.IsApplicable(context.get(), transformation_context));
  308. ApplyAndCheckFreshIds(transformation, context.get(),
  309. &transformation_context);
  310. ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(
  311. context.get(), validator_options, kConsoleMessageConsumer));
  312. }
  313. {
  314. TransformationPermuteFunctionParameters transformation(229, 109, {1, 0});
  315. ASSERT_TRUE(
  316. transformation.IsApplicable(context.get(), transformation_context));
  317. ApplyAndCheckFreshIds(transformation, context.get(),
  318. &transformation_context);
  319. ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(
  320. context.get(), validator_options, kConsoleMessageConsumer));
  321. }
  322. std::string after_transformation = R"(
  323. OpCapability Shader
  324. %1 = OpExtInstImport "GLSL.std.450"
  325. OpMemoryModel Logical GLSL450
  326. OpEntryPoint Fragment %4 "main" %72 %74
  327. OpExecutionMode %4 OriginUpperLeft
  328. OpSource ESSL 310
  329. OpName %4 "main"
  330. OpName %12 "g(f1;f1;"
  331. OpName %10 "x"
  332. OpName %11 "y"
  333. OpName %22 "f(f1;i1;vf2;"
  334. OpName %19 "x"
  335. OpName %20 "y"
  336. OpName %21 "z"
  337. OpName %28 "cond(i1;f1;"
  338. OpName %26 "a"
  339. OpName %27 "b"
  340. OpName %53 "param"
  341. OpName %54 "param"
  342. OpName %66 "param"
  343. OpName %67 "param"
  344. OpName %72 "color"
  345. OpName %74 "gl_FragCoord"
  346. OpName %75 "param"
  347. OpName %79 "param"
  348. OpName %85 "param"
  349. OpName %86 "param"
  350. OpName %91 "param"
  351. OpName %92 "param"
  352. OpName %93 "param"
  353. OpName %99 "param"
  354. OpName %100 "param"
  355. OpName %101 "param"
  356. OpDecorate %20 RelaxedPrecision
  357. OpDecorate %26 RelaxedPrecision
  358. OpDecorate %47 RelaxedPrecision
  359. OpDecorate %58 RelaxedPrecision
  360. OpDecorate %72 Location 0
  361. OpDecorate %74 BuiltIn FragCoord
  362. %2 = OpTypeVoid
  363. %3 = OpTypeFunction %2
  364. %6 = OpTypeFloat 32
  365. %7 = OpTypePointer Function %6
  366. %8 = OpTypeVector %6 4
  367. %9 = OpTypeFunction %8 %7 %7
  368. %14 = OpTypeInt 32 1
  369. %15 = OpTypePointer Function %14
  370. %16 = OpTypeVector %6 2
  371. %17 = OpTypePointer Function %16
  372. %18 = OpTypeFunction %8 %7 %15 %17
  373. %24 = OpTypeBool
  374. %31 = OpConstant %6 255
  375. %33 = OpConstant %6 0
  376. %34 = OpConstant %6 1
  377. %42 = OpTypeInt 32 0
  378. %43 = OpConstant %42 0
  379. %49 = OpConstant %42 1
  380. %64 = OpConstant %14 4
  381. %65 = OpConstant %6 5
  382. %71 = OpTypePointer Output %8
  383. %72 = OpVariable %71 Output
  384. %73 = OpTypePointer Input %8
  385. %74 = OpVariable %73 Input
  386. %76 = OpTypePointer Input %6
  387. %84 = OpConstant %14 5
  388. %90 = OpConstant %6 3
  389. %98 = OpConstant %6 4
  390. %206 = OpTypeFunction %2 %14 %16
  391. %223 = OpTypeFunction %2 %6 %8
  392. %224 = OpTypeFunction %2 %8 %6
  393. %233 = OpTypeFunction %2 %42 %24
  394. %25 = OpTypeFunction %24 %7 %15
  395. %107 = OpTypeFunction %2 %16 %14
  396. %4 = OpFunction %2 None %3
  397. %5 = OpLabel
  398. %66 = OpVariable %15 Function
  399. %67 = OpVariable %7 Function
  400. %75 = OpVariable %7 Function
  401. %79 = OpVariable %7 Function
  402. %85 = OpVariable %15 Function
  403. %86 = OpVariable %7 Function
  404. %91 = OpVariable %7 Function
  405. %92 = OpVariable %15 Function
  406. %93 = OpVariable %17 Function
  407. %99 = OpVariable %7 Function
  408. %100 = OpVariable %15 Function
  409. %101 = OpVariable %17 Function
  410. OpStore %66 %64
  411. OpStore %67 %65
  412. %68 = OpFunctionCall %24 %28 %67 %66
  413. OpSelectionMerge %70 None
  414. OpBranchConditional %68 %69 %83
  415. %69 = OpLabel
  416. %77 = OpAccessChain %76 %74 %43
  417. %78 = OpLoad %6 %77
  418. OpStore %75 %78
  419. %80 = OpAccessChain %76 %74 %49
  420. %81 = OpLoad %6 %80
  421. OpStore %79 %81
  422. %82 = OpFunctionCall %8 %12 %79 %75
  423. OpStore %72 %82
  424. OpBranch %70
  425. %83 = OpLabel
  426. OpStore %85 %84
  427. OpStore %86 %65
  428. %87 = OpFunctionCall %24 %28 %86 %85
  429. OpSelectionMerge %89 None
  430. OpBranchConditional %87 %88 %97
  431. %88 = OpLabel
  432. OpStore %91 %90
  433. OpStore %92 %64
  434. %94 = OpLoad %8 %74
  435. %95 = OpVectorShuffle %16 %94 %94 0 1
  436. OpStore %93 %95
  437. %96 = OpFunctionCall %8 %22 %91 %92 %93
  438. OpStore %72 %96
  439. OpBranch %89
  440. %97 = OpLabel
  441. OpStore %99 %98
  442. OpStore %100 %84
  443. %102 = OpLoad %8 %74
  444. %103 = OpVectorShuffle %16 %102 %102 0 1
  445. OpStore %101 %103
  446. %104 = OpFunctionCall %8 %22 %99 %100 %101
  447. OpStore %72 %104
  448. OpBranch %89
  449. %89 = OpLabel
  450. OpBranch %70
  451. %70 = OpLabel
  452. OpReturn
  453. OpFunctionEnd
  454. %12 = OpFunction %8 None %9
  455. %11 = OpFunctionParameter %7
  456. %10 = OpFunctionParameter %7
  457. %13 = OpLabel
  458. %30 = OpLoad %6 %10
  459. %32 = OpFDiv %6 %30 %31
  460. %35 = OpLoad %6 %11
  461. %36 = OpFDiv %6 %35 %31
  462. %37 = OpFSub %6 %34 %36
  463. %38 = OpCompositeConstruct %8 %32 %33 %37 %34
  464. OpReturnValue %38
  465. OpFunctionEnd
  466. %22 = OpFunction %8 None %18
  467. %19 = OpFunctionParameter %7
  468. %20 = OpFunctionParameter %15
  469. %21 = OpFunctionParameter %17
  470. %23 = OpLabel
  471. %53 = OpVariable %7 Function
  472. %54 = OpVariable %7 Function
  473. %41 = OpLoad %6 %19
  474. %44 = OpAccessChain %7 %21 %43
  475. %45 = OpLoad %6 %44
  476. %46 = OpFAdd %6 %41 %45
  477. %47 = OpLoad %14 %20
  478. %48 = OpConvertSToF %6 %47
  479. %50 = OpAccessChain %7 %21 %49
  480. %51 = OpLoad %6 %50
  481. %52 = OpFAdd %6 %48 %51
  482. OpStore %53 %46
  483. OpStore %54 %52
  484. %55 = OpFunctionCall %8 %12 %54 %53
  485. OpReturnValue %55
  486. OpFunctionEnd
  487. %28 = OpFunction %24 None %25
  488. %27 = OpFunctionParameter %7
  489. %26 = OpFunctionParameter %15
  490. %29 = OpLabel
  491. %58 = OpLoad %14 %26
  492. %59 = OpConvertSToF %6 %58
  493. %60 = OpLoad %6 %27
  494. %61 = OpFOrdLessThan %24 %59 %60
  495. OpReturnValue %61
  496. OpFunctionEnd
  497. %200 = OpFunction %2 None %107
  498. %208 = OpFunctionParameter %16
  499. %207 = OpFunctionParameter %14
  500. %202 = OpLabel
  501. OpReturn
  502. OpFunctionEnd
  503. %203 = OpFunction %2 None %206
  504. %209 = OpFunctionParameter %14
  505. %210 = OpFunctionParameter %16
  506. %205 = OpLabel
  507. OpReturn
  508. OpFunctionEnd
  509. %211 = OpFunction %2 None %223
  510. %212 = OpFunctionParameter %6
  511. %213 = OpFunctionParameter %8
  512. %214 = OpLabel
  513. OpReturn
  514. OpFunctionEnd
  515. %215 = OpFunction %2 None %224
  516. %216 = OpFunctionParameter %8
  517. %217 = OpFunctionParameter %6
  518. %218 = OpLabel
  519. OpReturn
  520. OpFunctionEnd
  521. %219 = OpFunction %2 None %223
  522. %221 = OpFunctionParameter %6
  523. %220 = OpFunctionParameter %8
  524. %222 = OpLabel
  525. OpReturn
  526. OpFunctionEnd
  527. %225 = OpFunction %2 None %233
  528. %226 = OpFunctionParameter %42
  529. %227 = OpFunctionParameter %24
  530. %228 = OpLabel
  531. OpReturn
  532. OpFunctionEnd
  533. %229 = OpFunction %2 None %233
  534. %231 = OpFunctionParameter %42
  535. %230 = OpFunctionParameter %24
  536. %232 = OpLabel
  537. OpReturn
  538. OpFunctionEnd
  539. )";
  540. ASSERT_TRUE(IsEqual(env, after_transformation, context.get()));
  541. }
  542. } // namespace
  543. } // namespace fuzz
  544. } // namespace spvtools