diff lib/FuzzMutate/RandomIRBuilder.cpp @ 134:3a76565eade5 LLVM5.0.1

update 5.0.1
author mir3636
date Sat, 17 Feb 2018 09:57:20 +0900
parents 803732b1fca8
children c2174574ed3a
line wrap: on
line diff
--- a/lib/FuzzMutate/RandomIRBuilder.cpp	Fri Feb 16 19:10:49 2018 +0900
+++ b/lib/FuzzMutate/RandomIRBuilder.cpp	Sat Feb 17 09:57:20 2018 +0900
@@ -15,7 +15,6 @@
 #include "llvm/IR/Function.h"
 #include "llvm/IR/Instructions.h"
 #include "llvm/IR/IntrinsicInst.h"
-#include "llvm/IR/Module.h"
 
 using namespace llvm;
 using namespace fuzzerop;
@@ -45,22 +44,27 @@
   // Generate some constants to choose from.
   auto RS = makeSampler<Value *>(Rand);
   RS.sample(Pred.generate(Srcs, KnownTypes));
-  assert(!RS.isEmpty() && "Failed to generate sources");
 
   // If we can find a pointer to load from, use it half the time.
   Value *Ptr = findPointer(BB, Insts, Srcs, Pred);
-  if (Ptr)
-    RS.sample(Ptr, RS.totalWeight());
+  if (Ptr) {
+    // Create load from the chosen pointer
+    auto IP = BB.getFirstInsertionPt();
+    if (auto *I = dyn_cast<Instruction>(Ptr)) {
+      IP = ++I->getIterator();
+      assert(IP != BB.end() && "guaranteed by the findPointer");
+    }
+    auto *NewLoad = new LoadInst(Ptr, "L", &*IP);
 
-  Value *Result = RS.getSelection();
-  if (Result != Ptr)
-    return Result;
+    // Only sample this load if it really matches the descriptor
+    if (Pred.matches(Srcs, NewLoad))
+      RS.sample(NewLoad, RS.totalWeight());
+    else
+      NewLoad->eraseFromParent();
+  }
 
-  // If we choose the pointer, we need to create a load.
-  auto IP = BB.getFirstInsertionPt();
-  if (auto *I = dyn_cast<Instruction>(Ptr))
-    IP = ++I->getIterator();
-  return new LoadInst(Ptr, "L", &*IP);
+  assert(!RS.isEmpty() && "Failed to generate sources");
+  return RS.getSelection();
 }
 
 static bool isCompatibleReplacement(const Instruction *I, const Use &Operand,
@@ -73,12 +77,13 @@
   case Instruction::ExtractValue:
     // TODO: We could potentially validate these, but for now just leave indices
     // alone.
-    if (Operand.getOperandNo() > 1)
+    if (Operand.getOperandNo() >= 1)
       return false;
     break;
   case Instruction::InsertValue:
   case Instruction::InsertElement:
-    if (Operand.getOperandNo() > 2)
+  case Instruction::ShuffleVector:
+    if (Operand.getOperandNo() >= 2)
       return false;
     break;
   default:
@@ -129,9 +134,20 @@
                                     ArrayRef<Instruction *> Insts,
                                     ArrayRef<Value *> Srcs, SourcePred Pred) {
   auto IsMatchingPtr = [&Srcs, &Pred](Instruction *Inst) {
-    if (auto PtrTy = dyn_cast<PointerType>(Inst->getType()))
+    // Invoke instructions sometimes produce valid pointers but currently
+    // we can't insert loads or stores from them
+    if (isa<TerminatorInst>(Inst))
+      return false;
+
+    if (auto PtrTy = dyn_cast<PointerType>(Inst->getType())) {
+      // We can never generate loads from non first class or non sized types
+      if (!PtrTy->getElementType()->isSized() ||
+          !PtrTy->getElementType()->isFirstClassType())
+        return false;
+
       // TODO: Check if this is horribly expensive.
       return Pred.matches(Srcs, UndefValue::get(PtrTy->getElementType()));
+    }
     return false;
   };
   if (auto RS = makeSampler(Rand, make_filter_range(Insts, IsMatchingPtr)))