fact_manager_test.cpp 50 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178
  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 <limits>
  15. #include "source/fuzz/fact_manager.h"
  16. #include "source/fuzz/uniform_buffer_element_descriptor.h"
  17. #include "test/fuzz/fuzz_test_util.h"
  18. namespace spvtools {
  19. namespace fuzz {
  20. namespace {
  21. using opt::analysis::BoolConstant;
  22. using opt::analysis::FloatConstant;
  23. using opt::analysis::IntConstant;
  24. using opt::analysis::ScalarConstant;
  25. using opt::analysis::Bool;
  26. using opt::analysis::Float;
  27. using opt::analysis::Integer;
  28. using opt::analysis::Type;
  29. bool AddFactHelper(
  30. FactManager* fact_manager, opt::IRContext* context,
  31. std::vector<uint32_t>&& words,
  32. const protobufs::UniformBufferElementDescriptor& descriptor) {
  33. protobufs::FactConstantUniform constant_uniform_fact;
  34. for (auto word : words) {
  35. constant_uniform_fact.add_constant_word(word);
  36. }
  37. *constant_uniform_fact.mutable_uniform_buffer_element_descriptor() =
  38. descriptor;
  39. protobufs::Fact fact;
  40. *fact.mutable_constant_uniform_fact() = constant_uniform_fact;
  41. return fact_manager->AddFact(fact, context);
  42. }
  43. TEST(FactManagerTest, ConstantsAvailableViaUniforms) {
  44. std::string shader = R"(
  45. OpCapability Shader
  46. OpCapability Int64
  47. OpCapability Float64
  48. %1 = OpExtInstImport "GLSL.std.450"
  49. OpMemoryModel Logical GLSL450
  50. OpEntryPoint Fragment %4 "main"
  51. OpExecutionMode %4 OriginUpperLeft
  52. OpSource GLSL 450
  53. OpName %4 "main"
  54. OpDecorate %100 DescriptorSet 0
  55. OpDecorate %100 Binding 0
  56. OpDecorate %200 DescriptorSet 0
  57. OpDecorate %200 Binding 1
  58. OpDecorate %300 DescriptorSet 0
  59. OpDecorate %300 Binding 2
  60. OpDecorate %400 DescriptorSet 0
  61. OpDecorate %400 Binding 3
  62. OpDecorate %500 DescriptorSet 0
  63. OpDecorate %500 Binding 4
  64. OpDecorate %600 DescriptorSet 0
  65. OpDecorate %600 Binding 5
  66. OpDecorate %700 DescriptorSet 0
  67. OpDecorate %700 Binding 6
  68. OpDecorate %800 DescriptorSet 1
  69. OpDecorate %800 Binding 0
  70. OpDecorate %900 DescriptorSet 1
  71. OpDecorate %900 Binding 1
  72. OpDecorate %1000 DescriptorSet 1
  73. OpDecorate %1000 Binding 2
  74. OpDecorate %1100 DescriptorSet 1
  75. OpDecorate %1100 Binding 3
  76. OpDecorate %1200 DescriptorSet 1
  77. OpDecorate %1200 Binding 4
  78. OpDecorate %1300 DescriptorSet 1
  79. OpDecorate %1300 Binding 5
  80. OpDecorate %1400 DescriptorSet 1
  81. OpDecorate %1400 Binding 6
  82. OpDecorate %1500 DescriptorSet 2
  83. OpDecorate %1500 Binding 0
  84. OpDecorate %1600 DescriptorSet 2
  85. OpDecorate %1600 Binding 1
  86. OpDecorate %1700 DescriptorSet 2
  87. OpDecorate %1700 Binding 2
  88. OpDecorate %1800 DescriptorSet 2
  89. OpDecorate %1800 Binding 3
  90. OpDecorate %1900 DescriptorSet 2
  91. OpDecorate %1900 Binding 4
  92. %2 = OpTypeVoid
  93. %3 = OpTypeFunction %2
  94. %10 = OpTypeInt 32 0
  95. %11 = OpTypeInt 32 1
  96. %12 = OpTypeInt 64 0
  97. %13 = OpTypeInt 64 1
  98. %15 = OpTypeFloat 32
  99. %16 = OpTypeFloat 64
  100. %17 = OpConstant %11 5
  101. %18 = OpConstant %11 20
  102. %19 = OpTypeVector %10 4
  103. %20 = OpConstant %11 6
  104. %21 = OpTypeVector %12 4
  105. %22 = OpConstant %11 10
  106. %23 = OpTypeVector %11 4
  107. %102 = OpTypeStruct %10 %10 %23
  108. %101 = OpTypePointer Uniform %102
  109. %100 = OpVariable %101 Uniform
  110. %203 = OpTypeArray %23 %17
  111. %202 = OpTypeArray %203 %18
  112. %201 = OpTypePointer Uniform %202
  113. %200 = OpVariable %201 Uniform
  114. %305 = OpTypeStruct %16 %16 %16 %11 %16
  115. %304 = OpTypeStruct %16 %16 %305
  116. %303 = OpTypeStruct %304
  117. %302 = OpTypeStruct %10 %303
  118. %301 = OpTypePointer Uniform %302
  119. %300 = OpVariable %301 Uniform
  120. %400 = OpVariable %101 Uniform
  121. %500 = OpVariable %201 Uniform
  122. %604 = OpTypeArray %13 %20
  123. %603 = OpTypeArray %604 %20
  124. %602 = OpTypeArray %603 %20
  125. %601 = OpTypePointer Uniform %602
  126. %600 = OpVariable %601 Uniform
  127. %703 = OpTypeArray %13 %20
  128. %702 = OpTypeArray %703 %20
  129. %701 = OpTypePointer Uniform %702
  130. %700 = OpVariable %701 Uniform
  131. %802 = OpTypeStruct %702 %602 %19 %202 %302
  132. %801 = OpTypePointer Uniform %802
  133. %800 = OpVariable %801 Uniform
  134. %902 = OpTypeStruct %702 %802 %19 %202 %302
  135. %901 = OpTypePointer Uniform %902
  136. %900 = OpVariable %901 Uniform
  137. %1003 = OpTypeStruct %802
  138. %1002 = OpTypeArray %1003 %20
  139. %1001 = OpTypePointer Uniform %1002
  140. %1000 = OpVariable %1001 Uniform
  141. %1101 = OpTypePointer Uniform %21
  142. %1100 = OpVariable %1101 Uniform
  143. %1202 = OpTypeArray %21 %20
  144. %1201 = OpTypePointer Uniform %1202
  145. %1200 = OpVariable %1201 Uniform
  146. %1302 = OpTypeArray %21 %20
  147. %1301 = OpTypePointer Uniform %1302
  148. %1300 = OpVariable %1301 Uniform
  149. %1402 = OpTypeArray %15 %22
  150. %1401 = OpTypePointer Uniform %1402
  151. %1400 = OpVariable %1401 Uniform
  152. %1501 = OpTypePointer Uniform %1402
  153. %1500 = OpVariable %1501 Uniform
  154. %1602 = OpTypeArray %1402 %22
  155. %1601 = OpTypePointer Uniform %1602
  156. %1600 = OpVariable %1601 Uniform
  157. %1704 = OpTypeStruct %16 %16 %16
  158. %1703 = OpTypeArray %1704 %22
  159. %1702 = OpTypeArray %1703 %22
  160. %1701 = OpTypePointer Uniform %1702
  161. %1700 = OpVariable %1701 Uniform
  162. %1800 = OpVariable %1701 Uniform
  163. %1906 = OpTypeStruct %16
  164. %1905 = OpTypeStruct %1906
  165. %1904 = OpTypeStruct %1905
  166. %1903 = OpTypeStruct %1904
  167. %1902 = OpTypeStruct %1903
  168. %1901 = OpTypePointer Uniform %1902
  169. %1900 = OpVariable %1901 Uniform
  170. %4 = OpFunction %2 None %3
  171. %5 = OpLabel
  172. OpReturn
  173. OpFunctionEnd
  174. )";
  175. const auto env = SPV_ENV_UNIVERSAL_1_3;
  176. const auto consumer = nullptr;
  177. const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
  178. ASSERT_TRUE(IsValid(env, context.get()));
  179. uint32_t buffer_int32_min[1];
  180. uint32_t buffer_int64_1[2];
  181. uint32_t buffer_int64_max[2];
  182. uint32_t buffer_uint64_1[2];
  183. uint32_t buffer_uint64_max[2];
  184. uint32_t buffer_float_10[1];
  185. uint32_t buffer_double_10[2];
  186. uint32_t buffer_double_20[2];
  187. {
  188. int32_t temp = std::numeric_limits<int32_t>::min();
  189. std::memcpy(&buffer_int32_min, &temp, sizeof(temp));
  190. }
  191. {
  192. int64_t temp = 1;
  193. std::memcpy(&buffer_int64_1, &temp, sizeof(temp));
  194. }
  195. {
  196. int64_t temp = std::numeric_limits<int64_t>::max();
  197. std::memcpy(&buffer_int64_max, &temp, sizeof(temp));
  198. }
  199. {
  200. uint64_t temp = 1;
  201. std::memcpy(&buffer_uint64_1, &temp, sizeof(temp));
  202. }
  203. {
  204. uint64_t temp = std::numeric_limits<uint64_t>::max();
  205. std::memcpy(&buffer_uint64_max, &temp, sizeof(temp));
  206. }
  207. {
  208. float temp = 10.0f;
  209. std::memcpy(&buffer_float_10, &temp, sizeof(float));
  210. }
  211. {
  212. double temp = 10.0;
  213. std::memcpy(&buffer_double_10, &temp, sizeof(temp));
  214. }
  215. {
  216. double temp = 20.0;
  217. std::memcpy(&buffer_double_20, &temp, sizeof(temp));
  218. }
  219. FactManager fact_manager;
  220. uint32_t type_int32_id = 11;
  221. uint32_t type_int64_id = 13;
  222. uint32_t type_uint32_id = 10;
  223. uint32_t type_uint64_id = 12;
  224. uint32_t type_float_id = 15;
  225. uint32_t type_double_id = 16;
  226. // Initially there should be no facts about uniforms.
  227. ASSERT_TRUE(fact_manager
  228. .GetConstantsAvailableFromUniformsForType(context.get(),
  229. type_uint32_id)
  230. .empty());
  231. // In the comments that follow we write v[...][...] to refer to uniform
  232. // variable v indexed with some given indices, when in practice v is
  233. // identified via a (descriptor set, binding) pair.
  234. // 100[2][3] == int(1)
  235. ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), {1},
  236. MakeUniformBufferElementDescriptor(0, 0, {2, 3})));
  237. // 200[1][2][3] == int(1)
  238. ASSERT_TRUE(
  239. AddFactHelper(&fact_manager, context.get(), {1},
  240. MakeUniformBufferElementDescriptor(0, 1, {1, 2, 3})));
  241. // 300[1][0][2][3] == int(1)
  242. ASSERT_TRUE(
  243. AddFactHelper(&fact_manager, context.get(), {1},
  244. MakeUniformBufferElementDescriptor(0, 2, {1, 0, 2, 3})));
  245. // 400[2][3] = int32_min
  246. ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), {buffer_int32_min[0]},
  247. MakeUniformBufferElementDescriptor(0, 3, {2, 3})));
  248. // 500[1][2][3] = int32_min
  249. ASSERT_TRUE(
  250. AddFactHelper(&fact_manager, context.get(), {buffer_int32_min[0]},
  251. MakeUniformBufferElementDescriptor(0, 4, {1, 2, 3})));
  252. // 600[1][2][3] = int64_max
  253. ASSERT_TRUE(AddFactHelper(
  254. &fact_manager, context.get(), {buffer_int64_max[0], buffer_int64_max[1]},
  255. MakeUniformBufferElementDescriptor(0, 5, {1, 2, 3})));
  256. // 700[1][1] = int64_max
  257. ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(),
  258. {buffer_int64_max[0], buffer_int64_max[1]},
  259. MakeUniformBufferElementDescriptor(0, 6, {1, 1})));
  260. // 800[2][3] = uint(1)
  261. ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), {1},
  262. MakeUniformBufferElementDescriptor(1, 0, {2, 3})));
  263. // 900[1][2][3] = uint(1)
  264. ASSERT_TRUE(
  265. AddFactHelper(&fact_manager, context.get(), {1},
  266. MakeUniformBufferElementDescriptor(1, 1, {1, 2, 3})));
  267. // 1000[1][0][2][3] = uint(1)
  268. ASSERT_TRUE(
  269. AddFactHelper(&fact_manager, context.get(), {1},
  270. MakeUniformBufferElementDescriptor(1, 2, {1, 0, 2, 3})));
  271. // 1100[0] = uint64(1)
  272. ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(),
  273. {buffer_uint64_1[0], buffer_uint64_1[1]},
  274. MakeUniformBufferElementDescriptor(1, 3, {0})));
  275. // 1200[0][0] = uint64_max
  276. ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(),
  277. {buffer_uint64_max[0], buffer_uint64_max[1]},
  278. MakeUniformBufferElementDescriptor(1, 4, {0, 0})));
  279. // 1300[1][0] = uint64_max
  280. ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(),
  281. {buffer_uint64_max[0], buffer_uint64_max[1]},
  282. MakeUniformBufferElementDescriptor(1, 5, {1, 0})));
  283. // 1400[6] = float(10.0)
  284. ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), {buffer_float_10[0]},
  285. MakeUniformBufferElementDescriptor(1, 6, {6})));
  286. // 1500[7] = float(10.0)
  287. ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), {buffer_float_10[0]},
  288. MakeUniformBufferElementDescriptor(2, 0, {7})));
  289. // 1600[9][9] = float(10.0)
  290. ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), {buffer_float_10[0]},
  291. MakeUniformBufferElementDescriptor(2, 1, {9, 9})));
  292. // 1700[9][9][1] = double(10.0)
  293. ASSERT_TRUE(AddFactHelper(
  294. &fact_manager, context.get(), {buffer_double_10[0], buffer_double_10[1]},
  295. MakeUniformBufferElementDescriptor(2, 2, {9, 9, 1})));
  296. // 1800[9][9][2] = double(10.0)
  297. ASSERT_TRUE(AddFactHelper(
  298. &fact_manager, context.get(), {buffer_double_10[0], buffer_double_10[1]},
  299. MakeUniformBufferElementDescriptor(2, 3, {9, 9, 2})));
  300. // 1900[0][0][0][0][0] = double(20.0)
  301. ASSERT_TRUE(AddFactHelper(
  302. &fact_manager, context.get(), {buffer_double_20[0], buffer_double_20[1]},
  303. MakeUniformBufferElementDescriptor(2, 4, {0, 0, 0, 0, 0})));
  304. opt::Instruction::OperandList operands = {
  305. {SPV_OPERAND_TYPE_LITERAL_INTEGER, {1}}};
  306. context->module()->AddGlobalValue(MakeUnique<opt::Instruction>(
  307. context.get(), SpvOpConstant, type_int32_id, 50, operands));
  308. operands = {{SPV_OPERAND_TYPE_LITERAL_INTEGER, {buffer_int32_min[0]}}};
  309. context->module()->AddGlobalValue(MakeUnique<opt::Instruction>(
  310. context.get(), SpvOpConstant, type_int32_id, 51, operands));
  311. operands = {{SPV_OPERAND_TYPE_LITERAL_INTEGER, {buffer_int64_max[0]}},
  312. {SPV_OPERAND_TYPE_LITERAL_INTEGER, {buffer_int64_max[1]}}};
  313. context->module()->AddGlobalValue(MakeUnique<opt::Instruction>(
  314. context.get(), SpvOpConstant, type_int64_id, 52, operands));
  315. operands = {{SPV_OPERAND_TYPE_LITERAL_INTEGER, {1}}};
  316. context->module()->AddGlobalValue(MakeUnique<opt::Instruction>(
  317. context.get(), SpvOpConstant, type_uint32_id, 53, operands));
  318. operands = {{SPV_OPERAND_TYPE_LITERAL_INTEGER, {buffer_uint64_1[0]}},
  319. {SPV_OPERAND_TYPE_LITERAL_INTEGER, {buffer_uint64_1[1]}}};
  320. context->module()->AddGlobalValue(MakeUnique<opt::Instruction>(
  321. context.get(), SpvOpConstant, type_uint64_id, 54, operands));
  322. operands = {{SPV_OPERAND_TYPE_LITERAL_INTEGER, {buffer_uint64_max[0]}},
  323. {SPV_OPERAND_TYPE_LITERAL_INTEGER, {buffer_uint64_max[1]}}};
  324. context->module()->AddGlobalValue(MakeUnique<opt::Instruction>(
  325. context.get(), SpvOpConstant, type_uint64_id, 55, operands));
  326. operands = {{SPV_OPERAND_TYPE_LITERAL_INTEGER, {buffer_float_10[0]}}};
  327. context->module()->AddGlobalValue(MakeUnique<opt::Instruction>(
  328. context.get(), SpvOpConstant, type_float_id, 56, operands));
  329. operands = {{SPV_OPERAND_TYPE_LITERAL_INTEGER, {buffer_double_10[0]}},
  330. {SPV_OPERAND_TYPE_LITERAL_INTEGER, {buffer_double_10[1]}}};
  331. context->module()->AddGlobalValue(MakeUnique<opt::Instruction>(
  332. context.get(), SpvOpConstant, type_double_id, 57, operands));
  333. operands = {{SPV_OPERAND_TYPE_LITERAL_INTEGER, {buffer_double_20[0]}},
  334. {SPV_OPERAND_TYPE_LITERAL_INTEGER, {buffer_double_20[1]}}};
  335. context->module()->AddGlobalValue(MakeUnique<opt::Instruction>(
  336. context.get(), SpvOpConstant, type_double_id, 58, operands));
  337. // A duplicate of the constant with id 59.
  338. operands = {{SPV_OPERAND_TYPE_LITERAL_INTEGER, {1}}};
  339. context->module()->AddGlobalValue(MakeUnique<opt::Instruction>(
  340. context.get(), SpvOpConstant, type_int32_id, 59, operands));
  341. context->InvalidateAnalysesExceptFor(opt::IRContext::Analysis::kAnalysisNone);
  342. // Constants 1 and int32_min are available.
  343. ASSERT_EQ(2, fact_manager
  344. .GetConstantsAvailableFromUniformsForType(context.get(),
  345. type_int32_id)
  346. .size());
  347. // Constant int64_max is available.
  348. ASSERT_EQ(1, fact_manager
  349. .GetConstantsAvailableFromUniformsForType(context.get(),
  350. type_int64_id)
  351. .size());
  352. // Constant 1u is available.
  353. ASSERT_EQ(1, fact_manager
  354. .GetConstantsAvailableFromUniformsForType(context.get(),
  355. type_uint32_id)
  356. .size());
  357. // Constants 1u and uint64_max are available.
  358. ASSERT_EQ(2, fact_manager
  359. .GetConstantsAvailableFromUniformsForType(context.get(),
  360. type_uint64_id)
  361. .size());
  362. // Constant 10.0 is available.
  363. ASSERT_EQ(1, fact_manager
  364. .GetConstantsAvailableFromUniformsForType(context.get(),
  365. type_float_id)
  366. .size());
  367. // Constants 10.0 and 20.0 are available.
  368. ASSERT_EQ(2, fact_manager
  369. .GetConstantsAvailableFromUniformsForType(context.get(),
  370. type_double_id)
  371. .size());
  372. ASSERT_EQ(std::numeric_limits<int64_t>::max(),
  373. context->get_constant_mgr()
  374. ->FindDeclaredConstant(
  375. fact_manager.GetConstantsAvailableFromUniformsForType(
  376. context.get(), type_int64_id)[0])
  377. ->AsIntConstant()
  378. ->GetS64());
  379. ASSERT_EQ(1, context->get_constant_mgr()
  380. ->FindDeclaredConstant(
  381. fact_manager.GetConstantsAvailableFromUniformsForType(
  382. context.get(), type_uint32_id)[0])
  383. ->AsIntConstant()
  384. ->GetU32());
  385. ASSERT_EQ(10.0f,
  386. context->get_constant_mgr()
  387. ->FindDeclaredConstant(
  388. fact_manager.GetConstantsAvailableFromUniformsForType(
  389. context.get(), type_float_id)[0])
  390. ->AsFloatConstant()
  391. ->GetFloat());
  392. const std::vector<uint32_t>& double_constant_ids =
  393. fact_manager.GetConstantsAvailableFromUniformsForType(context.get(),
  394. type_double_id);
  395. ASSERT_EQ(10.0, context->get_constant_mgr()
  396. ->FindDeclaredConstant(double_constant_ids[0])
  397. ->AsFloatConstant()
  398. ->GetDouble());
  399. ASSERT_EQ(20.0, context->get_constant_mgr()
  400. ->FindDeclaredConstant(double_constant_ids[1])
  401. ->AsFloatConstant()
  402. ->GetDouble());
  403. const std::vector<protobufs::UniformBufferElementDescriptor>
  404. descriptors_for_double_10 = fact_manager.GetUniformDescriptorsForConstant(
  405. context.get(), double_constant_ids[0]);
  406. ASSERT_EQ(2, descriptors_for_double_10.size());
  407. {
  408. auto temp = MakeUniformBufferElementDescriptor(2, 2, {9, 9, 1});
  409. ASSERT_TRUE(UniformBufferElementDescriptorEquals()(
  410. &temp, &descriptors_for_double_10[0]));
  411. }
  412. {
  413. auto temp = MakeUniformBufferElementDescriptor(2, 3, {9, 9, 2});
  414. ASSERT_TRUE(UniformBufferElementDescriptorEquals()(
  415. &temp, &descriptors_for_double_10[1]));
  416. }
  417. const std::vector<protobufs::UniformBufferElementDescriptor>
  418. descriptors_for_double_20 = fact_manager.GetUniformDescriptorsForConstant(
  419. context.get(), double_constant_ids[1]);
  420. ASSERT_EQ(1, descriptors_for_double_20.size());
  421. {
  422. auto temp = MakeUniformBufferElementDescriptor(2, 4, {0, 0, 0, 0, 0});
  423. ASSERT_TRUE(UniformBufferElementDescriptorEquals()(
  424. &temp, &descriptors_for_double_20[0]));
  425. }
  426. auto constant_1_id = fact_manager.GetConstantFromUniformDescriptor(
  427. context.get(), MakeUniformBufferElementDescriptor(2, 3, {9, 9, 2}));
  428. ASSERT_TRUE(constant_1_id);
  429. auto constant_2_id = fact_manager.GetConstantFromUniformDescriptor(
  430. context.get(), MakeUniformBufferElementDescriptor(2, 4, {0, 0, 0, 0, 0}));
  431. ASSERT_TRUE(constant_2_id);
  432. ASSERT_EQ(double_constant_ids[0], constant_1_id);
  433. ASSERT_EQ(double_constant_ids[1], constant_2_id);
  434. }
  435. TEST(FactManagerTest, TwoConstantsWithSameValue) {
  436. std::string shader = R"(
  437. OpCapability Shader
  438. %1 = OpExtInstImport "GLSL.std.450"
  439. OpMemoryModel Logical GLSL450
  440. OpEntryPoint Fragment %4 "main"
  441. OpExecutionMode %4 OriginUpperLeft
  442. OpSource ESSL 310
  443. OpName %4 "main"
  444. OpName %8 "x"
  445. OpName %10 "buf"
  446. OpMemberName %10 0 "a"
  447. OpName %12 ""
  448. OpDecorate %8 RelaxedPrecision
  449. OpMemberDecorate %10 0 RelaxedPrecision
  450. OpMemberDecorate %10 0 Offset 0
  451. OpDecorate %10 Block
  452. OpDecorate %12 DescriptorSet 0
  453. OpDecorate %12 Binding 0
  454. %2 = OpTypeVoid
  455. %3 = OpTypeFunction %2
  456. %6 = OpTypeInt 32 1
  457. %7 = OpTypePointer Function %6
  458. %9 = OpConstant %6 1
  459. %20 = OpConstant %6 1
  460. %10 = OpTypeStruct %6
  461. %11 = OpTypePointer Uniform %10
  462. %12 = OpVariable %11 Uniform
  463. %4 = OpFunction %2 None %3
  464. %5 = OpLabel
  465. %8 = OpVariable %7 Function
  466. OpStore %8 %9
  467. OpReturn
  468. OpFunctionEnd
  469. )";
  470. const auto env = SPV_ENV_UNIVERSAL_1_3;
  471. const auto consumer = nullptr;
  472. const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
  473. ASSERT_TRUE(IsValid(env, context.get()));
  474. FactManager fact_manager;
  475. auto uniform_buffer_element_descriptor =
  476. MakeUniformBufferElementDescriptor(0, 0, {0});
  477. // (0, 0, [0]) = int(1)
  478. ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), {1},
  479. uniform_buffer_element_descriptor));
  480. auto constants =
  481. fact_manager.GetConstantsAvailableFromUniformsForType(context.get(), 6);
  482. ASSERT_EQ(1, constants.size());
  483. ASSERT_TRUE(constants[0] == 9 || constants[0] == 20);
  484. auto constant = fact_manager.GetConstantFromUniformDescriptor(
  485. context.get(), uniform_buffer_element_descriptor);
  486. ASSERT_TRUE(constant == 9 || constant == 20);
  487. // Because the constants with ids 9 and 20 are equal, we should get the same
  488. // single uniform buffer element descriptor when we look up the descriptors
  489. // for either one of them.
  490. for (auto constant_id : {9u, 20u}) {
  491. auto descriptors = fact_manager.GetUniformDescriptorsForConstant(
  492. context.get(), constant_id);
  493. ASSERT_EQ(1, descriptors.size());
  494. ASSERT_TRUE(UniformBufferElementDescriptorEquals()(
  495. &uniform_buffer_element_descriptor, &descriptors[0]));
  496. }
  497. }
  498. TEST(FactManagerTest, NonFiniteFactsAreNotValid) {
  499. std::string shader = R"(
  500. OpCapability Shader
  501. OpCapability Float64
  502. %1 = OpExtInstImport "GLSL.std.450"
  503. OpMemoryModel Logical GLSL450
  504. OpEntryPoint Fragment %4 "main"
  505. OpExecutionMode %4 OriginUpperLeft
  506. OpSource ESSL 310
  507. OpName %4 "main"
  508. OpName %7 "buf"
  509. OpMemberName %7 0 "f"
  510. OpMemberName %7 1 "d"
  511. OpName %9 ""
  512. OpMemberDecorate %7 0 Offset 0
  513. OpMemberDecorate %7 1 Offset 8
  514. OpDecorate %7 Block
  515. OpDecorate %9 DescriptorSet 0
  516. OpDecorate %9 Binding 0
  517. %2 = OpTypeVoid
  518. %3 = OpTypeFunction %2
  519. %6 = OpTypeFloat 32
  520. %10 = OpTypeFloat 64
  521. %7 = OpTypeStruct %6 %10
  522. %8 = OpTypePointer Uniform %7
  523. %9 = OpVariable %8 Uniform
  524. %4 = OpFunction %2 None %3
  525. %5 = OpLabel
  526. OpReturn
  527. OpFunctionEnd
  528. )";
  529. const auto env = SPV_ENV_UNIVERSAL_1_3;
  530. const auto consumer = nullptr;
  531. const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
  532. ASSERT_TRUE(IsValid(env, context.get()));
  533. FactManager fact_manager;
  534. auto uniform_buffer_element_descriptor_f =
  535. MakeUniformBufferElementDescriptor(0, 0, {0});
  536. auto uniform_buffer_element_descriptor_d =
  537. MakeUniformBufferElementDescriptor(0, 0, {1});
  538. if (std::numeric_limits<float>::has_infinity) {
  539. // f == +inf
  540. float positive_infinity_float = std::numeric_limits<float>::infinity();
  541. uint32_t words[1];
  542. memcpy(words, &positive_infinity_float, sizeof(float));
  543. ASSERT_FALSE(AddFactHelper(&fact_manager, context.get(), {words[0]},
  544. uniform_buffer_element_descriptor_f));
  545. // f == -inf
  546. float negative_infinity_float = std::numeric_limits<float>::infinity();
  547. memcpy(words, &negative_infinity_float, sizeof(float));
  548. ASSERT_FALSE(AddFactHelper(&fact_manager, context.get(), {words[0]},
  549. uniform_buffer_element_descriptor_f));
  550. }
  551. if (std::numeric_limits<float>::has_quiet_NaN) {
  552. // f == NaN
  553. float quiet_nan_float = std::numeric_limits<float>::quiet_NaN();
  554. uint32_t words[1];
  555. memcpy(words, &quiet_nan_float, sizeof(float));
  556. ASSERT_FALSE(AddFactHelper(&fact_manager, context.get(), {words[0]},
  557. uniform_buffer_element_descriptor_f));
  558. }
  559. if (std::numeric_limits<double>::has_infinity) {
  560. // d == +inf
  561. double positive_infinity_double = std::numeric_limits<double>::infinity();
  562. uint32_t words[2];
  563. memcpy(words, &positive_infinity_double, sizeof(double));
  564. ASSERT_FALSE(AddFactHelper(&fact_manager, context.get(),
  565. {words[0], words[1]},
  566. uniform_buffer_element_descriptor_d));
  567. // d == -inf
  568. double negative_infinity_double = -std::numeric_limits<double>::infinity();
  569. memcpy(words, &negative_infinity_double, sizeof(double));
  570. ASSERT_FALSE(AddFactHelper(&fact_manager, context.get(),
  571. {words[0], words[1]},
  572. uniform_buffer_element_descriptor_d));
  573. }
  574. if (std::numeric_limits<double>::has_quiet_NaN) {
  575. // d == NaN
  576. double quiet_nan_double = std::numeric_limits<double>::quiet_NaN();
  577. uint32_t words[2];
  578. memcpy(words, &quiet_nan_double, sizeof(double));
  579. ASSERT_FALSE(AddFactHelper(&fact_manager, context.get(),
  580. {words[0], words[1]},
  581. uniform_buffer_element_descriptor_d));
  582. }
  583. }
  584. TEST(FactManagerTest, AmbiguousFact) {
  585. // This test came from the following GLSL:
  586. //
  587. // #version 310 es
  588. //
  589. // precision highp float;
  590. //
  591. // layout(set = 0, binding = 0) uniform buf {
  592. // float f;
  593. // };
  594. //
  595. // layout(set = 0, binding = 0) uniform buf2 {
  596. // float g;
  597. // };
  598. //
  599. // void main() {
  600. //
  601. // }
  602. std::string shader = R"(
  603. OpCapability Shader
  604. %1 = OpExtInstImport "GLSL.std.450"
  605. OpMemoryModel Logical GLSL450
  606. OpEntryPoint Fragment %4 "main"
  607. OpExecutionMode %4 OriginUpperLeft
  608. OpSource ESSL 310
  609. OpName %4 "main"
  610. OpName %7 "buf"
  611. OpMemberName %7 0 "f"
  612. OpName %9 ""
  613. OpName %10 "buf2"
  614. OpMemberName %10 0 "g"
  615. OpName %12 ""
  616. OpMemberDecorate %7 0 Offset 0
  617. OpDecorate %7 Block
  618. OpDecorate %9 DescriptorSet 0
  619. OpDecorate %9 Binding 0
  620. OpMemberDecorate %10 0 Offset 0
  621. OpDecorate %10 Block
  622. OpDecorate %12 DescriptorSet 0
  623. OpDecorate %12 Binding 0
  624. %2 = OpTypeVoid
  625. %3 = OpTypeFunction %2
  626. %6 = OpTypeFloat 32
  627. %7 = OpTypeStruct %6
  628. %8 = OpTypePointer Uniform %7
  629. %9 = OpVariable %8 Uniform
  630. %10 = OpTypeStruct %6
  631. %11 = OpTypePointer Uniform %10
  632. %12 = OpVariable %11 Uniform
  633. %4 = OpFunction %2 None %3
  634. %5 = OpLabel
  635. OpReturn
  636. OpFunctionEnd
  637. )";
  638. const auto env = SPV_ENV_UNIVERSAL_1_3;
  639. const auto consumer = nullptr;
  640. const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
  641. ASSERT_TRUE(IsValid(env, context.get()));
  642. FactManager fact_manager;
  643. auto uniform_buffer_element_descriptor =
  644. MakeUniformBufferElementDescriptor(0, 0, {0});
  645. // The fact cannot be added because it is ambiguous: there are two uniforms
  646. // with descriptor set 0 and binding 0.
  647. ASSERT_FALSE(AddFactHelper(&fact_manager, context.get(), {1},
  648. uniform_buffer_element_descriptor));
  649. }
  650. TEST(FactManagerTest, DataSynonymFacts) {
  651. // The SPIR-V types and constants come from the following code. The body of
  652. // the SPIR-V function then constructs a composite that is synonymous with
  653. // myT.
  654. //
  655. // #version 310 es
  656. //
  657. // precision highp float;
  658. //
  659. // struct S {
  660. // int a;
  661. // uvec2 b;
  662. // };
  663. //
  664. // struct T {
  665. // bool c[5];
  666. // mat4x2 d;
  667. // S e;
  668. // };
  669. //
  670. // void main() {
  671. // T myT = T(bool[5](true, false, true, false, true),
  672. // mat4x2(vec2(1.0, 2.0), vec2(3.0, 4.0),
  673. // vec2(5.0, 6.0), vec2(7.0, 8.0)),
  674. // S(10, uvec2(100u, 200u)));
  675. // }
  676. std::string shader = R"(
  677. OpCapability Shader
  678. %1 = OpExtInstImport "GLSL.std.450"
  679. OpMemoryModel Logical GLSL450
  680. OpEntryPoint Fragment %4 "main"
  681. OpExecutionMode %4 OriginUpperLeft
  682. OpSource ESSL 310
  683. OpName %4 "main"
  684. OpName %15 "S"
  685. OpMemberName %15 0 "a"
  686. OpMemberName %15 1 "b"
  687. OpName %16 "T"
  688. OpMemberName %16 0 "c"
  689. OpMemberName %16 1 "d"
  690. OpMemberName %16 2 "e"
  691. OpName %18 "myT"
  692. OpMemberDecorate %15 0 RelaxedPrecision
  693. OpMemberDecorate %15 1 RelaxedPrecision
  694. %2 = OpTypeVoid
  695. %3 = OpTypeFunction %2
  696. %6 = OpTypeBool
  697. %7 = OpTypeInt 32 0
  698. %8 = OpConstant %7 5
  699. %9 = OpTypeArray %6 %8
  700. %10 = OpTypeFloat 32
  701. %11 = OpTypeVector %10 2
  702. %12 = OpTypeMatrix %11 4
  703. %13 = OpTypeInt 32 1
  704. %14 = OpTypeVector %7 2
  705. %15 = OpTypeStruct %13 %14
  706. %16 = OpTypeStruct %9 %12 %15
  707. %17 = OpTypePointer Function %16
  708. %19 = OpConstantTrue %6
  709. %20 = OpConstantFalse %6
  710. %21 = OpConstantComposite %9 %19 %20 %19 %20 %19
  711. %22 = OpConstant %10 1
  712. %23 = OpConstant %10 2
  713. %24 = OpConstantComposite %11 %22 %23
  714. %25 = OpConstant %10 3
  715. %26 = OpConstant %10 4
  716. %27 = OpConstantComposite %11 %25 %26
  717. %28 = OpConstant %10 5
  718. %29 = OpConstant %10 6
  719. %30 = OpConstantComposite %11 %28 %29
  720. %31 = OpConstant %10 7
  721. %32 = OpConstant %10 8
  722. %33 = OpConstantComposite %11 %31 %32
  723. %34 = OpConstantComposite %12 %24 %27 %30 %33
  724. %35 = OpConstant %13 10
  725. %36 = OpConstant %7 100
  726. %37 = OpConstant %7 200
  727. %38 = OpConstantComposite %14 %36 %37
  728. %39 = OpConstantComposite %15 %35 %38
  729. %40 = OpConstantComposite %16 %21 %34 %39
  730. %4 = OpFunction %2 None %3
  731. %5 = OpLabel
  732. %18 = OpVariable %17 Function
  733. OpStore %18 %40
  734. %100 = OpCompositeConstruct %9 %19 %20 %19 %20 %19
  735. %101 = OpCompositeConstruct %11 %22 %23
  736. %102 = OpCompositeConstruct %11 %25 %26
  737. %103 = OpCompositeConstruct %11 %28 %29
  738. %104 = OpCompositeConstruct %11 %31 %32
  739. %105 = OpCompositeConstruct %12 %101 %102 %103 %104
  740. %106 = OpCompositeConstruct %14 %36 %37
  741. %107 = OpCompositeConstruct %15 %35 %106
  742. %108 = OpCompositeConstruct %16 %100 %105 %107
  743. OpReturn
  744. OpFunctionEnd
  745. )";
  746. const auto env = SPV_ENV_UNIVERSAL_1_3;
  747. const auto consumer = nullptr;
  748. const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
  749. ASSERT_TRUE(IsValid(env, context.get()));
  750. FactManager fact_manager;
  751. ASSERT_FALSE(fact_manager.IsSynonymous(
  752. MakeDataDescriptor(24, {}), MakeDataDescriptor(101, {}), context.get()));
  753. ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(24, {0}),
  754. MakeDataDescriptor(101, {0}),
  755. context.get()));
  756. ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(24, {1}),
  757. MakeDataDescriptor(101, {1}),
  758. context.get()));
  759. ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(24, {0}),
  760. MakeDataDescriptor(101, {1}),
  761. context.get()));
  762. fact_manager.AddFactDataSynonym(MakeDataDescriptor(24, {}),
  763. MakeDataDescriptor(101, {}), context.get());
  764. ASSERT_TRUE(fact_manager.IsSynonymous(
  765. MakeDataDescriptor(24, {}), MakeDataDescriptor(101, {}), context.get()));
  766. ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(24, {0}),
  767. MakeDataDescriptor(101, {0}),
  768. context.get()));
  769. ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(24, {1}),
  770. MakeDataDescriptor(101, {1}),
  771. context.get()));
  772. ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(24, {0}),
  773. MakeDataDescriptor(101, {1}),
  774. context.get()));
  775. ASSERT_FALSE(fact_manager.IsSynonymous(
  776. MakeDataDescriptor(27, {}), MakeDataDescriptor(102, {}), context.get()));
  777. ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(27, {0}),
  778. MakeDataDescriptor(102, {0}),
  779. context.get()));
  780. ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(27, {1}),
  781. MakeDataDescriptor(102, {1}),
  782. context.get()));
  783. fact_manager.AddFactDataSynonym(MakeDataDescriptor(27, {0}),
  784. MakeDataDescriptor(102, {0}), context.get());
  785. ASSERT_FALSE(fact_manager.IsSynonymous(
  786. MakeDataDescriptor(27, {}), MakeDataDescriptor(102, {}), context.get()));
  787. ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(27, {0}),
  788. MakeDataDescriptor(102, {0}),
  789. context.get()));
  790. ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(27, {1}),
  791. MakeDataDescriptor(102, {1}),
  792. context.get()));
  793. fact_manager.AddFactDataSynonym(MakeDataDescriptor(27, {1}),
  794. MakeDataDescriptor(102, {1}), context.get());
  795. ASSERT_TRUE(fact_manager.IsSynonymous(
  796. MakeDataDescriptor(27, {}), MakeDataDescriptor(102, {}), context.get()));
  797. ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(27, {0}),
  798. MakeDataDescriptor(102, {0}),
  799. context.get()));
  800. ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(27, {1}),
  801. MakeDataDescriptor(102, {1}),
  802. context.get()));
  803. ASSERT_FALSE(fact_manager.IsSynonymous(
  804. MakeDataDescriptor(30, {}), MakeDataDescriptor(103, {}), context.get()));
  805. ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(30, {0}),
  806. MakeDataDescriptor(103, {0}),
  807. context.get()));
  808. ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(30, {1}),
  809. MakeDataDescriptor(103, {1}),
  810. context.get()));
  811. ASSERT_FALSE(fact_manager.IsSynonymous(
  812. MakeDataDescriptor(33, {}), MakeDataDescriptor(104, {}), context.get()));
  813. ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(33, {0}),
  814. MakeDataDescriptor(104, {0}),
  815. context.get()));
  816. ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(33, {1}),
  817. MakeDataDescriptor(104, {1}),
  818. context.get()));
  819. ASSERT_FALSE(fact_manager.IsSynonymous(
  820. MakeDataDescriptor(34, {}), MakeDataDescriptor(105, {}), context.get()));
  821. ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(34, {0}),
  822. MakeDataDescriptor(105, {0}),
  823. context.get()));
  824. ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(34, {1}),
  825. MakeDataDescriptor(105, {1}),
  826. context.get()));
  827. ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(34, {2}),
  828. MakeDataDescriptor(105, {2}),
  829. context.get()));
  830. ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(34, {3}),
  831. MakeDataDescriptor(105, {3}),
  832. context.get()));
  833. fact_manager.AddFactDataSynonym(MakeDataDescriptor(30, {}),
  834. MakeDataDescriptor(103, {}), context.get());
  835. fact_manager.AddFactDataSynonym(MakeDataDescriptor(33, {}),
  836. MakeDataDescriptor(104, {}), context.get());
  837. fact_manager.AddFactDataSynonym(MakeDataDescriptor(34, {0}),
  838. MakeDataDescriptor(105, {0}), context.get());
  839. fact_manager.AddFactDataSynonym(MakeDataDescriptor(34, {1}),
  840. MakeDataDescriptor(105, {1}), context.get());
  841. fact_manager.AddFactDataSynonym(MakeDataDescriptor(34, {2}),
  842. MakeDataDescriptor(105, {2}), context.get());
  843. ASSERT_TRUE(fact_manager.IsSynonymous(
  844. MakeDataDescriptor(30, {}), MakeDataDescriptor(103, {}), context.get()));
  845. ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(30, {0}),
  846. MakeDataDescriptor(103, {0}),
  847. context.get()));
  848. ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(30, {1}),
  849. MakeDataDescriptor(103, {1}),
  850. context.get()));
  851. ASSERT_TRUE(fact_manager.IsSynonymous(
  852. MakeDataDescriptor(33, {}), MakeDataDescriptor(104, {}), context.get()));
  853. ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(33, {0}),
  854. MakeDataDescriptor(104, {0}),
  855. context.get()));
  856. ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(33, {1}),
  857. MakeDataDescriptor(104, {1}),
  858. context.get()));
  859. ASSERT_FALSE(fact_manager.IsSynonymous(
  860. MakeDataDescriptor(34, {}), MakeDataDescriptor(105, {}), context.get()));
  861. ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(34, {0}),
  862. MakeDataDescriptor(105, {0}),
  863. context.get()));
  864. ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(34, {1}),
  865. MakeDataDescriptor(105, {1}),
  866. context.get()));
  867. ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(34, {2}),
  868. MakeDataDescriptor(105, {2}),
  869. context.get()));
  870. ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(34, {3}),
  871. MakeDataDescriptor(105, {3}),
  872. context.get()));
  873. fact_manager.AddFactDataSynonym(MakeDataDescriptor(34, {3}),
  874. MakeDataDescriptor(105, {3}), context.get());
  875. ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(33, {0}),
  876. MakeDataDescriptor(104, {0}),
  877. context.get()));
  878. ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(34, {3}),
  879. MakeDataDescriptor(105, {3}),
  880. context.get()));
  881. ASSERT_FALSE(fact_manager.IsSynonymous(
  882. MakeDataDescriptor(21, {}), MakeDataDescriptor(100, {}), context.get()));
  883. fact_manager.AddFactDataSynonym(MakeDataDescriptor(21, {0}),
  884. MakeDataDescriptor(100, {0}), context.get());
  885. fact_manager.AddFactDataSynonym(MakeDataDescriptor(21, {1}),
  886. MakeDataDescriptor(100, {1}), context.get());
  887. fact_manager.AddFactDataSynonym(MakeDataDescriptor(21, {2}),
  888. MakeDataDescriptor(100, {2}), context.get());
  889. fact_manager.AddFactDataSynonym(MakeDataDescriptor(21, {3}),
  890. MakeDataDescriptor(100, {3}), context.get());
  891. fact_manager.AddFactDataSynonym(MakeDataDescriptor(21, {4}),
  892. MakeDataDescriptor(100, {4}), context.get());
  893. ASSERT_TRUE(fact_manager.IsSynonymous(
  894. MakeDataDescriptor(21, {}), MakeDataDescriptor(100, {}), context.get()));
  895. ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(39, {0}),
  896. MakeDataDescriptor(107, {0}),
  897. context.get()));
  898. ASSERT_FALSE(fact_manager.IsSynonymous(
  899. MakeDataDescriptor(35, {}), MakeDataDescriptor(39, {0}), context.get()));
  900. fact_manager.AddFactDataSynonym(MakeDataDescriptor(39, {0}),
  901. MakeDataDescriptor(35, {}), context.get());
  902. ASSERT_FALSE(fact_manager.IsSynonymous(MakeDataDescriptor(39, {0}),
  903. MakeDataDescriptor(107, {0}),
  904. context.get()));
  905. ASSERT_TRUE(fact_manager.IsSynonymous(
  906. MakeDataDescriptor(35, {}), MakeDataDescriptor(39, {0}), context.get()));
  907. ASSERT_FALSE(fact_manager.IsSynonymous(
  908. MakeDataDescriptor(38, {0}), MakeDataDescriptor(36, {}), context.get()));
  909. ASSERT_FALSE(fact_manager.IsSynonymous(
  910. MakeDataDescriptor(38, {1}), MakeDataDescriptor(37, {}), context.get()));
  911. ASSERT_FALSE(fact_manager.IsSynonymous(
  912. MakeDataDescriptor(106, {0}), MakeDataDescriptor(36, {}), context.get()));
  913. ASSERT_FALSE(fact_manager.IsSynonymous(
  914. MakeDataDescriptor(106, {1}), MakeDataDescriptor(37, {}), context.get()));
  915. ASSERT_FALSE(fact_manager.IsSynonymous(
  916. MakeDataDescriptor(38, {}), MakeDataDescriptor(106, {}), context.get()));
  917. fact_manager.AddFactDataSynonym(MakeDataDescriptor(38, {0}),
  918. MakeDataDescriptor(36, {}), context.get());
  919. fact_manager.AddFactDataSynonym(MakeDataDescriptor(106, {0}),
  920. MakeDataDescriptor(36, {}), context.get());
  921. fact_manager.AddFactDataSynonym(MakeDataDescriptor(38, {1}),
  922. MakeDataDescriptor(37, {}), context.get());
  923. fact_manager.AddFactDataSynonym(MakeDataDescriptor(106, {1}),
  924. MakeDataDescriptor(37, {}), context.get());
  925. ASSERT_TRUE(fact_manager.IsSynonymous(
  926. MakeDataDescriptor(38, {0}), MakeDataDescriptor(36, {}), context.get()));
  927. ASSERT_TRUE(fact_manager.IsSynonymous(
  928. MakeDataDescriptor(38, {1}), MakeDataDescriptor(37, {}), context.get()));
  929. ASSERT_TRUE(fact_manager.IsSynonymous(
  930. MakeDataDescriptor(106, {0}), MakeDataDescriptor(36, {}), context.get()));
  931. ASSERT_TRUE(fact_manager.IsSynonymous(
  932. MakeDataDescriptor(106, {1}), MakeDataDescriptor(37, {}), context.get()));
  933. ASSERT_TRUE(fact_manager.IsSynonymous(
  934. MakeDataDescriptor(38, {}), MakeDataDescriptor(106, {}), context.get()));
  935. ASSERT_FALSE(fact_manager.IsSynonymous(
  936. MakeDataDescriptor(40, {}), MakeDataDescriptor(108, {}), context.get()));
  937. fact_manager.AddFactDataSynonym(MakeDataDescriptor(107, {0}),
  938. MakeDataDescriptor(35, {}), context.get());
  939. fact_manager.AddFactDataSynonym(MakeDataDescriptor(40, {0}),
  940. MakeDataDescriptor(108, {0}), context.get());
  941. fact_manager.AddFactDataSynonym(MakeDataDescriptor(40, {1}),
  942. MakeDataDescriptor(108, {1}), context.get());
  943. fact_manager.AddFactDataSynonym(MakeDataDescriptor(40, {2}),
  944. MakeDataDescriptor(108, {2}), context.get());
  945. ASSERT_TRUE(fact_manager.IsSynonymous(
  946. MakeDataDescriptor(40, {}), MakeDataDescriptor(108, {}), context.get()));
  947. ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {0}),
  948. MakeDataDescriptor(108, {0}),
  949. context.get()));
  950. ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {1}),
  951. MakeDataDescriptor(108, {1}),
  952. context.get()));
  953. ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {2}),
  954. MakeDataDescriptor(108, {2}),
  955. context.get()));
  956. ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {0, 0}),
  957. MakeDataDescriptor(108, {0, 0}),
  958. context.get()));
  959. ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {0, 1}),
  960. MakeDataDescriptor(108, {0, 1}),
  961. context.get()));
  962. ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {0, 2}),
  963. MakeDataDescriptor(108, {0, 2}),
  964. context.get()));
  965. ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {0, 3}),
  966. MakeDataDescriptor(108, {0, 3}),
  967. context.get()));
  968. ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {0, 4}),
  969. MakeDataDescriptor(108, {0, 4}),
  970. context.get()));
  971. ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {1, 0}),
  972. MakeDataDescriptor(108, {1, 0}),
  973. context.get()));
  974. ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {1, 1}),
  975. MakeDataDescriptor(108, {1, 1}),
  976. context.get()));
  977. ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {1, 2}),
  978. MakeDataDescriptor(108, {1, 2}),
  979. context.get()));
  980. ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {1, 3}),
  981. MakeDataDescriptor(108, {1, 3}),
  982. context.get()));
  983. ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {1, 0, 0}),
  984. MakeDataDescriptor(108, {1, 0, 0}),
  985. context.get()));
  986. ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {1, 1, 0}),
  987. MakeDataDescriptor(108, {1, 1, 0}),
  988. context.get()));
  989. ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {1, 2, 0}),
  990. MakeDataDescriptor(108, {1, 2, 0}),
  991. context.get()));
  992. ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {1, 3, 0}),
  993. MakeDataDescriptor(108, {1, 3, 0}),
  994. context.get()));
  995. ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {1, 0, 1}),
  996. MakeDataDescriptor(108, {1, 0, 1}),
  997. context.get()));
  998. ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {1, 1, 1}),
  999. MakeDataDescriptor(108, {1, 1, 1}),
  1000. context.get()));
  1001. ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {1, 2, 1}),
  1002. MakeDataDescriptor(108, {1, 2, 1}),
  1003. context.get()));
  1004. ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {1, 3, 1}),
  1005. MakeDataDescriptor(108, {1, 3, 1}),
  1006. context.get()));
  1007. ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {2, 0}),
  1008. MakeDataDescriptor(108, {2, 0}),
  1009. context.get()));
  1010. ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {2, 1}),
  1011. MakeDataDescriptor(108, {2, 1}),
  1012. context.get()));
  1013. ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {2, 1, 0}),
  1014. MakeDataDescriptor(108, {2, 1, 0}),
  1015. context.get()));
  1016. ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(40, {2, 1, 1}),
  1017. MakeDataDescriptor(108, {2, 1, 1}),
  1018. context.get()));
  1019. }
  1020. TEST(FactManagerTest, RecursiveAdditionOfFacts) {
  1021. std::string shader = R"(
  1022. OpCapability Shader
  1023. %1 = OpExtInstImport "GLSL.std.450"
  1024. OpMemoryModel Logical GLSL450
  1025. OpEntryPoint Fragment %12 "main"
  1026. OpExecutionMode %12 OriginUpperLeft
  1027. OpSource ESSL 310
  1028. %2 = OpTypeVoid
  1029. %3 = OpTypeFunction %2
  1030. %6 = OpTypeFloat 32
  1031. %7 = OpTypeVector %6 4
  1032. %8 = OpTypeMatrix %7 4
  1033. %9 = OpConstant %6 0
  1034. %10 = OpConstantComposite %7 %9 %9 %9 %9
  1035. %11 = OpConstantComposite %8 %10 %10 %10 %10
  1036. %12 = OpFunction %2 None %3
  1037. %13 = OpLabel
  1038. OpReturn
  1039. OpFunctionEnd
  1040. )";
  1041. const auto env = SPV_ENV_UNIVERSAL_1_3;
  1042. const auto consumer = nullptr;
  1043. const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
  1044. ASSERT_TRUE(IsValid(env, context.get()));
  1045. FactManager fact_manager;
  1046. fact_manager.AddFactDataSynonym(MakeDataDescriptor(10, {}),
  1047. MakeDataDescriptor(11, {2}), context.get());
  1048. ASSERT_TRUE(fact_manager.IsSynonymous(
  1049. MakeDataDescriptor(10, {}), MakeDataDescriptor(11, {2}), context.get()));
  1050. ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(10, {0}),
  1051. MakeDataDescriptor(11, {2, 0}),
  1052. context.get()));
  1053. ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(10, {1}),
  1054. MakeDataDescriptor(11, {2, 1}),
  1055. context.get()));
  1056. ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(10, {2}),
  1057. MakeDataDescriptor(11, {2, 2}),
  1058. context.get()));
  1059. ASSERT_TRUE(fact_manager.IsSynonymous(MakeDataDescriptor(10, {3}),
  1060. MakeDataDescriptor(11, {2, 3}),
  1061. context.get()));
  1062. }
  1063. } // namespace
  1064. } // namespace fuzz
  1065. } // namespace spvtools