fuzzerutil_test.cpp 69 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817
  1. // Copyright (c) 2021 Shiyu Liu
  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 "gtest/gtest.h"
  15. #include "source/fuzz/fuzzer_util.h"
  16. #include "test/fuzz/fuzz_test_util.h"
  17. namespace spvtools {
  18. namespace fuzz {
  19. namespace {
  20. TEST(FuzzerUtilMaybeFindBlockTest, BasicTest) {
  21. std::string shader = R"(
  22. OpCapability Shader
  23. %1 = OpExtInstImport "GLSL.std.450"
  24. OpMemoryModel Logical GLSL450
  25. OpEntryPoint Fragment %4 "main"
  26. OpExecutionMode %4 OriginUpperLeft
  27. OpSource ESSL 310
  28. OpDecorate %8 RelaxedPrecision
  29. %2 = OpTypeVoid
  30. %3 = OpTypeFunction %2
  31. %6 = OpTypeInt 32 1
  32. %7 = OpTypePointer Function %6
  33. %9 = OpConstant %6 1
  34. %10 = OpConstant %6 2
  35. %4 = OpFunction %2 None %3
  36. %5 = OpLabel
  37. %8 = OpVariable %7 Function
  38. OpBranch %11
  39. %11 = OpLabel
  40. OpStore %8 %9
  41. OpBranch %12
  42. %12 = OpLabel
  43. OpStore %8 %10
  44. OpReturn
  45. OpFunctionEnd
  46. )";
  47. const auto env = SPV_ENV_UNIVERSAL_1_4;
  48. const auto consumer = nullptr;
  49. const std::unique_ptr<opt::IRContext> context =
  50. BuildModule(env, consumer, shader, kFuzzAssembleOption);
  51. spvtools::ValidatorOptions validator_options;
  52. ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
  53. kConsoleMessageConsumer));
  54. // Only blocks with id 11 and 12 can be found.
  55. // Should return nullptr when id is not a label or id was not found.
  56. uint32_t block_id1 = 11;
  57. uint32_t block_id2 = 12;
  58. uint32_t block_id3 = 13;
  59. uint32_t block_id4 = 8;
  60. opt::IRContext* ir_context = context.get();
  61. // Block with id 11 should be found.
  62. ASSERT_TRUE(fuzzerutil::MaybeFindBlock(ir_context, block_id1) != nullptr);
  63. // Block with id 12 should be found.
  64. ASSERT_TRUE(fuzzerutil::MaybeFindBlock(ir_context, block_id2) != nullptr);
  65. // Block with id 13 cannot be found.
  66. ASSERT_FALSE(fuzzerutil::MaybeFindBlock(ir_context, block_id3) != nullptr);
  67. // Block with id 8 exists but don't not of type OpLabel.
  68. ASSERT_FALSE(fuzzerutil::MaybeFindBlock(ir_context, block_id4) != nullptr);
  69. }
  70. TEST(FuzzerutilTest, FuzzerUtilMaybeGetBoolConstantTest) {
  71. std::string shader = R"(
  72. OpCapability Shader
  73. %1 = OpExtInstImport "GLSL.std.450"
  74. OpMemoryModel Logical GLSL450
  75. OpEntryPoint Fragment %4 "main" %36
  76. OpExecutionMode %4 OriginUpperLeft
  77. OpSource ESSL 310
  78. OpName %4 "main"
  79. OpName %8 "b1"
  80. OpName %10 "b2"
  81. OpName %12 "b3"
  82. OpName %13 "b4"
  83. OpName %16 "f1"
  84. OpName %18 "f2"
  85. OpName %20 "cf1"
  86. OpName %22 "cf2"
  87. OpName %26 "i1"
  88. OpName %28 "i2"
  89. OpName %30 "ci1"
  90. OpName %32 "ci2"
  91. OpName %36 "value"
  92. OpDecorate %26 RelaxedPrecision
  93. OpDecorate %28 RelaxedPrecision
  94. OpDecorate %30 RelaxedPrecision
  95. OpDecorate %32 RelaxedPrecision
  96. OpDecorate %36 Location 0
  97. %2 = OpTypeVoid
  98. %3 = OpTypeFunction %2
  99. %6 = OpTypeBool
  100. %7 = OpTypePointer Function %6
  101. %9 = OpConstantTrue %6
  102. %11 = OpConstantFalse %6
  103. %14 = OpTypeFloat 32
  104. %15 = OpTypePointer Function %14
  105. %17 = OpConstant %14 1.23000002
  106. %19 = OpConstant %14 1.11000001
  107. %21 = OpConstant %14 2
  108. %23 = OpConstant %14 3.29999995
  109. %24 = OpTypeInt 32 1
  110. %25 = OpTypePointer Function %24
  111. %27 = OpConstant %24 1
  112. %29 = OpConstant %24 100
  113. %31 = OpConstant %24 123
  114. %33 = OpConstant %24 1111
  115. %35 = OpTypePointer Input %14
  116. %36 = OpVariable %35 Input
  117. %4 = OpFunction %2 None %3
  118. %5 = OpLabel
  119. %8 = OpVariable %7 Function
  120. %10 = OpVariable %7 Function
  121. %12 = OpVariable %7 Function
  122. %13 = OpVariable %7 Function
  123. %16 = OpVariable %15 Function
  124. %18 = OpVariable %15 Function
  125. %20 = OpVariable %15 Function
  126. %22 = OpVariable %15 Function
  127. %26 = OpVariable %25 Function
  128. %28 = OpVariable %25 Function
  129. %30 = OpVariable %25 Function
  130. %32 = OpVariable %25 Function
  131. OpStore %8 %9
  132. OpStore %10 %11
  133. OpStore %12 %9
  134. OpStore %13 %11
  135. OpStore %16 %17
  136. OpStore %18 %19
  137. OpStore %20 %21
  138. OpStore %22 %23
  139. OpStore %26 %27
  140. OpStore %28 %29
  141. OpStore %30 %31
  142. OpStore %32 %33
  143. OpReturn
  144. OpFunctionEnd
  145. )";
  146. const auto env = SPV_ENV_UNIVERSAL_1_4;
  147. const auto consumer = nullptr;
  148. const std::unique_ptr<opt::IRContext> context =
  149. BuildModule(env, consumer, shader, kFuzzAssembleOption);
  150. spvtools::ValidatorOptions validator_options;
  151. ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
  152. kConsoleMessageConsumer));
  153. TransformationContext transformation_context(
  154. MakeUnique<FactManager>(context.get()), validator_options);
  155. opt::IRContext* ir_context = context.get();
  156. // A bool constant with value false exists and the id is 11.
  157. ASSERT_EQ(11, fuzzerutil::MaybeGetBoolConstant(
  158. ir_context, transformation_context, false, false));
  159. // A bool constant with value true exists and the id is 9.
  160. ASSERT_EQ(9, fuzzerutil::MaybeGetBoolConstant(
  161. ir_context, transformation_context, true, false));
  162. }
  163. TEST(FuzzerutilTest, FuzzerUtilMaybeGetBoolTypeTest) {
  164. std::string shader = R"(
  165. OpCapability Shader
  166. %1 = OpExtInstImport "GLSL.std.450"
  167. OpMemoryModel Logical GLSL450
  168. OpEntryPoint Fragment %4 "main" %92 %52 %53
  169. OpExecutionMode %4 OriginUpperLeft
  170. OpSource ESSL 310
  171. OpDecorate %92 BuiltIn FragCoord
  172. %2 = OpTypeVoid
  173. %3 = OpTypeFunction %2
  174. %6 = OpTypeInt 32 1
  175. %7 = OpTypeFloat 32
  176. %8 = OpTypeStruct %6 %7
  177. %9 = OpTypePointer Function %8
  178. %10 = OpTypeFunction %6 %9
  179. %14 = OpConstant %6 0
  180. %15 = OpTypePointer Function %6
  181. %51 = OpTypePointer Private %6
  182. %21 = OpConstant %6 2
  183. %23 = OpConstant %6 1
  184. %24 = OpConstant %7 1
  185. %25 = OpTypePointer Function %7
  186. %50 = OpTypePointer Private %7
  187. %34 = OpTypeBool
  188. %35 = OpConstantFalse %34
  189. %52 = OpVariable %50 Private
  190. %53 = OpVariable %51 Private
  191. %80 = OpConstantComposite %8 %21 %24
  192. %90 = OpTypeVector %7 4
  193. %91 = OpTypePointer Input %90
  194. %92 = OpVariable %91 Input
  195. %93 = OpConstantComposite %90 %24 %24 %24 %24
  196. %4 = OpFunction %2 None %3
  197. %5 = OpLabel
  198. %20 = OpVariable %9 Function
  199. %27 = OpVariable %9 Function
  200. %22 = OpAccessChain %15 %20 %14
  201. %44 = OpCopyObject %9 %20
  202. %26 = OpAccessChain %25 %20 %23
  203. %29 = OpFunctionCall %6 %12 %27
  204. %30 = OpAccessChain %15 %20 %14
  205. %45 = OpCopyObject %15 %30
  206. %81 = OpCopyObject %9 %27
  207. %33 = OpAccessChain %15 %20 %14
  208. OpSelectionMerge %37 None
  209. OpBranchConditional %35 %36 %37
  210. %36 = OpLabel
  211. %38 = OpAccessChain %15 %20 %14
  212. %40 = OpAccessChain %15 %20 %14
  213. %43 = OpAccessChain %15 %20 %14
  214. %82 = OpCopyObject %9 %27
  215. OpBranch %37
  216. %37 = OpLabel
  217. OpReturn
  218. OpFunctionEnd
  219. %12 = OpFunction %6 None %10
  220. %11 = OpFunctionParameter %9
  221. %13 = OpLabel
  222. %46 = OpCopyObject %9 %11
  223. %16 = OpAccessChain %15 %11 %14
  224. %95 = OpCopyObject %8 %80
  225. OpReturnValue %21
  226. %100 = OpLabel
  227. OpUnreachable
  228. OpFunctionEnd
  229. )";
  230. const auto env = SPV_ENV_UNIVERSAL_1_4;
  231. const auto consumer = nullptr;
  232. const std::unique_ptr<opt::IRContext> context =
  233. BuildModule(env, consumer, shader, kFuzzAssembleOption);
  234. spvtools::ValidatorOptions validator_options;
  235. ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
  236. kConsoleMessageConsumer));
  237. opt::IRContext* ir_context = context.get();
  238. // A bool type with result id of 34 exists.
  239. ASSERT_TRUE(fuzzerutil::MaybeGetBoolType(ir_context));
  240. }
  241. TEST(FuzzerutilTest, FuzzerUtilMaybeGetCompositeConstantTest) {
  242. std::string shader = R"(
  243. OpCapability Shader
  244. %1 = OpExtInstImport "GLSL.std.450"
  245. OpMemoryModel Logical GLSL450
  246. OpEntryPoint Fragment %4 "main" %54
  247. OpExecutionMode %4 OriginUpperLeft
  248. OpSource ESSL 310
  249. OpName %4 "main"
  250. OpName %8 "b1"
  251. OpName %10 "b2"
  252. OpName %12 "b3"
  253. OpName %13 "b4"
  254. OpName %16 "f1"
  255. OpName %18 "f2"
  256. OpName %22 "zc"
  257. OpName %24 "i1"
  258. OpName %28 "i2"
  259. OpName %30 "i3"
  260. OpName %32 "i4"
  261. OpName %37 "f_arr"
  262. OpName %47 "i_arr"
  263. OpName %54 "value"
  264. OpDecorate %22 RelaxedPrecision
  265. OpDecorate %24 RelaxedPrecision
  266. OpDecorate %28 RelaxedPrecision
  267. OpDecorate %30 RelaxedPrecision
  268. OpDecorate %32 RelaxedPrecision
  269. OpDecorate %47 RelaxedPrecision
  270. OpDecorate %54 Location 0
  271. %2 = OpTypeVoid
  272. %3 = OpTypeFunction %2
  273. %6 = OpTypeBool
  274. %7 = OpTypePointer Function %6
  275. %9 = OpConstantTrue %6
  276. %11 = OpConstantFalse %6
  277. %14 = OpTypeFloat 32
  278. %15 = OpTypePointer Function %14
  279. %17 = OpConstant %14 1.23000002
  280. %19 = OpConstant %14 1.11000001
  281. %20 = OpTypeInt 32 1
  282. %21 = OpTypePointer Function %20
  283. %23 = OpConstant %20 0
  284. %25 = OpConstant %20 1
  285. %26 = OpTypeInt 32 0
  286. %27 = OpTypePointer Function %26
  287. %29 = OpConstant %26 100
  288. %31 = OpConstant %20 -1
  289. %33 = OpConstant %20 -99
  290. %34 = OpConstant %26 5
  291. %35 = OpTypeArray %14 %34
  292. %36 = OpTypePointer Function %35
  293. %38 = OpConstant %14 5.5
  294. %39 = OpConstant %14 4.4000001
  295. %40 = OpConstant %14 3.29999995
  296. %41 = OpConstant %14 2.20000005
  297. %42 = OpConstant %14 1.10000002
  298. %43 = OpConstantComposite %35 %38 %39 %40 %41 %42
  299. %44 = OpConstant %26 3
  300. %45 = OpTypeArray %20 %44
  301. %46 = OpTypePointer Function %45
  302. %48 = OpConstant %20 3
  303. %49 = OpConstant %20 7
  304. %50 = OpConstant %20 9
  305. %51 = OpConstantComposite %45 %48 %49 %50
  306. %53 = OpTypePointer Input %14
  307. %54 = OpVariable %53 Input
  308. %4 = OpFunction %2 None %3
  309. %5 = OpLabel
  310. %8 = OpVariable %7 Function
  311. %10 = OpVariable %7 Function
  312. %12 = OpVariable %7 Function
  313. %13 = OpVariable %7 Function
  314. %16 = OpVariable %15 Function
  315. %18 = OpVariable %15 Function
  316. %22 = OpVariable %21 Function
  317. %24 = OpVariable %21 Function
  318. %28 = OpVariable %27 Function
  319. %30 = OpVariable %21 Function
  320. %32 = OpVariable %21 Function
  321. %37 = OpVariable %36 Function
  322. %47 = OpVariable %46 Function
  323. OpStore %8 %9
  324. OpStore %10 %11
  325. OpStore %12 %9
  326. OpStore %13 %11
  327. OpStore %16 %17
  328. OpStore %18 %19
  329. OpStore %22 %23
  330. OpStore %24 %25
  331. OpStore %28 %29
  332. OpStore %30 %31
  333. OpStore %32 %33
  334. OpStore %37 %43
  335. OpStore %47 %51
  336. OpReturn
  337. OpFunctionEnd
  338. )";
  339. const auto env = SPV_ENV_UNIVERSAL_1_4;
  340. const auto consumer = nullptr;
  341. const std::unique_ptr<opt::IRContext> context =
  342. BuildModule(env, consumer, shader, kFuzzAssembleOption);
  343. spvtools::ValidatorOptions validator_options;
  344. ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
  345. kConsoleMessageConsumer));
  346. TransformationContext transformation_context(
  347. MakeUnique<FactManager>(context.get()), validator_options);
  348. opt::IRContext* ir_context = context.get();
  349. // %43 = OpConstantComposite %35 %38 %39 %40 %41 %42
  350. // %51 = OpConstantComposite %45 %48 %49 %50
  351. // This should pass as a float array with 5 elements exist and its id is 43.
  352. ASSERT_EQ(43, fuzzerutil::MaybeGetCompositeConstant(
  353. ir_context, transformation_context, {38, 39, 40, 41, 42},
  354. 35, false));
  355. // This should pass as an int array with 3 elements exist and its id is 51.
  356. ASSERT_EQ(51,
  357. fuzzerutil::MaybeGetCompositeConstant(
  358. ir_context, transformation_context, {48, 49, 50}, 45, false));
  359. // An int array with 2 elements does not exist.
  360. ASSERT_EQ(0, fuzzerutil::MaybeGetCompositeConstant(
  361. ir_context, transformation_context, {48, 49}, 45, false));
  362. }
  363. TEST(FuzzerutilTest, FuzzerUtilMaybeGetFloatConstantTest) {
  364. std::string shader = R"(
  365. OpCapability Shader
  366. %1 = OpExtInstImport "GLSL.std.450"
  367. OpMemoryModel Logical GLSL450
  368. OpEntryPoint Fragment %4 "main" %36
  369. OpExecutionMode %4 OriginUpperLeft
  370. OpSource ESSL 310
  371. OpName %4 "main"
  372. OpName %8 "b1"
  373. OpName %10 "b2"
  374. OpName %12 "b3"
  375. OpName %13 "b4"
  376. OpName %16 "f1"
  377. OpName %18 "f2"
  378. OpName %20 "cf1"
  379. OpName %22 "cf2"
  380. OpName %26 "i1"
  381. OpName %28 "i2"
  382. OpName %30 "ci1"
  383. OpName %32 "ci2"
  384. OpName %36 "value"
  385. OpDecorate %26 RelaxedPrecision
  386. OpDecorate %28 RelaxedPrecision
  387. OpDecorate %30 RelaxedPrecision
  388. OpDecorate %32 RelaxedPrecision
  389. OpDecorate %36 Location 0
  390. %2 = OpTypeVoid
  391. %3 = OpTypeFunction %2
  392. %6 = OpTypeBool
  393. %7 = OpTypePointer Function %6
  394. %9 = OpConstantTrue %6
  395. %11 = OpConstantFalse %6
  396. %14 = OpTypeFloat 32
  397. %15 = OpTypePointer Function %14
  398. %17 = OpConstant %14 1.23000002
  399. %19 = OpConstant %14 1.11000001
  400. %21 = OpConstant %14 2
  401. %23 = OpConstant %14 3.29999995
  402. %24 = OpTypeInt 32 1
  403. %25 = OpTypePointer Function %24
  404. %27 = OpConstant %24 1
  405. %29 = OpConstant %24 100
  406. %31 = OpConstant %24 123
  407. %33 = OpConstant %24 1111
  408. %35 = OpTypePointer Input %14
  409. %36 = OpVariable %35 Input
  410. %4 = OpFunction %2 None %3
  411. %5 = OpLabel
  412. %8 = OpVariable %7 Function
  413. %10 = OpVariable %7 Function
  414. %12 = OpVariable %7 Function
  415. %13 = OpVariable %7 Function
  416. %16 = OpVariable %15 Function
  417. %18 = OpVariable %15 Function
  418. %20 = OpVariable %15 Function
  419. %22 = OpVariable %15 Function
  420. %26 = OpVariable %25 Function
  421. %28 = OpVariable %25 Function
  422. %30 = OpVariable %25 Function
  423. %32 = OpVariable %25 Function
  424. OpStore %8 %9
  425. OpStore %10 %11
  426. OpStore %12 %9
  427. OpStore %13 %11
  428. OpStore %16 %17
  429. OpStore %18 %19
  430. OpStore %20 %21
  431. OpStore %22 %23
  432. OpStore %26 %27
  433. OpStore %28 %29
  434. OpStore %30 %31
  435. OpStore %32 %33
  436. OpReturn
  437. OpFunctionEnd
  438. )";
  439. const auto env = SPV_ENV_UNIVERSAL_1_4;
  440. const auto consumer = nullptr;
  441. const std::unique_ptr<opt::IRContext> context =
  442. BuildModule(env, consumer, shader, kFuzzAssembleOption);
  443. spvtools::ValidatorOptions validator_options;
  444. ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
  445. kConsoleMessageConsumer));
  446. TransformationContext transformation_context(
  447. MakeUnique<FactManager>(context.get()), validator_options);
  448. opt::IRContext* ir_context = context.get();
  449. uint32_t word1 = fuzzerutil::FloatToWord(2);
  450. uint32_t word2 = fuzzerutil::FloatToWord(1.23f);
  451. // A 32 bit float constant of value 2 exists and its id is 21.
  452. ASSERT_EQ(21, fuzzerutil::MaybeGetFloatConstant(
  453. ir_context, transformation_context,
  454. std::vector<uint32_t>{word1}, 32, false));
  455. // A 32 bit float constant of value 1.23 exists and its id is 17.
  456. ASSERT_EQ(17, fuzzerutil::MaybeGetFloatConstant(
  457. ir_context, transformation_context,
  458. std::vector<uint32_t>{word2}, 32, false));
  459. }
  460. TEST(FuzzerutilTest, FuzzerUtilMaybeGetFloatTypeTest) {
  461. std::string shader = R"(
  462. OpCapability Shader
  463. %1 = OpExtInstImport "GLSL.std.450"
  464. OpMemoryModel Logical GLSL450
  465. OpEntryPoint Fragment %4 "main" %92 %52 %53
  466. OpExecutionMode %4 OriginUpperLeft
  467. OpSource ESSL 310
  468. OpDecorate %92 BuiltIn FragCoord
  469. %2 = OpTypeVoid
  470. %3 = OpTypeFunction %2
  471. %6 = OpTypeInt 32 1
  472. %7 = OpTypeFloat 32
  473. %8 = OpTypeStruct %6 %7
  474. %9 = OpTypePointer Function %8
  475. %10 = OpTypeFunction %6 %9
  476. %14 = OpConstant %6 0
  477. %15 = OpTypePointer Function %6
  478. %51 = OpTypePointer Private %6
  479. %21 = OpConstant %6 2
  480. %23 = OpConstant %6 1
  481. %24 = OpConstant %7 1
  482. %25 = OpTypePointer Function %7
  483. %50 = OpTypePointer Private %7
  484. %34 = OpTypeBool
  485. %35 = OpConstantFalse %34
  486. %52 = OpVariable %50 Private
  487. %53 = OpVariable %51 Private
  488. %80 = OpConstantComposite %8 %21 %24
  489. %90 = OpTypeVector %7 4
  490. %91 = OpTypePointer Input %90
  491. %92 = OpVariable %91 Input
  492. %93 = OpConstantComposite %90 %24 %24 %24 %24
  493. %4 = OpFunction %2 None %3
  494. %5 = OpLabel
  495. %20 = OpVariable %9 Function
  496. %27 = OpVariable %9 Function
  497. %22 = OpAccessChain %15 %20 %14
  498. %44 = OpCopyObject %9 %20
  499. %26 = OpAccessChain %25 %20 %23
  500. %29 = OpFunctionCall %6 %12 %27
  501. %30 = OpAccessChain %15 %20 %14
  502. %45 = OpCopyObject %15 %30
  503. %81 = OpCopyObject %9 %27
  504. %33 = OpAccessChain %15 %20 %14
  505. OpSelectionMerge %37 None
  506. OpBranchConditional %35 %36 %37
  507. %36 = OpLabel
  508. %38 = OpAccessChain %15 %20 %14
  509. %40 = OpAccessChain %15 %20 %14
  510. %43 = OpAccessChain %15 %20 %14
  511. %82 = OpCopyObject %9 %27
  512. OpBranch %37
  513. %37 = OpLabel
  514. OpReturn
  515. OpFunctionEnd
  516. %12 = OpFunction %6 None %10
  517. %11 = OpFunctionParameter %9
  518. %13 = OpLabel
  519. %46 = OpCopyObject %9 %11
  520. %16 = OpAccessChain %15 %11 %14
  521. %95 = OpCopyObject %8 %80
  522. OpReturnValue %21
  523. %100 = OpLabel
  524. OpUnreachable
  525. OpFunctionEnd
  526. )";
  527. const auto env = SPV_ENV_UNIVERSAL_1_4;
  528. const auto consumer = nullptr;
  529. const std::unique_ptr<opt::IRContext> context =
  530. BuildModule(env, consumer, shader, kFuzzAssembleOption);
  531. spvtools::ValidatorOptions validator_options;
  532. ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
  533. kConsoleMessageConsumer));
  534. opt::IRContext* ir_context = context.get();
  535. // A float type with width = 32 and result id of 7 exists.
  536. ASSERT_EQ(7, fuzzerutil::MaybeGetFloatType(ir_context, 32));
  537. // A float int type with width = 32 exists, but the id should be 7.
  538. ASSERT_NE(5, fuzzerutil::MaybeGetFloatType(ir_context, 32));
  539. // A float type with width 30 does not exist.
  540. ASSERT_EQ(0, fuzzerutil::MaybeGetFloatType(ir_context, 30));
  541. }
  542. TEST(FuzzerutilTest, FuzzerUtilMaybeGetIntegerConstantFromValueAndTypeTest) {
  543. std::string shader = R"(
  544. OpCapability Shader
  545. %1 = OpExtInstImport "GLSL.std.450"
  546. OpMemoryModel Logical GLSL450
  547. OpEntryPoint Fragment %4 "main" %36
  548. OpExecutionMode %4 OriginUpperLeft
  549. OpSource ESSL 310
  550. OpName %4 "main"
  551. OpName %8 "b1"
  552. OpName %10 "b2"
  553. OpName %12 "b3"
  554. OpName %13 "b4"
  555. OpName %16 "f1"
  556. OpName %18 "f2"
  557. OpName %22 "zc"
  558. OpName %24 "i1"
  559. OpName %28 "i2"
  560. OpName %30 "i3"
  561. OpName %32 "i4"
  562. OpName %36 "value"
  563. OpDecorate %22 RelaxedPrecision
  564. OpDecorate %24 RelaxedPrecision
  565. OpDecorate %28 RelaxedPrecision
  566. OpDecorate %30 RelaxedPrecision
  567. OpDecorate %32 RelaxedPrecision
  568. OpDecorate %36 Location 0
  569. %2 = OpTypeVoid
  570. %3 = OpTypeFunction %2
  571. %6 = OpTypeBool
  572. %7 = OpTypePointer Function %6
  573. %9 = OpConstantTrue %6
  574. %11 = OpConstantFalse %6
  575. %14 = OpTypeFloat 32
  576. %15 = OpTypePointer Function %14
  577. %17 = OpConstant %14 1.23000002
  578. %19 = OpConstant %14 1.11000001
  579. %20 = OpTypeInt 32 1
  580. %21 = OpTypePointer Function %20
  581. %23 = OpConstant %20 0
  582. %25 = OpConstant %20 1
  583. %26 = OpTypeInt 32 0
  584. %27 = OpTypePointer Function %26
  585. %29 = OpConstant %26 100
  586. %31 = OpConstant %20 -1
  587. %33 = OpConstant %20 -99
  588. %35 = OpTypePointer Input %14
  589. %36 = OpVariable %35 Input
  590. %4 = OpFunction %2 None %3
  591. %5 = OpLabel
  592. %8 = OpVariable %7 Function
  593. %10 = OpVariable %7 Function
  594. %12 = OpVariable %7 Function
  595. %13 = OpVariable %7 Function
  596. %16 = OpVariable %15 Function
  597. %18 = OpVariable %15 Function
  598. %22 = OpVariable %21 Function
  599. %24 = OpVariable %21 Function
  600. %28 = OpVariable %27 Function
  601. %30 = OpVariable %21 Function
  602. %32 = OpVariable %21 Function
  603. OpStore %8 %9
  604. OpStore %10 %11
  605. OpStore %12 %9
  606. OpStore %13 %11
  607. OpStore %16 %17
  608. OpStore %18 %19
  609. OpStore %22 %23
  610. OpStore %24 %25
  611. OpStore %28 %29
  612. OpStore %30 %31
  613. OpStore %32 %33
  614. OpReturn
  615. OpFunctionEnd
  616. )";
  617. const auto env = SPV_ENV_UNIVERSAL_1_4;
  618. const auto consumer = nullptr;
  619. const std::unique_ptr<opt::IRContext> context =
  620. BuildModule(env, consumer, shader, kFuzzAssembleOption);
  621. spvtools::ValidatorOptions validator_options;
  622. ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
  623. kConsoleMessageConsumer));
  624. opt::IRContext* ir_context = context.get();
  625. // A 32 bit signed int constant (with int type id 20) with value 1 exists and
  626. // the id is 25.
  627. ASSERT_EQ(25, fuzzerutil::MaybeGetIntegerConstantFromValueAndType(ir_context,
  628. 1, 20));
  629. // A 32 bit unsigned int constant (with int type id 0) with value 100 exists
  630. // and the id is 29.
  631. ASSERT_EQ(29, fuzzerutil::MaybeGetIntegerConstantFromValueAndType(ir_context,
  632. 100, 26));
  633. // A 32 bit unsigned int constant with value 50 does not exist.
  634. ASSERT_EQ(0, fuzzerutil::MaybeGetIntegerConstantFromValueAndType(ir_context,
  635. 50, 26));
  636. }
  637. TEST(FuzzerutilTest, FuzzerUtilMaybeGetIntegerConstantTest) {
  638. std::string shader = R"(
  639. OpCapability Shader
  640. OpCapability Shader
  641. %1 = OpExtInstImport "GLSL.std.450"
  642. OpMemoryModel Logical GLSL450
  643. OpEntryPoint Fragment %4 "main" %36
  644. OpExecutionMode %4 OriginUpperLeft
  645. OpSource ESSL 310
  646. OpName %4 "main"
  647. OpName %8 "b1"
  648. OpName %10 "b2"
  649. OpName %12 "b3"
  650. OpName %13 "b4"
  651. OpName %16 "f1"
  652. OpName %18 "f2"
  653. OpName %22 "zc"
  654. OpName %24 "i1"
  655. OpName %28 "i2"
  656. OpName %30 "i3"
  657. OpName %32 "i4"
  658. OpName %36 "value"
  659. OpDecorate %22 RelaxedPrecision
  660. OpDecorate %24 RelaxedPrecision
  661. OpDecorate %28 RelaxedPrecision
  662. OpDecorate %30 RelaxedPrecision
  663. OpDecorate %32 RelaxedPrecision
  664. OpDecorate %36 Location 0
  665. %2 = OpTypeVoid
  666. %3 = OpTypeFunction %2
  667. %6 = OpTypeBool
  668. %7 = OpTypePointer Function %6
  669. %9 = OpConstantTrue %6
  670. %11 = OpConstantFalse %6
  671. %14 = OpTypeFloat 32
  672. %15 = OpTypePointer Function %14
  673. %17 = OpConstant %14 1.23000002
  674. %19 = OpConstant %14 1.11000001
  675. %20 = OpTypeInt 32 1
  676. %21 = OpTypePointer Function %20
  677. %23 = OpConstant %20 0
  678. %25 = OpConstant %20 1
  679. %26 = OpTypeInt 32 0
  680. %27 = OpTypePointer Function %26
  681. %29 = OpConstant %26 100
  682. %31 = OpConstant %20 -1
  683. %33 = OpConstant %20 -99
  684. %35 = OpTypePointer Input %14
  685. %36 = OpVariable %35 Input
  686. %4 = OpFunction %2 None %3
  687. %5 = OpLabel
  688. %8 = OpVariable %7 Function
  689. %10 = OpVariable %7 Function
  690. %12 = OpVariable %7 Function
  691. %13 = OpVariable %7 Function
  692. %16 = OpVariable %15 Function
  693. %18 = OpVariable %15 Function
  694. %22 = OpVariable %21 Function
  695. %24 = OpVariable %21 Function
  696. %28 = OpVariable %27 Function
  697. %30 = OpVariable %21 Function
  698. %32 = OpVariable %21 Function
  699. OpStore %8 %9
  700. OpStore %10 %11
  701. OpStore %12 %9
  702. OpStore %13 %11
  703. OpStore %16 %17
  704. OpStore %18 %19
  705. OpStore %22 %23
  706. OpStore %24 %25
  707. OpStore %28 %29
  708. OpStore %30 %31
  709. OpStore %32 %33
  710. OpReturn
  711. OpFunctionEnd
  712. )";
  713. const auto env = SPV_ENV_UNIVERSAL_1_4;
  714. const auto consumer = nullptr;
  715. const std::unique_ptr<opt::IRContext> context =
  716. BuildModule(env, consumer, shader, kFuzzAssembleOption);
  717. spvtools::ValidatorOptions validator_options;
  718. ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
  719. kConsoleMessageConsumer));
  720. TransformationContext transformation_context(
  721. MakeUnique<FactManager>(context.get()), validator_options);
  722. opt::IRContext* ir_context = context.get();
  723. // A 32 bit unsigned int constant with value 1 exists and the id is 25.
  724. ASSERT_EQ(25, fuzzerutil::MaybeGetIntegerConstant(
  725. ir_context, transformation_context,
  726. std::vector<uint32_t>{1}, 32, true, false));
  727. // A 32 bit unsigned int constant with value 100 exists and the id is 29.
  728. ASSERT_EQ(29, fuzzerutil::MaybeGetIntegerConstant(
  729. ir_context, transformation_context,
  730. std::vector<uint32_t>{100}, 32, false, false));
  731. // A 32 bit signed int constant with value 99 doesn't not exist and should
  732. // return 0.
  733. ASSERT_EQ(0, fuzzerutil::MaybeGetIntegerConstant(
  734. ir_context, transformation_context,
  735. std::vector<uint32_t>{99}, 32, true, false));
  736. }
  737. TEST(FuzzerutilTest, FuzzerUtilMaybeGetIntegerTypeTest) {
  738. std::string shader = R"(
  739. OpCapability Shader
  740. %1 = OpExtInstImport "GLSL.std.450"
  741. OpMemoryModel Logical GLSL450
  742. OpEntryPoint Fragment %4 "main" %92 %52 %53
  743. OpExecutionMode %4 OriginUpperLeft
  744. OpSource ESSL 310
  745. OpDecorate %92 BuiltIn FragCoord
  746. %2 = OpTypeVoid
  747. %3 = OpTypeFunction %2
  748. %6 = OpTypeInt 32 1
  749. %7 = OpTypeFloat 32
  750. %8 = OpTypeStruct %6 %7
  751. %9 = OpTypePointer Function %8
  752. %10 = OpTypeFunction %6 %9
  753. %14 = OpConstant %6 0
  754. %15 = OpTypePointer Function %6
  755. %51 = OpTypePointer Private %6
  756. %21 = OpConstant %6 2
  757. %23 = OpConstant %6 1
  758. %24 = OpConstant %7 1
  759. %25 = OpTypePointer Function %7
  760. %50 = OpTypePointer Private %7
  761. %34 = OpTypeBool
  762. %35 = OpConstantFalse %34
  763. %52 = OpVariable %50 Private
  764. %53 = OpVariable %51 Private
  765. %80 = OpConstantComposite %8 %21 %24
  766. %90 = OpTypeVector %7 4
  767. %91 = OpTypePointer Input %90
  768. %92 = OpVariable %91 Input
  769. %93 = OpConstantComposite %90 %24 %24 %24 %24
  770. %4 = OpFunction %2 None %3
  771. %5 = OpLabel
  772. %20 = OpVariable %9 Function
  773. %27 = OpVariable %9 Function
  774. %22 = OpAccessChain %15 %20 %14
  775. %44 = OpCopyObject %9 %20
  776. %26 = OpAccessChain %25 %20 %23
  777. %29 = OpFunctionCall %6 %12 %27
  778. %30 = OpAccessChain %15 %20 %14
  779. %45 = OpCopyObject %15 %30
  780. %81 = OpCopyObject %9 %27
  781. %33 = OpAccessChain %15 %20 %14
  782. OpSelectionMerge %37 None
  783. OpBranchConditional %35 %36 %37
  784. %36 = OpLabel
  785. %38 = OpAccessChain %15 %20 %14
  786. %40 = OpAccessChain %15 %20 %14
  787. %43 = OpAccessChain %15 %20 %14
  788. %82 = OpCopyObject %9 %27
  789. OpBranch %37
  790. %37 = OpLabel
  791. OpReturn
  792. OpFunctionEnd
  793. %12 = OpFunction %6 None %10
  794. %11 = OpFunctionParameter %9
  795. %13 = OpLabel
  796. %46 = OpCopyObject %9 %11
  797. %16 = OpAccessChain %15 %11 %14
  798. %95 = OpCopyObject %8 %80
  799. OpReturnValue %21
  800. %100 = OpLabel
  801. OpUnreachable
  802. OpFunctionEnd
  803. )";
  804. const auto env = SPV_ENV_UNIVERSAL_1_4;
  805. const auto consumer = nullptr;
  806. const std::unique_ptr<opt::IRContext> context =
  807. BuildModule(env, consumer, shader, kFuzzAssembleOption);
  808. spvtools::ValidatorOptions validator_options;
  809. ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
  810. kConsoleMessageConsumer));
  811. opt::IRContext* ir_context = context.get();
  812. // A signed int type with width = 32 and result id of 6 exists.
  813. ASSERT_EQ(6, fuzzerutil::MaybeGetIntegerType(ir_context, 32, true));
  814. // A signed int type with width = 32 exists, but the id should be 6.
  815. ASSERT_FALSE(fuzzerutil::MaybeGetIntegerType(ir_context, 32, true) == 5);
  816. // A int type with width = 32 and result id of 6 exists, but it should be a
  817. // signed int.
  818. ASSERT_EQ(0, fuzzerutil::MaybeGetIntegerType(ir_context, 32, false));
  819. // A signed int type with width 30 does not exist.
  820. ASSERT_EQ(0, fuzzerutil::MaybeGetIntegerType(ir_context, 30, true));
  821. // An unsigned int type with width 22 does not exist.
  822. ASSERT_EQ(0, fuzzerutil::MaybeGetIntegerType(ir_context, 22, false));
  823. }
  824. TEST(FuzzerutilTest, FuzzerUtilMaybeGetPointerTypeTest) {
  825. std::string shader = R"(
  826. OpCapability Shader
  827. %1 = OpExtInstImport "GLSL.std.450"
  828. OpMemoryModel Logical GLSL450
  829. OpEntryPoint Fragment %4 "main" %92 %52 %53
  830. OpExecutionMode %4 OriginUpperLeft
  831. OpSource ESSL 310
  832. OpDecorate %92 BuiltIn FragCoord
  833. %2 = OpTypeVoid
  834. %3 = OpTypeFunction %2
  835. %6 = OpTypeInt 32 1
  836. %7 = OpTypeFloat 32
  837. %8 = OpTypeStruct %6 %7
  838. %9 = OpTypePointer Function %8
  839. %10 = OpTypeFunction %6 %9
  840. %14 = OpConstant %6 0
  841. %15 = OpTypePointer Function %6
  842. %51 = OpTypePointer Private %6
  843. %21 = OpConstant %6 2
  844. %23 = OpConstant %6 1
  845. %24 = OpConstant %7 1
  846. %25 = OpTypePointer Function %7
  847. %50 = OpTypePointer Private %7
  848. %34 = OpTypeBool
  849. %35 = OpConstantFalse %34
  850. %52 = OpVariable %50 Private
  851. %53 = OpVariable %51 Private
  852. %80 = OpConstantComposite %8 %21 %24
  853. %90 = OpTypeVector %7 4
  854. %91 = OpTypePointer Input %90
  855. %92 = OpVariable %91 Input
  856. %93 = OpConstantComposite %90 %24 %24 %24 %24
  857. %4 = OpFunction %2 None %3
  858. %5 = OpLabel
  859. %20 = OpVariable %9 Function
  860. %27 = OpVariable %9 Function
  861. %22 = OpAccessChain %15 %20 %14
  862. %44 = OpCopyObject %9 %20
  863. %26 = OpAccessChain %25 %20 %23
  864. %29 = OpFunctionCall %6 %12 %27
  865. %30 = OpAccessChain %15 %20 %14
  866. %45 = OpCopyObject %15 %30
  867. %81 = OpCopyObject %9 %27
  868. %33 = OpAccessChain %15 %20 %14
  869. OpSelectionMerge %37 None
  870. OpBranchConditional %35 %36 %37
  871. %36 = OpLabel
  872. %38 = OpAccessChain %15 %20 %14
  873. %40 = OpAccessChain %15 %20 %14
  874. %43 = OpAccessChain %15 %20 %14
  875. %82 = OpCopyObject %9 %27
  876. OpBranch %37
  877. %37 = OpLabel
  878. OpReturn
  879. OpFunctionEnd
  880. %12 = OpFunction %6 None %10
  881. %11 = OpFunctionParameter %9
  882. %13 = OpLabel
  883. %46 = OpCopyObject %9 %11
  884. %16 = OpAccessChain %15 %11 %14
  885. %95 = OpCopyObject %8 %80
  886. OpReturnValue %21
  887. %100 = OpLabel
  888. OpUnreachable
  889. OpFunctionEnd
  890. )";
  891. const auto env = SPV_ENV_UNIVERSAL_1_4;
  892. const auto consumer = nullptr;
  893. const std::unique_ptr<opt::IRContext> context =
  894. BuildModule(env, consumer, shader, kFuzzAssembleOption);
  895. spvtools::ValidatorOptions validator_options;
  896. ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
  897. kConsoleMessageConsumer));
  898. opt::IRContext* ir_context = context.get();
  899. auto private_storage_class = spv::StorageClass::Private;
  900. auto function_storage_class = spv::StorageClass::Function;
  901. auto input_storage_class = spv::StorageClass::Input;
  902. // A valid pointer must have the correct |pointee_type_id| and |storageClass|.
  903. // A function type pointer with id = 9 and pointee type id 8 should be found.
  904. ASSERT_EQ(9, fuzzerutil::MaybeGetPointerType(ir_context, 8,
  905. function_storage_class));
  906. // A function type pointer with id = 15 and pointee type id 6 should be found.
  907. ASSERT_EQ(15, fuzzerutil::MaybeGetPointerType(ir_context, 6,
  908. function_storage_class));
  909. // A function type pointer with id = 25 and pointee type id 7 should be found.
  910. ASSERT_EQ(25, fuzzerutil::MaybeGetPointerType(ir_context, 7,
  911. function_storage_class));
  912. // A private type pointer with id=51 and pointee type id 6 should be found.
  913. ASSERT_EQ(51, fuzzerutil::MaybeGetPointerType(ir_context, 6,
  914. private_storage_class));
  915. // A function pointer with id=50 and pointee type id 7 should be found.
  916. ASSERT_EQ(50, fuzzerutil::MaybeGetPointerType(ir_context, 7,
  917. private_storage_class));
  918. // A input type pointer with id=91 and pointee type id 90 should be found.
  919. ASSERT_EQ(
  920. 91, fuzzerutil::MaybeGetPointerType(ir_context, 90, input_storage_class));
  921. // A pointer with id=91 and pointee type 90 exists, but the type should be
  922. // input.
  923. ASSERT_EQ(0, fuzzerutil::MaybeGetPointerType(ir_context, 90,
  924. function_storage_class));
  925. // A input type pointer with id=91 exists but the pointee id should be 90.
  926. ASSERT_EQ(
  927. 0, fuzzerutil::MaybeGetPointerType(ir_context, 89, input_storage_class));
  928. // A input type pointer with pointee id 90 exists but result id of the pointer
  929. // should be 91.
  930. ASSERT_NE(
  931. 58, fuzzerutil::MaybeGetPointerType(ir_context, 90, input_storage_class));
  932. }
  933. TEST(FuzzerutilTest, FuzzerUtilMaybeGetScalarConstantTest) {
  934. std::string shader = R"(
  935. OpCapability Shader
  936. %1 = OpExtInstImport "GLSL.std.450"
  937. OpMemoryModel Logical GLSL450
  938. OpEntryPoint Fragment %4 "main" %56
  939. OpExecutionMode %4 OriginUpperLeft
  940. OpSource ESSL 310
  941. OpName %4 "main"
  942. OpName %8 "b1"
  943. OpName %10 "b2"
  944. OpName %12 "b3"
  945. OpName %13 "b4"
  946. OpName %16 "f1"
  947. OpName %18 "f2"
  948. OpName %22 "zc"
  949. OpName %24 "i1"
  950. OpName %28 "i2"
  951. OpName %30 "i"
  952. OpName %32 "i3"
  953. OpName %34 "i4"
  954. OpName %39 "f_arr"
  955. OpName %49 "i_arr"
  956. OpName %56 "value"
  957. OpDecorate %22 RelaxedPrecision
  958. OpDecorate %24 RelaxedPrecision
  959. OpDecorate %28 RelaxedPrecision
  960. OpDecorate %30 RelaxedPrecision
  961. OpDecorate %32 RelaxedPrecision
  962. OpDecorate %34 RelaxedPrecision
  963. OpDecorate %49 RelaxedPrecision
  964. OpDecorate %56 Location 0
  965. %2 = OpTypeVoid
  966. %3 = OpTypeFunction %2
  967. %6 = OpTypeBool
  968. %7 = OpTypePointer Function %6
  969. %9 = OpConstantTrue %6
  970. %11 = OpConstantFalse %6
  971. %14 = OpTypeFloat 32
  972. %15 = OpTypePointer Function %14
  973. %17 = OpConstant %14 1.23000002
  974. %19 = OpConstant %14 1.11000001
  975. %20 = OpTypeInt 32 1
  976. %21 = OpTypePointer Function %20
  977. %23 = OpConstant %20 0
  978. %25 = OpConstant %20 1
  979. %26 = OpTypeInt 32 0
  980. %27 = OpTypePointer Function %26
  981. %29 = OpConstant %26 100
  982. %31 = OpConstant %26 0
  983. %33 = OpConstant %20 -1
  984. %35 = OpConstant %20 -99
  985. %36 = OpConstant %26 5
  986. %37 = OpTypeArray %14 %36
  987. %38 = OpTypePointer Function %37
  988. %40 = OpConstant %14 5.5
  989. %41 = OpConstant %14 4.4000001
  990. %42 = OpConstant %14 3.29999995
  991. %43 = OpConstant %14 2.20000005
  992. %44 = OpConstant %14 1.10000002
  993. %45 = OpConstantComposite %37 %40 %41 %42 %43 %44
  994. %46 = OpConstant %26 3
  995. %47 = OpTypeArray %20 %46
  996. %48 = OpTypePointer Function %47
  997. %50 = OpConstant %20 3
  998. %51 = OpConstant %20 7
  999. %52 = OpConstant %20 9
  1000. %53 = OpConstantComposite %47 %50 %51 %52
  1001. %55 = OpTypePointer Input %14
  1002. %56 = OpVariable %55 Input
  1003. %4 = OpFunction %2 None %3
  1004. %5 = OpLabel
  1005. %8 = OpVariable %7 Function
  1006. %10 = OpVariable %7 Function
  1007. %12 = OpVariable %7 Function
  1008. %13 = OpVariable %7 Function
  1009. %16 = OpVariable %15 Function
  1010. %18 = OpVariable %15 Function
  1011. %22 = OpVariable %21 Function
  1012. %24 = OpVariable %21 Function
  1013. %28 = OpVariable %27 Function
  1014. %30 = OpVariable %27 Function
  1015. %32 = OpVariable %21 Function
  1016. %34 = OpVariable %21 Function
  1017. %39 = OpVariable %38 Function
  1018. %49 = OpVariable %48 Function
  1019. OpStore %8 %9
  1020. OpStore %10 %11
  1021. OpStore %12 %9
  1022. OpStore %13 %11
  1023. OpStore %16 %17
  1024. OpStore %18 %19
  1025. OpStore %22 %23
  1026. OpStore %24 %25
  1027. OpStore %28 %29
  1028. OpStore %30 %31
  1029. OpStore %32 %33
  1030. OpStore %34 %35
  1031. OpStore %39 %45
  1032. OpStore %49 %53
  1033. OpReturn
  1034. OpFunctionEnd
  1035. )";
  1036. const auto env = SPV_ENV_UNIVERSAL_1_4;
  1037. const auto consumer = nullptr;
  1038. const std::unique_ptr<opt::IRContext> context =
  1039. BuildModule(env, consumer, shader, kFuzzAssembleOption);
  1040. spvtools::ValidatorOptions validator_options;
  1041. ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
  1042. kConsoleMessageConsumer));
  1043. TransformationContext transformation_context(
  1044. MakeUnique<FactManager>(context.get()), validator_options);
  1045. opt::IRContext* ir_context = context.get();
  1046. std::vector<uint32_t> uint_words1 = fuzzerutil::IntToWords(100, 32, false);
  1047. std::vector<uint32_t> uint_words2 = fuzzerutil::IntToWords(0, 32, false);
  1048. std::vector<uint32_t> int_words1 = fuzzerutil::IntToWords(-99, 32, true);
  1049. std::vector<uint32_t> int_words2 = fuzzerutil::IntToWords(1, 32, true);
  1050. uint32_t float_word1 = fuzzerutil::FloatToWord(1.11f);
  1051. uint32_t float_word2 = fuzzerutil::FloatToWord(4.4f);
  1052. // A unsigned int of value 100 that has a scalar type id of 26 exists and its
  1053. // id is 29.
  1054. ASSERT_EQ(
  1055. 29, fuzzerutil::MaybeGetScalarConstant(ir_context, transformation_context,
  1056. uint_words1, 26, false));
  1057. // A unsigned int of value 0 that has a scalar type id of 26 exists and its id
  1058. // is 29.
  1059. ASSERT_EQ(
  1060. 31, fuzzerutil::MaybeGetScalarConstant(ir_context, transformation_context,
  1061. uint_words2, 26, false));
  1062. // A signed int of value -99 that has a scalar type id of 20 exists and its id
  1063. // is 35.
  1064. ASSERT_EQ(35, fuzzerutil::MaybeGetScalarConstant(
  1065. ir_context, transformation_context, int_words1, 20, false));
  1066. // A signed int of value 1 that has a scalar type id of 20 exists and its id
  1067. // is 25.
  1068. ASSERT_EQ(25, fuzzerutil::MaybeGetScalarConstant(
  1069. ir_context, transformation_context, int_words2, 20, false));
  1070. // A float of value 1.11 that has a scalar type id of 14 exists and its id
  1071. // is 19.
  1072. ASSERT_EQ(19, fuzzerutil::MaybeGetScalarConstant(
  1073. ir_context, transformation_context,
  1074. std::vector<uint32_t>{float_word1}, 14, false));
  1075. // A signed int of value 1 that has a scalar type id of 20 exists and its id
  1076. // is 25.
  1077. ASSERT_EQ(41, fuzzerutil::MaybeGetScalarConstant(
  1078. ir_context, transformation_context,
  1079. std::vector<uint32_t>{float_word2}, 14, false));
  1080. }
  1081. TEST(FuzzerutilTest, FuzzerUtilMaybeGetStructTypeTest) {
  1082. std::string shader = R"(
  1083. OpCapability Shader
  1084. %1 = OpExtInstImport "GLSL.std.450"
  1085. OpMemoryModel Logical GLSL450
  1086. OpEntryPoint Fragment %4 "main" %92 %52 %53
  1087. OpExecutionMode %4 OriginUpperLeft
  1088. OpSource ESSL 310
  1089. OpDecorate %92 BuiltIn FragCoord
  1090. %2 = OpTypeVoid
  1091. %3 = OpTypeFunction %2
  1092. %6 = OpTypeInt 32 1
  1093. %7 = OpTypeFloat 32
  1094. %8 = OpTypeStruct %6 %7
  1095. %9 = OpTypePointer Function %8
  1096. %10 = OpTypeFunction %6 %9
  1097. %14 = OpConstant %6 0
  1098. %15 = OpTypePointer Function %6
  1099. %51 = OpTypePointer Private %6
  1100. %21 = OpConstant %6 2
  1101. %23 = OpConstant %6 1
  1102. %24 = OpConstant %7 1
  1103. %25 = OpTypePointer Function %7
  1104. %50 = OpTypePointer Private %7
  1105. %34 = OpTypeBool
  1106. %35 = OpConstantFalse %34
  1107. %52 = OpVariable %50 Private
  1108. %53 = OpVariable %51 Private
  1109. %80 = OpConstantComposite %8 %21 %24
  1110. %90 = OpTypeVector %7 4
  1111. %91 = OpTypePointer Input %90
  1112. %92 = OpVariable %91 Input
  1113. %93 = OpConstantComposite %90 %24 %24 %24 %24
  1114. %4 = OpFunction %2 None %3
  1115. %5 = OpLabel
  1116. %20 = OpVariable %9 Function
  1117. %27 = OpVariable %9 Function
  1118. %22 = OpAccessChain %15 %20 %14
  1119. %44 = OpCopyObject %9 %20
  1120. %26 = OpAccessChain %25 %20 %23
  1121. %29 = OpFunctionCall %6 %12 %27
  1122. %30 = OpAccessChain %15 %20 %14
  1123. %45 = OpCopyObject %15 %30
  1124. %81 = OpCopyObject %9 %27
  1125. %33 = OpAccessChain %15 %20 %14
  1126. OpSelectionMerge %37 None
  1127. OpBranchConditional %35 %36 %37
  1128. %36 = OpLabel
  1129. %38 = OpAccessChain %15 %20 %14
  1130. %40 = OpAccessChain %15 %20 %14
  1131. %43 = OpAccessChain %15 %20 %14
  1132. %82 = OpCopyObject %9 %27
  1133. OpBranch %37
  1134. %37 = OpLabel
  1135. OpReturn
  1136. OpFunctionEnd
  1137. %12 = OpFunction %6 None %10
  1138. %11 = OpFunctionParameter %9
  1139. %13 = OpLabel
  1140. %46 = OpCopyObject %9 %11
  1141. %16 = OpAccessChain %15 %11 %14
  1142. %95 = OpCopyObject %8 %80
  1143. OpReturnValue %21
  1144. %100 = OpLabel
  1145. OpUnreachable
  1146. OpFunctionEnd
  1147. )";
  1148. const auto env = SPV_ENV_UNIVERSAL_1_4;
  1149. const auto consumer = nullptr;
  1150. const std::unique_ptr<opt::IRContext> context =
  1151. BuildModule(env, consumer, shader, kFuzzAssembleOption);
  1152. spvtools::ValidatorOptions validator_options;
  1153. ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
  1154. kConsoleMessageConsumer));
  1155. opt::IRContext* ir_context = context.get();
  1156. // 6 and 7 are all valid ids from OpTypeInt and OpTypeFloat
  1157. // so the result id of 8 should be found.
  1158. ASSERT_EQ(8, fuzzerutil::MaybeGetStructType(ir_context,
  1159. std::vector<uint32_t>{6, 7}));
  1160. // |component_type_id| of 16 does not exist in the module, so such a struct
  1161. // type cannot be found.
  1162. ASSERT_EQ(0, fuzzerutil::MaybeGetStructType(ir_context,
  1163. std::vector<uint32_t>(6, 16)));
  1164. // |component_type_id| of 10 is of OpTypeFunction type and thus the struct
  1165. // cannot be found.
  1166. ASSERT_EQ(0, fuzzerutil::MaybeGetStructType(ir_context,
  1167. std::vector<uint32_t>(6, 10)));
  1168. }
  1169. TEST(FuzzerutilTest, FuzzerUtilMaybeGetVectorTypeTest) {
  1170. std::string shader = R"(
  1171. OpCapability Shader
  1172. %1 = OpExtInstImport "GLSL.std.450"
  1173. OpMemoryModel Logical GLSL450
  1174. OpEntryPoint Fragment %4 "main" %92 %52 %53
  1175. OpExecutionMode %4 OriginUpperLeft
  1176. OpSource ESSL 310
  1177. OpDecorate %92 BuiltIn FragCoord
  1178. %2 = OpTypeVoid
  1179. %3 = OpTypeFunction %2
  1180. %6 = OpTypeInt 32 1
  1181. %7 = OpTypeFloat 32
  1182. %8 = OpTypeStruct %6 %7
  1183. %9 = OpTypePointer Function %8
  1184. %10 = OpTypeFunction %6 %9
  1185. %14 = OpConstant %6 0
  1186. %15 = OpTypePointer Function %6
  1187. %51 = OpTypePointer Private %6
  1188. %21 = OpConstant %6 2
  1189. %23 = OpConstant %6 1
  1190. %24 = OpConstant %7 1
  1191. %25 = OpTypePointer Function %7
  1192. %50 = OpTypePointer Private %7
  1193. %34 = OpTypeBool
  1194. %35 = OpConstantFalse %34
  1195. %52 = OpVariable %50 Private
  1196. %53 = OpVariable %51 Private
  1197. %80 = OpConstantComposite %8 %21 %24
  1198. %90 = OpTypeVector %7 4
  1199. %91 = OpTypePointer Input %90
  1200. %92 = OpVariable %91 Input
  1201. %93 = OpConstantComposite %90 %24 %24 %24 %24
  1202. %4 = OpFunction %2 None %3
  1203. %5 = OpLabel
  1204. %20 = OpVariable %9 Function
  1205. %27 = OpVariable %9 Function
  1206. %22 = OpAccessChain %15 %20 %14
  1207. %44 = OpCopyObject %9 %20
  1208. %26 = OpAccessChain %25 %20 %23
  1209. %29 = OpFunctionCall %6 %12 %27
  1210. %30 = OpAccessChain %15 %20 %14
  1211. %45 = OpCopyObject %15 %30
  1212. %81 = OpCopyObject %9 %27
  1213. %33 = OpAccessChain %15 %20 %14
  1214. OpSelectionMerge %37 None
  1215. OpBranchConditional %35 %36 %37
  1216. %36 = OpLabel
  1217. %38 = OpAccessChain %15 %20 %14
  1218. %40 = OpAccessChain %15 %20 %14
  1219. %43 = OpAccessChain %15 %20 %14
  1220. %82 = OpCopyObject %9 %27
  1221. OpBranch %37
  1222. %37 = OpLabel
  1223. OpReturn
  1224. OpFunctionEnd
  1225. %12 = OpFunction %6 None %10
  1226. %11 = OpFunctionParameter %9
  1227. %13 = OpLabel
  1228. %46 = OpCopyObject %9 %11
  1229. %16 = OpAccessChain %15 %11 %14
  1230. %95 = OpCopyObject %8 %80
  1231. OpReturnValue %21
  1232. %100 = OpLabel
  1233. OpUnreachable
  1234. OpFunctionEnd
  1235. )";
  1236. const auto env = SPV_ENV_UNIVERSAL_1_4;
  1237. const auto consumer = nullptr;
  1238. const std::unique_ptr<opt::IRContext> context =
  1239. BuildModule(env, consumer, shader, kFuzzAssembleOption);
  1240. spvtools::ValidatorOptions validator_options;
  1241. ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
  1242. kConsoleMessageConsumer));
  1243. opt::IRContext* ir_context = context.get();
  1244. // The vector type with |element_count| 4 and |component_type_id| 7
  1245. // is present and has a result id of 90.
  1246. ASSERT_EQ(90, fuzzerutil::MaybeGetVectorType(ir_context, 7, 4));
  1247. // The vector type with |element_count| 3 and |component_type_id| 7
  1248. // is not present in the module.
  1249. ASSERT_EQ(0, fuzzerutil::MaybeGetVectorType(ir_context, 7, 3));
  1250. #ifndef NDEBUG
  1251. // It should abort with |component_type_id| of 100
  1252. // |component_type_id| must be a valid result id of an OpTypeInt,
  1253. // OpTypeFloat or OpTypeBool instruction in the module.
  1254. ASSERT_DEATH(fuzzerutil::MaybeGetVectorType(ir_context, 100, 4),
  1255. "\\|component_type_id\\| is invalid");
  1256. // It should abort with |element_count| of 5.
  1257. // |element_count| must be in the range [2,4].
  1258. ASSERT_DEATH(fuzzerutil::MaybeGetVectorType(ir_context, 7, 5),
  1259. "Precondition: component count must be in range \\[2, 4\\].");
  1260. #endif
  1261. }
  1262. TEST(FuzzerutilTest, FuzzerUtilMaybeGetVoidTypeTest) {
  1263. std::string shader = R"(
  1264. OpCapability Shader
  1265. %1 = OpExtInstImport "GLSL.std.450"
  1266. OpMemoryModel Logical GLSL450
  1267. OpEntryPoint Fragment %4 "main" %92 %52 %53
  1268. OpExecutionMode %4 OriginUpperLeft
  1269. OpSource ESSL 310
  1270. OpDecorate %92 BuiltIn FragCoord
  1271. %2 = OpTypeVoid
  1272. %3 = OpTypeFunction %2
  1273. %6 = OpTypeInt 32 1
  1274. %7 = OpTypeFloat 32
  1275. %8 = OpTypeStruct %6 %7
  1276. %9 = OpTypePointer Function %8
  1277. %10 = OpTypeFunction %6 %9
  1278. %14 = OpConstant %6 0
  1279. %15 = OpTypePointer Function %6
  1280. %51 = OpTypePointer Private %6
  1281. %21 = OpConstant %6 2
  1282. %23 = OpConstant %6 1
  1283. %24 = OpConstant %7 1
  1284. %25 = OpTypePointer Function %7
  1285. %50 = OpTypePointer Private %7
  1286. %34 = OpTypeBool
  1287. %35 = OpConstantFalse %34
  1288. %52 = OpVariable %50 Private
  1289. %53 = OpVariable %51 Private
  1290. %80 = OpConstantComposite %8 %21 %24
  1291. %90 = OpTypeVector %7 4
  1292. %91 = OpTypePointer Input %90
  1293. %92 = OpVariable %91 Input
  1294. %93 = OpConstantComposite %90 %24 %24 %24 %24
  1295. %4 = OpFunction %2 None %3
  1296. %5 = OpLabel
  1297. %20 = OpVariable %9 Function
  1298. %27 = OpVariable %9 Function
  1299. %22 = OpAccessChain %15 %20 %14
  1300. %44 = OpCopyObject %9 %20
  1301. %26 = OpAccessChain %25 %20 %23
  1302. %29 = OpFunctionCall %6 %12 %27
  1303. %30 = OpAccessChain %15 %20 %14
  1304. %45 = OpCopyObject %15 %30
  1305. %81 = OpCopyObject %9 %27
  1306. %33 = OpAccessChain %15 %20 %14
  1307. OpSelectionMerge %37 None
  1308. OpBranchConditional %35 %36 %37
  1309. %36 = OpLabel
  1310. %38 = OpAccessChain %15 %20 %14
  1311. %40 = OpAccessChain %15 %20 %14
  1312. %43 = OpAccessChain %15 %20 %14
  1313. %82 = OpCopyObject %9 %27
  1314. OpBranch %37
  1315. %37 = OpLabel
  1316. OpReturn
  1317. OpFunctionEnd
  1318. %12 = OpFunction %6 None %10
  1319. %11 = OpFunctionParameter %9
  1320. %13 = OpLabel
  1321. %46 = OpCopyObject %9 %11
  1322. %16 = OpAccessChain %15 %11 %14
  1323. %95 = OpCopyObject %8 %80
  1324. OpReturnValue %21
  1325. %100 = OpLabel
  1326. OpUnreachable
  1327. OpFunctionEnd
  1328. )";
  1329. const auto env = SPV_ENV_UNIVERSAL_1_4;
  1330. const auto consumer = nullptr;
  1331. const std::unique_ptr<opt::IRContext> context =
  1332. BuildModule(env, consumer, shader, kFuzzAssembleOption);
  1333. spvtools::ValidatorOptions validator_options;
  1334. ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
  1335. kConsoleMessageConsumer));
  1336. opt::IRContext* ir_context = context.get();
  1337. // A void type with a result id of 2 can be found.
  1338. ASSERT_EQ(2, fuzzerutil::MaybeGetVoidType(ir_context));
  1339. }
  1340. TEST(FuzzerutilTest, FuzzerUtilMaybeGetZeroConstantTest) {
  1341. std::string shader = R"(
  1342. OpCapability Shader
  1343. %1 = OpExtInstImport "GLSL.std.450"
  1344. OpMemoryModel Logical GLSL450
  1345. OpEntryPoint Fragment %4 "main" %56
  1346. OpExecutionMode %4 OriginUpperLeft
  1347. OpSource ESSL 310
  1348. OpName %4 "main"
  1349. OpName %8 "b1"
  1350. OpName %10 "b2"
  1351. OpName %12 "b3"
  1352. OpName %13 "b4"
  1353. OpName %16 "f1"
  1354. OpName %18 "f2"
  1355. OpName %22 "zc"
  1356. OpName %24 "i1"
  1357. OpName %28 "i2"
  1358. OpName %30 "i"
  1359. OpName %32 "i3"
  1360. OpName %34 "i4"
  1361. OpName %39 "f_arr"
  1362. OpName %49 "i_arr"
  1363. OpName %56 "value"
  1364. OpDecorate %22 RelaxedPrecision
  1365. OpDecorate %24 RelaxedPrecision
  1366. OpDecorate %28 RelaxedPrecision
  1367. OpDecorate %30 RelaxedPrecision
  1368. OpDecorate %32 RelaxedPrecision
  1369. OpDecorate %34 RelaxedPrecision
  1370. OpDecorate %49 RelaxedPrecision
  1371. OpDecorate %56 Location 0
  1372. %2 = OpTypeVoid
  1373. %3 = OpTypeFunction %2
  1374. %6 = OpTypeBool
  1375. %7 = OpTypePointer Function %6
  1376. %9 = OpConstantTrue %6
  1377. %11 = OpConstantFalse %6
  1378. %14 = OpTypeFloat 32
  1379. %15 = OpTypePointer Function %14
  1380. %17 = OpConstant %14 1.23000002
  1381. %19 = OpConstant %14 1.11000001
  1382. %20 = OpTypeInt 32 1
  1383. %21 = OpTypePointer Function %20
  1384. %23 = OpConstant %20 0
  1385. %25 = OpConstant %20 1
  1386. %26 = OpTypeInt 32 0
  1387. %27 = OpTypePointer Function %26
  1388. %29 = OpConstant %26 100
  1389. %31 = OpConstant %26 0
  1390. %33 = OpConstant %20 -1
  1391. %35 = OpConstant %20 -99
  1392. %36 = OpConstant %26 5
  1393. %37 = OpTypeArray %14 %36
  1394. %38 = OpTypePointer Function %37
  1395. %40 = OpConstant %14 5.5
  1396. %41 = OpConstant %14 4.4000001
  1397. %42 = OpConstant %14 3.29999995
  1398. %43 = OpConstant %14 2.20000005
  1399. %44 = OpConstant %14 1.10000002
  1400. %45 = OpConstantComposite %37 %40 %41 %42 %43 %44
  1401. %46 = OpConstant %26 3
  1402. %47 = OpTypeArray %20 %46
  1403. %48 = OpTypePointer Function %47
  1404. %50 = OpConstant %20 3
  1405. %51 = OpConstant %20 7
  1406. %52 = OpConstant %20 9
  1407. %53 = OpConstantComposite %47 %50 %51 %52
  1408. %55 = OpTypePointer Input %14
  1409. %56 = OpVariable %55 Input
  1410. %4 = OpFunction %2 None %3
  1411. %5 = OpLabel
  1412. %8 = OpVariable %7 Function
  1413. %10 = OpVariable %7 Function
  1414. %12 = OpVariable %7 Function
  1415. %13 = OpVariable %7 Function
  1416. %16 = OpVariable %15 Function
  1417. %18 = OpVariable %15 Function
  1418. %22 = OpVariable %21 Function
  1419. %24 = OpVariable %21 Function
  1420. %28 = OpVariable %27 Function
  1421. %30 = OpVariable %27 Function
  1422. %32 = OpVariable %21 Function
  1423. %34 = OpVariable %21 Function
  1424. %39 = OpVariable %38 Function
  1425. %49 = OpVariable %48 Function
  1426. OpStore %8 %9
  1427. OpStore %10 %11
  1428. OpStore %12 %9
  1429. OpStore %13 %11
  1430. OpStore %16 %17
  1431. OpStore %18 %19
  1432. OpStore %22 %23
  1433. OpStore %24 %25
  1434. OpStore %28 %29
  1435. OpStore %30 %31
  1436. OpStore %32 %33
  1437. OpStore %34 %35
  1438. OpStore %39 %45
  1439. OpStore %49 %53
  1440. OpReturn
  1441. OpFunctionEnd
  1442. )";
  1443. const auto env = SPV_ENV_UNIVERSAL_1_4;
  1444. const auto consumer = nullptr;
  1445. const std::unique_ptr<opt::IRContext> context =
  1446. BuildModule(env, consumer, shader, kFuzzAssembleOption);
  1447. spvtools::ValidatorOptions validator_options;
  1448. ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
  1449. kConsoleMessageConsumer));
  1450. TransformationContext transformation_context(
  1451. MakeUnique<FactManager>(context.get()), validator_options);
  1452. opt::IRContext* ir_context = context.get();
  1453. // The id of a boolean constant will be returned give boolean type id 6.
  1454. uint32_t maybe_bool_id = fuzzerutil::MaybeGetZeroConstant(
  1455. ir_context, transformation_context, 6, false);
  1456. // The id of a 32 bit float constant will be returned given the float type
  1457. // id 14.
  1458. uint32_t maybe_float_id = fuzzerutil::MaybeGetZeroConstant(
  1459. ir_context, transformation_context, 14, false);
  1460. uint32_t maybe_signed_int_id = fuzzerutil::MaybeGetZeroConstant(
  1461. ir_context, transformation_context, 20, false);
  1462. uint32_t maybe_unsigned_int_id = fuzzerutil::MaybeGetZeroConstant(
  1463. ir_context, transformation_context, 26, false);
  1464. // Lists of possible ids for float, signed int, unsigned int and array.
  1465. std::vector<uint32_t> float_ids{17, 19};
  1466. std::vector<uint32_t> signed_int_ids{23, 25, 31, 33};
  1467. ASSERT_TRUE(maybe_bool_id == 9 || maybe_bool_id == 11);
  1468. ASSERT_TRUE(std::find(signed_int_ids.begin(), signed_int_ids.end(),
  1469. maybe_signed_int_id) != signed_int_ids.end());
  1470. // There is a unsigned int typed zero constant and its id is 31.
  1471. ASSERT_EQ(31, maybe_unsigned_int_id);
  1472. // There is no zero float constant.
  1473. ASSERT_TRUE(std::find(float_ids.begin(), float_ids.end(), maybe_float_id) ==
  1474. float_ids.end());
  1475. }
  1476. TEST(FuzzerutilTest, TypesAreCompatible) {
  1477. const std::string shader = R"(
  1478. OpCapability Shader
  1479. %1 = OpExtInstImport "GLSL.std.450"
  1480. OpMemoryModel Logical GLSL450
  1481. OpEntryPoint Fragment %4 "main"
  1482. OpExecutionMode %4 OriginUpperLeft
  1483. OpSource ESSL 320
  1484. %2 = OpTypeVoid
  1485. %3 = OpTypeFunction %2
  1486. %6 = OpTypeInt 32 1
  1487. %9 = OpTypeInt 32 0
  1488. %8 = OpTypeStruct %6
  1489. %10 = OpTypePointer StorageBuffer %8
  1490. %11 = OpVariable %10 StorageBuffer
  1491. %86 = OpTypeStruct %9
  1492. %87 = OpTypePointer Workgroup %86
  1493. %88 = OpVariable %87 Workgroup
  1494. %89 = OpTypePointer Workgroup %9
  1495. %19 = OpConstant %9 0
  1496. %18 = OpConstant %9 1
  1497. %12 = OpConstant %6 0
  1498. %13 = OpTypePointer StorageBuffer %6
  1499. %15 = OpConstant %6 2
  1500. %16 = OpConstant %6 7
  1501. %20 = OpConstant %9 64
  1502. %4 = OpFunction %2 None %3
  1503. %5 = OpLabel
  1504. %14 = OpAccessChain %13 %11 %12
  1505. %90 = OpAccessChain %89 %88 %19
  1506. %21 = OpAtomicLoad %6 %14 %15 %20
  1507. %22 = OpAtomicExchange %6 %14 %15 %20 %16
  1508. %23 = OpAtomicCompareExchange %6 %14 %15 %20 %12 %16 %15
  1509. %24 = OpAtomicIIncrement %6 %14 %15 %20
  1510. %25 = OpAtomicIDecrement %6 %14 %15 %20
  1511. %26 = OpAtomicIAdd %6 %14 %15 %20 %16
  1512. %27 = OpAtomicISub %6 %14 %15 %20 %16
  1513. %28 = OpAtomicSMin %6 %14 %15 %20 %16
  1514. %29 = OpAtomicUMin %9 %90 %15 %20 %18
  1515. %30 = OpAtomicSMax %6 %14 %15 %20 %15
  1516. %31 = OpAtomicUMax %9 %90 %15 %20 %18
  1517. %32 = OpAtomicAnd %6 %14 %15 %20 %16
  1518. %33 = OpAtomicOr %6 %14 %15 %20 %16
  1519. %34 = OpAtomicXor %6 %14 %15 %20 %16
  1520. OpAtomicStore %14 %15 %20 %16
  1521. OpReturn
  1522. OpFunctionEnd
  1523. )";
  1524. const auto env = SPV_ENV_UNIVERSAL_1_3;
  1525. const auto consumer = nullptr;
  1526. const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
  1527. spvtools::ValidatorOptions validator_options;
  1528. ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
  1529. kConsoleMessageConsumer));
  1530. const uint32_t int_type = 6; // The id of OpTypeInt 32 1
  1531. const uint32_t uint_type = 9; // The id of OpTypeInt 32 0
  1532. // OpAtomicLoad
  1533. #ifndef NDEBUG
  1534. ASSERT_DEATH(
  1535. fuzzerutil::TypesAreCompatible(context.get(), spv::Op::OpAtomicLoad, 0,
  1536. int_type, uint_type),
  1537. "Signedness check should not occur on a pointer operand.");
  1538. #endif
  1539. ASSERT_TRUE(fuzzerutil::TypesAreCompatible(
  1540. context.get(), spv::Op::OpAtomicLoad, 1, int_type, uint_type));
  1541. ASSERT_TRUE(fuzzerutil::TypesAreCompatible(
  1542. context.get(), spv::Op::OpAtomicLoad, 2, int_type, uint_type));
  1543. // OpAtomicExchange
  1544. #ifndef NDEBUG
  1545. ASSERT_DEATH(
  1546. fuzzerutil::TypesAreCompatible(context.get(), spv::Op::OpAtomicExchange,
  1547. 0, int_type, uint_type),
  1548. "Signedness check should not occur on a pointer operand.");
  1549. #endif
  1550. ASSERT_TRUE(fuzzerutil::TypesAreCompatible(
  1551. context.get(), spv::Op::OpAtomicExchange, 1, int_type, uint_type));
  1552. ASSERT_TRUE(fuzzerutil::TypesAreCompatible(
  1553. context.get(), spv::Op::OpAtomicExchange, 2, int_type, uint_type));
  1554. ASSERT_FALSE(fuzzerutil::TypesAreCompatible(
  1555. context.get(), spv::Op::OpAtomicExchange, 3, int_type, uint_type));
  1556. // OpAtomicStore
  1557. #ifndef NDEBUG
  1558. ASSERT_DEATH(
  1559. fuzzerutil::TypesAreCompatible(context.get(), spv::Op::OpAtomicStore, 0,
  1560. int_type, uint_type),
  1561. "Signedness check should not occur on a pointer operand.");
  1562. #endif
  1563. ASSERT_TRUE(fuzzerutil::TypesAreCompatible(
  1564. context.get(), spv::Op::OpAtomicStore, 1, int_type, uint_type));
  1565. ASSERT_TRUE(fuzzerutil::TypesAreCompatible(
  1566. context.get(), spv::Op::OpAtomicStore, 2, int_type, uint_type));
  1567. ASSERT_FALSE(fuzzerutil::TypesAreCompatible(
  1568. context.get(), spv::Op::OpAtomicStore, 3, int_type, uint_type));
  1569. // OpAtomicCompareExchange
  1570. #ifndef NDEBUG
  1571. ASSERT_DEATH(fuzzerutil::TypesAreCompatible(context.get(),
  1572. spv::Op::OpAtomicCompareExchange,
  1573. 0, int_type, uint_type),
  1574. "Signedness check should not occur on a pointer operand.");
  1575. #endif
  1576. ASSERT_TRUE(fuzzerutil::TypesAreCompatible(
  1577. context.get(), spv::Op::OpAtomicCompareExchange, 1, int_type, uint_type));
  1578. ASSERT_TRUE(fuzzerutil::TypesAreCompatible(
  1579. context.get(), spv::Op::OpAtomicCompareExchange, 2, int_type, uint_type));
  1580. ASSERT_TRUE(fuzzerutil::TypesAreCompatible(
  1581. context.get(), spv::Op::OpAtomicCompareExchange, 3, int_type, uint_type));
  1582. ASSERT_FALSE(fuzzerutil::TypesAreCompatible(
  1583. context.get(), spv::Op::OpAtomicCompareExchange, 4, int_type, uint_type));
  1584. // OpAtomicIIncrement
  1585. #ifndef NDEBUG
  1586. ASSERT_DEATH(
  1587. fuzzerutil::TypesAreCompatible(context.get(), spv::Op::OpAtomicIIncrement,
  1588. 0, int_type, uint_type),
  1589. "Signedness check should not occur on a pointer operand.");
  1590. #endif
  1591. ASSERT_TRUE(fuzzerutil::TypesAreCompatible(
  1592. context.get(), spv::Op::OpAtomicIIncrement, 1, int_type, uint_type));
  1593. ASSERT_TRUE(fuzzerutil::TypesAreCompatible(
  1594. context.get(), spv::Op::OpAtomicIIncrement, 2, int_type, uint_type));
  1595. // OpAtomicIDecrement
  1596. #ifndef NDEBUG
  1597. ASSERT_DEATH(
  1598. fuzzerutil::TypesAreCompatible(context.get(), spv::Op::OpAtomicStore, 0,
  1599. int_type, uint_type),
  1600. "Signedness check should not occur on a pointer operand.");
  1601. #endif
  1602. ASSERT_TRUE(fuzzerutil::TypesAreCompatible(
  1603. context.get(), spv::Op::OpAtomicStore, 1, int_type, uint_type));
  1604. ASSERT_TRUE(fuzzerutil::TypesAreCompatible(
  1605. context.get(), spv::Op::OpAtomicStore, 2, int_type, uint_type));
  1606. // OpAtomicIAdd
  1607. #ifndef NDEBUG
  1608. ASSERT_DEATH(
  1609. fuzzerutil::TypesAreCompatible(context.get(), spv::Op::OpAtomicIAdd, 0,
  1610. int_type, uint_type),
  1611. "Signedness check should not occur on a pointer operand.");
  1612. #endif
  1613. ASSERT_TRUE(fuzzerutil::TypesAreCompatible(
  1614. context.get(), spv::Op::OpAtomicIAdd, 1, int_type, uint_type));
  1615. ASSERT_TRUE(fuzzerutil::TypesAreCompatible(
  1616. context.get(), spv::Op::OpAtomicIAdd, 2, int_type, uint_type));
  1617. ASSERT_FALSE(fuzzerutil::TypesAreCompatible(
  1618. context.get(), spv::Op::OpAtomicIAdd, 3, int_type, uint_type));
  1619. // OpAtomicISub
  1620. #ifndef NDEBUG
  1621. ASSERT_DEATH(
  1622. fuzzerutil::TypesAreCompatible(context.get(), spv::Op::OpAtomicISub, 0,
  1623. int_type, uint_type),
  1624. "Signedness check should not occur on a pointer operand.");
  1625. #endif
  1626. ASSERT_TRUE(fuzzerutil::TypesAreCompatible(
  1627. context.get(), spv::Op::OpAtomicISub, 1, int_type, uint_type));
  1628. ASSERT_TRUE(fuzzerutil::TypesAreCompatible(
  1629. context.get(), spv::Op::OpAtomicISub, 2, int_type, uint_type));
  1630. ASSERT_FALSE(fuzzerutil::TypesAreCompatible(
  1631. context.get(), spv::Op::OpAtomicISub, 3, int_type, uint_type));
  1632. // OpAtomicSMin
  1633. #ifndef NDEBUG
  1634. ASSERT_DEATH(
  1635. fuzzerutil::TypesAreCompatible(context.get(), spv::Op::OpAtomicSMin, 0,
  1636. int_type, uint_type),
  1637. "Signedness check should not occur on a pointer operand.");
  1638. #endif
  1639. ASSERT_TRUE(fuzzerutil::TypesAreCompatible(
  1640. context.get(), spv::Op::OpAtomicSMin, 1, int_type, uint_type));
  1641. ASSERT_TRUE(fuzzerutil::TypesAreCompatible(
  1642. context.get(), spv::Op::OpAtomicSMin, 2, int_type, uint_type));
  1643. ASSERT_FALSE(fuzzerutil::TypesAreCompatible(
  1644. context.get(), spv::Op::OpAtomicSMin, 3, int_type, uint_type));
  1645. // OpAtomicUMin
  1646. #ifndef NDEBUG
  1647. ASSERT_DEATH(
  1648. fuzzerutil::TypesAreCompatible(context.get(), spv::Op::OpAtomicUMin, 0,
  1649. int_type, uint_type),
  1650. "Signedness check should not occur on a pointer operand.");
  1651. #endif
  1652. ASSERT_TRUE(fuzzerutil::TypesAreCompatible(
  1653. context.get(), spv::Op::OpAtomicUMin, 1, int_type, uint_type));
  1654. ASSERT_TRUE(fuzzerutil::TypesAreCompatible(
  1655. context.get(), spv::Op::OpAtomicUMin, 2, int_type, uint_type));
  1656. ASSERT_FALSE(fuzzerutil::TypesAreCompatible(
  1657. context.get(), spv::Op::OpAtomicUMin, 3, int_type, uint_type));
  1658. // OpAtomicSMax
  1659. #ifndef NDEBUG
  1660. ASSERT_DEATH(
  1661. fuzzerutil::TypesAreCompatible(context.get(), spv::Op::OpAtomicSMax, 0,
  1662. int_type, uint_type),
  1663. "Signedness check should not occur on a pointer operand.");
  1664. #endif
  1665. ASSERT_TRUE(fuzzerutil::TypesAreCompatible(
  1666. context.get(), spv::Op::OpAtomicSMax, 1, int_type, uint_type));
  1667. ASSERT_TRUE(fuzzerutil::TypesAreCompatible(
  1668. context.get(), spv::Op::OpAtomicSMax, 2, int_type, uint_type));
  1669. ASSERT_FALSE(fuzzerutil::TypesAreCompatible(
  1670. context.get(), spv::Op::OpAtomicSMax, 3, int_type, uint_type));
  1671. // OpAtomicUMax
  1672. #ifndef NDEBUG
  1673. ASSERT_DEATH(
  1674. fuzzerutil::TypesAreCompatible(context.get(), spv::Op::OpAtomicUMax, 0,
  1675. int_type, uint_type),
  1676. "Signedness check should not occur on a pointer operand.");
  1677. #endif
  1678. ASSERT_TRUE(fuzzerutil::TypesAreCompatible(
  1679. context.get(), spv::Op::OpAtomicUMax, 1, int_type, uint_type));
  1680. ASSERT_TRUE(fuzzerutil::TypesAreCompatible(
  1681. context.get(), spv::Op::OpAtomicUMax, 2, int_type, uint_type));
  1682. ASSERT_FALSE(fuzzerutil::TypesAreCompatible(
  1683. context.get(), spv::Op::OpAtomicUMax, 3, int_type, uint_type));
  1684. // OpAtomicAnd
  1685. #ifndef NDEBUG
  1686. ASSERT_DEATH(fuzzerutil::TypesAreCompatible(
  1687. context.get(), spv::Op::OpAtomicAnd, 0, int_type, uint_type),
  1688. "Signedness check should not occur on a pointer operand.");
  1689. #endif
  1690. ASSERT_TRUE(fuzzerutil::TypesAreCompatible(
  1691. context.get(), spv::Op::OpAtomicAnd, 1, int_type, uint_type));
  1692. ASSERT_TRUE(fuzzerutil::TypesAreCompatible(
  1693. context.get(), spv::Op::OpAtomicAnd, 2, int_type, uint_type));
  1694. ASSERT_FALSE(fuzzerutil::TypesAreCompatible(
  1695. context.get(), spv::Op::OpAtomicAnd, 3, int_type, uint_type));
  1696. // OpAtomicOr
  1697. #ifndef NDEBUG
  1698. ASSERT_DEATH(fuzzerutil::TypesAreCompatible(
  1699. context.get(), spv::Op::OpAtomicOr, 0, int_type, uint_type),
  1700. "Signedness check should not occur on a pointer operand.");
  1701. #endif
  1702. ASSERT_TRUE(fuzzerutil::TypesAreCompatible(context.get(), spv::Op::OpAtomicOr,
  1703. 1, int_type, uint_type));
  1704. ASSERT_TRUE(fuzzerutil::TypesAreCompatible(context.get(), spv::Op::OpAtomicOr,
  1705. 2, int_type, uint_type));
  1706. ASSERT_FALSE(fuzzerutil::TypesAreCompatible(
  1707. context.get(), spv::Op::OpAtomicOr, 3, int_type, uint_type));
  1708. // OpAtomicXor
  1709. #ifndef NDEBUG
  1710. ASSERT_DEATH(fuzzerutil::TypesAreCompatible(
  1711. context.get(), spv::Op::OpAtomicXor, 0, int_type, uint_type),
  1712. "Signedness check should not occur on a pointer operand.");
  1713. #endif
  1714. ASSERT_TRUE(fuzzerutil::TypesAreCompatible(
  1715. context.get(), spv::Op::OpAtomicXor, 1, int_type, uint_type));
  1716. ASSERT_TRUE(fuzzerutil::TypesAreCompatible(
  1717. context.get(), spv::Op::OpAtomicXor, 2, int_type, uint_type));
  1718. ASSERT_FALSE(fuzzerutil::TypesAreCompatible(
  1719. context.get(), spv::Op::OpAtomicXor, 3, int_type, uint_type));
  1720. }
  1721. } // namespace
  1722. } // namespace fuzz
  1723. } // namespace spvtools