[llvm] 3c47dd4 - [FuzzMutate] Support opaque pointers
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Thu Mar 10 05:36:27 PST 2022
Author: Nikita Popov
Date: 2022-03-10T14:36:20+01:00
New Revision: 3c47dd47a42a87b9724a558a6baeab5a8d6e4a69
URL: https://github.com/llvm/llvm-project/commit/3c47dd47a42a87b9724a558a6baeab5a8d6e4a69
DIFF: https://github.com/llvm/llvm-project/commit/3c47dd47a42a87b9724a558a6baeab5a8d6e4a69.diff
LOG: [FuzzMutate] Support opaque pointers
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.
Added:
Modified:
llvm/include/llvm/FuzzMutate/OpDescriptor.h
llvm/lib/FuzzMutate/Operations.cpp
llvm/lib/FuzzMutate/RandomIRBuilder.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/FuzzMutate/OpDescriptor.h b/llvm/include/llvm/FuzzMutate/OpDescriptor.h
index 43c8109207665..1d49cd5a1a8c1 100644
--- a/llvm/include/llvm/FuzzMutate/OpDescriptor.h
+++ b/llvm/include/llvm/FuzzMutate/OpDescriptor.h
@@ -146,7 +146,8 @@ static inline SourcePred sizedPtrType() {
return false;
if (const auto *PtrT = dyn_cast<PointerType>(V->getType()))
- return PtrT->getPointerElementType()->isSized();
+ return PtrT->isOpaque() ||
+ PtrT->getNonOpaquePointerElementType()->isSized();
return false;
};
auto Make = [](ArrayRef<Value *>, ArrayRef<Type *> Ts) {
diff --git a/llvm/lib/FuzzMutate/Operations.cpp b/llvm/lib/FuzzMutate/Operations.cpp
index 221a3a84b49be..7db24bb98b77b 100644
--- a/llvm/lib/FuzzMutate/Operations.cpp
+++ b/llvm/lib/FuzzMutate/Operations.cpp
@@ -169,14 +169,21 @@ OpDescriptor llvm::fuzzerop::splitBlockDescriptor(unsigned Weight) {
OpDescriptor llvm::fuzzerop::gepDescriptor(unsigned Weight) {
auto buildGEP = [](ArrayRef<Value *> Srcs, Instruction *Inst) {
- Type *Ty = Srcs[0]->getType()->getPointerElementType();
- auto Indices = makeArrayRef(Srcs).drop_front(1);
+ // TODO: It would be better to generate a random type here, rather than
+ // generating a random value and picking its type.
+ Type *Ty = Srcs[0]->getType()->isOpaquePointerTy()
+ ? Srcs[1]->getType()
+ : Srcs[0]->getType()->getNonOpaquePointerElementType();
+ auto Indices = makeArrayRef(Srcs).drop_front(2);
return GetElementPtrInst::Create(Ty, Srcs[0], Indices, "G", Inst);
};
// TODO: Handle aggregates and vectors
// TODO: Support multiple indices.
// TODO: Try to avoid meaningless accesses.
- return {Weight, {sizedPtrType(), anyIntType()}, buildGEP};
+ SourcePred sizedType(
+ [](ArrayRef<Value *>, const Value *V) { return V->getType()->isSized(); },
+ None);
+ return {Weight, {sizedPtrType(), sizedType, anyIntType()}, buildGEP};
}
static uint64_t getAggregateNumElements(Type *T) {
diff --git a/llvm/lib/FuzzMutate/RandomIRBuilder.cpp b/llvm/lib/FuzzMutate/RandomIRBuilder.cpp
index 27c3bdfb22a8e..0579dde7a999f 100644
--- a/llvm/lib/FuzzMutate/RandomIRBuilder.cpp
+++ b/llvm/lib/FuzzMutate/RandomIRBuilder.cpp
@@ -53,8 +53,11 @@ Value *RandomIRBuilder::newSource(BasicBlock &BB, ArrayRef<Instruction *> Insts,
IP = ++I->getIterator();
assert(IP != BB.end() && "guaranteed by the findPointer");
}
- auto *NewLoad =
- new LoadInst(Ptr->getType()->getPointerElementType(), Ptr, "L", &*IP);
+ // For opaque pointers, pick the type independently.
+ Type *AccessTy = Ptr->getType()->isOpaquePointerTy()
+ ? RS.getSelection()->getType()
+ : Ptr->getType()->getNonOpaquePointerElementType();
+ auto *NewLoad = new LoadInst(AccessTy, Ptr, "L", &*IP);
// Only sample this load if it really matches the descriptor
if (Pred.matches(Srcs, NewLoad))
@@ -139,9 +142,12 @@ Value *RandomIRBuilder::findPointer(BasicBlock &BB,
if (Inst->isTerminator())
return false;
- if (auto PtrTy = dyn_cast<PointerType>(Inst->getType())) {
+ if (auto *PtrTy = dyn_cast<PointerType>(Inst->getType())) {
+ if (PtrTy->isOpaque())
+ return true;
+
// We can never generate loads from non first class or non sized types
- Type *ElemTy = PtrTy->getPointerElementType();
+ Type *ElemTy = PtrTy->getNonOpaquePointerElementType();
if (!ElemTy->isSized() || !ElemTy->isFirstClassType())
return false;
More information about the llvm-commits
mailing list