xref: /llvm-project/llvm/unittests/Bitcode/BitReaderTest.cpp (revision 5d8dfd39e1135dfdea044ff40f1c6dbef3489e73)
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