transformation_composite_construct_test.cpp 54 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356
  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_composite_construct.h"
  15. #include "source/fuzz/data_descriptor.h"
  16. #include "source/fuzz/instruction_descriptor.h"
  17. #include "test/fuzz/fuzz_test_util.h"
  18. namespace spvtools {
  19. namespace fuzz {
  20. namespace {
  21. TEST(TransformationCompositeConstructTest, ConstructArrays) {
  22. std::string shader = R"(
  23. OpCapability Shader
  24. %1 = OpExtInstImport "GLSL.std.450"
  25. OpMemoryModel Logical GLSL450
  26. OpEntryPoint Fragment %4 "main"
  27. OpExecutionMode %4 OriginUpperLeft
  28. OpSource ESSL 310
  29. OpName %4 "main"
  30. OpName %11 "floats"
  31. OpName %22 "x"
  32. OpName %39 "vecs"
  33. OpName %49 "bools"
  34. OpName %60 "many_uvec3s"
  35. OpDecorate %60 RelaxedPrecision
  36. %2 = OpTypeVoid
  37. %3 = OpTypeFunction %2
  38. %6 = OpTypeFloat 32
  39. %7 = OpTypeInt 32 0
  40. %8 = OpConstant %7 2
  41. %9 = OpTypeArray %6 %8
  42. %10 = OpTypePointer Function %9
  43. %12 = OpTypeInt 32 1
  44. %13 = OpConstant %12 0
  45. %14 = OpConstant %6 1
  46. %15 = OpTypePointer Function %6
  47. %17 = OpConstant %12 1
  48. %18 = OpConstant %6 2
  49. %20 = OpTypeVector %6 2
  50. %21 = OpTypePointer Function %20
  51. %32 = OpTypeBool
  52. %36 = OpConstant %7 3
  53. %37 = OpTypeArray %20 %36
  54. %38 = OpTypePointer Private %37
  55. %39 = OpVariable %38 Private
  56. %40 = OpConstant %6 3
  57. %41 = OpConstantComposite %20 %40 %40
  58. %42 = OpTypePointer Private %20
  59. %44 = OpConstant %12 2
  60. %47 = OpTypeArray %32 %36
  61. %48 = OpTypePointer Function %47
  62. %50 = OpConstantTrue %32
  63. %51 = OpTypePointer Function %32
  64. %56 = OpTypeVector %7 3
  65. %57 = OpTypeArray %56 %8
  66. %58 = OpTypeArray %57 %8
  67. %59 = OpTypePointer Function %58
  68. %61 = OpConstant %7 4
  69. %62 = OpConstantComposite %56 %61 %61 %61
  70. %63 = OpTypePointer Function %56
  71. %65 = OpConstant %7 5
  72. %66 = OpConstantComposite %56 %65 %65 %65
  73. %67 = OpConstant %7 6
  74. %68 = OpConstantComposite %56 %67 %67 %67
  75. %69 = OpConstantComposite %57 %66 %68
  76. %100 = OpUndef %57
  77. %70 = OpTypePointer Function %57
  78. %4 = OpFunction %2 None %3
  79. %5 = OpLabel
  80. %11 = OpVariable %10 Function
  81. %22 = OpVariable %21 Function
  82. %49 = OpVariable %48 Function
  83. %60 = OpVariable %59 Function
  84. %16 = OpAccessChain %15 %11 %13
  85. OpStore %16 %14
  86. %19 = OpAccessChain %15 %11 %17
  87. OpStore %19 %18
  88. %23 = OpAccessChain %15 %11 %13
  89. %24 = OpLoad %6 %23
  90. %25 = OpAccessChain %15 %11 %17
  91. %26 = OpLoad %6 %25
  92. %27 = OpCompositeConstruct %20 %24 %26
  93. OpStore %22 %27
  94. %28 = OpAccessChain %15 %11 %13
  95. %29 = OpLoad %6 %28
  96. %30 = OpAccessChain %15 %11 %17
  97. %31 = OpLoad %6 %30
  98. %33 = OpFOrdGreaterThan %32 %29 %31
  99. OpSelectionMerge %35 None
  100. OpBranchConditional %33 %34 %35
  101. %34 = OpLabel
  102. %43 = OpAccessChain %42 %39 %17
  103. OpStore %43 %41
  104. %45 = OpLoad %20 %22
  105. %46 = OpAccessChain %42 %39 %44
  106. OpStore %46 %45
  107. OpBranch %35
  108. %35 = OpLabel
  109. %52 = OpAccessChain %51 %49 %13
  110. OpStore %52 %50
  111. %53 = OpAccessChain %51 %49 %13
  112. %54 = OpLoad %32 %53
  113. %55 = OpAccessChain %51 %49 %17
  114. OpStore %55 %54
  115. %64 = OpAccessChain %63 %60 %13 %13
  116. OpStore %64 %62
  117. %71 = OpAccessChain %70 %60 %17
  118. OpStore %71 %69
  119. OpReturn
  120. OpFunctionEnd
  121. )";
  122. const auto env = SPV_ENV_UNIVERSAL_1_3;
  123. const auto consumer = nullptr;
  124. const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
  125. ASSERT_TRUE(IsValid(env, context.get()));
  126. FactManager fact_manager;
  127. // Make a vec2[3]
  128. TransformationCompositeConstruct make_vec2_array_length_3(
  129. 37, {41, 45, 27}, MakeInstructionDescriptor(46, SpvOpAccessChain, 0),
  130. 200);
  131. // Bad: there are too many components
  132. TransformationCompositeConstruct make_vec2_array_length_3_bad(
  133. 37, {41, 45, 27, 27}, MakeInstructionDescriptor(46, SpvOpAccessChain, 0),
  134. 200);
  135. ASSERT_TRUE(
  136. make_vec2_array_length_3.IsApplicable(context.get(), fact_manager));
  137. ASSERT_FALSE(
  138. make_vec2_array_length_3_bad.IsApplicable(context.get(), fact_manager));
  139. make_vec2_array_length_3.Apply(context.get(), &fact_manager);
  140. ASSERT_TRUE(IsValid(env, context.get()));
  141. ASSERT_TRUE(fact_manager.IsSynonymous(
  142. MakeDataDescriptor(41, {}), MakeDataDescriptor(200, {0}), context.get()));
  143. ASSERT_TRUE(fact_manager.IsSynonymous(
  144. MakeDataDescriptor(45, {}), MakeDataDescriptor(200, {1}), context.get()));
  145. ASSERT_TRUE(fact_manager.IsSynonymous(
  146. MakeDataDescriptor(27, {}), MakeDataDescriptor(200, {2}), context.get()));
  147. // Make a float[2]
  148. TransformationCompositeConstruct make_float_array_length_2(
  149. 9, {24, 40}, MakeInstructionDescriptor(71, SpvOpStore, 0), 201);
  150. // Bad: %41 does not have type float
  151. TransformationCompositeConstruct make_float_array_length_2_bad(
  152. 9, {41, 40}, MakeInstructionDescriptor(71, SpvOpStore, 0), 201);
  153. ASSERT_TRUE(
  154. make_float_array_length_2.IsApplicable(context.get(), fact_manager));
  155. ASSERT_FALSE(
  156. make_float_array_length_2_bad.IsApplicable(context.get(), fact_manager));
  157. make_float_array_length_2.Apply(context.get(), &fact_manager);
  158. ASSERT_TRUE(IsValid(env, context.get()));
  159. ASSERT_TRUE(fact_manager.IsSynonymous(
  160. MakeDataDescriptor(24, {}), MakeDataDescriptor(201, {0}), context.get()));
  161. ASSERT_TRUE(fact_manager.IsSynonymous(
  162. MakeDataDescriptor(40, {}), MakeDataDescriptor(201, {1}), context.get()));
  163. // Make a bool[3]
  164. TransformationCompositeConstruct make_bool_array_length_3(
  165. 47, {33, 50, 50}, MakeInstructionDescriptor(33, SpvOpSelectionMerge, 0),
  166. 202);
  167. // Bad: %54 is not available at the desired program point.
  168. TransformationCompositeConstruct make_bool_array_length_3_bad(
  169. 47, {33, 54, 50}, MakeInstructionDescriptor(33, SpvOpSelectionMerge, 0),
  170. 202);
  171. ASSERT_TRUE(
  172. make_bool_array_length_3.IsApplicable(context.get(), fact_manager));
  173. ASSERT_FALSE(
  174. make_bool_array_length_3_bad.IsApplicable(context.get(), fact_manager));
  175. make_bool_array_length_3.Apply(context.get(), &fact_manager);
  176. ASSERT_TRUE(IsValid(env, context.get()));
  177. ASSERT_TRUE(fact_manager.IsSynonymous(
  178. MakeDataDescriptor(33, {}), MakeDataDescriptor(202, {0}), context.get()));
  179. ASSERT_TRUE(fact_manager.IsSynonymous(
  180. MakeDataDescriptor(50, {}), MakeDataDescriptor(202, {1}), context.get()));
  181. ASSERT_TRUE(fact_manager.IsSynonymous(
  182. MakeDataDescriptor(50, {}), MakeDataDescriptor(202, {2}), context.get()));
  183. // make a uvec3[2][2]
  184. TransformationCompositeConstruct make_uvec3_array_length_2_2(
  185. 58, {69, 100}, MakeInstructionDescriptor(64, SpvOpStore, 0), 203);
  186. // Bad: Skip count 100 is too large.
  187. TransformationCompositeConstruct make_uvec3_array_length_2_2_bad(
  188. 58, {33, 54}, MakeInstructionDescriptor(64, SpvOpStore, 100), 203);
  189. ASSERT_TRUE(
  190. make_uvec3_array_length_2_2.IsApplicable(context.get(), fact_manager));
  191. ASSERT_FALSE(make_uvec3_array_length_2_2_bad.IsApplicable(context.get(),
  192. fact_manager));
  193. make_uvec3_array_length_2_2.Apply(context.get(), &fact_manager);
  194. ASSERT_TRUE(IsValid(env, context.get()));
  195. ASSERT_TRUE(fact_manager.IsSynonymous(
  196. MakeDataDescriptor(69, {}), MakeDataDescriptor(203, {0}), context.get()));
  197. ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(100, {}),
  198. MakeDataDescriptor(203, {1}),
  199. context.get()));
  200. std::string after_transformation = R"(
  201. OpCapability Shader
  202. %1 = OpExtInstImport "GLSL.std.450"
  203. OpMemoryModel Logical GLSL450
  204. OpEntryPoint Fragment %4 "main"
  205. OpExecutionMode %4 OriginUpperLeft
  206. OpSource ESSL 310
  207. OpName %4 "main"
  208. OpName %11 "floats"
  209. OpName %22 "x"
  210. OpName %39 "vecs"
  211. OpName %49 "bools"
  212. OpName %60 "many_uvec3s"
  213. OpDecorate %60 RelaxedPrecision
  214. %2 = OpTypeVoid
  215. %3 = OpTypeFunction %2
  216. %6 = OpTypeFloat 32
  217. %7 = OpTypeInt 32 0
  218. %8 = OpConstant %7 2
  219. %9 = OpTypeArray %6 %8
  220. %10 = OpTypePointer Function %9
  221. %12 = OpTypeInt 32 1
  222. %13 = OpConstant %12 0
  223. %14 = OpConstant %6 1
  224. %15 = OpTypePointer Function %6
  225. %17 = OpConstant %12 1
  226. %18 = OpConstant %6 2
  227. %20 = OpTypeVector %6 2
  228. %21 = OpTypePointer Function %20
  229. %32 = OpTypeBool
  230. %36 = OpConstant %7 3
  231. %37 = OpTypeArray %20 %36
  232. %38 = OpTypePointer Private %37
  233. %39 = OpVariable %38 Private
  234. %40 = OpConstant %6 3
  235. %41 = OpConstantComposite %20 %40 %40
  236. %42 = OpTypePointer Private %20
  237. %44 = OpConstant %12 2
  238. %47 = OpTypeArray %32 %36
  239. %48 = OpTypePointer Function %47
  240. %50 = OpConstantTrue %32
  241. %51 = OpTypePointer Function %32
  242. %56 = OpTypeVector %7 3
  243. %57 = OpTypeArray %56 %8
  244. %58 = OpTypeArray %57 %8
  245. %59 = OpTypePointer Function %58
  246. %61 = OpConstant %7 4
  247. %62 = OpConstantComposite %56 %61 %61 %61
  248. %63 = OpTypePointer Function %56
  249. %65 = OpConstant %7 5
  250. %66 = OpConstantComposite %56 %65 %65 %65
  251. %67 = OpConstant %7 6
  252. %68 = OpConstantComposite %56 %67 %67 %67
  253. %69 = OpConstantComposite %57 %66 %68
  254. %100 = OpUndef %57
  255. %70 = OpTypePointer Function %57
  256. %4 = OpFunction %2 None %3
  257. %5 = OpLabel
  258. %11 = OpVariable %10 Function
  259. %22 = OpVariable %21 Function
  260. %49 = OpVariable %48 Function
  261. %60 = OpVariable %59 Function
  262. %16 = OpAccessChain %15 %11 %13
  263. OpStore %16 %14
  264. %19 = OpAccessChain %15 %11 %17
  265. OpStore %19 %18
  266. %23 = OpAccessChain %15 %11 %13
  267. %24 = OpLoad %6 %23
  268. %25 = OpAccessChain %15 %11 %17
  269. %26 = OpLoad %6 %25
  270. %27 = OpCompositeConstruct %20 %24 %26
  271. OpStore %22 %27
  272. %28 = OpAccessChain %15 %11 %13
  273. %29 = OpLoad %6 %28
  274. %30 = OpAccessChain %15 %11 %17
  275. %31 = OpLoad %6 %30
  276. %33 = OpFOrdGreaterThan %32 %29 %31
  277. %202 = OpCompositeConstruct %47 %33 %50 %50
  278. OpSelectionMerge %35 None
  279. OpBranchConditional %33 %34 %35
  280. %34 = OpLabel
  281. %43 = OpAccessChain %42 %39 %17
  282. OpStore %43 %41
  283. %45 = OpLoad %20 %22
  284. %200 = OpCompositeConstruct %37 %41 %45 %27
  285. %46 = OpAccessChain %42 %39 %44
  286. OpStore %46 %45
  287. OpBranch %35
  288. %35 = OpLabel
  289. %52 = OpAccessChain %51 %49 %13
  290. OpStore %52 %50
  291. %53 = OpAccessChain %51 %49 %13
  292. %54 = OpLoad %32 %53
  293. %55 = OpAccessChain %51 %49 %17
  294. OpStore %55 %54
  295. %64 = OpAccessChain %63 %60 %13 %13
  296. %203 = OpCompositeConstruct %58 %69 %100
  297. OpStore %64 %62
  298. %71 = OpAccessChain %70 %60 %17
  299. %201 = OpCompositeConstruct %9 %24 %40
  300. OpStore %71 %69
  301. OpReturn
  302. OpFunctionEnd
  303. )";
  304. ASSERT_TRUE(IsEqual(env, after_transformation, context.get()));
  305. }
  306. TEST(TransformationCompositeConstructTest, ConstructMatrices) {
  307. std::string shader = R"(
  308. OpCapability Shader
  309. %1 = OpExtInstImport "GLSL.std.450"
  310. OpMemoryModel Logical GLSL450
  311. OpEntryPoint Fragment %4 "main"
  312. OpExecutionMode %4 OriginUpperLeft
  313. OpSource ESSL 310
  314. OpName %4 "main"
  315. OpName %9 "v1"
  316. OpName %12 "v2"
  317. OpName %14 "v3"
  318. OpName %19 "v4"
  319. OpName %26 "v5"
  320. OpName %29 "v6"
  321. OpName %34 "m34"
  322. OpName %37 "m43"
  323. OpName %43 "vecs"
  324. %2 = OpTypeVoid
  325. %3 = OpTypeFunction %2
  326. %6 = OpTypeFloat 32
  327. %7 = OpTypeVector %6 3
  328. %8 = OpTypePointer Function %7
  329. %10 = OpConstant %6 1
  330. %11 = OpConstantComposite %7 %10 %10 %10
  331. %17 = OpTypeVector %6 4
  332. %18 = OpTypePointer Function %17
  333. %21 = OpConstant %6 2
  334. %32 = OpTypeMatrix %17 3
  335. %33 = OpTypePointer Private %32
  336. %34 = OpVariable %33 Private
  337. %35 = OpTypeMatrix %7 4
  338. %36 = OpTypePointer Private %35
  339. %37 = OpVariable %36 Private
  340. %38 = OpTypeVector %6 2
  341. %39 = OpTypeInt 32 0
  342. %40 = OpConstant %39 3
  343. %41 = OpTypeArray %38 %40
  344. %42 = OpTypePointer Private %41
  345. %43 = OpVariable %42 Private
  346. %100 = OpUndef %7
  347. %101 = OpUndef %17
  348. %4 = OpFunction %2 None %3
  349. %5 = OpLabel
  350. %9 = OpVariable %8 Function
  351. %12 = OpVariable %8 Function
  352. %14 = OpVariable %8 Function
  353. %19 = OpVariable %18 Function
  354. %26 = OpVariable %18 Function
  355. %29 = OpVariable %18 Function
  356. OpStore %9 %11
  357. %13 = OpLoad %7 %9
  358. OpStore %12 %13
  359. %15 = OpLoad %7 %12
  360. %16 = OpVectorShuffle %7 %15 %15 2 1 0
  361. OpStore %14 %16
  362. %20 = OpLoad %7 %14
  363. %22 = OpCompositeExtract %6 %20 0
  364. %23 = OpCompositeExtract %6 %20 1
  365. %24 = OpCompositeExtract %6 %20 2
  366. %25 = OpCompositeConstruct %17 %22 %23 %24 %21
  367. OpStore %19 %25
  368. %27 = OpLoad %17 %19
  369. %28 = OpVectorShuffle %17 %27 %27 3 2 1 0
  370. OpStore %26 %28
  371. %30 = OpLoad %7 %9
  372. %31 = OpVectorShuffle %17 %30 %30 0 0 1 1
  373. OpStore %29 %31
  374. OpReturn
  375. OpFunctionEnd
  376. )";
  377. const auto env = SPV_ENV_UNIVERSAL_1_3;
  378. const auto consumer = nullptr;
  379. const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
  380. ASSERT_TRUE(IsValid(env, context.get()));
  381. FactManager fact_manager;
  382. // make a mat3x4
  383. TransformationCompositeConstruct make_mat34(
  384. 32, {25, 28, 31}, MakeInstructionDescriptor(31, SpvOpReturn, 0), 200);
  385. // Bad: %35 is mat4x3, not mat3x4.
  386. TransformationCompositeConstruct make_mat34_bad(
  387. 35, {25, 28, 31}, MakeInstructionDescriptor(31, SpvOpReturn, 0), 200);
  388. ASSERT_TRUE(make_mat34.IsApplicable(context.get(), fact_manager));
  389. ASSERT_FALSE(make_mat34_bad.IsApplicable(context.get(), fact_manager));
  390. make_mat34.Apply(context.get(), &fact_manager);
  391. ASSERT_TRUE(IsValid(env, context.get()));
  392. ASSERT_TRUE(fact_manager.IsSynonymous(
  393. MakeDataDescriptor(25, {}), MakeDataDescriptor(200, {0}), context.get()));
  394. ASSERT_TRUE(fact_manager.IsSynonymous(
  395. MakeDataDescriptor(28, {}), MakeDataDescriptor(200, {1}), context.get()));
  396. ASSERT_TRUE(fact_manager.IsSynonymous(
  397. MakeDataDescriptor(31, {}), MakeDataDescriptor(200, {2}), context.get()));
  398. // make a mat4x3
  399. TransformationCompositeConstruct make_mat43(
  400. 35, {11, 13, 16, 100}, MakeInstructionDescriptor(31, SpvOpStore, 0), 201);
  401. // Bad: %25 does not match the matrix's column type.
  402. TransformationCompositeConstruct make_mat43_bad(
  403. 35, {25, 13, 16, 100}, MakeInstructionDescriptor(31, SpvOpStore, 0), 201);
  404. ASSERT_TRUE(make_mat43.IsApplicable(context.get(), fact_manager));
  405. ASSERT_FALSE(make_mat43_bad.IsApplicable(context.get(), fact_manager));
  406. make_mat43.Apply(context.get(), &fact_manager);
  407. ASSERT_TRUE(IsValid(env, context.get()));
  408. ASSERT_TRUE(fact_manager.IsSynonymous(
  409. MakeDataDescriptor(11, {}), MakeDataDescriptor(201, {0}), context.get()));
  410. ASSERT_TRUE(fact_manager.IsSynonymous(
  411. MakeDataDescriptor(13, {}), MakeDataDescriptor(201, {1}), context.get()));
  412. ASSERT_TRUE(fact_manager.IsSynonymous(
  413. MakeDataDescriptor(16, {}), MakeDataDescriptor(201, {2}), context.get()));
  414. ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(100, {}),
  415. MakeDataDescriptor(201, {3}),
  416. context.get()));
  417. std::string after_transformation = R"(
  418. OpCapability Shader
  419. %1 = OpExtInstImport "GLSL.std.450"
  420. OpMemoryModel Logical GLSL450
  421. OpEntryPoint Fragment %4 "main"
  422. OpExecutionMode %4 OriginUpperLeft
  423. OpSource ESSL 310
  424. OpName %4 "main"
  425. OpName %9 "v1"
  426. OpName %12 "v2"
  427. OpName %14 "v3"
  428. OpName %19 "v4"
  429. OpName %26 "v5"
  430. OpName %29 "v6"
  431. OpName %34 "m34"
  432. OpName %37 "m43"
  433. OpName %43 "vecs"
  434. %2 = OpTypeVoid
  435. %3 = OpTypeFunction %2
  436. %6 = OpTypeFloat 32
  437. %7 = OpTypeVector %6 3
  438. %8 = OpTypePointer Function %7
  439. %10 = OpConstant %6 1
  440. %11 = OpConstantComposite %7 %10 %10 %10
  441. %17 = OpTypeVector %6 4
  442. %18 = OpTypePointer Function %17
  443. %21 = OpConstant %6 2
  444. %32 = OpTypeMatrix %17 3
  445. %33 = OpTypePointer Private %32
  446. %34 = OpVariable %33 Private
  447. %35 = OpTypeMatrix %7 4
  448. %36 = OpTypePointer Private %35
  449. %37 = OpVariable %36 Private
  450. %38 = OpTypeVector %6 2
  451. %39 = OpTypeInt 32 0
  452. %40 = OpConstant %39 3
  453. %41 = OpTypeArray %38 %40
  454. %42 = OpTypePointer Private %41
  455. %43 = OpVariable %42 Private
  456. %100 = OpUndef %7
  457. %101 = OpUndef %17
  458. %4 = OpFunction %2 None %3
  459. %5 = OpLabel
  460. %9 = OpVariable %8 Function
  461. %12 = OpVariable %8 Function
  462. %14 = OpVariable %8 Function
  463. %19 = OpVariable %18 Function
  464. %26 = OpVariable %18 Function
  465. %29 = OpVariable %18 Function
  466. OpStore %9 %11
  467. %13 = OpLoad %7 %9
  468. OpStore %12 %13
  469. %15 = OpLoad %7 %12
  470. %16 = OpVectorShuffle %7 %15 %15 2 1 0
  471. OpStore %14 %16
  472. %20 = OpLoad %7 %14
  473. %22 = OpCompositeExtract %6 %20 0
  474. %23 = OpCompositeExtract %6 %20 1
  475. %24 = OpCompositeExtract %6 %20 2
  476. %25 = OpCompositeConstruct %17 %22 %23 %24 %21
  477. OpStore %19 %25
  478. %27 = OpLoad %17 %19
  479. %28 = OpVectorShuffle %17 %27 %27 3 2 1 0
  480. OpStore %26 %28
  481. %30 = OpLoad %7 %9
  482. %31 = OpVectorShuffle %17 %30 %30 0 0 1 1
  483. %201 = OpCompositeConstruct %35 %11 %13 %16 %100
  484. OpStore %29 %31
  485. %200 = OpCompositeConstruct %32 %25 %28 %31
  486. OpReturn
  487. OpFunctionEnd
  488. )";
  489. ASSERT_TRUE(IsEqual(env, after_transformation, context.get()));
  490. }
  491. TEST(TransformationCompositeConstructTest, ConstructStructs) {
  492. std::string shader = R"(
  493. OpCapability Shader
  494. %1 = OpExtInstImport "GLSL.std.450"
  495. OpMemoryModel Logical GLSL450
  496. OpEntryPoint Fragment %4 "main"
  497. OpExecutionMode %4 OriginUpperLeft
  498. OpSource ESSL 310
  499. OpName %4 "main"
  500. OpName %9 "Inner"
  501. OpMemberName %9 0 "a"
  502. OpMemberName %9 1 "b"
  503. OpName %11 "i1"
  504. OpName %22 "i2"
  505. OpName %33 "Outer"
  506. OpMemberName %33 0 "c"
  507. OpMemberName %33 1 "d"
  508. OpMemberName %33 2 "e"
  509. OpName %35 "o"
  510. %2 = OpTypeVoid
  511. %3 = OpTypeFunction %2
  512. %6 = OpTypeFloat 32
  513. %7 = OpTypeVector %6 2
  514. %8 = OpTypeInt 32 1
  515. %9 = OpTypeStruct %7 %8
  516. %10 = OpTypePointer Function %9
  517. %12 = OpConstant %8 0
  518. %13 = OpConstant %6 2
  519. %14 = OpTypeInt 32 0
  520. %15 = OpConstant %14 0
  521. %16 = OpTypePointer Function %6
  522. %18 = OpConstant %8 1
  523. %19 = OpConstant %8 3
  524. %20 = OpTypePointer Function %8
  525. %23 = OpTypePointer Function %7
  526. %31 = OpConstant %14 2
  527. %32 = OpTypeArray %9 %31
  528. %33 = OpTypeStruct %32 %9 %6
  529. %34 = OpTypePointer Function %33
  530. %36 = OpConstant %6 1
  531. %37 = OpConstantComposite %7 %36 %13
  532. %38 = OpConstant %8 2
  533. %39 = OpConstantComposite %9 %37 %38
  534. %40 = OpConstant %6 3
  535. %41 = OpConstant %6 4
  536. %42 = OpConstantComposite %7 %40 %41
  537. %56 = OpConstant %6 5
  538. %100 = OpUndef %9
  539. %4 = OpFunction %2 None %3
  540. %5 = OpLabel
  541. %11 = OpVariable %10 Function
  542. %22 = OpVariable %10 Function
  543. %35 = OpVariable %34 Function
  544. %17 = OpAccessChain %16 %11 %12 %15
  545. OpStore %17 %13
  546. %21 = OpAccessChain %20 %11 %18
  547. OpStore %21 %19
  548. %24 = OpAccessChain %23 %11 %12
  549. %25 = OpLoad %7 %24
  550. %26 = OpAccessChain %23 %22 %12
  551. OpStore %26 %25
  552. %27 = OpAccessChain %20 %11 %18
  553. %28 = OpLoad %8 %27
  554. %29 = OpIAdd %8 %28 %18
  555. %30 = OpAccessChain %20 %22 %18
  556. OpStore %30 %29
  557. %43 = OpAccessChain %20 %11 %18
  558. %44 = OpLoad %8 %43
  559. %45 = OpCompositeConstruct %9 %42 %44
  560. %46 = OpCompositeConstruct %32 %39 %45
  561. %47 = OpLoad %9 %22
  562. %48 = OpCompositeConstruct %33 %46 %47 %40
  563. OpStore %35 %48
  564. %49 = OpLoad %9 %11
  565. %50 = OpAccessChain %10 %35 %12 %12
  566. OpStore %50 %49
  567. %51 = OpLoad %9 %22
  568. %52 = OpAccessChain %10 %35 %12 %18
  569. OpStore %52 %51
  570. %53 = OpAccessChain %10 %35 %12 %12
  571. %54 = OpLoad %9 %53
  572. %55 = OpAccessChain %10 %35 %18
  573. OpStore %55 %54
  574. %57 = OpAccessChain %16 %35 %38
  575. OpStore %57 %56
  576. OpReturn
  577. OpFunctionEnd
  578. )";
  579. const auto env = SPV_ENV_UNIVERSAL_1_3;
  580. const auto consumer = nullptr;
  581. const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
  582. ASSERT_TRUE(IsValid(env, context.get()));
  583. FactManager fact_manager;
  584. // make an Inner
  585. TransformationCompositeConstruct make_inner(
  586. 9, {25, 19}, MakeInstructionDescriptor(57, SpvOpAccessChain, 0), 200);
  587. // Bad: Too few fields to make the struct.
  588. TransformationCompositeConstruct make_inner_bad(
  589. 9, {25}, MakeInstructionDescriptor(57, SpvOpAccessChain, 0), 200);
  590. ASSERT_TRUE(make_inner.IsApplicable(context.get(), fact_manager));
  591. ASSERT_FALSE(make_inner_bad.IsApplicable(context.get(), fact_manager));
  592. make_inner.Apply(context.get(), &fact_manager);
  593. ASSERT_TRUE(IsValid(env, context.get()));
  594. ASSERT_TRUE(fact_manager.IsSynonymous(
  595. MakeDataDescriptor(25, {}), MakeDataDescriptor(200, {0}), context.get()));
  596. ASSERT_TRUE(fact_manager.IsSynonymous(
  597. MakeDataDescriptor(19, {}), MakeDataDescriptor(200, {1}), context.get()));
  598. // make an Outer
  599. TransformationCompositeConstruct make_outer(
  600. 33, {46, 200, 56}, MakeInstructionDescriptor(200, SpvOpAccessChain, 0),
  601. 201);
  602. // Bad: %200 is not available at the desired program point.
  603. TransformationCompositeConstruct make_outer_bad(
  604. 33, {46, 200, 56},
  605. MakeInstructionDescriptor(200, SpvOpCompositeConstruct, 0), 201);
  606. ASSERT_TRUE(make_outer.IsApplicable(context.get(), fact_manager));
  607. ASSERT_FALSE(make_outer_bad.IsApplicable(context.get(), fact_manager));
  608. make_outer.Apply(context.get(), &fact_manager);
  609. ASSERT_TRUE(IsValid(env, context.get()));
  610. ASSERT_TRUE(fact_manager.IsSynonymous(
  611. MakeDataDescriptor(46, {}), MakeDataDescriptor(201, {0}), context.get()));
  612. ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(200, {}),
  613. MakeDataDescriptor(201, {1}),
  614. context.get()));
  615. ASSERT_TRUE(fact_manager.IsSynonymous(
  616. MakeDataDescriptor(56, {}), MakeDataDescriptor(201, {2}), context.get()));
  617. std::string after_transformation = R"(
  618. OpCapability Shader
  619. %1 = OpExtInstImport "GLSL.std.450"
  620. OpMemoryModel Logical GLSL450
  621. OpEntryPoint Fragment %4 "main"
  622. OpExecutionMode %4 OriginUpperLeft
  623. OpSource ESSL 310
  624. OpName %4 "main"
  625. OpName %9 "Inner"
  626. OpMemberName %9 0 "a"
  627. OpMemberName %9 1 "b"
  628. OpName %11 "i1"
  629. OpName %22 "i2"
  630. OpName %33 "Outer"
  631. OpMemberName %33 0 "c"
  632. OpMemberName %33 1 "d"
  633. OpMemberName %33 2 "e"
  634. OpName %35 "o"
  635. %2 = OpTypeVoid
  636. %3 = OpTypeFunction %2
  637. %6 = OpTypeFloat 32
  638. %7 = OpTypeVector %6 2
  639. %8 = OpTypeInt 32 1
  640. %9 = OpTypeStruct %7 %8
  641. %10 = OpTypePointer Function %9
  642. %12 = OpConstant %8 0
  643. %13 = OpConstant %6 2
  644. %14 = OpTypeInt 32 0
  645. %15 = OpConstant %14 0
  646. %16 = OpTypePointer Function %6
  647. %18 = OpConstant %8 1
  648. %19 = OpConstant %8 3
  649. %20 = OpTypePointer Function %8
  650. %23 = OpTypePointer Function %7
  651. %31 = OpConstant %14 2
  652. %32 = OpTypeArray %9 %31
  653. %33 = OpTypeStruct %32 %9 %6
  654. %34 = OpTypePointer Function %33
  655. %36 = OpConstant %6 1
  656. %37 = OpConstantComposite %7 %36 %13
  657. %38 = OpConstant %8 2
  658. %39 = OpConstantComposite %9 %37 %38
  659. %40 = OpConstant %6 3
  660. %41 = OpConstant %6 4
  661. %42 = OpConstantComposite %7 %40 %41
  662. %56 = OpConstant %6 5
  663. %100 = OpUndef %9
  664. %4 = OpFunction %2 None %3
  665. %5 = OpLabel
  666. %11 = OpVariable %10 Function
  667. %22 = OpVariable %10 Function
  668. %35 = OpVariable %34 Function
  669. %17 = OpAccessChain %16 %11 %12 %15
  670. OpStore %17 %13
  671. %21 = OpAccessChain %20 %11 %18
  672. OpStore %21 %19
  673. %24 = OpAccessChain %23 %11 %12
  674. %25 = OpLoad %7 %24
  675. %26 = OpAccessChain %23 %22 %12
  676. OpStore %26 %25
  677. %27 = OpAccessChain %20 %11 %18
  678. %28 = OpLoad %8 %27
  679. %29 = OpIAdd %8 %28 %18
  680. %30 = OpAccessChain %20 %22 %18
  681. OpStore %30 %29
  682. %43 = OpAccessChain %20 %11 %18
  683. %44 = OpLoad %8 %43
  684. %45 = OpCompositeConstruct %9 %42 %44
  685. %46 = OpCompositeConstruct %32 %39 %45
  686. %47 = OpLoad %9 %22
  687. %48 = OpCompositeConstruct %33 %46 %47 %40
  688. OpStore %35 %48
  689. %49 = OpLoad %9 %11
  690. %50 = OpAccessChain %10 %35 %12 %12
  691. OpStore %50 %49
  692. %51 = OpLoad %9 %22
  693. %52 = OpAccessChain %10 %35 %12 %18
  694. OpStore %52 %51
  695. %53 = OpAccessChain %10 %35 %12 %12
  696. %54 = OpLoad %9 %53
  697. %55 = OpAccessChain %10 %35 %18
  698. OpStore %55 %54
  699. %200 = OpCompositeConstruct %9 %25 %19
  700. %201 = OpCompositeConstruct %33 %46 %200 %56
  701. %57 = OpAccessChain %16 %35 %38
  702. OpStore %57 %56
  703. OpReturn
  704. OpFunctionEnd
  705. )";
  706. ASSERT_TRUE(IsEqual(env, after_transformation, context.get()));
  707. }
  708. TEST(TransformationCompositeConstructTest, ConstructVectors) {
  709. std::string shader = R"(
  710. OpCapability Shader
  711. %1 = OpExtInstImport "GLSL.std.450"
  712. OpMemoryModel Logical GLSL450
  713. OpEntryPoint Fragment %4 "main"
  714. OpExecutionMode %4 OriginUpperLeft
  715. OpSource ESSL 310
  716. OpName %4 "main"
  717. OpName %9 "v2"
  718. OpName %27 "v3"
  719. OpName %46 "v4"
  720. OpName %53 "iv2"
  721. OpName %61 "uv3"
  722. OpName %72 "bv4"
  723. OpName %88 "uv2"
  724. OpName %95 "bv3"
  725. OpName %104 "bv2"
  726. OpName %116 "iv3"
  727. OpName %124 "iv4"
  728. OpName %133 "uv4"
  729. %2 = OpTypeVoid
  730. %3 = OpTypeFunction %2
  731. %6 = OpTypeFloat 32
  732. %7 = OpTypeVector %6 2
  733. %8 = OpTypePointer Function %7
  734. %10 = OpConstant %6 1
  735. %11 = OpConstant %6 2
  736. %12 = OpConstantComposite %7 %10 %11
  737. %13 = OpTypeInt 32 0
  738. %14 = OpConstant %13 0
  739. %15 = OpTypePointer Function %6
  740. %18 = OpConstant %13 1
  741. %21 = OpTypeBool
  742. %25 = OpTypeVector %6 3
  743. %26 = OpTypePointer Function %25
  744. %33 = OpConstant %6 3
  745. %34 = OpConstant %6 -0.756802499
  746. %38 = OpConstant %13 2
  747. %44 = OpTypeVector %6 4
  748. %45 = OpTypePointer Function %44
  749. %50 = OpTypeInt 32 1
  750. %51 = OpTypeVector %50 2
  751. %52 = OpTypePointer Function %51
  752. %57 = OpTypePointer Function %50
  753. %59 = OpTypeVector %13 3
  754. %60 = OpTypePointer Function %59
  755. %65 = OpConstant %13 3
  756. %67 = OpTypePointer Function %13
  757. %70 = OpTypeVector %21 4
  758. %71 = OpTypePointer Function %70
  759. %73 = OpConstantTrue %21
  760. %74 = OpTypePointer Function %21
  761. %86 = OpTypeVector %13 2
  762. %87 = OpTypePointer Function %86
  763. %93 = OpTypeVector %21 3
  764. %94 = OpTypePointer Function %93
  765. %102 = OpTypeVector %21 2
  766. %103 = OpTypePointer Function %102
  767. %111 = OpConstantFalse %21
  768. %114 = OpTypeVector %50 3
  769. %115 = OpTypePointer Function %114
  770. %117 = OpConstant %50 3
  771. %122 = OpTypeVector %50 4
  772. %123 = OpTypePointer Function %122
  773. %131 = OpTypeVector %13 4
  774. %132 = OpTypePointer Function %131
  775. %4 = OpFunction %2 None %3
  776. %5 = OpLabel
  777. %9 = OpVariable %8 Function
  778. %27 = OpVariable %26 Function
  779. %46 = OpVariable %45 Function
  780. %53 = OpVariable %52 Function
  781. %61 = OpVariable %60 Function
  782. %72 = OpVariable %71 Function
  783. %88 = OpVariable %87 Function
  784. %95 = OpVariable %94 Function
  785. %104 = OpVariable %103 Function
  786. %116 = OpVariable %115 Function
  787. %124 = OpVariable %123 Function
  788. %133 = OpVariable %132 Function
  789. OpStore %9 %12
  790. %16 = OpAccessChain %15 %9 %14
  791. %17 = OpLoad %6 %16
  792. %19 = OpAccessChain %15 %9 %18
  793. %20 = OpLoad %6 %19
  794. %22 = OpFOrdGreaterThan %21 %17 %20
  795. OpSelectionMerge %24 None
  796. OpBranchConditional %22 %23 %101
  797. %23 = OpLabel
  798. %28 = OpAccessChain %15 %9 %14
  799. %29 = OpLoad %6 %28
  800. %30 = OpAccessChain %15 %9 %18
  801. %31 = OpLoad %6 %30
  802. %32 = OpFAdd %6 %29 %31
  803. %35 = OpCompositeConstruct %25 %32 %33 %34
  804. OpStore %27 %35
  805. %36 = OpAccessChain %15 %27 %14
  806. %37 = OpLoad %6 %36
  807. %39 = OpAccessChain %15 %27 %38
  808. %40 = OpLoad %6 %39
  809. %41 = OpFOrdLessThan %21 %37 %40
  810. OpSelectionMerge %43 None
  811. OpBranchConditional %41 %42 %69
  812. %42 = OpLabel
  813. %47 = OpAccessChain %15 %9 %18
  814. %48 = OpLoad %6 %47
  815. %49 = OpAccessChain %15 %46 %14
  816. OpStore %49 %48
  817. %54 = OpAccessChain %15 %27 %38
  818. %55 = OpLoad %6 %54
  819. %56 = OpConvertFToS %50 %55
  820. %58 = OpAccessChain %57 %53 %14
  821. OpStore %58 %56
  822. %62 = OpAccessChain %15 %46 %14
  823. %63 = OpLoad %6 %62
  824. %64 = OpConvertFToU %13 %63
  825. %66 = OpIAdd %13 %64 %65
  826. %68 = OpAccessChain %67 %61 %14
  827. OpStore %68 %66
  828. OpBranch %43
  829. %69 = OpLabel
  830. %75 = OpAccessChain %74 %72 %14
  831. OpStore %75 %73
  832. %76 = OpAccessChain %74 %72 %14
  833. %77 = OpLoad %21 %76
  834. %78 = OpLogicalNot %21 %77
  835. %79 = OpAccessChain %74 %72 %18
  836. OpStore %79 %78
  837. %80 = OpAccessChain %74 %72 %14
  838. %81 = OpLoad %21 %80
  839. %82 = OpAccessChain %74 %72 %18
  840. %83 = OpLoad %21 %82
  841. %84 = OpLogicalAnd %21 %81 %83
  842. %85 = OpAccessChain %74 %72 %38
  843. OpStore %85 %84
  844. %89 = OpAccessChain %67 %88 %14
  845. %90 = OpLoad %13 %89
  846. %91 = OpINotEqual %21 %90 %14
  847. %92 = OpAccessChain %74 %72 %65
  848. OpStore %92 %91
  849. OpBranch %43
  850. %43 = OpLabel
  851. %96 = OpLoad %70 %72
  852. %97 = OpCompositeExtract %21 %96 0
  853. %98 = OpCompositeExtract %21 %96 1
  854. %99 = OpCompositeExtract %21 %96 2
  855. %100 = OpCompositeConstruct %93 %97 %98 %99
  856. OpStore %95 %100
  857. OpBranch %24
  858. %101 = OpLabel
  859. %105 = OpAccessChain %67 %88 %14
  860. %106 = OpLoad %13 %105
  861. %107 = OpINotEqual %21 %106 %14
  862. %108 = OpCompositeConstruct %102 %107 %107
  863. OpStore %104 %108
  864. OpBranch %24
  865. %24 = OpLabel
  866. %109 = OpAccessChain %74 %104 %18
  867. %110 = OpLoad %21 %109
  868. %112 = OpLogicalOr %21 %110 %111
  869. %113 = OpAccessChain %74 %104 %14
  870. OpStore %113 %112
  871. %118 = OpAccessChain %57 %116 %14
  872. OpStore %118 %117
  873. %119 = OpAccessChain %57 %116 %14
  874. %120 = OpLoad %50 %119
  875. %121 = OpAccessChain %57 %53 %18
  876. OpStore %121 %120
  877. %125 = OpAccessChain %57 %116 %14
  878. %126 = OpLoad %50 %125
  879. %127 = OpAccessChain %57 %53 %18
  880. %128 = OpLoad %50 %127
  881. %129 = OpIAdd %50 %126 %128
  882. %130 = OpAccessChain %57 %124 %65
  883. OpStore %130 %129
  884. %134 = OpAccessChain %57 %116 %14
  885. %135 = OpLoad %50 %134
  886. %136 = OpBitcast %13 %135
  887. %137 = OpAccessChain %67 %133 %14
  888. OpStore %137 %136
  889. OpReturn
  890. OpFunctionEnd
  891. )";
  892. const auto env = SPV_ENV_UNIVERSAL_1_3;
  893. const auto consumer = nullptr;
  894. const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
  895. ASSERT_TRUE(IsValid(env, context.get()));
  896. FactManager fact_manager;
  897. TransformationCompositeConstruct make_vec2(
  898. 7, {17, 11}, MakeInstructionDescriptor(100, SpvOpStore, 0), 200);
  899. // Bad: not enough data for a vec2
  900. TransformationCompositeConstruct make_vec2_bad(
  901. 7, {11}, MakeInstructionDescriptor(100, SpvOpStore, 0), 200);
  902. ASSERT_TRUE(make_vec2.IsApplicable(context.get(), fact_manager));
  903. ASSERT_FALSE(make_vec2_bad.IsApplicable(context.get(), fact_manager));
  904. make_vec2.Apply(context.get(), &fact_manager);
  905. ASSERT_TRUE(IsValid(env, context.get()));
  906. ASSERT_TRUE(fact_manager.IsSynonymous(
  907. MakeDataDescriptor(17, {}), MakeDataDescriptor(200, {0}), context.get()));
  908. ASSERT_TRUE(fact_manager.IsSynonymous(
  909. MakeDataDescriptor(11, {}), MakeDataDescriptor(200, {1}), context.get()));
  910. TransformationCompositeConstruct make_vec3(
  911. 25, {12, 32}, MakeInstructionDescriptor(35, SpvOpCompositeConstruct, 0),
  912. 201);
  913. // Bad: too much data for a vec3
  914. TransformationCompositeConstruct make_vec3_bad(
  915. 25, {12, 32, 32},
  916. MakeInstructionDescriptor(35, SpvOpCompositeConstruct, 0), 201);
  917. ASSERT_TRUE(make_vec3.IsApplicable(context.get(), fact_manager));
  918. ASSERT_FALSE(make_vec3_bad.IsApplicable(context.get(), fact_manager));
  919. make_vec3.Apply(context.get(), &fact_manager);
  920. ASSERT_TRUE(IsValid(env, context.get()));
  921. ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(12, {0}),
  922. MakeDataDescriptor(201, {0}),
  923. context.get()));
  924. ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(12, {1}),
  925. MakeDataDescriptor(201, {1}),
  926. context.get()));
  927. ASSERT_TRUE(fact_manager.IsSynonymous(
  928. MakeDataDescriptor(32, {}), MakeDataDescriptor(201, {2}), context.get()));
  929. TransformationCompositeConstruct make_vec4(
  930. 44, {32, 32, 10, 11}, MakeInstructionDescriptor(75, SpvOpAccessChain, 0),
  931. 202);
  932. // Bad: id 48 is not available at the insertion points
  933. TransformationCompositeConstruct make_vec4_bad(
  934. 44, {48, 32, 10, 11}, MakeInstructionDescriptor(75, SpvOpAccessChain, 0),
  935. 202);
  936. ASSERT_TRUE(make_vec4.IsApplicable(context.get(), fact_manager));
  937. ASSERT_FALSE(make_vec4_bad.IsApplicable(context.get(), fact_manager));
  938. make_vec4.Apply(context.get(), &fact_manager);
  939. ASSERT_TRUE(IsValid(env, context.get()));
  940. ASSERT_TRUE(fact_manager.IsSynonymous(
  941. MakeDataDescriptor(32, {}), MakeDataDescriptor(202, {0}), context.get()));
  942. ASSERT_TRUE(fact_manager.IsSynonymous(
  943. MakeDataDescriptor(32, {}), MakeDataDescriptor(202, {1}), context.get()));
  944. ASSERT_TRUE(fact_manager.IsSynonymous(
  945. MakeDataDescriptor(10, {}), MakeDataDescriptor(202, {2}), context.get()));
  946. ASSERT_TRUE(fact_manager.IsSynonymous(
  947. MakeDataDescriptor(11, {}), MakeDataDescriptor(202, {3}), context.get()));
  948. TransformationCompositeConstruct make_ivec2(
  949. 51, {126, 120}, MakeInstructionDescriptor(128, SpvOpLoad, 0), 203);
  950. // Bad: if 128 is not available at the instruction that defines 128
  951. TransformationCompositeConstruct make_ivec2_bad(
  952. 51, {128, 120}, MakeInstructionDescriptor(128, SpvOpLoad, 0), 203);
  953. ASSERT_TRUE(make_ivec2.IsApplicable(context.get(), fact_manager));
  954. ASSERT_FALSE(make_ivec2_bad.IsApplicable(context.get(), fact_manager));
  955. make_ivec2.Apply(context.get(), &fact_manager);
  956. ASSERT_TRUE(IsValid(env, context.get()));
  957. ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(126, {}),
  958. MakeDataDescriptor(203, {0}),
  959. context.get()));
  960. ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(120, {}),
  961. MakeDataDescriptor(203, {1}),
  962. context.get()));
  963. TransformationCompositeConstruct make_ivec3(
  964. 114, {56, 117, 56}, MakeInstructionDescriptor(66, SpvOpAccessChain, 0),
  965. 204);
  966. // Bad because 1300 is not an id
  967. TransformationCompositeConstruct make_ivec3_bad(
  968. 114, {56, 117, 1300}, MakeInstructionDescriptor(66, SpvOpAccessChain, 0),
  969. 204);
  970. ASSERT_TRUE(make_ivec3.IsApplicable(context.get(), fact_manager));
  971. ASSERT_FALSE(make_ivec3_bad.IsApplicable(context.get(), fact_manager));
  972. make_ivec3.Apply(context.get(), &fact_manager);
  973. ASSERT_TRUE(IsValid(env, context.get()));
  974. ASSERT_TRUE(fact_manager.IsSynonymous(
  975. MakeDataDescriptor(56, {}), MakeDataDescriptor(204, {0}), context.get()));
  976. ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(117, {}),
  977. MakeDataDescriptor(204, {1}),
  978. context.get()));
  979. ASSERT_TRUE(fact_manager.IsSynonymous(
  980. MakeDataDescriptor(56, {}), MakeDataDescriptor(204, {2}), context.get()));
  981. TransformationCompositeConstruct make_ivec4(
  982. 122, {56, 117, 117, 117}, MakeInstructionDescriptor(66, SpvOpIAdd, 0),
  983. 205);
  984. // Bad because 86 is the wrong type.
  985. TransformationCompositeConstruct make_ivec4_bad(
  986. 86, {56, 117, 117, 117}, MakeInstructionDescriptor(66, SpvOpIAdd, 0),
  987. 205);
  988. ASSERT_TRUE(make_ivec4.IsApplicable(context.get(), fact_manager));
  989. ASSERT_FALSE(make_ivec4_bad.IsApplicable(context.get(), fact_manager));
  990. make_ivec4.Apply(context.get(), &fact_manager);
  991. ASSERT_TRUE(IsValid(env, context.get()));
  992. ASSERT_TRUE(fact_manager.IsSynonymous(
  993. MakeDataDescriptor(56, {}), MakeDataDescriptor(205, {0}), context.get()));
  994. ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(117, {}),
  995. MakeDataDescriptor(205, {1}),
  996. context.get()));
  997. ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(117, {}),
  998. MakeDataDescriptor(205, {2}),
  999. context.get()));
  1000. ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(117, {}),
  1001. MakeDataDescriptor(205, {3}),
  1002. context.get()));
  1003. TransformationCompositeConstruct make_uvec2(
  1004. 86, {18, 38}, MakeInstructionDescriptor(133, SpvOpAccessChain, 0), 206);
  1005. TransformationCompositeConstruct make_uvec2_bad(
  1006. 86, {18, 38}, MakeInstructionDescriptor(133, SpvOpAccessChain, 200), 206);
  1007. ASSERT_TRUE(make_uvec2.IsApplicable(context.get(), fact_manager));
  1008. ASSERT_FALSE(make_uvec2_bad.IsApplicable(context.get(), fact_manager));
  1009. make_uvec2.Apply(context.get(), &fact_manager);
  1010. ASSERT_TRUE(IsValid(env, context.get()));
  1011. ASSERT_TRUE(fact_manager.IsSynonymous(
  1012. MakeDataDescriptor(18, {}), MakeDataDescriptor(206, {0}), context.get()));
  1013. ASSERT_TRUE(fact_manager.IsSynonymous(
  1014. MakeDataDescriptor(38, {}), MakeDataDescriptor(206, {1}), context.get()));
  1015. TransformationCompositeConstruct make_uvec3(
  1016. 59, {14, 18, 136}, MakeInstructionDescriptor(137, SpvOpReturn, 0), 207);
  1017. // Bad because 1300 is not an id
  1018. TransformationCompositeConstruct make_uvec3_bad(
  1019. 59, {14, 18, 1300}, MakeInstructionDescriptor(137, SpvOpReturn, 0), 207);
  1020. ASSERT_TRUE(make_uvec3.IsApplicable(context.get(), fact_manager));
  1021. ASSERT_FALSE(make_uvec3_bad.IsApplicable(context.get(), fact_manager));
  1022. make_uvec3.Apply(context.get(), &fact_manager);
  1023. ASSERT_TRUE(IsValid(env, context.get()));
  1024. ASSERT_TRUE(fact_manager.IsSynonymous(
  1025. MakeDataDescriptor(14, {}), MakeDataDescriptor(207, {0}), context.get()));
  1026. ASSERT_TRUE(fact_manager.IsSynonymous(
  1027. MakeDataDescriptor(18, {}), MakeDataDescriptor(207, {1}), context.get()));
  1028. ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(136, {}),
  1029. MakeDataDescriptor(207, {2}),
  1030. context.get()));
  1031. TransformationCompositeConstruct make_uvec4(
  1032. 131, {14, 18, 136, 136},
  1033. MakeInstructionDescriptor(137, SpvOpAccessChain, 0), 208);
  1034. // Bad because 86 is the wrong type.
  1035. TransformationCompositeConstruct make_uvec4_bad(
  1036. 86, {14, 18, 136, 136},
  1037. MakeInstructionDescriptor(137, SpvOpAccessChain, 0), 208);
  1038. ASSERT_TRUE(make_uvec4.IsApplicable(context.get(), fact_manager));
  1039. ASSERT_FALSE(make_uvec4_bad.IsApplicable(context.get(), fact_manager));
  1040. make_uvec4.Apply(context.get(), &fact_manager);
  1041. ASSERT_TRUE(IsValid(env, context.get()));
  1042. ASSERT_TRUE(fact_manager.IsSynonymous(
  1043. MakeDataDescriptor(14, {}), MakeDataDescriptor(208, {0}), context.get()));
  1044. ASSERT_TRUE(fact_manager.IsSynonymous(
  1045. MakeDataDescriptor(18, {}), MakeDataDescriptor(208, {1}), context.get()));
  1046. ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(136, {}),
  1047. MakeDataDescriptor(208, {2}),
  1048. context.get()));
  1049. ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(136, {}),
  1050. MakeDataDescriptor(208, {3}),
  1051. context.get()));
  1052. TransformationCompositeConstruct make_bvec2(
  1053. 102,
  1054. {
  1055. 111,
  1056. 41,
  1057. },
  1058. MakeInstructionDescriptor(75, SpvOpAccessChain, 0), 209);
  1059. // Bad because 0 is not a valid base instruction id
  1060. TransformationCompositeConstruct make_bvec2_bad(
  1061. 102,
  1062. {
  1063. 111,
  1064. 41,
  1065. },
  1066. MakeInstructionDescriptor(0, SpvOpExtInstImport, 0), 209);
  1067. ASSERT_TRUE(make_bvec2.IsApplicable(context.get(), fact_manager));
  1068. ASSERT_FALSE(make_bvec2_bad.IsApplicable(context.get(), fact_manager));
  1069. make_bvec2.Apply(context.get(), &fact_manager);
  1070. ASSERT_TRUE(IsValid(env, context.get()));
  1071. ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(111, {}),
  1072. MakeDataDescriptor(209, {0}),
  1073. context.get()));
  1074. ASSERT_TRUE(fact_manager.IsSynonymous(
  1075. MakeDataDescriptor(41, {}), MakeDataDescriptor(209, {1}), context.get()));
  1076. TransformationCompositeConstruct make_bvec3(
  1077. 93, {108, 73}, MakeInstructionDescriptor(108, SpvOpStore, 0), 210);
  1078. // Bad because there are too many components for a bvec3
  1079. TransformationCompositeConstruct make_bvec3_bad(
  1080. 93, {108, 108}, MakeInstructionDescriptor(108, SpvOpStore, 0), 210);
  1081. ASSERT_TRUE(make_bvec3.IsApplicable(context.get(), fact_manager));
  1082. ASSERT_FALSE(make_bvec3_bad.IsApplicable(context.get(), fact_manager));
  1083. make_bvec3.Apply(context.get(), &fact_manager);
  1084. ASSERT_TRUE(IsValid(env, context.get()));
  1085. ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(108, {0}),
  1086. MakeDataDescriptor(210, {0}),
  1087. context.get()));
  1088. ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(108, {1}),
  1089. MakeDataDescriptor(210, {1}),
  1090. context.get()));
  1091. ASSERT_TRUE(fact_manager.IsSynonymous(
  1092. MakeDataDescriptor(73, {}), MakeDataDescriptor(210, {2}), context.get()));
  1093. TransformationCompositeConstruct make_bvec4(
  1094. 70, {108, 108}, MakeInstructionDescriptor(108, SpvOpBranch, 0), 211);
  1095. // Bad because 21 is a type, not a result id
  1096. TransformationCompositeConstruct make_bvec4_bad(
  1097. 70, {21, 108}, MakeInstructionDescriptor(108, SpvOpBranch, 0), 211);
  1098. ASSERT_TRUE(make_bvec4.IsApplicable(context.get(), fact_manager));
  1099. ASSERT_FALSE(make_bvec4_bad.IsApplicable(context.get(), fact_manager));
  1100. make_bvec4.Apply(context.get(), &fact_manager);
  1101. ASSERT_TRUE(IsValid(env, context.get()));
  1102. ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(108, {0}),
  1103. MakeDataDescriptor(211, {0}),
  1104. context.get()));
  1105. ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(108, {1}),
  1106. MakeDataDescriptor(211, {1}),
  1107. context.get()));
  1108. ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(108, {0}),
  1109. MakeDataDescriptor(211, {2}),
  1110. context.get()));
  1111. ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(108, {1}),
  1112. MakeDataDescriptor(211, {3}),
  1113. context.get()));
  1114. std::string after_transformation = R"(
  1115. OpCapability Shader
  1116. %1 = OpExtInstImport "GLSL.std.450"
  1117. OpMemoryModel Logical GLSL450
  1118. OpEntryPoint Fragment %4 "main"
  1119. OpExecutionMode %4 OriginUpperLeft
  1120. OpSource ESSL 310
  1121. OpName %4 "main"
  1122. OpName %9 "v2"
  1123. OpName %27 "v3"
  1124. OpName %46 "v4"
  1125. OpName %53 "iv2"
  1126. OpName %61 "uv3"
  1127. OpName %72 "bv4"
  1128. OpName %88 "uv2"
  1129. OpName %95 "bv3"
  1130. OpName %104 "bv2"
  1131. OpName %116 "iv3"
  1132. OpName %124 "iv4"
  1133. OpName %133 "uv4"
  1134. %2 = OpTypeVoid
  1135. %3 = OpTypeFunction %2
  1136. %6 = OpTypeFloat 32
  1137. %7 = OpTypeVector %6 2
  1138. %8 = OpTypePointer Function %7
  1139. %10 = OpConstant %6 1
  1140. %11 = OpConstant %6 2
  1141. %12 = OpConstantComposite %7 %10 %11
  1142. %13 = OpTypeInt 32 0
  1143. %14 = OpConstant %13 0
  1144. %15 = OpTypePointer Function %6
  1145. %18 = OpConstant %13 1
  1146. %21 = OpTypeBool
  1147. %25 = OpTypeVector %6 3
  1148. %26 = OpTypePointer Function %25
  1149. %33 = OpConstant %6 3
  1150. %34 = OpConstant %6 -0.756802499
  1151. %38 = OpConstant %13 2
  1152. %44 = OpTypeVector %6 4
  1153. %45 = OpTypePointer Function %44
  1154. %50 = OpTypeInt 32 1
  1155. %51 = OpTypeVector %50 2
  1156. %52 = OpTypePointer Function %51
  1157. %57 = OpTypePointer Function %50
  1158. %59 = OpTypeVector %13 3
  1159. %60 = OpTypePointer Function %59
  1160. %65 = OpConstant %13 3
  1161. %67 = OpTypePointer Function %13
  1162. %70 = OpTypeVector %21 4
  1163. %71 = OpTypePointer Function %70
  1164. %73 = OpConstantTrue %21
  1165. %74 = OpTypePointer Function %21
  1166. %86 = OpTypeVector %13 2
  1167. %87 = OpTypePointer Function %86
  1168. %93 = OpTypeVector %21 3
  1169. %94 = OpTypePointer Function %93
  1170. %102 = OpTypeVector %21 2
  1171. %103 = OpTypePointer Function %102
  1172. %111 = OpConstantFalse %21
  1173. %114 = OpTypeVector %50 3
  1174. %115 = OpTypePointer Function %114
  1175. %117 = OpConstant %50 3
  1176. %122 = OpTypeVector %50 4
  1177. %123 = OpTypePointer Function %122
  1178. %131 = OpTypeVector %13 4
  1179. %132 = OpTypePointer Function %131
  1180. %4 = OpFunction %2 None %3
  1181. %5 = OpLabel
  1182. %9 = OpVariable %8 Function
  1183. %27 = OpVariable %26 Function
  1184. %46 = OpVariable %45 Function
  1185. %53 = OpVariable %52 Function
  1186. %61 = OpVariable %60 Function
  1187. %72 = OpVariable %71 Function
  1188. %88 = OpVariable %87 Function
  1189. %95 = OpVariable %94 Function
  1190. %104 = OpVariable %103 Function
  1191. %116 = OpVariable %115 Function
  1192. %124 = OpVariable %123 Function
  1193. %133 = OpVariable %132 Function
  1194. OpStore %9 %12
  1195. %206 = OpCompositeConstruct %86 %18 %38
  1196. %16 = OpAccessChain %15 %9 %14
  1197. %17 = OpLoad %6 %16
  1198. %19 = OpAccessChain %15 %9 %18
  1199. %20 = OpLoad %6 %19
  1200. %22 = OpFOrdGreaterThan %21 %17 %20
  1201. OpSelectionMerge %24 None
  1202. OpBranchConditional %22 %23 %101
  1203. %23 = OpLabel
  1204. %28 = OpAccessChain %15 %9 %14
  1205. %29 = OpLoad %6 %28
  1206. %30 = OpAccessChain %15 %9 %18
  1207. %31 = OpLoad %6 %30
  1208. %32 = OpFAdd %6 %29 %31
  1209. %201 = OpCompositeConstruct %25 %12 %32
  1210. %35 = OpCompositeConstruct %25 %32 %33 %34
  1211. OpStore %27 %35
  1212. %36 = OpAccessChain %15 %27 %14
  1213. %37 = OpLoad %6 %36
  1214. %39 = OpAccessChain %15 %27 %38
  1215. %40 = OpLoad %6 %39
  1216. %41 = OpFOrdLessThan %21 %37 %40
  1217. OpSelectionMerge %43 None
  1218. OpBranchConditional %41 %42 %69
  1219. %42 = OpLabel
  1220. %47 = OpAccessChain %15 %9 %18
  1221. %48 = OpLoad %6 %47
  1222. %49 = OpAccessChain %15 %46 %14
  1223. OpStore %49 %48
  1224. %54 = OpAccessChain %15 %27 %38
  1225. %55 = OpLoad %6 %54
  1226. %56 = OpConvertFToS %50 %55
  1227. %58 = OpAccessChain %57 %53 %14
  1228. OpStore %58 %56
  1229. %62 = OpAccessChain %15 %46 %14
  1230. %63 = OpLoad %6 %62
  1231. %64 = OpConvertFToU %13 %63
  1232. %205 = OpCompositeConstruct %122 %56 %117 %117 %117
  1233. %66 = OpIAdd %13 %64 %65
  1234. %204 = OpCompositeConstruct %114 %56 %117 %56
  1235. %68 = OpAccessChain %67 %61 %14
  1236. OpStore %68 %66
  1237. OpBranch %43
  1238. %69 = OpLabel
  1239. %202 = OpCompositeConstruct %44 %32 %32 %10 %11
  1240. %209 = OpCompositeConstruct %102 %111 %41
  1241. %75 = OpAccessChain %74 %72 %14
  1242. OpStore %75 %73
  1243. %76 = OpAccessChain %74 %72 %14
  1244. %77 = OpLoad %21 %76
  1245. %78 = OpLogicalNot %21 %77
  1246. %79 = OpAccessChain %74 %72 %18
  1247. OpStore %79 %78
  1248. %80 = OpAccessChain %74 %72 %14
  1249. %81 = OpLoad %21 %80
  1250. %82 = OpAccessChain %74 %72 %18
  1251. %83 = OpLoad %21 %82
  1252. %84 = OpLogicalAnd %21 %81 %83
  1253. %85 = OpAccessChain %74 %72 %38
  1254. OpStore %85 %84
  1255. %89 = OpAccessChain %67 %88 %14
  1256. %90 = OpLoad %13 %89
  1257. %91 = OpINotEqual %21 %90 %14
  1258. %92 = OpAccessChain %74 %72 %65
  1259. OpStore %92 %91
  1260. OpBranch %43
  1261. %43 = OpLabel
  1262. %96 = OpLoad %70 %72
  1263. %97 = OpCompositeExtract %21 %96 0
  1264. %98 = OpCompositeExtract %21 %96 1
  1265. %99 = OpCompositeExtract %21 %96 2
  1266. %100 = OpCompositeConstruct %93 %97 %98 %99
  1267. %200 = OpCompositeConstruct %7 %17 %11
  1268. OpStore %95 %100
  1269. OpBranch %24
  1270. %101 = OpLabel
  1271. %105 = OpAccessChain %67 %88 %14
  1272. %106 = OpLoad %13 %105
  1273. %107 = OpINotEqual %21 %106 %14
  1274. %108 = OpCompositeConstruct %102 %107 %107
  1275. %210 = OpCompositeConstruct %93 %108 %73
  1276. OpStore %104 %108
  1277. %211 = OpCompositeConstruct %70 %108 %108
  1278. OpBranch %24
  1279. %24 = OpLabel
  1280. %109 = OpAccessChain %74 %104 %18
  1281. %110 = OpLoad %21 %109
  1282. %112 = OpLogicalOr %21 %110 %111
  1283. %113 = OpAccessChain %74 %104 %14
  1284. OpStore %113 %112
  1285. %118 = OpAccessChain %57 %116 %14
  1286. OpStore %118 %117
  1287. %119 = OpAccessChain %57 %116 %14
  1288. %120 = OpLoad %50 %119
  1289. %121 = OpAccessChain %57 %53 %18
  1290. OpStore %121 %120
  1291. %125 = OpAccessChain %57 %116 %14
  1292. %126 = OpLoad %50 %125
  1293. %127 = OpAccessChain %57 %53 %18
  1294. %203 = OpCompositeConstruct %51 %126 %120
  1295. %128 = OpLoad %50 %127
  1296. %129 = OpIAdd %50 %126 %128
  1297. %130 = OpAccessChain %57 %124 %65
  1298. OpStore %130 %129
  1299. %134 = OpAccessChain %57 %116 %14
  1300. %135 = OpLoad %50 %134
  1301. %136 = OpBitcast %13 %135
  1302. %208 = OpCompositeConstruct %131 %14 %18 %136 %136
  1303. %137 = OpAccessChain %67 %133 %14
  1304. OpStore %137 %136
  1305. %207 = OpCompositeConstruct %59 %14 %18 %136
  1306. OpReturn
  1307. OpFunctionEnd
  1308. )";
  1309. ASSERT_TRUE(IsEqual(env, after_transformation, context.get()));
  1310. }
  1311. } // namespace
  1312. } // namespace fuzz
  1313. } // namespace spvtools