fuzzer_context.h 22 KB

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