fuzzer_shrinker_test.cpp 38 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162
  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 <functional>
  15. #include <vector>
  16. #include "gtest/gtest.h"
  17. #include "source/fuzz/fuzzer.h"
  18. #include "source/fuzz/fuzzer_util.h"
  19. #include "source/fuzz/pseudo_random_generator.h"
  20. #include "source/fuzz/shrinker.h"
  21. #include "source/fuzz/uniform_buffer_element_descriptor.h"
  22. #include "test/fuzz/fuzz_test_util.h"
  23. namespace spvtools {
  24. namespace fuzz {
  25. namespace {
  26. // The following SPIR-V came from this GLSL:
  27. //
  28. // #version 310 es
  29. //
  30. // void foo() {
  31. // int x;
  32. // x = 2;
  33. // for (int i = 0; i < 100; i++) {
  34. // x += i;
  35. // x = x * 2;
  36. // }
  37. // return;
  38. // }
  39. //
  40. // void main() {
  41. // foo();
  42. // for (int i = 0; i < 10; i++) {
  43. // int j = 20;
  44. // while(j > 0) {
  45. // foo();
  46. // j--;
  47. // }
  48. // do {
  49. // i++;
  50. // } while(i < 4);
  51. // }
  52. // }
  53. const std::string kTestShader1 = R"(
  54. OpCapability Shader
  55. %1 = OpExtInstImport "GLSL.std.450"
  56. OpMemoryModel Logical GLSL450
  57. OpEntryPoint Fragment %4 "main"
  58. OpExecutionMode %4 OriginUpperLeft
  59. OpSource ESSL 310
  60. OpName %4 "main"
  61. OpName %6 "foo("
  62. OpName %10 "x"
  63. OpName %12 "i"
  64. OpName %33 "i"
  65. OpName %42 "j"
  66. OpDecorate %10 RelaxedPrecision
  67. OpDecorate %12 RelaxedPrecision
  68. OpDecorate %19 RelaxedPrecision
  69. OpDecorate %23 RelaxedPrecision
  70. OpDecorate %24 RelaxedPrecision
  71. OpDecorate %25 RelaxedPrecision
  72. OpDecorate %26 RelaxedPrecision
  73. OpDecorate %27 RelaxedPrecision
  74. OpDecorate %28 RelaxedPrecision
  75. OpDecorate %30 RelaxedPrecision
  76. OpDecorate %33 RelaxedPrecision
  77. OpDecorate %39 RelaxedPrecision
  78. OpDecorate %42 RelaxedPrecision
  79. OpDecorate %49 RelaxedPrecision
  80. OpDecorate %52 RelaxedPrecision
  81. OpDecorate %53 RelaxedPrecision
  82. OpDecorate %58 RelaxedPrecision
  83. OpDecorate %59 RelaxedPrecision
  84. OpDecorate %60 RelaxedPrecision
  85. OpDecorate %63 RelaxedPrecision
  86. OpDecorate %64 RelaxedPrecision
  87. %2 = OpTypeVoid
  88. %3 = OpTypeFunction %2
  89. %8 = OpTypeInt 32 1
  90. %9 = OpTypePointer Function %8
  91. %11 = OpConstant %8 2
  92. %13 = OpConstant %8 0
  93. %20 = OpConstant %8 100
  94. %21 = OpTypeBool
  95. %29 = OpConstant %8 1
  96. %40 = OpConstant %8 10
  97. %43 = OpConstant %8 20
  98. %61 = OpConstant %8 4
  99. %4 = OpFunction %2 None %3
  100. %5 = OpLabel
  101. %33 = OpVariable %9 Function
  102. %42 = OpVariable %9 Function
  103. %32 = OpFunctionCall %2 %6
  104. OpStore %33 %13
  105. OpBranch %34
  106. %34 = OpLabel
  107. OpLoopMerge %36 %37 None
  108. OpBranch %38
  109. %38 = OpLabel
  110. %39 = OpLoad %8 %33
  111. %41 = OpSLessThan %21 %39 %40
  112. OpBranchConditional %41 %35 %36
  113. %35 = OpLabel
  114. OpStore %42 %43
  115. OpBranch %44
  116. %44 = OpLabel
  117. OpLoopMerge %46 %47 None
  118. OpBranch %48
  119. %48 = OpLabel
  120. %49 = OpLoad %8 %42
  121. %50 = OpSGreaterThan %21 %49 %13
  122. OpBranchConditional %50 %45 %46
  123. %45 = OpLabel
  124. %51 = OpFunctionCall %2 %6
  125. %52 = OpLoad %8 %42
  126. %53 = OpISub %8 %52 %29
  127. OpStore %42 %53
  128. OpBranch %47
  129. %47 = OpLabel
  130. OpBranch %44
  131. %46 = OpLabel
  132. OpBranch %54
  133. %54 = OpLabel
  134. OpLoopMerge %56 %57 None
  135. OpBranch %55
  136. %55 = OpLabel
  137. %58 = OpLoad %8 %33
  138. %59 = OpIAdd %8 %58 %29
  139. OpStore %33 %59
  140. OpBranch %57
  141. %57 = OpLabel
  142. %60 = OpLoad %8 %33
  143. %62 = OpSLessThan %21 %60 %61
  144. OpBranchConditional %62 %54 %56
  145. %56 = OpLabel
  146. OpBranch %37
  147. %37 = OpLabel
  148. %63 = OpLoad %8 %33
  149. %64 = OpIAdd %8 %63 %29
  150. OpStore %33 %64
  151. OpBranch %34
  152. %36 = OpLabel
  153. OpReturn
  154. OpFunctionEnd
  155. %6 = OpFunction %2 None %3
  156. %7 = OpLabel
  157. %10 = OpVariable %9 Function
  158. %12 = OpVariable %9 Function
  159. OpStore %10 %11
  160. OpStore %12 %13
  161. OpBranch %14
  162. %14 = OpLabel
  163. OpLoopMerge %16 %17 None
  164. OpBranch %18
  165. %18 = OpLabel
  166. %19 = OpLoad %8 %12
  167. %22 = OpSLessThan %21 %19 %20
  168. OpBranchConditional %22 %15 %16
  169. %15 = OpLabel
  170. %23 = OpLoad %8 %12
  171. %24 = OpLoad %8 %10
  172. %25 = OpIAdd %8 %24 %23
  173. OpStore %10 %25
  174. %26 = OpLoad %8 %10
  175. %27 = OpIMul %8 %26 %11
  176. OpStore %10 %27
  177. OpBranch %17
  178. %17 = OpLabel
  179. %28 = OpLoad %8 %12
  180. %30 = OpIAdd %8 %28 %29
  181. OpStore %12 %30
  182. OpBranch %14
  183. %16 = OpLabel
  184. OpReturn
  185. OpFunctionEnd
  186. )";
  187. // The following SPIR-V came from this GLSL, which was then optimized using
  188. // spirv-opt with the -O argument:
  189. //
  190. // #version 310 es
  191. //
  192. // precision highp float;
  193. //
  194. // layout(location = 0) out vec4 _GLF_color;
  195. //
  196. // layout(set = 0, binding = 0) uniform buf0 {
  197. // vec2 injectionSwitch;
  198. // };
  199. // layout(set = 0, binding = 1) uniform buf1 {
  200. // vec2 resolution;
  201. // };
  202. // bool checkSwap(float a, float b)
  203. // {
  204. // return gl_FragCoord.y < resolution.y / 2.0 ? a > b : a < b;
  205. // }
  206. // void main()
  207. // {
  208. // float data[10];
  209. // for(int i = 0; i < 10; i++)
  210. // {
  211. // data[i] = float(10 - i) * injectionSwitch.y;
  212. // }
  213. // for(int i = 0; i < 9; i++)
  214. // {
  215. // for(int j = 0; j < 10; j++)
  216. // {
  217. // if(j < i + 1)
  218. // {
  219. // continue;
  220. // }
  221. // bool doSwap = checkSwap(data[i], data[j]);
  222. // if(doSwap)
  223. // {
  224. // float temp = data[i];
  225. // data[i] = data[j];
  226. // data[j] = temp;
  227. // }
  228. // }
  229. // }
  230. // if(gl_FragCoord.x < resolution.x / 2.0)
  231. // {
  232. // _GLF_color = vec4(data[0] / 10.0, data[5] / 10.0, data[9] / 10.0, 1.0);
  233. // }
  234. // else
  235. // {
  236. // _GLF_color = vec4(data[5] / 10.0, data[9] / 10.0, data[0] / 10.0, 1.0);
  237. // }
  238. // }
  239. const std::string kTestShader2 = R"(
  240. OpCapability Shader
  241. %1 = OpExtInstImport "GLSL.std.450"
  242. OpMemoryModel Logical GLSL450
  243. OpEntryPoint Fragment %4 "main" %16 %139 %25 %68
  244. OpExecutionMode %4 OriginUpperLeft
  245. OpSource ESSL 310
  246. OpName %4 "main"
  247. OpName %16 "gl_FragCoord"
  248. OpName %23 "buf1"
  249. OpMemberName %23 0 "resolution"
  250. OpName %25 ""
  251. OpName %61 "data"
  252. OpName %66 "buf0"
  253. OpMemberName %66 0 "injectionSwitch"
  254. OpName %68 ""
  255. OpName %139 "_GLF_color"
  256. OpDecorate %16 BuiltIn FragCoord
  257. OpMemberDecorate %23 0 Offset 0
  258. OpDecorate %23 Block
  259. OpDecorate %25 DescriptorSet 0
  260. OpDecorate %25 Binding 1
  261. OpDecorate %64 RelaxedPrecision
  262. OpMemberDecorate %66 0 Offset 0
  263. OpDecorate %66 Block
  264. OpDecorate %68 DescriptorSet 0
  265. OpDecorate %68 Binding 0
  266. OpDecorate %75 RelaxedPrecision
  267. OpDecorate %95 RelaxedPrecision
  268. OpDecorate %126 RelaxedPrecision
  269. OpDecorate %128 RelaxedPrecision
  270. OpDecorate %139 Location 0
  271. OpDecorate %182 RelaxedPrecision
  272. OpDecorate %183 RelaxedPrecision
  273. OpDecorate %184 RelaxedPrecision
  274. %2 = OpTypeVoid
  275. %3 = OpTypeFunction %2
  276. %6 = OpTypeFloat 32
  277. %7 = OpTypePointer Function %6
  278. %8 = OpTypeBool
  279. %14 = OpTypeVector %6 4
  280. %15 = OpTypePointer Input %14
  281. %16 = OpVariable %15 Input
  282. %17 = OpTypeInt 32 0
  283. %18 = OpConstant %17 1
  284. %19 = OpTypePointer Input %6
  285. %22 = OpTypeVector %6 2
  286. %23 = OpTypeStruct %22
  287. %24 = OpTypePointer Uniform %23
  288. %25 = OpVariable %24 Uniform
  289. %26 = OpTypeInt 32 1
  290. %27 = OpConstant %26 0
  291. %28 = OpTypePointer Uniform %6
  292. %56 = OpConstant %26 10
  293. %58 = OpConstant %17 10
  294. %59 = OpTypeArray %6 %58
  295. %60 = OpTypePointer Function %59
  296. %66 = OpTypeStruct %22
  297. %67 = OpTypePointer Uniform %66
  298. %68 = OpVariable %67 Uniform
  299. %74 = OpConstant %26 1
  300. %83 = OpConstant %26 9
  301. %129 = OpConstant %17 0
  302. %138 = OpTypePointer Output %14
  303. %139 = OpVariable %138 Output
  304. %144 = OpConstant %26 5
  305. %151 = OpConstant %6 1
  306. %194 = OpConstant %6 0.5
  307. %195 = OpConstant %6 0.100000001
  308. %4 = OpFunction %2 None %3
  309. %5 = OpLabel
  310. %61 = OpVariable %60 Function
  311. OpBranch %50
  312. %50 = OpLabel
  313. %182 = OpPhi %26 %27 %5 %75 %51
  314. %57 = OpSLessThan %8 %182 %56
  315. OpLoopMerge %52 %51 None
  316. OpBranchConditional %57 %51 %52
  317. %51 = OpLabel
  318. %64 = OpISub %26 %56 %182
  319. %65 = OpConvertSToF %6 %64
  320. %69 = OpAccessChain %28 %68 %27 %18
  321. %70 = OpLoad %6 %69
  322. %71 = OpFMul %6 %65 %70
  323. %72 = OpAccessChain %7 %61 %182
  324. OpStore %72 %71
  325. %75 = OpIAdd %26 %182 %74
  326. OpBranch %50
  327. %52 = OpLabel
  328. OpBranch %77
  329. %77 = OpLabel
  330. %183 = OpPhi %26 %27 %52 %128 %88
  331. %84 = OpSLessThan %8 %183 %83
  332. OpLoopMerge %79 %88 None
  333. OpBranchConditional %84 %78 %79
  334. %78 = OpLabel
  335. OpBranch %86
  336. %86 = OpLabel
  337. %184 = OpPhi %26 %27 %78 %126 %89
  338. %92 = OpSLessThan %8 %184 %56
  339. OpLoopMerge %1000 %89 None
  340. OpBranchConditional %92 %87 %1000
  341. %87 = OpLabel
  342. %95 = OpIAdd %26 %183 %74
  343. %96 = OpSLessThan %8 %184 %95
  344. OpSelectionMerge %98 None
  345. OpBranchConditional %96 %97 %98
  346. %97 = OpLabel
  347. OpBranch %89
  348. %98 = OpLabel
  349. %104 = OpAccessChain %7 %61 %183
  350. %105 = OpLoad %6 %104
  351. %107 = OpAccessChain %7 %61 %184
  352. %108 = OpLoad %6 %107
  353. %166 = OpAccessChain %19 %16 %18
  354. %167 = OpLoad %6 %166
  355. %168 = OpAccessChain %28 %25 %27 %18
  356. %169 = OpLoad %6 %168
  357. %170 = OpFMul %6 %169 %194
  358. %171 = OpFOrdLessThan %8 %167 %170
  359. OpSelectionMerge %172 None
  360. OpBranchConditional %171 %173 %174
  361. %173 = OpLabel
  362. %177 = OpFOrdGreaterThan %8 %105 %108
  363. OpBranch %172
  364. %174 = OpLabel
  365. %180 = OpFOrdLessThan %8 %105 %108
  366. OpBranch %172
  367. %172 = OpLabel
  368. %186 = OpPhi %8 %177 %173 %180 %174
  369. OpSelectionMerge %112 None
  370. OpBranchConditional %186 %111 %112
  371. %111 = OpLabel
  372. %116 = OpLoad %6 %104
  373. %120 = OpLoad %6 %107
  374. OpStore %104 %120
  375. OpStore %107 %116
  376. OpBranch %112
  377. %112 = OpLabel
  378. OpBranch %89
  379. %89 = OpLabel
  380. %126 = OpIAdd %26 %184 %74
  381. OpBranch %86
  382. %1000 = OpLabel
  383. OpBranch %88
  384. %88 = OpLabel
  385. %128 = OpIAdd %26 %183 %74
  386. OpBranch %77
  387. %79 = OpLabel
  388. %130 = OpAccessChain %19 %16 %129
  389. %131 = OpLoad %6 %130
  390. %132 = OpAccessChain %28 %25 %27 %129
  391. %133 = OpLoad %6 %132
  392. %134 = OpFMul %6 %133 %194
  393. %135 = OpFOrdLessThan %8 %131 %134
  394. OpSelectionMerge %137 None
  395. OpBranchConditional %135 %136 %153
  396. %136 = OpLabel
  397. %140 = OpAccessChain %7 %61 %27
  398. %141 = OpLoad %6 %140
  399. %143 = OpFMul %6 %141 %195
  400. %145 = OpAccessChain %7 %61 %144
  401. %146 = OpLoad %6 %145
  402. %147 = OpFMul %6 %146 %195
  403. %148 = OpAccessChain %7 %61 %83
  404. %149 = OpLoad %6 %148
  405. %150 = OpFMul %6 %149 %195
  406. %152 = OpCompositeConstruct %14 %143 %147 %150 %151
  407. OpStore %139 %152
  408. OpBranch %137
  409. %153 = OpLabel
  410. %154 = OpAccessChain %7 %61 %144
  411. %155 = OpLoad %6 %154
  412. %156 = OpFMul %6 %155 %195
  413. %157 = OpAccessChain %7 %61 %83
  414. %158 = OpLoad %6 %157
  415. %159 = OpFMul %6 %158 %195
  416. %160 = OpAccessChain %7 %61 %27
  417. %161 = OpLoad %6 %160
  418. %162 = OpFMul %6 %161 %195
  419. %163 = OpCompositeConstruct %14 %156 %159 %162 %151
  420. OpStore %139 %163
  421. OpBranch %137
  422. %137 = OpLabel
  423. OpReturn
  424. OpFunctionEnd
  425. )";
  426. // The following SPIR-V came from this GLSL, which was then optimized using
  427. // spirv-opt with the -O argument:
  428. //
  429. // #version 310 es
  430. //
  431. // precision highp float;
  432. //
  433. // layout(location = 0) out vec4 _GLF_color;
  434. //
  435. // layout(set = 0, binding = 0) uniform buf0 {
  436. // vec2 resolution;
  437. // };
  438. // void main(void)
  439. // {
  440. // float A[50];
  441. // for(
  442. // int i = 0;
  443. // i < 200;
  444. // i ++
  445. // )
  446. // {
  447. // if(i >= int(resolution.x))
  448. // {
  449. // break;
  450. // }
  451. // if((4 * (i / 4)) == i)
  452. // {
  453. // A[i / 4] = float(i);
  454. // }
  455. // }
  456. // for(
  457. // int i = 0;
  458. // i < 50;
  459. // i ++
  460. // )
  461. // {
  462. // if(i < int(gl_FragCoord.x))
  463. // {
  464. // break;
  465. // }
  466. // if(i > 0)
  467. // {
  468. // A[i] += A[i - 1];
  469. // }
  470. // }
  471. // if(int(gl_FragCoord.x) < 20)
  472. // {
  473. // _GLF_color = vec4(A[0] / resolution.x, A[4] / resolution.y, 1.0, 1.0);
  474. // }
  475. // else
  476. // if(int(gl_FragCoord.x) < 40)
  477. // {
  478. // _GLF_color = vec4(A[5] / resolution.x, A[9] / resolution.y, 1.0, 1.0);
  479. // }
  480. // else
  481. // if(int(gl_FragCoord.x) < 60)
  482. // {
  483. // _GLF_color = vec4(A[10] / resolution.x, A[14] / resolution.y,
  484. // 1.0, 1.0);
  485. // }
  486. // else
  487. // if(int(gl_FragCoord.x) < 80)
  488. // {
  489. // _GLF_color = vec4(A[15] / resolution.x, A[19] / resolution.y,
  490. // 1.0, 1.0);
  491. // }
  492. // else
  493. // if(int(gl_FragCoord.x) < 100)
  494. // {
  495. // _GLF_color = vec4(A[20] / resolution.x, A[24] / resolution.y,
  496. // 1.0, 1.0);
  497. // }
  498. // else
  499. // if(int(gl_FragCoord.x) < 120)
  500. // {
  501. // _GLF_color = vec4(A[25] / resolution.x, A[29] / resolution.y,
  502. // 1.0, 1.0);
  503. // }
  504. // else
  505. // if(int(gl_FragCoord.x) < 140)
  506. // {
  507. // _GLF_color = vec4(A[30] / resolution.x, A[34] / resolution.y,
  508. // 1.0, 1.0);
  509. // }
  510. // else
  511. // if(int(gl_FragCoord.x) < 160)
  512. // {
  513. // _GLF_color = vec4(A[35] / resolution.x, A[39] /
  514. // resolution.y, 1.0, 1.0);
  515. // }
  516. // else
  517. // if(int(gl_FragCoord.x) < 180)
  518. // {
  519. // _GLF_color = vec4(A[40] / resolution.x, A[44] /
  520. // resolution.y, 1.0, 1.0);
  521. // }
  522. // else
  523. // if(int(gl_FragCoord.x) < 180)
  524. // {
  525. // _GLF_color = vec4(A[45] / resolution.x, A[49] /
  526. // resolution.y, 1.0, 1.0);
  527. // }
  528. // else
  529. // {
  530. // discard;
  531. // }
  532. // }
  533. const std::string kTestShader3 = R"(
  534. OpCapability Shader
  535. %1 = OpExtInstImport "GLSL.std.450"
  536. OpMemoryModel Logical GLSL450
  537. OpEntryPoint Fragment %4 "main" %68 %100 %24
  538. OpExecutionMode %4 OriginUpperLeft
  539. OpSource ESSL 310
  540. OpName %4 "main"
  541. OpName %22 "buf0"
  542. OpMemberName %22 0 "resolution"
  543. OpName %24 ""
  544. OpName %46 "A"
  545. OpName %68 "gl_FragCoord"
  546. OpName %100 "_GLF_color"
  547. OpMemberDecorate %22 0 Offset 0
  548. OpDecorate %22 Block
  549. OpDecorate %24 DescriptorSet 0
  550. OpDecorate %24 Binding 0
  551. OpDecorate %37 RelaxedPrecision
  552. OpDecorate %38 RelaxedPrecision
  553. OpDecorate %55 RelaxedPrecision
  554. OpDecorate %68 BuiltIn FragCoord
  555. OpDecorate %83 RelaxedPrecision
  556. OpDecorate %91 RelaxedPrecision
  557. OpDecorate %100 Location 0
  558. OpDecorate %302 RelaxedPrecision
  559. OpDecorate %304 RelaxedPrecision
  560. %2 = OpTypeVoid
  561. %3 = OpTypeFunction %2
  562. %6 = OpTypeInt 32 1
  563. %9 = OpConstant %6 0
  564. %16 = OpConstant %6 200
  565. %17 = OpTypeBool
  566. %20 = OpTypeFloat 32
  567. %21 = OpTypeVector %20 2
  568. %22 = OpTypeStruct %21
  569. %23 = OpTypePointer Uniform %22
  570. %24 = OpVariable %23 Uniform
  571. %25 = OpTypeInt 32 0
  572. %26 = OpConstant %25 0
  573. %27 = OpTypePointer Uniform %20
  574. %35 = OpConstant %6 4
  575. %43 = OpConstant %25 50
  576. %44 = OpTypeArray %20 %43
  577. %45 = OpTypePointer Function %44
  578. %51 = OpTypePointer Function %20
  579. %54 = OpConstant %6 1
  580. %63 = OpConstant %6 50
  581. %66 = OpTypeVector %20 4
  582. %67 = OpTypePointer Input %66
  583. %68 = OpVariable %67 Input
  584. %69 = OpTypePointer Input %20
  585. %95 = OpConstant %6 20
  586. %99 = OpTypePointer Output %66
  587. %100 = OpVariable %99 Output
  588. %108 = OpConstant %25 1
  589. %112 = OpConstant %20 1
  590. %118 = OpConstant %6 40
  591. %122 = OpConstant %6 5
  592. %128 = OpConstant %6 9
  593. %139 = OpConstant %6 60
  594. %143 = OpConstant %6 10
  595. %149 = OpConstant %6 14
  596. %160 = OpConstant %6 80
  597. %164 = OpConstant %6 15
  598. %170 = OpConstant %6 19
  599. %181 = OpConstant %6 100
  600. %190 = OpConstant %6 24
  601. %201 = OpConstant %6 120
  602. %205 = OpConstant %6 25
  603. %211 = OpConstant %6 29
  604. %222 = OpConstant %6 140
  605. %226 = OpConstant %6 30
  606. %232 = OpConstant %6 34
  607. %243 = OpConstant %6 160
  608. %247 = OpConstant %6 35
  609. %253 = OpConstant %6 39
  610. %264 = OpConstant %6 180
  611. %273 = OpConstant %6 44
  612. %287 = OpConstant %6 45
  613. %293 = OpConstant %6 49
  614. %4 = OpFunction %2 None %3
  615. %5 = OpLabel
  616. %46 = OpVariable %45 Function
  617. OpBranch %10
  618. %10 = OpLabel
  619. %302 = OpPhi %6 %9 %5 %55 %42
  620. %18 = OpSLessThan %17 %302 %16
  621. OpLoopMerge %12 %42 None
  622. OpBranchConditional %18 %11 %12
  623. %11 = OpLabel
  624. %28 = OpAccessChain %27 %24 %9 %26
  625. %29 = OpLoad %20 %28
  626. %30 = OpConvertFToS %6 %29
  627. %31 = OpSGreaterThanEqual %17 %302 %30
  628. OpSelectionMerge %33 None
  629. OpBranchConditional %31 %32 %33
  630. %32 = OpLabel
  631. OpBranch %12
  632. %33 = OpLabel
  633. %37 = OpSDiv %6 %302 %35
  634. %38 = OpIMul %6 %35 %37
  635. %40 = OpIEqual %17 %38 %302
  636. OpBranchConditional %40 %41 %42
  637. %41 = OpLabel
  638. %50 = OpConvertSToF %20 %302
  639. %52 = OpAccessChain %51 %46 %37
  640. OpStore %52 %50
  641. OpBranch %42
  642. %42 = OpLabel
  643. %55 = OpIAdd %6 %302 %54
  644. OpBranch %10
  645. %12 = OpLabel
  646. OpBranch %57
  647. %57 = OpLabel
  648. %304 = OpPhi %6 %9 %12 %91 %80
  649. %64 = OpSLessThan %17 %304 %63
  650. OpLoopMerge %59 %80 None
  651. OpBranchConditional %64 %58 %59
  652. %58 = OpLabel
  653. %70 = OpAccessChain %69 %68 %26
  654. %71 = OpLoad %20 %70
  655. %72 = OpConvertFToS %6 %71
  656. %73 = OpSLessThan %17 %304 %72
  657. OpSelectionMerge %75 None
  658. OpBranchConditional %73 %74 %75
  659. %74 = OpLabel
  660. OpBranch %59
  661. %75 = OpLabel
  662. %78 = OpSGreaterThan %17 %304 %9
  663. OpBranchConditional %78 %79 %80
  664. %79 = OpLabel
  665. %83 = OpISub %6 %304 %54
  666. %84 = OpAccessChain %51 %46 %83
  667. %85 = OpLoad %20 %84
  668. %86 = OpAccessChain %51 %46 %304
  669. %87 = OpLoad %20 %86
  670. %88 = OpFAdd %20 %87 %85
  671. OpStore %86 %88
  672. OpBranch %80
  673. %80 = OpLabel
  674. %91 = OpIAdd %6 %304 %54
  675. OpBranch %57
  676. %59 = OpLabel
  677. %92 = OpAccessChain %69 %68 %26
  678. %93 = OpLoad %20 %92
  679. %94 = OpConvertFToS %6 %93
  680. %96 = OpSLessThan %17 %94 %95
  681. OpSelectionMerge %98 None
  682. OpBranchConditional %96 %97 %114
  683. %97 = OpLabel
  684. %101 = OpAccessChain %51 %46 %9
  685. %102 = OpLoad %20 %101
  686. %103 = OpAccessChain %27 %24 %9 %26
  687. %104 = OpLoad %20 %103
  688. %105 = OpFDiv %20 %102 %104
  689. %106 = OpAccessChain %51 %46 %35
  690. %107 = OpLoad %20 %106
  691. %109 = OpAccessChain %27 %24 %9 %108
  692. %110 = OpLoad %20 %109
  693. %111 = OpFDiv %20 %107 %110
  694. %113 = OpCompositeConstruct %66 %105 %111 %112 %112
  695. OpStore %100 %113
  696. OpBranch %98
  697. %114 = OpLabel
  698. %119 = OpSLessThan %17 %94 %118
  699. OpSelectionMerge %121 None
  700. OpBranchConditional %119 %120 %135
  701. %120 = OpLabel
  702. %123 = OpAccessChain %51 %46 %122
  703. %124 = OpLoad %20 %123
  704. %125 = OpAccessChain %27 %24 %9 %26
  705. %126 = OpLoad %20 %125
  706. %127 = OpFDiv %20 %124 %126
  707. %129 = OpAccessChain %51 %46 %128
  708. %130 = OpLoad %20 %129
  709. %131 = OpAccessChain %27 %24 %9 %108
  710. %132 = OpLoad %20 %131
  711. %133 = OpFDiv %20 %130 %132
  712. %134 = OpCompositeConstruct %66 %127 %133 %112 %112
  713. OpStore %100 %134
  714. OpBranch %121
  715. %135 = OpLabel
  716. %140 = OpSLessThan %17 %94 %139
  717. OpSelectionMerge %142 None
  718. OpBranchConditional %140 %141 %156
  719. %141 = OpLabel
  720. %144 = OpAccessChain %51 %46 %143
  721. %145 = OpLoad %20 %144
  722. %146 = OpAccessChain %27 %24 %9 %26
  723. %147 = OpLoad %20 %146
  724. %148 = OpFDiv %20 %145 %147
  725. %150 = OpAccessChain %51 %46 %149
  726. %151 = OpLoad %20 %150
  727. %152 = OpAccessChain %27 %24 %9 %108
  728. %153 = OpLoad %20 %152
  729. %154 = OpFDiv %20 %151 %153
  730. %155 = OpCompositeConstruct %66 %148 %154 %112 %112
  731. OpStore %100 %155
  732. OpBranch %142
  733. %156 = OpLabel
  734. %161 = OpSLessThan %17 %94 %160
  735. OpSelectionMerge %163 None
  736. OpBranchConditional %161 %162 %177
  737. %162 = OpLabel
  738. %165 = OpAccessChain %51 %46 %164
  739. %166 = OpLoad %20 %165
  740. %167 = OpAccessChain %27 %24 %9 %26
  741. %168 = OpLoad %20 %167
  742. %169 = OpFDiv %20 %166 %168
  743. %171 = OpAccessChain %51 %46 %170
  744. %172 = OpLoad %20 %171
  745. %173 = OpAccessChain %27 %24 %9 %108
  746. %174 = OpLoad %20 %173
  747. %175 = OpFDiv %20 %172 %174
  748. %176 = OpCompositeConstruct %66 %169 %175 %112 %112
  749. OpStore %100 %176
  750. OpBranch %163
  751. %177 = OpLabel
  752. %182 = OpSLessThan %17 %94 %181
  753. OpSelectionMerge %184 None
  754. OpBranchConditional %182 %183 %197
  755. %183 = OpLabel
  756. %185 = OpAccessChain %51 %46 %95
  757. %186 = OpLoad %20 %185
  758. %187 = OpAccessChain %27 %24 %9 %26
  759. %188 = OpLoad %20 %187
  760. %189 = OpFDiv %20 %186 %188
  761. %191 = OpAccessChain %51 %46 %190
  762. %192 = OpLoad %20 %191
  763. %193 = OpAccessChain %27 %24 %9 %108
  764. %194 = OpLoad %20 %193
  765. %195 = OpFDiv %20 %192 %194
  766. %196 = OpCompositeConstruct %66 %189 %195 %112 %112
  767. OpStore %100 %196
  768. OpBranch %184
  769. %197 = OpLabel
  770. %202 = OpSLessThan %17 %94 %201
  771. OpSelectionMerge %204 None
  772. OpBranchConditional %202 %203 %218
  773. %203 = OpLabel
  774. %206 = OpAccessChain %51 %46 %205
  775. %207 = OpLoad %20 %206
  776. %208 = OpAccessChain %27 %24 %9 %26
  777. %209 = OpLoad %20 %208
  778. %210 = OpFDiv %20 %207 %209
  779. %212 = OpAccessChain %51 %46 %211
  780. %213 = OpLoad %20 %212
  781. %214 = OpAccessChain %27 %24 %9 %108
  782. %215 = OpLoad %20 %214
  783. %216 = OpFDiv %20 %213 %215
  784. %217 = OpCompositeConstruct %66 %210 %216 %112 %112
  785. OpStore %100 %217
  786. OpBranch %204
  787. %218 = OpLabel
  788. %223 = OpSLessThan %17 %94 %222
  789. OpSelectionMerge %225 None
  790. OpBranchConditional %223 %224 %239
  791. %224 = OpLabel
  792. %227 = OpAccessChain %51 %46 %226
  793. %228 = OpLoad %20 %227
  794. %229 = OpAccessChain %27 %24 %9 %26
  795. %230 = OpLoad %20 %229
  796. %231 = OpFDiv %20 %228 %230
  797. %233 = OpAccessChain %51 %46 %232
  798. %234 = OpLoad %20 %233
  799. %235 = OpAccessChain %27 %24 %9 %108
  800. %236 = OpLoad %20 %235
  801. %237 = OpFDiv %20 %234 %236
  802. %238 = OpCompositeConstruct %66 %231 %237 %112 %112
  803. OpStore %100 %238
  804. OpBranch %225
  805. %239 = OpLabel
  806. %244 = OpSLessThan %17 %94 %243
  807. OpSelectionMerge %246 None
  808. OpBranchConditional %244 %245 %260
  809. %245 = OpLabel
  810. %248 = OpAccessChain %51 %46 %247
  811. %249 = OpLoad %20 %248
  812. %250 = OpAccessChain %27 %24 %9 %26
  813. %251 = OpLoad %20 %250
  814. %252 = OpFDiv %20 %249 %251
  815. %254 = OpAccessChain %51 %46 %253
  816. %255 = OpLoad %20 %254
  817. %256 = OpAccessChain %27 %24 %9 %108
  818. %257 = OpLoad %20 %256
  819. %258 = OpFDiv %20 %255 %257
  820. %259 = OpCompositeConstruct %66 %252 %258 %112 %112
  821. OpStore %100 %259
  822. OpBranch %246
  823. %260 = OpLabel
  824. %265 = OpSLessThan %17 %94 %264
  825. OpSelectionMerge %267 None
  826. OpBranchConditional %265 %266 %280
  827. %266 = OpLabel
  828. %268 = OpAccessChain %51 %46 %118
  829. %269 = OpLoad %20 %268
  830. %270 = OpAccessChain %27 %24 %9 %26
  831. %271 = OpLoad %20 %270
  832. %272 = OpFDiv %20 %269 %271
  833. %274 = OpAccessChain %51 %46 %273
  834. %275 = OpLoad %20 %274
  835. %276 = OpAccessChain %27 %24 %9 %108
  836. %277 = OpLoad %20 %276
  837. %278 = OpFDiv %20 %275 %277
  838. %279 = OpCompositeConstruct %66 %272 %278 %112 %112
  839. OpStore %100 %279
  840. OpBranch %267
  841. %280 = OpLabel
  842. OpSelectionMerge %285 None
  843. OpBranchConditional %265 %285 %300
  844. %285 = OpLabel
  845. %288 = OpAccessChain %51 %46 %287
  846. %289 = OpLoad %20 %288
  847. %290 = OpAccessChain %27 %24 %9 %26
  848. %291 = OpLoad %20 %290
  849. %292 = OpFDiv %20 %289 %291
  850. %294 = OpAccessChain %51 %46 %293
  851. %295 = OpLoad %20 %294
  852. %296 = OpAccessChain %27 %24 %9 %108
  853. %297 = OpLoad %20 %296
  854. %298 = OpFDiv %20 %295 %297
  855. %299 = OpCompositeConstruct %66 %292 %298 %112 %112
  856. OpStore %100 %299
  857. OpBranch %267
  858. %300 = OpLabel
  859. OpKill
  860. %267 = OpLabel
  861. OpBranch %246
  862. %246 = OpLabel
  863. OpBranch %225
  864. %225 = OpLabel
  865. OpBranch %204
  866. %204 = OpLabel
  867. OpBranch %184
  868. %184 = OpLabel
  869. OpBranch %163
  870. %163 = OpLabel
  871. OpBranch %142
  872. %142 = OpLabel
  873. OpBranch %121
  874. %121 = OpLabel
  875. OpBranch %98
  876. %98 = OpLabel
  877. OpReturn
  878. OpFunctionEnd
  879. )";
  880. // Abstract class exposing an interestingness function as a virtual method.
  881. class InterestingnessTest {
  882. public:
  883. virtual ~InterestingnessTest() = default;
  884. // Abstract method that subclasses should implement for specific notions of
  885. // interestingness. Its signature matches Shrinker::InterestingnessFunction.
  886. // Argument |binary| is the SPIR-V binary to be checked; |counter| is used for
  887. // debugging purposes.
  888. virtual bool Interesting(const std::vector<uint32_t>& binary,
  889. uint32_t counter) = 0;
  890. // Yields the Interesting instance method wrapped in a function object.
  891. Shrinker::InterestingnessFunction AsFunction() {
  892. return std::bind(&InterestingnessTest::Interesting, this,
  893. std::placeholders::_1, std::placeholders::_2);
  894. }
  895. };
  896. // A test that says all binaries are interesting.
  897. class AlwaysInteresting : public InterestingnessTest {
  898. public:
  899. bool Interesting(const std::vector<uint32_t>&, uint32_t) override {
  900. return true;
  901. }
  902. };
  903. // A test that says a binary is interesting first time round, and uninteresting
  904. // thereafter.
  905. class OnlyInterestingFirstTime : public InterestingnessTest {
  906. public:
  907. explicit OnlyInterestingFirstTime() : first_time_(true) {}
  908. bool Interesting(const std::vector<uint32_t>&, uint32_t) override {
  909. if (first_time_) {
  910. first_time_ = false;
  911. return true;
  912. }
  913. return false;
  914. }
  915. private:
  916. bool first_time_;
  917. };
  918. // A test that says a binary is interesting first time round, after which
  919. // interestingness ping pongs between false and true.
  920. class PingPong : public InterestingnessTest {
  921. public:
  922. explicit PingPong() : interesting_(false) {}
  923. bool Interesting(const std::vector<uint32_t>&, uint32_t) override {
  924. interesting_ = !interesting_;
  925. return interesting_;
  926. }
  927. private:
  928. bool interesting_;
  929. };
  930. // A test that says a binary is interesting first time round, thereafter
  931. // decides at random whether it is interesting. This allows the logic of the
  932. // shrinker to be exercised quite a bit.
  933. class InterestingThenRandom : public InterestingnessTest {
  934. public:
  935. InterestingThenRandom(const PseudoRandomGenerator& random_generator)
  936. : first_time_(true), random_generator_(random_generator) {}
  937. bool Interesting(const std::vector<uint32_t>&, uint32_t) override {
  938. if (first_time_) {
  939. first_time_ = false;
  940. return true;
  941. }
  942. return random_generator_.RandomBool();
  943. }
  944. private:
  945. bool first_time_;
  946. PseudoRandomGenerator random_generator_;
  947. };
  948. // |binary_in| and |initial_facts| are a SPIR-V binary and sequence of facts to
  949. // which |transformation_sequence_in| can be applied. Shrinking of
  950. // |transformation_sequence_in| gets performed with respect to
  951. // |interestingness_function|. If |expected_binary_out| is non-empty, it must
  952. // match the binary obtained by applying the final shrunk set of
  953. // transformations, in which case the number of such transformations should
  954. // equal |expected_transformations_out_size|.
  955. //
  956. // The |step_limit| parameter restricts the number of steps that the shrinker
  957. // will try; it can be set to something small for a faster (but less thorough)
  958. // test.
  959. //
  960. // The |validator_options| parameter provides validator options that should be
  961. // used during shrinking.
  962. void RunAndCheckShrinker(
  963. const spv_target_env& target_env, const std::vector<uint32_t>& binary_in,
  964. const protobufs::FactSequence& initial_facts,
  965. const protobufs::TransformationSequence& transformation_sequence_in,
  966. const Shrinker::InterestingnessFunction& interestingness_function,
  967. const std::vector<uint32_t>& expected_binary_out,
  968. uint32_t expected_transformations_out_size, uint32_t step_limit,
  969. spv_validator_options validator_options) {
  970. // Run the shrinker.
  971. auto shrinker_result =
  972. Shrinker(target_env, kConsoleMessageConsumer, binary_in, initial_facts,
  973. transformation_sequence_in, interestingness_function, step_limit,
  974. false, validator_options)
  975. .Run();
  976. ASSERT_TRUE(Shrinker::ShrinkerResultStatus::kComplete ==
  977. shrinker_result.status ||
  978. Shrinker::ShrinkerResultStatus::kStepLimitReached ==
  979. shrinker_result.status);
  980. // If a non-empty expected binary was provided, check that it matches the
  981. // result of shrinking and that the expected number of transformations remain.
  982. if (!expected_binary_out.empty()) {
  983. ASSERT_EQ(expected_binary_out, shrinker_result.transformed_binary);
  984. ASSERT_EQ(
  985. expected_transformations_out_size,
  986. static_cast<uint32_t>(
  987. shrinker_result.applied_transformations.transformation_size()));
  988. }
  989. }
  990. // Assembles the given |shader| text, and then:
  991. // - Runs the fuzzer with |seed| to yield a set of transformations
  992. // - Shrinks the transformation with various interestingness functions,
  993. // asserting some properties about the result each time
  994. void RunFuzzerAndShrinker(const std::string& shader,
  995. const protobufs::FactSequence& initial_facts,
  996. uint32_t seed) {
  997. const auto env = SPV_ENV_UNIVERSAL_1_5;
  998. std::vector<uint32_t> binary_in;
  999. SpirvTools t(env);
  1000. t.SetMessageConsumer(kConsoleMessageConsumer);
  1001. ASSERT_TRUE(t.Assemble(shader, &binary_in, kFuzzAssembleOption));
  1002. ASSERT_TRUE(t.Validate(binary_in));
  1003. std::vector<fuzzerutil::ModuleSupplier> donor_suppliers;
  1004. for (auto donor : {&kTestShader1, &kTestShader2, &kTestShader3}) {
  1005. donor_suppliers.emplace_back([donor]() {
  1006. return BuildModule(env, kConsoleMessageConsumer, *donor,
  1007. kFuzzAssembleOption);
  1008. });
  1009. }
  1010. // Run the fuzzer and check that it successfully yields a valid binary.
  1011. spvtools::ValidatorOptions validator_options;
  1012. // Depending on the seed, decide whether to enable all passes and which
  1013. // repeated pass manager to use.
  1014. bool enable_all_passes = (seed % 4) == 0;
  1015. RepeatedPassStrategy repeated_pass_strategy;
  1016. if ((seed % 3) == 0) {
  1017. repeated_pass_strategy = RepeatedPassStrategy::kSimple;
  1018. } else if ((seed % 3) == 1) {
  1019. repeated_pass_strategy = RepeatedPassStrategy::kLoopedWithRecommendations;
  1020. } else {
  1021. repeated_pass_strategy = RepeatedPassStrategy::kRandomWithRecommendations;
  1022. }
  1023. std::unique_ptr<opt::IRContext> ir_context;
  1024. ASSERT_TRUE(fuzzerutil::BuildIRContext(
  1025. env, kConsoleMessageConsumer, binary_in, validator_options, &ir_context));
  1026. auto fuzzer_context = MakeUnique<FuzzerContext>(
  1027. MakeUnique<PseudoRandomGenerator>(seed),
  1028. FuzzerContext::GetMinFreshId(ir_context.get()), false);
  1029. auto transformation_context = MakeUnique<TransformationContext>(
  1030. MakeUnique<FactManager>(ir_context.get()), validator_options);
  1031. transformation_context->GetFactManager()->AddInitialFacts(
  1032. kConsoleMessageConsumer, initial_facts);
  1033. Fuzzer fuzzer(std::move(ir_context), std::move(transformation_context),
  1034. std::move(fuzzer_context), kConsoleMessageConsumer,
  1035. donor_suppliers, enable_all_passes, repeated_pass_strategy,
  1036. true, validator_options, false);
  1037. auto fuzzer_result = fuzzer.Run(0);
  1038. ASSERT_NE(Fuzzer::Status::kFuzzerPassLedToInvalidModule,
  1039. fuzzer_result.status);
  1040. std::vector<uint32_t> transformed_binary;
  1041. fuzzer.GetIRContext()->module()->ToBinary(&transformed_binary, true);
  1042. ASSERT_TRUE(t.Validate(transformed_binary));
  1043. const uint32_t kReasonableStepLimit = 50;
  1044. const uint32_t kSmallStepLimit = 20;
  1045. // With the AlwaysInteresting test, we should quickly shrink to the original
  1046. // binary with no transformations remaining.
  1047. RunAndCheckShrinker(env, binary_in, initial_facts,
  1048. fuzzer.GetTransformationSequence(),
  1049. AlwaysInteresting().AsFunction(), binary_in, 0,
  1050. kReasonableStepLimit, validator_options);
  1051. // With the OnlyInterestingFirstTime test, no shrinking should be achieved.
  1052. RunAndCheckShrinker(
  1053. env, binary_in, initial_facts, fuzzer.GetTransformationSequence(),
  1054. OnlyInterestingFirstTime().AsFunction(), transformed_binary,
  1055. static_cast<uint32_t>(
  1056. fuzzer.GetTransformationSequence().transformation_size()),
  1057. kReasonableStepLimit, validator_options);
  1058. // The PingPong test is unpredictable; passing an empty expected binary
  1059. // means that we don't check anything beyond that shrinking completes
  1060. // successfully.
  1061. RunAndCheckShrinker(
  1062. env, binary_in, initial_facts, fuzzer.GetTransformationSequence(),
  1063. PingPong().AsFunction(), {}, 0, kSmallStepLimit, validator_options);
  1064. // The InterestingThenRandom test is unpredictable; passing an empty
  1065. // expected binary means that we do not check anything about shrinking
  1066. // results.
  1067. RunAndCheckShrinker(
  1068. env, binary_in, initial_facts, fuzzer.GetTransformationSequence(),
  1069. InterestingThenRandom(PseudoRandomGenerator(seed)).AsFunction(), {}, 0,
  1070. kSmallStepLimit, validator_options);
  1071. }
  1072. TEST(FuzzerShrinkerTest, Miscellaneous1) {
  1073. RunFuzzerAndShrinker(kTestShader1, protobufs::FactSequence(), 2);
  1074. }
  1075. TEST(FuzzerShrinkerTest, Miscellaneous2) {
  1076. RunFuzzerAndShrinker(kTestShader2, protobufs::FactSequence(), 19);
  1077. }
  1078. TEST(FuzzerShrinkerTest, Miscellaneous3) {
  1079. // Add the facts "resolution.x == 250" and "resolution.y == 100".
  1080. protobufs::FactSequence facts;
  1081. {
  1082. protobufs::FactConstantUniform resolution_x_eq_250;
  1083. *resolution_x_eq_250.mutable_uniform_buffer_element_descriptor() =
  1084. MakeUniformBufferElementDescriptor(0, 0, {0, 0});
  1085. *resolution_x_eq_250.mutable_constant_word()->Add() = 250;
  1086. protobufs::Fact temp;
  1087. *temp.mutable_constant_uniform_fact() = resolution_x_eq_250;
  1088. *facts.mutable_fact()->Add() = temp;
  1089. }
  1090. {
  1091. protobufs::FactConstantUniform resolution_y_eq_100;
  1092. *resolution_y_eq_100.mutable_uniform_buffer_element_descriptor() =
  1093. MakeUniformBufferElementDescriptor(0, 0, {0, 1});
  1094. *resolution_y_eq_100.mutable_constant_word()->Add() = 100;
  1095. protobufs::Fact temp;
  1096. *temp.mutable_constant_uniform_fact() = resolution_y_eq_100;
  1097. *facts.mutable_fact()->Add() = temp;
  1098. }
  1099. // Also add an invalid fact, which should be ignored.
  1100. {
  1101. protobufs::FactConstantUniform bad_fact;
  1102. // The descriptor set, binding and indices used here deliberately make no
  1103. // sense.
  1104. *bad_fact.mutable_uniform_buffer_element_descriptor() =
  1105. MakeUniformBufferElementDescriptor(22, 33, {44, 55});
  1106. *bad_fact.mutable_constant_word()->Add() = 100;
  1107. protobufs::Fact temp;
  1108. *temp.mutable_constant_uniform_fact() = bad_fact;
  1109. *facts.mutable_fact()->Add() = temp;
  1110. }
  1111. // Do 2 fuzzer runs, starting from an initial seed of 194 (seed value chosen
  1112. // arbitrarily).
  1113. RunFuzzerAndShrinker(kTestShader3, facts, 194);
  1114. }
  1115. } // namespace
  1116. } // namespace fuzz
  1117. } // namespace spvtools