summaryrefslogtreecommitdiff
path: root/llvm/lib/FuzzMutate/IRMutator.cpp
AgeCommit message (Collapse)Author
2025-06-24[FuzzMutate] Properly handle intrinsics and avoid illegal code genertion ↵Manuel Carrasco
(#145495) This PR addresses issues related to the `amdgcn_cs_chain` intrinsic: 1. Ensures the intrinsic's special attribute and calling convention requirements are not violated by the mutator. 2. Enforces the necessary unreachable statement following this type of intrinsic, preventing the fuzzer from generating invalid code.
2025-06-06[FuzzMutate] Use llvm::any_of (NFC) (#143227)Kazu Hirata
Note that llvm::any_of can accommodate std::begin(Range), not just Range.begin().
2025-06-05[FuzzMutate] Prevent UB caused by parameter ABI attributes (#139737)Manuel Carrasco
This PR prevents the IRMutator from incorrectly calling functions that have ABI attributes, otherwise the mutations introduce UB.
2025-05-12[FuzzMutate] Match the callee's and callsite's calling conventions. (#139100)Manuel Carrasco
The mutator can generate calls with undefined behavior because it is not matching the calling conventions.
2025-05-12[FuzzMutate] Prevent the mutator from generating invalid IR caused by ↵Manuel Carrasco
non-callable CCs (#139080) The current implementation can generate invalid IR due to illegal use of CCs. This matches the behaviour of the IRVerifier.
2025-04-19[llvm] Construct SmallVector with iterator ranges (NFC) (#136460)Kazu Hirata
2025-01-24[NFC][DebugInfo] Use iterator moveBefore at many call-sites (#123583)Jeremy Morse
As part of the "RemoveDIs" project, BasicBlock::iterator now carries a debug-info bit that's needed when getFirstNonPHI and similar feed into instruction insertion positions. Call-sites where that's necessary were updated a year ago; but to ensure some type safety however, we'd like to have all calls to moveBefore use iterators. This patch adds a (guaranteed dereferenceable) iterator-taking moveBefore, and changes a bunch of call-sites where it's obviously safe to change to use it by just calling getIterator() on an instruction pointer. A follow-up patch will contain less-obviously-safe changes. We'll eventually deprecate and remove the instruction-pointer insertBefore, but not before adding concise documentation of what considerations are needed (very few).
2024-09-25[FuzzMutate] Avoid repeated hash lookups (NFC) (#109903)Kazu Hirata
2024-08-08[DebugInfo][RemoveDIs] Use iterator-insertion in unittests and fuzzer (#102015)Jeremy Morse
These are the final few places in LLVM that use instruction pointers to insert instructions -- use iterators instead, which is needed for debug-info correctness in the future. Most of this is a gentle scattering of getIterator calls or not deref-then-addrofing iterators. libfuzzer does require a storage change to keep built instruction positions in a container though. The unit-test changes are very straightforwards. This leaves us in a position where libfuzzer can't fuzz on either of debug-info records, however I don't believe that fuzzing of debug-info is in scope for the library.
2024-06-21[IR] Don't include PassInstrumentation.h in PassManager.h (NFC) (#96219)Nikita Popov
Move PassInstrumentationAnalysis into PassInstrumentation.h and stop including it in PassManager.h (effectively inverting the direction of the dependency). Most places using PassManager are not interested in PassInstrumentation, and we no longer have any uses of it in PassManager.h itself (only in PassManagerImpl.h).
2023-06-01[FuzzMutate] Handle BB without predecessor, avoid insertion after `musttail ↵Henry Yu
call`, avoid sinking token type FuzzMutate didn't consider some corner cases and leads to mutation failure when mutating some modules. This patch fixes 3 bugs: - Add null check when encountering basic blocks without predecessor to avoid segmentation fault - Avoid insertion after `musttail call` instruction - Avoid sinking token type Unit tests are also added. Reviewed By: Peter Differential Revision: https://reviews.llvm.org/D151936
2023-06-01[FuzzMutate] Avoid calling function with metadata/token parameter/return ↵Henry Yu
type for `InsertFunctionStrategy` When there is a function with metadata/token parameter/return type, `InsertFunctionStrategy` will crash. This patch fixes the problem by falling back to create function declaration when the sampled function contains metadata/token parameter/return type. Reviewed By: Peter Differential Revision: https://reviews.llvm.org/D150627
2023-05-09[FuzzMutate] Module size heuristicsZhenkai Weng
IRMutation::mutateModule() currently requires the bitcode size of the module. To compute the bitcode size, one way is to write the module to a buffer using BitcodeWriter and calculating the buffer size. This would be fine for a single mutation, but infeasible for repeated mutations due to the large overhead. It turns out that the only IR strategy weight calculation method that depends on the current module size is InstDeleterStrategy, which deletes instructions more frequently as the module size approaches a given max size. However, there is no real need for the size to be in bytes of bitcode, so we can use a different metric. One alternative is to let the size be the number of objects in the Module, including instructions, basic blocks, globals, and aliases. Although getting the number of instructions is still O(n), it should have significantly less overhead than BitcodeWriter. This suggestion would cause a change to the IRMutator API, since IRMutator::mutateModule() can calculate the Module size itself. Reviewed By: Peter Differential Revision: https://reviews.llvm.org/D149989
2023-05-04[FuzzMutate] Make ShuffleBlockStrategy deterministicZhenkai Weng
This revision makes ShuffleBlockStrategy deterministic by replacing SmallPtrSet with other data structures that has a deterministic iteration order. Reviewed By: Peter Differential Revision: https://reviews.llvm.org/D149676
2023-04-26[FuzzMutate] Skip EHPad during mutation and avoid replacing callee with ↵Henry Yu
pointer when sinking This patch addresses 2 problems: - In `ShuffleBlockStrategy`, when `BB` is an EHPad, `BB.getFirstInsertionPt()` will return `BB.end()`, which cannot be dereferenced and will cause crash in following loop. - In `isCompatibleReplacement`, a call instruction's callee might be replaced by a pointer, causing 2 subproblems: - we cannot guarantee that the pointer is a function pointer (even if it is, we cannot guarantee it matches the signature). - after such a replacement, `getCalledFunction` will from then on return `nullptr` (since it's indirect call) which causes Segmentation Fault in the lines below. This patch fixes the first problem by checking if a block to be mutated is an EHPad in base class `IRMutationStrategy` and skipping mutating it if so. This patch fixes the second problem by avoiding replacing callee with pointer and adding a null check for indirect calls. Reviewed By: Peter Differential Revision: https://reviews.llvm.org/D148853
2023-04-25[FuzzMutate] Correct type cast and add unit test for FCmpZhenkai Weng
This revision fixes an incorrect type cast from Instruction to ICmpInstr, which should have been to FCmpInstr instead. It turns out that StrategiesTest.cpp was missing a test case for InstModificationIRStrategy and FCmp, which is also now implemented in this revision. After this revision, [[ https://reviews.llvm.org/D148854 | llvm-stress in D148854 ]] no longer crashes randomly. Reviewed By: Peter Differential Revision: https://reviews.llvm.org/D148972
2023-04-25[FuzzMutate] Correct type cast and add unit test for FCmpPeter Rong
This revision fixes an incorrect type cast from Instruction to ICmpInstr, which should have been to FCmpInstr instead. It turns out that StrategiesTest.cpp was missing a test case for InstModificationIRStrategy and FCmp, which is also now implemented in this revision. After this revision, [[ https://reviews.llvm.org/D148854 | llvm-stress in D148854 ]] no longer crashes randomly. Reviewed By: Peter Differential Revision: https://reviews.llvm.org/D148972
2023-04-21[FuzzMutate] Correct type cast and add unit test for FCmpPeter Rong
This revision fixes an incorrect type cast from Instruction to ICmpInstr, which should have been to FCmpInstr instead. It turns out that StrategiesTest.cpp was missing a test case for InstModificationIRStrategy and FCmp, which is also now implemented in this revision. After this revision, [[ https://reviews.llvm.org/D148854 | llvm-stress in D148854 ]] no longer crashes randomly. Reviewed By: Peter Differential Revision: https://reviews.llvm.org/D148972
2023-04-19[FuzzMutate] InsertFunctionStrategyPeter Rong
InsertFunctionStrategy does two things: 1. Add a random function declaration or definition to the module. This would replace previously used `createEmptyFunction`. 2. Add a random function call between instructions. Reviewed By: arsenm Differential Revision: https://reviews.llvm.org/D148568
2023-01-14[llvm] Include <optional> instead of "llvm/ADT/Optional.h" (NFC)Kazu Hirata
This is part of an effort to migrate from llvm::Optional to std::optional: https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2023-01-05Move from llvm::makeArrayRef to ArrayRef deduction guides - llvm/ partserge-sans-paille
Use deduction guides instead of helper functions. The only non-automatic changes have been: 1. ArrayRef(some_uint8_pointer, 0) needs to be changed into ArrayRef(some_uint8_pointer, (size_t)0) to avoid an ambiguous call with ArrayRef((uint8_t*), (uint8_t*)) 2. CVSymbol sym(makeArrayRef(symStorage)); needed to be rewritten as CVSymbol sym{ArrayRef(symStorage)}; otherwise the compiler is confused and thinks we have a (bad) function prototype. There was a few similar situation across the codebase. 3. ADL doesn't seem to work the same for deduction-guides and functions, so at some point the llvm namespace must be explicitly stated. 4. The "reference mode" of makeArrayRef(ArrayRef<T> &) that acts as no-op is not supported (a constructor cannot achieve that). Per reviewers' comment, some useless makeArrayRef have been removed in the process. This is a follow-up to https://reviews.llvm.org/D140896 that introduced the deduction guides. Differential Revision: https://reviews.llvm.org/D140955
2022-12-20[llvm] Use std::optional instead of OptionalKazu Hirata
This is part of an effort to migrate from llvm::Optional to std::optional: https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2022-12-13[FuzzMutate] InstModStrategy: switch nsw/nuw/inbount instead of repeated ↵Peter Rong
setting it Reviewed By: arsenm Differential Revision: https://reviews.llvm.org/D139890
2022-12-12[FuzzMutate] InstModificationStrategy, add FastMath flags and exact flags to ↵Peter Rong
instructions. I think there are more attributes, flags we can add to `call`, functions declarations and global variables. Let's start with these two flags. Reviewed By: arsenm Differential Revision: https://reviews.llvm.org/D139594
2022-12-12[FuzzMutate] New InsertCFGStrategyPeter Rong
Mutating CFG is hard as we have to maintain dominator relations. We avoid this problem by inserting a CFG into a splitted block. switch, ret, and br instructions are generated. Reviewed By: arsenm Differential Revision: https://reviews.llvm.org/D139067
2022-12-02[llvm] Use std::nullopt instead of None (NFC)Kazu Hirata
This patch mechanically replaces None with std::nullopt where the compiler would warn if None were deprecated. The intent is to reduce the amount of manual work required in migrating from Optional to std::optional. This is part of an effort to migrate from llvm::Optional to std::optional: https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2022-11-30[FuzzMutate] New InsertPHINode strategy.Peter Rong
PHI Node can't be modeled like other instructions since its operand number depends on predecessors. So we have a stand alone strategy for it. Signed-off-by: Peter Rong <PeterRong96@gmail.com> Reviewed By: arsenm Differential Revision: https://reviews.llvm.org/D138959
2022-11-29[FuzzMutate] SinkInstructionStrategyPeter Rong
Randomlly select an instruction and try to use it in the future by replacing it with another instruction's operand. Reviewed By: arsenm Differential Revision: https://reviews.llvm.org/D138948
2022-11-28[FuzzMutate] New strategy `ShuffleBlockStrategy`Peter Rong
`ShuffleBlockStrategy` will shuffle the instructions in a basic block without breaking the dependency of instructions. It is implemented as a topological sort, only we randomly select instructions with no dependency. Reviewed By: arsenm Differential Revision: https://reviews.llvm.org/D138339
2022-11-18[FuzzMutate] Update InstModifierStrategyPeter Rong
We can randomly switch two operands of an instruction now Signed-off-by: Peter Rong <PeterRong96@gmail.com>
2022-11-18[FuzzMutate] change of format and comment for further codePeter Rong
Signed-off-by: Peter Rong <PeterRong96@gmail.com>
2022-05-07[FuzzMutate] Move LLVM module (de)serialization from FuzzerCLI -> IRMutator. NFCSam McCall
These are not directly related to the CLI, and are mostly (always?) used when mutating the modules as part of fuzzing. Motivation: split FuzzerCLI into its own library that does not depend on IR. Subprojects that don't use IR should be be fuzzed without the dependency. Differential Revision: https://reviews.llvm.org/D125080
2022-03-16Revert "[FuzzMutate] Don't insert instructions after musttail call"Nikita Popov
This reverts commit 6a23d2764467bd45c2e02828f6175a0b9f9a1005. The newly added tests fail on the llvm-clang-x86_64-sie-win buildbot. Not sure why a failure only occurs there, possibly differen PRNG sequence?
2022-03-16[FuzzMutate] Don't insert instructions after musttail callNikita Popov
2022-03-12Cleanup includes: DebugInfo & CodeGenserge-sans-paille
Discourse thread: https://discourse.llvm.org/t/include-what-you-use-include-cleanup Differential Revision: https://reviews.llvm.org/D121332
2022-03-11[IRMutator] Handle module with only declarationsNikita Popov
There was a mismatch here, with one check checking whether there are any functions, and the other collecting only non-declaration functions.
2021-06-08[FuzzMutate] Fix getWeight of InstDeleterIRStrategyJustin Bogner
The comment states the following, for calculating the Line variable: > Draw a line starting from when we only have 1k left and increasing > linearly to double the current weight. However, the value was not calculated as described. Instead, it would result in a negative value, which resulted in the function always returning 0 afterwards. ``` // Invariant: CurrentSize <= MaxSize - 200 // Invariant: CurrentWeight >= 0 int Line = (-2 * CurrentWeight) * (MaxSize - CurrentSize + 1000); // {Line <= 0} ``` This commit fixes the issue and linearly interpolates as described. Patch by Loris Reiff. Thanks! Differential Revision: https://reviews.llvm.org/D96207
2021-01-23[FuzzMutate] Add mutator to modify instruction flags.Florian Hahn
This patch adds a new InstModificationIRStrategy to mutate flags/options for instructions. For example, it may add or remove nuw/nsw flags from add, mul, sub, shl instructions or change the predicate for icmp instructions. Subtle changes such as those mentioned above should lead to a more interesting range of inputs. The presence or absence of overflow flags can expose subtle bugs, for example. Reviewed By: bogner Differential Revision: https://reviews.llvm.org/D94905
2019-01-19Update the file headers across all of the LLVM projects in the monorepoChandler Carruth
to reflect the new license. We understand that people may be surprised that we're moving the header entirely to discuss the new license. We checked this carefully with the Foundation's lawyer and we believe this is the correct approach. Essentially, all code in the project is now made available by the LLVM project under our new license, so you will see that the license headers include that license only. Some of our contributors have contributed code under our old license, and accordingly, we have retained a copy of our old license notice in the top-level files in each project and repository. llvm-svn: 351636
2018-09-20[New PM] Introducing PassInstrumentation frameworkFedor Sergeev
Pass Execution Instrumentation interface enables customizable instrumentation of pass execution, as per "RFC: Pass Execution Instrumentation interface" posted 06/07/2018 on llvm-dev@ The intent is to provide a common machinery to implement all the pass-execution-debugging features like print-before/after, opt-bisect, time-passes etc. Here we get a basic implementation consisting of: * PassInstrumentationCallbacks class that handles registration of callbacks and access to them. * PassInstrumentation class that handles instrumentation-point interfaces that call into PassInstrumentationCallbacks. * Callbacks accept StringRef which is just a name of the Pass right now. There were some ideas to pass an opaque wrapper for the pointer to pass instance, however it appears that pointer does not actually identify the instance (adaptors and managers might have the same address with the pass they govern). Hence it was decided to go simple for now and then later decide on what the proper mental model of identifying a "pass in a phase of pipeline" is. * Callbacks accept llvm::Any serving as a wrapper for const IRUnit*, to remove direct dependencies on different IRUnits (e.g. Analyses). * PassInstrumentationAnalysis analysis is explicitly requested from PassManager through usual AnalysisManager::getResult. All pass managers were updated to run that to get PassInstrumentation object for instrumentation calls. * Using tuples/index_sequence getAnalysisResult helper to extract generic AnalysisManager's extra args out of a generic PassManager's extra args. This is the only way I was able to explicitly run getResult for PassInstrumentationAnalysis out of a generic code like PassManager::run or RepeatedPass::run. TODO: Upon lengthy discussions we agreed to accept this as an initial implementation and then get rid of getAnalysisResult by improving RepeatedPass implementation. * PassBuilder takes PassInstrumentationCallbacks object to pass it further into PassInstrumentationAnalysis. Callbacks registration should be performed directly through PassInstrumentationCallbacks. * new-pm tests updated to account for PassInstrumentationAnalysis being run * Added PassInstrumentation tests to PassBuilderCallbacks unit tests. Other unit tests updated with registration of the now-required PassInstrumentationAnalysis. Made getName helper to return std::string (instead of StringRef initially) to fix asan builtbot failures on CGSCC tests. Reviewers: chandlerc, philip.pfaffe Differential Revision: https://reviews.llvm.org/D47858 llvm-svn: 342664
2018-09-20Temporarily Revert "[New PM] Introducing PassInstrumentation framework"Eric Christopher
as it was causing failures in the asan buildbot. This reverts commit r342597. llvm-svn: 342616
2018-09-19[New PM] Introducing PassInstrumentation frameworkFedor Sergeev
Pass Execution Instrumentation interface enables customizable instrumentation of pass execution, as per "RFC: Pass Execution Instrumentation interface" posted 06/07/2018 on llvm-dev@ The intent is to provide a common machinery to implement all the pass-execution-debugging features like print-before/after, opt-bisect, time-passes etc. Here we get a basic implementation consisting of: * PassInstrumentationCallbacks class that handles registration of callbacks and access to them. * PassInstrumentation class that handles instrumentation-point interfaces that call into PassInstrumentationCallbacks. * Callbacks accept StringRef which is just a name of the Pass right now. There were some ideas to pass an opaque wrapper for the pointer to pass instance, however it appears that pointer does not actually identify the instance (adaptors and managers might have the same address with the pass they govern). Hence it was decided to go simple for now and then later decide on what the proper mental model of identifying a "pass in a phase of pipeline" is. * Callbacks accept llvm::Any serving as a wrapper for const IRUnit*, to remove direct dependencies on different IRUnits (e.g. Analyses). * PassInstrumentationAnalysis analysis is explicitly requested from PassManager through usual AnalysisManager::getResult. All pass managers were updated to run that to get PassInstrumentation object for instrumentation calls. * Using tuples/index_sequence getAnalysisResult helper to extract generic AnalysisManager's extra args out of a generic PassManager's extra args. This is the only way I was able to explicitly run getResult for PassInstrumentationAnalysis out of a generic code like PassManager::run or RepeatedPass::run. TODO: Upon lengthy discussions we agreed to accept this as an initial implementation and then get rid of getAnalysisResult by improving RepeatedPass implementation. * PassBuilder takes PassInstrumentationCallbacks object to pass it further into PassInstrumentationAnalysis. Callbacks registration should be performed directly through PassInstrumentationCallbacks. * new-pm tests updated to account for PassInstrumentationAnalysis being run * Added PassInstrumentation tests to PassBuilderCallbacks unit tests. Other unit tests updated with registration of the now-required PassInstrumentationAnalysis. Reviewers: chandlerc, philip.pfaffe Differential Revision: https://reviews.llvm.org/D47858 llvm-svn: 342597
2018-09-19Revert rL342544: [New PM] Introducing PassInstrumentation frameworkFedor Sergeev
A bunch of bots fail to compile unittests. Reverting. llvm-svn: 342552
2018-09-19[New PM] Introducing PassInstrumentation frameworkFedor Sergeev
Summary: Pass Execution Instrumentation interface enables customizable instrumentation of pass execution, as per "RFC: Pass Execution Instrumentation interface" posted 06/07/2018 on llvm-dev@ The intent is to provide a common machinery to implement all the pass-execution-debugging features like print-before/after, opt-bisect, time-passes etc. Here we get a basic implementation consisting of: * PassInstrumentationCallbacks class that handles registration of callbacks and access to them. * PassInstrumentation class that handles instrumentation-point interfaces that call into PassInstrumentationCallbacks. * Callbacks accept StringRef which is just a name of the Pass right now. There were some ideas to pass an opaque wrapper for the pointer to pass instance, however it appears that pointer does not actually identify the instance (adaptors and managers might have the same address with the pass they govern). Hence it was decided to go simple for now and then later decide on what the proper mental model of identifying a "pass in a phase of pipeline" is. * Callbacks accept llvm::Any serving as a wrapper for const IRUnit*, to remove direct dependencies on different IRUnits (e.g. Analyses). * PassInstrumentationAnalysis analysis is explicitly requested from PassManager through usual AnalysisManager::getResult. All pass managers were updated to run that to get PassInstrumentation object for instrumentation calls. * Using tuples/index_sequence getAnalysisResult helper to extract generic AnalysisManager's extra args out of a generic PassManager's extra args. This is the only way I was able to explicitly run getResult for PassInstrumentationAnalysis out of a generic code like PassManager::run or RepeatedPass::run. TODO: Upon lengthy discussions we agreed to accept this as an initial implementation and then get rid of getAnalysisResult by improving RepeatedPass implementation. * PassBuilder takes PassInstrumentationCallbacks object to pass it further into PassInstrumentationAnalysis. Callbacks registration should be performed directly through PassInstrumentationCallbacks. * new-pm tests updated to account for PassInstrumentationAnalysis being run * Added PassInstrumentation tests to PassBuilderCallbacks unit tests. Other unit tests updated with registration of the now-required PassInstrumentationAnalysis. Reviewers: chandlerc, philip.pfaffe Differential Revision: https://reviews.llvm.org/D47858 llvm-svn: 342544
2018-01-25[FuzzMutate] Inst deleter doesn't work with PhiNodesIgor Laevsky
Differential Revision: https://reviews.llvm.org/D42412 llvm-svn: 323409
2017-12-19[FuzzMutate] Don't crash when mutator is unable to find operationIgor Laevsky
Differential Revision: https://reviews.llvm.org/D41009 llvm-svn: 321062
2017-11-30[FuzzMutate] Bailout from injecting into empty basic blocks.Igor Laevsky
In rare cases we can receive request to inject into completelly empty basic block. In the normal case all basic blocks contain at least terminator instruction, but it is possible that the only instruction is catchpad instruction which is not part of the instruction iterator. This case seems rare enough to not care about it. Submiting without review, since it seems almost NFC. I couldn't come up with any reasonable way to test this. llvm-svn: 319444
2017-11-30[FuzzMutate] Don't crash when we can't remove instruction from empty functionIgor Laevsky
Differential Revision: https://reviews.llvm.org/D40393 llvm-svn: 319438
2017-08-21Re-apply "Introduce FuzzMutate library"Justin Bogner
Same as r311392 with some fixes for library dependencies. Thanks to Chapuni for helping work those out! Original commit message: This introduces the FuzzMutate library, which provides structured fuzzing for LLVM IR, as described in my EuroLLVM 2017 talk. Most of the basic mutators to inject and delete IR are provided, with support for most basic operations. llvm-svn: 311402
2017-08-21Revert "Re-apply "Introduce FuzzMutate library""Justin Bogner
The dependencies for the new library seem to be misconfigured on some linux configs: http://bb.pgr.jp/builders/llvm-i686-linux-RA/builds/5435/steps/build_all/logs/stdio This reverts r311392. llvm-svn: 311393