This patch replaces uses of StringRef::{starts,ends}with with
StringRef::{starts,ends}_with for consistency with
std::{string,string_view}::{starts,ends}_with in C++20.
I'm planning to deprecate and eventually remove
StringRef::{starts,ends}with.
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
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
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
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
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
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
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
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
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
Source and Sink are required when generating a new instruction.
(Term defined by previous author, in LLVM terms it's probably Use and User.)
Previously, only instructions in the same block is considered when taking source and sink.
In this patch, more source and sink types are considered.
For source, we have SrcFromInstInCurBlock, FunctionArgument, InstInDominator, SrcFromGlobalVariable, and NewConstOrStack.
For sink, we have SinkToInstInCurBlock, PointersInDominator, InstInDominatee, NewStore, and SinkToGlobalVariable.
A unit test to make sure source always dominates an instruction, and the instruction always dominates the sink is included.
Reviewed By: arsenm
Differential Revision: https://reviews.llvm.org/D139907
Source and Sink are required when generating a new instruction.
(Term defined by previous author, in LLVM terms it's probably Use and User.)
Previously, only instructions in the same block is considered when taking source and sink.
In this patch, more source and sink types are considered.
For source, we have SrcFromInstInCurBlock, FunctionArgument, InstInDominator, SrcFromGlobalVariable, and NewConstOrStack.
For sink, we have SinkToInstInCurBlock, PointersInDominator, InstInDominatee, NewStore, and SinkToGlobalVariable.
A unit test to make sure source always dominates an instruction, and the instruction always dominates the sink is included.
Reviewed By: arsenm
Differential Revision: https://reviews.llvm.org/D139907
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
This is a fairly large changeset, but it can be broken into a few
pieces:
- `llvm/Support/*TargetParser*` are all moved from the LLVM Support
component into a new LLVM Component called "TargetParser". This
potentially enables using tablegen to maintain this information, as
is shown in https://reviews.llvm.org/D137517. This cannot currently
be done, as llvm-tblgen relies on LLVM's Support component.
- This also moves two files from Support which use and depend on
information in the TargetParser:
- `llvm/Support/Host.{h,cpp}` which contains functions for inspecting
the current Host machine for info about it, primarily to support
getting the host triple, but also for `-mcpu=native` support in e.g.
Clang. This is fairly tightly intertwined with the information in
`X86TargetParser.h`, so keeping them in the same component makes
sense.
- `llvm/ADT/Triple.h` and `llvm/Support/Triple.cpp`, which contains
the target triple parser and representation. This is very intertwined
with the Arm target parser, because the arm architecture version
appears in canonical triples on arm platforms.
- I moved the relevant unittests to their own directory.
And so, we end up with a single component that has all the information
about the following, which to me seems like a unified component:
- Triples that LLVM Knows about
- Architecture names and CPUs that LLVM knows about
- CPU detection logic for LLVM
Given this, I have also moved `RISCVISAInfo.h` into this component, as
it seems to me to be part of that same set of functionality.
If you get link errors in your components after this patch, you likely
need to add TargetParser into LLVM_LINK_COMPONENTS in CMake.
Differential Revision: https://reviews.llvm.org/D137838
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
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
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
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
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
`connectToSink` uses a value by putting it in a future instruction.
It will replace the operand of a future instruction with the current value.
However, if current value is an `Instruction` and put into a switch case, the module is invalid.
We fix that by only connecting to Br/Switch's condition, and don't touch other operands.
Will have other strategies to mutate other Br/Switch operands to be patched once this patch is passed
Reviewed By: arsenm
Differential Revision: https://reviews.llvm.org/D138890
`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
All llvm-project fuzzers use this library to parse command-line arguments.
Many of them don't deal with LLVM IR or modules in any way. Bundling those
functions in one library forces build dependencies that don't need to be there.
Among other things, this means check-clang-pseudo no longer depends on most of
LLVM.
Differential Revision: https://reviews.llvm.org/D125081
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
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?
Avoid checks that are irrelevant for opaque pointers, and pick
load/GEP types independently of the pointer type.
The GEP case at least could be done more efficiently by directly
generating a type, but this would require some significant API
changes.
Instead use either Type::getPointerElementType() or
Type::getNonOpaquePointerElementType().
This is part of D117885, in preparation for deprecating the API.
There was an alias between 'simplifycfg' and 'simplify-cfg' in the
PassRegistry. That was the original reason for this patch, which
effectively removes the alias.
This patch also replaces all occurrances of 'simplify-cfg'
by 'simplifycfg'. Reason for choosing that form for the name is
that it matches the DEBUG_TYPE for the pass, and the legacy PM name
and also how it is spelled out in other passes such as
'loop-simplifycfg', and in other options such as
'simplifycfg-merge-cond-stores'.
I for some reason the name should be changed to 'simplify-cfg' in
the future, then I think such a renaming should be more widely done
and not only impacting the PassRegistry.
Reviewed By: aeubanks
Differential Revision: https://reviews.llvm.org/D105627
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
In future patches I will be setting the IsText parameter frequently so I will refactor the args to be in the following order. I have removed the FileSize parameter because it is never used.
```
static ErrorOr<std::unique_ptr<MemoryBuffer>>
getFile(const Twine &Filename, bool IsText = false,
bool RequiresNullTerminator = true, bool IsVolatile = false);
static ErrorOr<std::unique_ptr<MemoryBuffer>>
getFileOrSTDIN(const Twine &Filename, bool IsText = false,
bool RequiresNullTerminator = true);
static ErrorOr<std::unique_ptr<MB>>
getFileAux(const Twine &Filename, uint64_t MapSize, uint64_t Offset,
bool IsText, bool RequiresNullTerminator, bool IsVolatile);
static ErrorOr<std::unique_ptr<WritableMemoryBuffer>>
getFile(const Twine &Filename, bool IsVolatile = false);
```
Reviewed By: jhenderson
Differential Revision: https://reviews.llvm.org/D99182