1 //===- llvm/unittest/Bitcode/BitReaderTest.cpp - Tests for BitReader ------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "llvm/ADT/SmallString.h" 11 #include "llvm/AsmParser/Parser.h" 12 #include "llvm/Bitcode/BitstreamWriter.h" 13 #include "llvm/Bitcode/ReaderWriter.h" 14 #include "llvm/IR/Constants.h" 15 #include "llvm/IR/Instructions.h" 16 #include "llvm/IR/LLVMContext.h" 17 #include "llvm/IR/Module.h" 18 #include "llvm/IR/Verifier.h" 19 #include "llvm/Support/Debug.h" 20 #include "llvm/Support/MemoryBuffer.h" 21 #include "llvm/Support/SourceMgr.h" 22 #include "gtest/gtest.h" 23 24 using namespace llvm; 25 26 namespace { 27 28 std::unique_ptr<Module> parseAssembly(const char *Assembly) { 29 SMDiagnostic Error; 30 std::unique_ptr<Module> M = 31 parseAssemblyString(Assembly, Error, getGlobalContext()); 32 33 std::string ErrMsg; 34 raw_string_ostream OS(ErrMsg); 35 Error.print("", OS); 36 37 // A failure here means that the test itself is buggy. 38 if (!M) 39 report_fatal_error(OS.str().c_str()); 40 41 return M; 42 } 43 44 static void writeModuleToBuffer(std::unique_ptr<Module> Mod, 45 SmallVectorImpl<char> &Buffer) { 46 raw_svector_ostream OS(Buffer); 47 WriteBitcodeToFile(Mod.get(), OS); 48 } 49 50 static std::unique_ptr<Module> getLazyModuleFromAssembly(LLVMContext &Context, 51 SmallString<1024> &Mem, 52 const char *Assembly) { 53 writeModuleToBuffer(parseAssembly(Assembly), Mem); 54 std::unique_ptr<MemoryBuffer> Buffer = 55 MemoryBuffer::getMemBuffer(Mem.str(), "test", false); 56 ErrorOr<Module *> ModuleOrErr = 57 getLazyBitcodeModule(std::move(Buffer), Context); 58 return std::unique_ptr<Module>(ModuleOrErr.get()); 59 } 60 61 TEST(BitReaderTest, DematerializeFunctionPreservesLinkageType) { 62 SmallString<1024> Mem; 63 64 LLVMContext Context; 65 std::unique_ptr<Module> M = getLazyModuleFromAssembly( 66 Context, Mem, "define internal i32 @func() {\n" 67 "ret i32 0\n" 68 "}\n"); 69 70 EXPECT_FALSE(verifyModule(*M, &dbgs())); 71 72 M->getFunction("func")->materialize(); 73 EXPECT_FALSE(M->getFunction("func")->empty()); 74 EXPECT_TRUE(M->getFunction("func")->getLinkage() == 75 GlobalValue::InternalLinkage); 76 77 // Check that the linkage type is preserved after dematerialization. 78 M->getFunction("func")->Dematerialize(); 79 EXPECT_TRUE(M->getFunction("func")->empty()); 80 EXPECT_TRUE(M->getFunction("func")->getLinkage() == 81 GlobalValue::InternalLinkage); 82 EXPECT_FALSE(verifyModule(*M, &dbgs())); 83 } 84 85 // Tests that lazy evaluation can parse functions out of order. 86 TEST(BitReaderTest, MaterializeFunctionsOutOfOrder) { 87 SmallString<1024> Mem; 88 LLVMContext Context; 89 std::unique_ptr<Module> M = getLazyModuleFromAssembly( 90 Context, Mem, "define void @f() {\n" 91 " unreachable\n" 92 "}\n" 93 "define void @g() {\n" 94 " unreachable\n" 95 "}\n" 96 "define void @h() {\n" 97 " unreachable\n" 98 "}\n" 99 "define void @j() {\n" 100 " unreachable\n" 101 "}\n"); 102 EXPECT_FALSE(verifyModule(*M, &dbgs())); 103 104 Function *F = M->getFunction("f"); 105 Function *G = M->getFunction("g"); 106 Function *H = M->getFunction("h"); 107 Function *J = M->getFunction("j"); 108 109 // Initially all functions are not materialized (no basic blocks). 110 EXPECT_TRUE(F->empty()); 111 EXPECT_TRUE(G->empty()); 112 EXPECT_TRUE(H->empty()); 113 EXPECT_TRUE(J->empty()); 114 EXPECT_FALSE(verifyModule(*M, &dbgs())); 115 116 // Materialize h. 117 H->materialize(); 118 EXPECT_TRUE(F->empty()); 119 EXPECT_TRUE(G->empty()); 120 EXPECT_FALSE(H->empty()); 121 EXPECT_TRUE(J->empty()); 122 EXPECT_FALSE(verifyModule(*M, &dbgs())); 123 124 // Materialize g. 125 G->materialize(); 126 EXPECT_TRUE(F->empty()); 127 EXPECT_FALSE(G->empty()); 128 EXPECT_FALSE(H->empty()); 129 EXPECT_TRUE(J->empty()); 130 EXPECT_FALSE(verifyModule(*M, &dbgs())); 131 132 // Materialize j. 133 J->materialize(); 134 EXPECT_TRUE(F->empty()); 135 EXPECT_FALSE(G->empty()); 136 EXPECT_FALSE(H->empty()); 137 EXPECT_FALSE(J->empty()); 138 EXPECT_FALSE(verifyModule(*M, &dbgs())); 139 140 // Materialize f. 141 F->materialize(); 142 EXPECT_FALSE(F->empty()); 143 EXPECT_FALSE(G->empty()); 144 EXPECT_FALSE(H->empty()); 145 EXPECT_FALSE(J->empty()); 146 EXPECT_FALSE(verifyModule(*M, &dbgs())); 147 } 148 149 TEST(BitReaderTest, MaterializeFunctionsForBlockAddr) { // PR11677 150 SmallString<1024> Mem; 151 152 LLVMContext Context; 153 std::unique_ptr<Module> M = getLazyModuleFromAssembly( 154 Context, Mem, "@table = constant i8* blockaddress(@func, %bb)\n" 155 "define void @func() {\n" 156 " unreachable\n" 157 "bb:\n" 158 " unreachable\n" 159 "}\n"); 160 EXPECT_FALSE(verifyModule(*M, &dbgs())); 161 162 // Try (and fail) to dematerialize @func. 163 M->getFunction("func")->Dematerialize(); 164 EXPECT_FALSE(M->getFunction("func")->empty()); 165 } 166 167 TEST(BitReaderTest, MaterializeFunctionsForBlockAddrInFunctionBefore) { 168 SmallString<1024> Mem; 169 170 LLVMContext Context; 171 std::unique_ptr<Module> M = getLazyModuleFromAssembly( 172 Context, Mem, "define i8* @before() {\n" 173 " ret i8* blockaddress(@func, %bb)\n" 174 "}\n" 175 "define void @other() {\n" 176 " unreachable\n" 177 "}\n" 178 "define void @func() {\n" 179 " unreachable\n" 180 "bb:\n" 181 " unreachable\n" 182 "}\n"); 183 EXPECT_TRUE(M->getFunction("before")->empty()); 184 EXPECT_TRUE(M->getFunction("func")->empty()); 185 EXPECT_FALSE(verifyModule(*M, &dbgs())); 186 187 // Materialize @before, pulling in @func. 188 EXPECT_FALSE(M->getFunction("before")->materialize()); 189 EXPECT_FALSE(M->getFunction("func")->empty()); 190 EXPECT_TRUE(M->getFunction("other")->empty()); 191 EXPECT_FALSE(verifyModule(*M, &dbgs())); 192 193 // Try (and fail) to dematerialize @func. 194 M->getFunction("func")->Dematerialize(); 195 EXPECT_FALSE(M->getFunction("func")->empty()); 196 EXPECT_FALSE(verifyModule(*M, &dbgs())); 197 } 198 199 TEST(BitReaderTest, MaterializeFunctionsForBlockAddrInFunctionAfter) { 200 SmallString<1024> Mem; 201 202 LLVMContext Context; 203 std::unique_ptr<Module> M = getLazyModuleFromAssembly( 204 Context, Mem, "define void @func() {\n" 205 " unreachable\n" 206 "bb:\n" 207 " unreachable\n" 208 "}\n" 209 "define void @other() {\n" 210 " unreachable\n" 211 "}\n" 212 "define i8* @after() {\n" 213 " ret i8* blockaddress(@func, %bb)\n" 214 "}\n"); 215 EXPECT_TRUE(M->getFunction("after")->empty()); 216 EXPECT_TRUE(M->getFunction("func")->empty()); 217 EXPECT_FALSE(verifyModule(*M, &dbgs())); 218 219 // Materialize @after, pulling in @func. 220 EXPECT_FALSE(M->getFunction("after")->materialize()); 221 EXPECT_FALSE(M->getFunction("func")->empty()); 222 EXPECT_TRUE(M->getFunction("other")->empty()); 223 EXPECT_FALSE(verifyModule(*M, &dbgs())); 224 225 // Try (and fail) to dematerialize @func. 226 M->getFunction("func")->Dematerialize(); 227 EXPECT_FALSE(M->getFunction("func")->empty()); 228 EXPECT_FALSE(verifyModule(*M, &dbgs())); 229 } 230 231 } // end namespace 232