fuzzer_context.h 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610
  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. #ifndef SOURCE_FUZZ_FUZZER_CONTEXT_H_
  15. #define SOURCE_FUZZ_FUZZER_CONTEXT_H_
  16. #include <functional>
  17. #include <utility>
  18. #include "source/fuzz/protobufs/spirvfuzz_protobufs.h"
  19. #include "source/fuzz/random_generator.h"
  20. #include "source/opt/function.h"
  21. #include "source/opt/ir_context.h"
  22. namespace spvtools {
  23. namespace fuzz {
  24. // Encapsulates all parameters that control the fuzzing process, such as the
  25. // source of randomness and the probabilities with which transformations are
  26. // applied.
  27. class FuzzerContext {
  28. public:
  29. // Constructs a fuzzer context with a given random generator and the minimum
  30. // value that can be used for fresh ids.
  31. FuzzerContext(std::unique_ptr<RandomGenerator> random_generator,
  32. uint32_t min_fresh_id, bool is_wgsl_compatible);
  33. ~FuzzerContext();
  34. // Returns a random boolean.
  35. bool ChooseEven();
  36. // Returns true if and only if a randomly-chosen integer in the range [0, 100]
  37. // is less than |percentage_chance|.
  38. bool ChoosePercentage(uint32_t percentage_chance);
  39. // Returns a random index into |sequence|, which is expected to have a 'size'
  40. // method, and which must be non-empty. Typically 'HasSizeMethod' will be an
  41. // std::vector.
  42. template <typename HasSizeMethod>
  43. uint32_t RandomIndex(const HasSizeMethod& sequence) const {
  44. assert(sequence.size() > 0);
  45. return random_generator_->RandomUint32(
  46. static_cast<uint32_t>(sequence.size()));
  47. }
  48. // Selects a random index into |sequence|, removes the element at that index
  49. // and returns it.
  50. template <typename T>
  51. T RemoveAtRandomIndex(std::vector<T>* sequence) const {
  52. uint32_t index = RandomIndex(*sequence);
  53. T result = sequence->at(index);
  54. sequence->erase(sequence->begin() + index);
  55. return result;
  56. }
  57. // Randomly shuffles a |sequence| between |lo| and |hi| indices inclusively.
  58. // |lo| and |hi| must be valid indices to the |sequence|.
  59. template <typename T>
  60. void Shuffle(std::vector<T>* sequence, size_t lo, size_t hi) const {
  61. auto& array = *sequence;
  62. if (array.empty()) {
  63. return;
  64. }
  65. assert(lo <= hi && hi < array.size() && "lo and/or hi indices are invalid");
  66. // i > lo to account for potential infinite loop when lo == 0
  67. for (size_t i = hi; i > lo; --i) {
  68. auto index =
  69. random_generator_->RandomUint32(static_cast<uint32_t>(i - lo + 1));
  70. if (lo + index != i) {
  71. // Introduce std::swap to the scope but don't use it
  72. // directly since there might be a better overload
  73. using std::swap;
  74. swap(array[lo + index], array[i]);
  75. }
  76. }
  77. }
  78. // Randomly shuffles a |sequence|.
  79. template <typename T>
  80. void Shuffle(std::vector<T>* sequence) const {
  81. if (!sequence->empty()) {
  82. Shuffle(sequence, 0, sequence->size() - 1);
  83. }
  84. }
  85. // Yields an id that is guaranteed not to be used in the module being fuzzed,
  86. // or to have been issued before.
  87. uint32_t GetFreshId();
  88. // Returns a vector of |count| fresh ids.
  89. std::vector<uint32_t> GetFreshIds(uint32_t count);
  90. // A suggested limit on the id bound for the module being fuzzed. This is
  91. // useful for deciding when to stop the overall fuzzing process. Furthermore,
  92. // fuzzer passes that run the risk of spiralling out of control can
  93. // periodically check this limit and terminate early if it has been reached.
  94. uint32_t GetIdBoundLimit() const;
  95. // A suggested limit on the number of transformations that should be applied.
  96. // Also useful to control the overall fuzzing process and rein in individual
  97. // fuzzer passes.
  98. uint32_t GetTransformationLimit() const;
  99. // Returns the minimum fresh id that can be used given the |ir_context|.
  100. static uint32_t GetMinFreshId(opt::IRContext* ir_context);
  101. // Returns true if all transformations should be compatible with WGSL.
  102. bool IsWgslCompatible() const {
  103. return is_wgsl_compatible_;
  104. }
  105. // Probabilities associated with applying various transformations.
  106. // Keep them in alphabetical order.
  107. uint32_t GetChanceOfAcceptingRepeatedPassRecommendation() const {
  108. return chance_of_accepting_repeated_pass_recommendation_;
  109. }
  110. uint32_t GetChanceOfAddingAccessChain() const {
  111. return chance_of_adding_access_chain_;
  112. }
  113. uint32_t GetChanceOfAddingAnotherPassToPassLoop() const {
  114. return chance_of_adding_another_pass_to_pass_loop_;
  115. }
  116. uint32_t GetChanceOfAddingAnotherStructField() const {
  117. return chance_of_adding_another_struct_field_;
  118. }
  119. uint32_t GetChanceOfAddingArrayOrStructType() const {
  120. return chance_of_adding_array_or_struct_type_;
  121. }
  122. uint32_t GetChanceOfAddingAtomicLoad() const {
  123. return chance_of_adding_atomic_load_;
  124. }
  125. uint32_t GetChanceOfAddingAtomicStore() const {
  126. return chance_of_adding_atomic_store_;
  127. }
  128. uint32_t GetChanceOfAddingBitInstructionSynonym() const {
  129. return chance_of_adding_bit_instruction_synonym_;
  130. }
  131. uint32_t GetChanceOfAddingBothBranchesWhenReplacingOpSelect() const {
  132. return chance_of_adding_both_branches_when_replacing_opselect_;
  133. }
  134. uint32_t GetChanceOfAddingCompositeExtract() const {
  135. return chance_of_adding_composite_extract_;
  136. }
  137. uint32_t GetChanceOfAddingCompositeInsert() const {
  138. return chance_of_adding_composite_insert_;
  139. }
  140. uint32_t GetChanceOfAddingCopyMemory() const {
  141. return chance_of_adding_copy_memory_;
  142. }
  143. uint32_t GetChanceOfAddingDeadBlock() const {
  144. return chance_of_adding_dead_block_;
  145. }
  146. uint32_t GetChanceOfAddingDeadBreak() const {
  147. return chance_of_adding_dead_break_;
  148. }
  149. uint32_t GetChanceOfAddingDeadContinue() const {
  150. return chance_of_adding_dead_continue_;
  151. }
  152. uint32_t GetChanceOfAddingEquationInstruction() const {
  153. return chance_of_adding_equation_instruction_;
  154. }
  155. uint32_t GetChanceOfAddingGlobalVariable() const {
  156. return chance_of_adding_global_variable_;
  157. }
  158. uint32_t GetChanceOfAddingImageSampleUnusedComponents() const {
  159. return chance_of_adding_image_sample_unused_components_;
  160. }
  161. uint32_t GetChanceOfAddingLoad() const { return chance_of_adding_load_; }
  162. uint32_t GetChanceOfAddingLocalVariable() const {
  163. return chance_of_adding_local_variable_;
  164. }
  165. uint32_t GetChanceOfAddingLoopPreheader() const {
  166. return chance_of_adding_loop_preheader_;
  167. }
  168. uint32_t GetChanceOfAddingMatrixType() const {
  169. return chance_of_adding_matrix_type_;
  170. }
  171. uint32_t GetChanceOfAddingNoContractionDecoration() const {
  172. return chance_of_adding_no_contraction_decoration_;
  173. }
  174. uint32_t GetChanceOfAddingOpPhiSynonym() const {
  175. return chance_of_adding_opphi_synonym_;
  176. }
  177. uint32_t GetChanceOfAddingParameters() const {
  178. return chance_of_adding_parameters;
  179. }
  180. uint32_t GetChanceOfAddingRelaxedDecoration() const {
  181. return chance_of_adding_relaxed_decoration_;
  182. }
  183. uint32_t GetChanceOfAddingStore() const { return chance_of_adding_store_; }
  184. uint32_t GetChanceOfAddingSynonyms() const {
  185. return chance_of_adding_synonyms_;
  186. }
  187. uint32_t GetChanceOfAddingTrueBranchWhenReplacingOpSelect() const {
  188. return chance_of_adding_true_branch_when_replacing_opselect_;
  189. }
  190. uint32_t GetChanceOfAddingVectorShuffle() const {
  191. return chance_of_adding_vector_shuffle_;
  192. }
  193. uint32_t GetChanceOfAddingVectorType() const {
  194. return chance_of_adding_vector_type_;
  195. }
  196. uint32_t GetChanceOfAdjustingBranchWeights() const {
  197. return chance_of_adjusting_branch_weights_;
  198. }
  199. uint32_t GetChanceOfAdjustingFunctionControl() const {
  200. return chance_of_adjusting_function_control_;
  201. }
  202. uint32_t GetChanceOfAdjustingLoopControl() const {
  203. return chance_of_adjusting_loop_control_;
  204. }
  205. uint32_t GetChanceOfAdjustingMemoryOperandsMask() const {
  206. return chance_of_adjusting_memory_operands_mask_;
  207. }
  208. uint32_t GetChanceOfAdjustingSelectionControl() const {
  209. return chance_of_adjusting_selection_control_;
  210. }
  211. uint32_t GetChanceOfCallingFunction() const {
  212. return chance_of_calling_function_;
  213. }
  214. uint32_t GetChanceOfChoosingStructTypeVsArrayType() const {
  215. return chance_of_choosing_struct_type_vs_array_type_;
  216. }
  217. uint32_t GetChanceOfChoosingWorkgroupStorageClass() const {
  218. return chance_of_choosing_workgroup_storage_class_;
  219. }
  220. uint32_t GetChanceOfConstructingComposite() const {
  221. return chance_of_constructing_composite_;
  222. }
  223. uint32_t GetChanceOfCopyingObject() const {
  224. return chance_of_copying_object_;
  225. }
  226. uint32_t GetChanceOfCreatingIntSynonymsUsingLoops() const {
  227. return chance_of_creating_int_synonyms_using_loops_;
  228. }
  229. uint32_t GetChanceOfDonatingAdditionalModule() const {
  230. return chance_of_donating_additional_module_;
  231. }
  232. uint32_t GetChanceOfDuplicatingRegionWithSelection() const {
  233. return chance_of_duplicating_region_with_selection_;
  234. }
  235. uint32_t GetChanceOfExpandingVectorReduction() const {
  236. return chance_of_expanding_vector_reduction_;
  237. }
  238. uint32_t GetChanceOfFlatteningConditionalBranch() const {
  239. return chance_of_flattening_conditional_branch_;
  240. }
  241. uint32_t GetChanceOfGoingDeeperToExtractComposite() const {
  242. return chance_of_going_deeper_to_extract_composite_;
  243. }
  244. uint32_t GetChanceOfGoingDeeperToInsertInComposite() const {
  245. return chance_of_going_deeper_to_insert_in_composite_;
  246. }
  247. uint32_t GetChanceOfGoingDeeperWhenMakingAccessChain() const {
  248. return chance_of_going_deeper_when_making_access_chain_;
  249. }
  250. uint32_t GetChanceOfHavingTwoBlocksInLoopToCreateIntSynonym() const {
  251. return chance_of_having_two_blocks_in_loop_to_create_int_synonym_;
  252. }
  253. uint32_t GetChanceOfInliningFunction() const {
  254. return chance_of_inlining_function_;
  255. }
  256. uint32_t GetChanceOfInterchangingSignednessOfIntegerOperands() const {
  257. return chance_of_interchanging_signedness_of_integer_operands_;
  258. }
  259. uint32_t GetChanceOfInterchangingZeroLikeConstants() const {
  260. return chance_of_interchanging_zero_like_constants_;
  261. }
  262. uint32_t GetChanceOfInvertingComparisonOperators() const {
  263. return chance_of_inverting_comparison_operators_;
  264. }
  265. uint32_t ChanceOfMakingDonorLivesafe() const {
  266. return chance_of_making_donor_livesafe_;
  267. }
  268. uint32_t GetChanceOfMakingVectorOperationDynamic() const {
  269. return chance_of_making_vector_operation_dynamic_;
  270. }
  271. uint32_t GetChanceOfMergingBlocks() const {
  272. return chance_of_merging_blocks_;
  273. }
  274. uint32_t GetChanceOfMergingFunctionReturns() const {
  275. return chance_of_merging_function_returns_;
  276. }
  277. uint32_t GetChanceOfMovingBlockDown() const {
  278. return chance_of_moving_block_down_;
  279. }
  280. uint32_t GetChanceOfMutatingPointer() const {
  281. return chance_of_mutating_pointer_;
  282. }
  283. uint32_t GetChanceOfObfuscatingConstant() const {
  284. return chance_of_obfuscating_constant_;
  285. }
  286. uint32_t GetChanceOfOutliningFunction() const {
  287. return chance_of_outlining_function_;
  288. }
  289. uint32_t GetChanceOfPermutingFunctionVariables() const {
  290. return chance_of_permuting_function_variables_;
  291. }
  292. uint32_t GetChanceOfPermutingInstructions() const {
  293. return chance_of_permuting_instructions_;
  294. }
  295. uint32_t GetChanceOfPermutingParameters() const {
  296. return chance_of_permuting_parameters_;
  297. }
  298. uint32_t GetChanceOfPermutingPhiOperands() const {
  299. return chance_of_permuting_phi_operands_;
  300. }
  301. uint32_t GetChanceOfPropagatingInstructionsDown() const {
  302. return chance_of_propagating_instructions_down_;
  303. }
  304. uint32_t GetChanceOfPropagatingInstructionsUp() const {
  305. return chance_of_propagating_instructions_up_;
  306. }
  307. uint32_t GetChanceOfPushingIdThroughVariable() const {
  308. return chance_of_pushing_id_through_variable_;
  309. }
  310. uint32_t GetChanceOfReplacingAddSubMulWithCarryingExtended() const {
  311. return chance_of_replacing_add_sub_mul_with_carrying_extended_;
  312. }
  313. uint32_t GetChanceOfReplacingBranchFromDeadBlockWithExit() const {
  314. return chance_of_replacing_branch_from_dead_block_with_exit_;
  315. }
  316. uint32_t GetChanceOfReplacingCopyMemoryWithLoadStore() const {
  317. return chance_of_replacing_copy_memory_with_load_store_;
  318. }
  319. uint32_t GetChanceOfReplacingCopyObjectWithStoreLoad() const {
  320. return chance_of_replacing_copyobject_with_store_load_;
  321. }
  322. uint32_t GetChanceOfReplacingIdWithSynonym() const {
  323. return chance_of_replacing_id_with_synonym_;
  324. }
  325. uint32_t GetChanceOfReplacingIrrelevantId() const {
  326. return chance_of_replacing_irrelevant_id_;
  327. }
  328. uint32_t GetChanceOfReplacingLinearAlgebraInstructions() const {
  329. return chance_of_replacing_linear_algebra_instructions_;
  330. }
  331. uint32_t GetChanceOfReplacingLoadStoreWithCopyMemory() const {
  332. return chance_of_replacing_load_store_with_copy_memory_;
  333. }
  334. uint32_t GetChanceOfReplacingOpPhiIdFromDeadPredecessor() const {
  335. return chance_of_replacing_opphi_id_from_dead_predecessor_;
  336. }
  337. uint32_t GetChanceOfReplacingOpselectWithConditionalBranch() const {
  338. return chance_of_replacing_opselect_with_conditional_branch_;
  339. }
  340. uint32_t GetChanceOfReplacingParametersWithGlobals() const {
  341. return chance_of_replacing_parameters_with_globals_;
  342. }
  343. uint32_t GetChanceOfReplacingParametersWithStruct() const {
  344. return chance_of_replacing_parameters_with_struct_;
  345. }
  346. uint32_t GetChanceOfSplittingBlock() const {
  347. return chance_of_splitting_block_;
  348. }
  349. uint32_t GetChanceOfSwappingAnotherPairOfFunctionVariables() const {
  350. return chance_of_swapping_another_pair_of_function_variables_;
  351. }
  352. uint32_t GetChanceOfSwappingConditionalBranchOperands() const {
  353. return chance_of_swapping_conditional_branch_operands_;
  354. }
  355. uint32_t GetChanceOfSwappingFunctions() const {
  356. return chance_of_swapping_functions_;
  357. }
  358. uint32_t GetChanceOfTogglingAccessChainInstruction() const {
  359. return chance_of_toggling_access_chain_instruction_;
  360. }
  361. uint32_t GetChanceOfWrappingRegionInSelection() const {
  362. return chance_of_wrapping_region_in_selection_;
  363. }
  364. uint32_t GetChanceOfWrappingVectorSynonym() const {
  365. return chance_of_wrapping_vector_synonym_;
  366. }
  367. // Other functions to control transformations. Keep them in alphabetical
  368. // order.
  369. uint32_t GetMaximumEquivalenceClassSizeForDataSynonymFactClosure() const {
  370. return max_equivalence_class_size_for_data_synonym_fact_closure_;
  371. }
  372. uint32_t GetMaximumNumberOfFunctionParameters() const {
  373. return max_number_of_function_parameters_;
  374. }
  375. uint32_t GetMaximumNumberOfParametersReplacedWithStruct() const {
  376. return max_number_of_parameters_replaced_with_struct_;
  377. }
  378. std::pair<uint32_t, uint32_t> GetRandomBranchWeights() {
  379. std::pair<uint32_t, uint32_t> branch_weights = {0, 0};
  380. while (branch_weights.first == 0 && branch_weights.second == 0) {
  381. // Using INT32_MAX to do not overflow UINT32_MAX when the branch weights
  382. // are added together.
  383. branch_weights.first = random_generator_->RandomUint32(INT32_MAX);
  384. branch_weights.second = random_generator_->RandomUint32(INT32_MAX);
  385. }
  386. return branch_weights;
  387. }
  388. std::vector<uint32_t> GetRandomComponentsForVectorShuffle(
  389. uint32_t max_component_index) {
  390. // Component count must be in range [2, 4].
  391. std::vector<uint32_t> components(random_generator_->RandomUint32(2) + 2);
  392. for (uint32_t& component : components) {
  393. component = random_generator_->RandomUint32(max_component_index);
  394. }
  395. return components;
  396. }
  397. uint32_t GetRandomCompositeExtractIndex(uint32_t number_of_members) {
  398. assert(number_of_members > 0 && "Composite object must have some members");
  399. return ChooseBetweenMinAndMax({0, number_of_members - 1});
  400. }
  401. uint32_t GetRandomIndexForAccessChain(uint32_t composite_size_bound) {
  402. return random_generator_->RandomUint32(composite_size_bound);
  403. }
  404. uint32_t GetRandomIndexForCompositeInsert(uint32_t number_of_components) {
  405. return random_generator_->RandomUint32(number_of_components);
  406. }
  407. uint32_t GetRandomIndexForWrappingVector(uint32_t vector_width) {
  408. return random_generator_->RandomUint32(vector_width);
  409. }
  410. int64_t GetRandomValueForStepConstantInLoop() {
  411. return random_generator_->RandomUint64(UINT64_MAX);
  412. }
  413. uint32_t GetRandomLoopControlPartialCount() {
  414. return random_generator_->RandomUint32(max_loop_control_partial_count_);
  415. }
  416. uint32_t GetRandomLoopControlPeelCount() {
  417. return random_generator_->RandomUint32(max_loop_control_peel_count_);
  418. }
  419. uint32_t GetRandomLoopLimit() {
  420. return random_generator_->RandomUint32(max_loop_limit_);
  421. }
  422. uint32_t GetRandomNumberOfLoopIterations(uint32_t max_num_iterations) {
  423. return ChooseBetweenMinAndMax({1, max_num_iterations});
  424. }
  425. uint32_t GetRandomNumberOfNewParameters(uint32_t num_of_params) {
  426. assert(num_of_params < GetMaximumNumberOfFunctionParameters());
  427. return ChooseBetweenMinAndMax(
  428. {1, std::min(max_number_of_new_parameters_,
  429. GetMaximumNumberOfFunctionParameters() - num_of_params)});
  430. }
  431. uint32_t GetRandomNumberOfParametersReplacedWithStruct(uint32_t num_params) {
  432. assert(num_params != 0 && "A function must have parameters to replace");
  433. return ChooseBetweenMinAndMax(
  434. {1, std::min(num_params,
  435. GetMaximumNumberOfParametersReplacedWithStruct())});
  436. }
  437. uint32_t GetRandomSizeForNewArray() {
  438. // Ensure that the array size is non-zero.
  439. return random_generator_->RandomUint32(max_new_array_size_limit_ - 1) + 1;
  440. }
  441. protobufs::TransformationAddSynonym::SynonymType GetRandomSynonymType();
  442. uint32_t GetRandomUnusedComponentCountForImageSample(
  443. uint32_t max_unused_component_count) {
  444. // Ensure that the number of unused components is non-zero.
  445. return random_generator_->RandomUint32(max_unused_component_count) + 1;
  446. }
  447. uint32_t GetWidthOfWrappingVector() {
  448. return 2 + random_generator_->RandomUint32(3);
  449. }
  450. bool GoDeeperInConstantObfuscation(uint32_t depth) {
  451. return go_deeper_in_constant_obfuscation_(depth, random_generator_.get());
  452. }
  453. private:
  454. // The source of randomness.
  455. std::unique_ptr<RandomGenerator> random_generator_;
  456. // The next fresh id to be issued.
  457. uint32_t next_fresh_id_;
  458. // True if all transformations should be compatible with WGSL spec.
  459. bool is_wgsl_compatible_;
  460. // Probabilities associated with applying various transformations.
  461. // Keep them in alphabetical order.
  462. uint32_t chance_of_accepting_repeated_pass_recommendation_;
  463. uint32_t chance_of_adding_access_chain_;
  464. uint32_t chance_of_adding_another_pass_to_pass_loop_;
  465. uint32_t chance_of_adding_another_struct_field_;
  466. uint32_t chance_of_adding_array_or_struct_type_;
  467. uint32_t chance_of_adding_atomic_load_;
  468. uint32_t chance_of_adding_atomic_store_;
  469. uint32_t chance_of_adding_bit_instruction_synonym_;
  470. uint32_t chance_of_adding_both_branches_when_replacing_opselect_;
  471. uint32_t chance_of_adding_composite_extract_;
  472. uint32_t chance_of_adding_composite_insert_;
  473. uint32_t chance_of_adding_copy_memory_;
  474. uint32_t chance_of_adding_dead_block_;
  475. uint32_t chance_of_adding_dead_break_;
  476. uint32_t chance_of_adding_dead_continue_;
  477. uint32_t chance_of_adding_equation_instruction_;
  478. uint32_t chance_of_adding_global_variable_;
  479. uint32_t chance_of_adding_image_sample_unused_components_;
  480. uint32_t chance_of_adding_load_;
  481. uint32_t chance_of_adding_local_variable_;
  482. uint32_t chance_of_adding_loop_preheader_;
  483. uint32_t chance_of_adding_matrix_type_;
  484. uint32_t chance_of_adding_no_contraction_decoration_;
  485. uint32_t chance_of_adding_opphi_synonym_;
  486. uint32_t chance_of_adding_parameters;
  487. uint32_t chance_of_adding_relaxed_decoration_;
  488. uint32_t chance_of_adding_store_;
  489. uint32_t chance_of_adding_synonyms_;
  490. uint32_t chance_of_adding_true_branch_when_replacing_opselect_;
  491. uint32_t chance_of_adding_vector_shuffle_;
  492. uint32_t chance_of_adding_vector_type_;
  493. uint32_t chance_of_adjusting_branch_weights_;
  494. uint32_t chance_of_adjusting_function_control_;
  495. uint32_t chance_of_adjusting_loop_control_;
  496. uint32_t chance_of_adjusting_memory_operands_mask_;
  497. uint32_t chance_of_adjusting_selection_control_;
  498. uint32_t chance_of_calling_function_;
  499. uint32_t chance_of_choosing_struct_type_vs_array_type_;
  500. uint32_t chance_of_choosing_workgroup_storage_class_;
  501. uint32_t chance_of_constructing_composite_;
  502. uint32_t chance_of_copying_object_;
  503. uint32_t chance_of_creating_int_synonyms_using_loops_;
  504. uint32_t chance_of_donating_additional_module_;
  505. uint32_t chance_of_duplicating_region_with_selection_;
  506. uint32_t chance_of_expanding_vector_reduction_;
  507. uint32_t chance_of_flattening_conditional_branch_;
  508. uint32_t chance_of_going_deeper_to_extract_composite_;
  509. uint32_t chance_of_going_deeper_to_insert_in_composite_;
  510. uint32_t chance_of_going_deeper_when_making_access_chain_;
  511. uint32_t chance_of_having_two_blocks_in_loop_to_create_int_synonym_;
  512. uint32_t chance_of_inlining_function_;
  513. uint32_t chance_of_interchanging_signedness_of_integer_operands_;
  514. uint32_t chance_of_interchanging_zero_like_constants_;
  515. uint32_t chance_of_inverting_comparison_operators_;
  516. uint32_t chance_of_making_donor_livesafe_;
  517. uint32_t chance_of_making_vector_operation_dynamic_;
  518. uint32_t chance_of_merging_blocks_;
  519. uint32_t chance_of_merging_function_returns_;
  520. uint32_t chance_of_moving_block_down_;
  521. uint32_t chance_of_mutating_pointer_;
  522. uint32_t chance_of_obfuscating_constant_;
  523. uint32_t chance_of_outlining_function_;
  524. uint32_t chance_of_permuting_function_variables_;
  525. uint32_t chance_of_permuting_instructions_;
  526. uint32_t chance_of_permuting_parameters_;
  527. uint32_t chance_of_permuting_phi_operands_;
  528. uint32_t chance_of_propagating_instructions_down_;
  529. uint32_t chance_of_propagating_instructions_up_;
  530. uint32_t chance_of_pushing_id_through_variable_;
  531. uint32_t chance_of_replacing_add_sub_mul_with_carrying_extended_;
  532. uint32_t chance_of_replacing_branch_from_dead_block_with_exit_;
  533. uint32_t chance_of_replacing_copy_memory_with_load_store_;
  534. uint32_t chance_of_replacing_copyobject_with_store_load_;
  535. uint32_t chance_of_replacing_id_with_synonym_;
  536. uint32_t chance_of_replacing_irrelevant_id_;
  537. uint32_t chance_of_replacing_linear_algebra_instructions_;
  538. uint32_t chance_of_replacing_load_store_with_copy_memory_;
  539. uint32_t chance_of_replacing_opphi_id_from_dead_predecessor_;
  540. uint32_t chance_of_replacing_opselect_with_conditional_branch_;
  541. uint32_t chance_of_replacing_parameters_with_globals_;
  542. uint32_t chance_of_replacing_parameters_with_struct_;
  543. uint32_t chance_of_splitting_block_;
  544. uint32_t chance_of_swapping_another_pair_of_function_variables_;
  545. uint32_t chance_of_swapping_conditional_branch_operands_;
  546. uint32_t chance_of_swapping_functions_;
  547. uint32_t chance_of_toggling_access_chain_instruction_;
  548. uint32_t chance_of_wrapping_region_in_selection_;
  549. uint32_t chance_of_wrapping_vector_synonym_;
  550. // Limits associated with various quantities for which random values are
  551. // chosen during fuzzing.
  552. // Keep them in alphabetical order.
  553. uint32_t max_equivalence_class_size_for_data_synonym_fact_closure_;
  554. uint32_t max_loop_control_partial_count_;
  555. uint32_t max_loop_control_peel_count_;
  556. uint32_t max_loop_limit_;
  557. uint32_t max_new_array_size_limit_;
  558. uint32_t max_number_of_function_parameters_;
  559. uint32_t max_number_of_new_parameters_;
  560. uint32_t max_number_of_parameters_replaced_with_struct_;
  561. // Functions to determine with what probability to go deeper when generating
  562. // or mutating constructs recursively.
  563. const std::function<bool(uint32_t, RandomGenerator*)>&
  564. go_deeper_in_constant_obfuscation_;
  565. // Requires |min_max.first| <= |min_max.second|, and returns a value in the
  566. // range [ |min_max.first|, |min_max.second| ]
  567. uint32_t ChooseBetweenMinAndMax(const std::pair<uint32_t, uint32_t>& min_max);
  568. };
  569. } // namespace fuzz
  570. } // namespace spvtools
  571. #endif // SOURCE_FUZZ_FUZZER_CONTEXT_H_