1 //===- InjectorIRStrategyTest.cpp - Tests for injector strategy -----------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "llvm/ADT/StringRef.h" 10 #include "llvm/AsmParser/Parser.h" 11 #include "llvm/AsmParser/SlotMapping.h" 12 #include "llvm/FuzzMutate/IRMutator.h" 13 #include "llvm/FuzzMutate/Operations.h" 14 #include "llvm/IR/Instructions.h" 15 #include "llvm/IR/LLVMContext.h" 16 #include "llvm/IR/Module.h" 17 #include "llvm/IR/Verifier.h" 18 #include "llvm/Support/SourceMgr.h" 19 20 #include "gtest/gtest.h" 21 22 using namespace llvm; 23 24 static constexpr int Seed = 5; 25 26 namespace { 27 28 std::unique_ptr<IRMutator> createInjectorMutator() { 29 std::vector<TypeGetter> Types{ 30 Type::getInt1Ty, Type::getInt8Ty, Type::getInt16Ty, Type::getInt32Ty, 31 Type::getInt64Ty, Type::getFloatTy, Type::getDoubleTy}; 32 33 std::vector<std::unique_ptr<IRMutationStrategy>> Strategies; 34 Strategies.push_back( 35 std::make_unique<InjectorIRStrategy>( 36 InjectorIRStrategy::getDefaultOps())); 37 38 return std::make_unique<IRMutator>(std::move(Types), std::move(Strategies)); 39 } 40 41 std::unique_ptr<IRMutator> createDeleterMutator() { 42 std::vector<TypeGetter> Types{ 43 Type::getInt1Ty, Type::getInt8Ty, Type::getInt16Ty, Type::getInt32Ty, 44 Type::getInt64Ty, Type::getFloatTy, Type::getDoubleTy}; 45 46 std::vector<std::unique_ptr<IRMutationStrategy>> Strategies; 47 Strategies.push_back(std::make_unique<InstDeleterIRStrategy>()); 48 49 return std::make_unique<IRMutator>(std::move(Types), std::move(Strategies)); 50 } 51 52 std::unique_ptr<Module> parseAssembly( 53 const char *Assembly, LLVMContext &Context) { 54 55 SMDiagnostic Error; 56 std::unique_ptr<Module> M = parseAssemblyString(Assembly, Error, Context); 57 58 std::string ErrMsg; 59 raw_string_ostream OS(ErrMsg); 60 Error.print("", OS); 61 62 assert(M && !verifyModule(*M, &errs())); 63 return M; 64 } 65 66 void IterateOnSource(StringRef Source, IRMutator &Mutator) { 67 LLVMContext Ctx; 68 69 for (int i = 0; i < 10; ++i) { 70 auto M = parseAssembly(Source.data(), Ctx); 71 ASSERT_TRUE(M && !verifyModule(*M, &errs())); 72 73 Mutator.mutateModule(*M, Seed, Source.size(), Source.size() + 100); 74 EXPECT_TRUE(!verifyModule(*M, &errs())); 75 } 76 } 77 78 TEST(InjectorIRStrategyTest, EmptyModule) { 79 // Test that we can inject into empty module 80 81 LLVMContext Ctx; 82 auto M = std::make_unique<Module>("M", Ctx); 83 ASSERT_TRUE(M && !verifyModule(*M, &errs())); 84 85 auto Mutator = createInjectorMutator(); 86 ASSERT_TRUE(Mutator); 87 88 Mutator->mutateModule(*M, Seed, 1, 1); 89 EXPECT_TRUE(!verifyModule(*M, &errs())); 90 } 91 92 TEST(InstDeleterIRStrategyTest, EmptyFunction) { 93 // Test that we don't crash even if we can't remove from one of the functions. 94 95 StringRef Source = "" 96 "define <8 x i32> @func1() {\n" 97 "ret <8 x i32> undef\n" 98 "}\n" 99 "\n" 100 "define i32 @func2() {\n" 101 "%A9 = alloca i32\n" 102 "%L6 = load i32, i32* %A9\n" 103 "ret i32 %L6\n" 104 "}\n"; 105 106 auto Mutator = createDeleterMutator(); 107 ASSERT_TRUE(Mutator); 108 109 IterateOnSource(Source, *Mutator); 110 } 111 112 TEST(InstDeleterIRStrategyTest, PhiNodes) { 113 // Test that inst deleter works correctly with the phi nodes. 114 115 LLVMContext Ctx; 116 StringRef Source = "\n\ 117 define i32 @earlyreturncrash(i32 %x) {\n\ 118 entry:\n\ 119 switch i32 %x, label %sw.epilog [\n\ 120 i32 1, label %sw.bb1\n\ 121 ]\n\ 122 \n\ 123 sw.bb1:\n\ 124 br label %sw.epilog\n\ 125 \n\ 126 sw.epilog:\n\ 127 %a.0 = phi i32 [ 7, %entry ], [ 9, %sw.bb1 ]\n\ 128 %b.0 = phi i32 [ 10, %entry ], [ 4, %sw.bb1 ]\n\ 129 ret i32 %a.0\n\ 130 }"; 131 132 auto Mutator = createDeleterMutator(); 133 ASSERT_TRUE(Mutator); 134 135 IterateOnSource(Source, *Mutator); 136 } 137 138 } 139