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/ADT/STLExtras.h" 12 #include "llvm/AsmParser/Parser.h" 13 #include "llvm/Bitcode/BitstreamWriter.h" 14 #include "llvm/Bitcode/ReaderWriter.h" 15 #include "llvm/IR/Constants.h" 16 #include "llvm/IR/Instructions.h" 17 #include "llvm/IR/LLVMContext.h" 18 #include "llvm/IR/Module.h" 19 #include "llvm/IR/Verifier.h" 20 #include "llvm/Support/DataStream.h" 21 #include "llvm/Support/Debug.h" 22 #include "llvm/Support/MemoryBuffer.h" 23 #include "llvm/Support/SourceMgr.h" 24 #include "gtest/gtest.h" 25 26 using namespace llvm; 27 28 namespace { 29 30 std::unique_ptr<Module> parseAssembly(const char *Assembly) { 31 SMDiagnostic Error; 32 std::unique_ptr<Module> M = 33 parseAssemblyString(Assembly, Error, getGlobalContext()); 34 35 std::string ErrMsg; 36 raw_string_ostream OS(ErrMsg); 37 Error.print("", OS); 38 39 // A failure here means that the test itself is buggy. 40 if (!M) 41 report_fatal_error(OS.str().c_str()); 42 43 return M; 44 } 45 46 static void writeModuleToBuffer(std::unique_ptr<Module> Mod, 47 SmallVectorImpl<char> &Buffer) { 48 raw_svector_ostream OS(Buffer); 49 WriteBitcodeToFile(Mod.get(), OS); 50 } 51 52 static std::unique_ptr<Module> getLazyModuleFromAssembly(LLVMContext &Context, 53 SmallString<1024> &Mem, 54 const char *Assembly) { 55 writeModuleToBuffer(parseAssembly(Assembly), Mem); 56 std::unique_ptr<MemoryBuffer> Buffer = 57 MemoryBuffer::getMemBuffer(Mem.str(), "test", false); 58 ErrorOr<std::unique_ptr<Module>> ModuleOrErr = 59 getLazyBitcodeModule(std::move(Buffer), Context); 60 return std::move(ModuleOrErr.get()); 61 } 62 63 class BufferDataStreamer : public DataStreamer { 64 std::unique_ptr<MemoryBuffer> Buffer; 65 unsigned Pos = 0; 66 size_t GetBytes(unsigned char *Out, size_t Len) override { 67 StringRef Buf = Buffer->getBuffer(); 68 size_t Left = Buf.size() - Pos; 69 Len = std::min(Left, Len); 70 memcpy(Out, Buffer->getBuffer().substr(Pos).data(), Len); 71 Pos += Len; 72 return Len; 73 } 74 75 public: 76 BufferDataStreamer(std::unique_ptr<MemoryBuffer> Buffer) 77 : Buffer(std::move(Buffer)) {} 78 }; 79 80 static std::unique_ptr<Module> 81 getStreamedModuleFromAssembly(LLVMContext &Context, SmallString<1024> &Mem, 82 const char *Assembly) { 83 writeModuleToBuffer(parseAssembly(Assembly), Mem); 84 std::unique_ptr<MemoryBuffer> Buffer = 85 MemoryBuffer::getMemBuffer(Mem.str(), "test", false); 86 auto Streamer = llvm::make_unique<BufferDataStreamer>(std::move(Buffer)); 87 ErrorOr<std::unique_ptr<Module>> ModuleOrErr = 88 getStreamedBitcodeModule("test", std::move(Streamer), Context); 89 return std::move(ModuleOrErr.get()); 90 } 91 92 TEST(BitReaderTest, MateralizeForwardRefWithStream) { 93 SmallString<1024> Mem; 94 95 LLVMContext Context; 96 std::unique_ptr<Module> M = getStreamedModuleFromAssembly( 97 Context, Mem, "@table = constant i8* blockaddress(@func, %bb)\n" 98 "define void @func() {\n" 99 " unreachable\n" 100 "bb:\n" 101 " unreachable\n" 102 "}\n"); 103 EXPECT_FALSE(M->getFunction("func")->empty()); 104 } 105 106 TEST(BitReaderTest, DematerializeFunctionPreservesLinkageType) { 107 SmallString<1024> Mem; 108 109 LLVMContext Context; 110 std::unique_ptr<Module> M = getLazyModuleFromAssembly( 111 Context, Mem, "define internal i32 @func() {\n" 112 "ret i32 0\n" 113 "}\n"); 114 115 EXPECT_FALSE(verifyModule(*M, &dbgs())); 116 117 M->getFunction("func")->materialize(); 118 EXPECT_FALSE(M->getFunction("func")->empty()); 119 EXPECT_TRUE(M->getFunction("func")->getLinkage() == 120 GlobalValue::InternalLinkage); 121 122 // Check that the linkage type is preserved after dematerialization. 123 M->getFunction("func")->dematerialize(); 124 EXPECT_TRUE(M->getFunction("func")->empty()); 125 EXPECT_TRUE(M->getFunction("func")->getLinkage() == 126 GlobalValue::InternalLinkage); 127 EXPECT_FALSE(verifyModule(*M, &dbgs())); 128 } 129 130 // Tests that lazy evaluation can parse functions out of order. 131 TEST(BitReaderTest, MaterializeFunctionsOutOfOrder) { 132 SmallString<1024> Mem; 133 LLVMContext Context; 134 std::unique_ptr<Module> M = getLazyModuleFromAssembly( 135 Context, Mem, "define void @f() {\n" 136 " unreachable\n" 137 "}\n" 138 "define void @g() {\n" 139 " unreachable\n" 140 "}\n" 141 "define void @h() {\n" 142 " unreachable\n" 143 "}\n" 144 "define void @j() {\n" 145 " unreachable\n" 146 "}\n"); 147 EXPECT_FALSE(verifyModule(*M, &dbgs())); 148 149 Function *F = M->getFunction("f"); 150 Function *G = M->getFunction("g"); 151 Function *H = M->getFunction("h"); 152 Function *J = M->getFunction("j"); 153 154 // Initially all functions are not materialized (no basic blocks). 155 EXPECT_TRUE(F->empty()); 156 EXPECT_TRUE(G->empty()); 157 EXPECT_TRUE(H->empty()); 158 EXPECT_TRUE(J->empty()); 159 EXPECT_FALSE(verifyModule(*M, &dbgs())); 160 161 // Materialize h. 162 H->materialize(); 163 EXPECT_TRUE(F->empty()); 164 EXPECT_TRUE(G->empty()); 165 EXPECT_FALSE(H->empty()); 166 EXPECT_TRUE(J->empty()); 167 EXPECT_FALSE(verifyModule(*M, &dbgs())); 168 169 // Materialize g. 170 G->materialize(); 171 EXPECT_TRUE(F->empty()); 172 EXPECT_FALSE(G->empty()); 173 EXPECT_FALSE(H->empty()); 174 EXPECT_TRUE(J->empty()); 175 EXPECT_FALSE(verifyModule(*M, &dbgs())); 176 177 // Materialize j. 178 J->materialize(); 179 EXPECT_TRUE(F->empty()); 180 EXPECT_FALSE(G->empty()); 181 EXPECT_FALSE(H->empty()); 182 EXPECT_FALSE(J->empty()); 183 EXPECT_FALSE(verifyModule(*M, &dbgs())); 184 185 // Materialize f. 186 F->materialize(); 187 EXPECT_FALSE(F->empty()); 188 EXPECT_FALSE(G->empty()); 189 EXPECT_FALSE(H->empty()); 190 EXPECT_FALSE(J->empty()); 191 EXPECT_FALSE(verifyModule(*M, &dbgs())); 192 } 193 194 TEST(BitReaderTest, MaterializeFunctionsForBlockAddr) { // PR11677 195 SmallString<1024> Mem; 196 197 LLVMContext Context; 198 std::unique_ptr<Module> M = getLazyModuleFromAssembly( 199 Context, Mem, "@table = constant i8* blockaddress(@func, %bb)\n" 200 "define void @func() {\n" 201 " unreachable\n" 202 "bb:\n" 203 " unreachable\n" 204 "}\n"); 205 EXPECT_FALSE(verifyModule(*M, &dbgs())); 206 207 // Try (and fail) to dematerialize @func. 208 M->getFunction("func")->dematerialize(); 209 EXPECT_FALSE(M->getFunction("func")->empty()); 210 } 211 212 TEST(BitReaderTest, MaterializeFunctionsForBlockAddrInFunctionBefore) { 213 SmallString<1024> Mem; 214 215 LLVMContext Context; 216 std::unique_ptr<Module> M = getLazyModuleFromAssembly( 217 Context, Mem, "define i8* @before() {\n" 218 " ret i8* blockaddress(@func, %bb)\n" 219 "}\n" 220 "define void @other() {\n" 221 " unreachable\n" 222 "}\n" 223 "define void @func() {\n" 224 " unreachable\n" 225 "bb:\n" 226 " unreachable\n" 227 "}\n"); 228 EXPECT_TRUE(M->getFunction("before")->empty()); 229 EXPECT_TRUE(M->getFunction("func")->empty()); 230 EXPECT_FALSE(verifyModule(*M, &dbgs())); 231 232 // Materialize @before, pulling in @func. 233 EXPECT_FALSE(M->getFunction("before")->materialize()); 234 EXPECT_FALSE(M->getFunction("func")->empty()); 235 EXPECT_TRUE(M->getFunction("other")->empty()); 236 EXPECT_FALSE(verifyModule(*M, &dbgs())); 237 238 // Try (and fail) to dematerialize @func. 239 M->getFunction("func")->dematerialize(); 240 EXPECT_FALSE(M->getFunction("func")->empty()); 241 EXPECT_FALSE(verifyModule(*M, &dbgs())); 242 } 243 244 TEST(BitReaderTest, MaterializeFunctionsForBlockAddrInFunctionAfter) { 245 SmallString<1024> Mem; 246 247 LLVMContext Context; 248 std::unique_ptr<Module> M = getLazyModuleFromAssembly( 249 Context, Mem, "define void @func() {\n" 250 " unreachable\n" 251 "bb:\n" 252 " unreachable\n" 253 "}\n" 254 "define void @other() {\n" 255 " unreachable\n" 256 "}\n" 257 "define i8* @after() {\n" 258 " ret i8* blockaddress(@func, %bb)\n" 259 "}\n"); 260 EXPECT_TRUE(M->getFunction("after")->empty()); 261 EXPECT_TRUE(M->getFunction("func")->empty()); 262 EXPECT_FALSE(verifyModule(*M, &dbgs())); 263 264 // Materialize @after, pulling in @func. 265 EXPECT_FALSE(M->getFunction("after")->materialize()); 266 EXPECT_FALSE(M->getFunction("func")->empty()); 267 EXPECT_TRUE(M->getFunction("other")->empty()); 268 EXPECT_FALSE(verifyModule(*M, &dbgs())); 269 270 // Try (and fail) to dematerialize @func. 271 M->getFunction("func")->dematerialize(); 272 EXPECT_FALSE(M->getFunction("func")->empty()); 273 EXPECT_FALSE(verifyModule(*M, &dbgs())); 274 } 275 276 } // end namespace 277