xref: /llvm-project/llvm/unittests/Bitcode/BitReaderTest.cpp (revision 387bee91f095c197270b4d0a9e19cc86b2edea73)
1 //===- llvm/unittest/Bitcode/BitReaderTest.cpp - Tests for BitReader ------===//
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 "BitReaderTestCode.h"
10 #include "llvm/ADT/STLExtras.h"
11 #include "llvm/ADT/SmallString.h"
12 #include "llvm/AsmParser/Parser.h"
13 #include "llvm/Bitcode/BitcodeReader.h"
14 #include "llvm/Bitcode/BitcodeWriter.h"
15 #include "llvm/IR/Constants.h"
16 #include "llvm/IR/InstrTypes.h"
17 #include "llvm/IR/LLVMContext.h"
18 #include "llvm/IR/Module.h"
19 #include "llvm/IR/Verifier.h"
20 #include "llvm/Support/Debug.h"
21 #include "llvm/Support/Error.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(LLVMContext &Context,
31                                       const char *Assembly) {
32   SMDiagnostic Error;
33   std::unique_ptr<Module> M = parseAssemblyString(Assembly, Error, Context);
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(ErrMsg.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, OS);
50 }
51 
52 static std::unique_ptr<Module> getLazyModuleFromAssembly(LLVMContext &Context,
53                                                          SmallString<1024> &Mem,
54                                                          const char *Assembly) {
55   writeModuleToBuffer(parseAssembly(Context, Assembly), Mem);
56   Expected<std::unique_ptr<Module>> ModuleOrErr =
57       getLazyBitcodeModule(MemoryBufferRef(Mem.str(), "test"), Context);
58   if (!ModuleOrErr)
59     report_fatal_error("Could not parse bitcode module");
60   return std::move(ModuleOrErr.get());
61 }
62 
63 // Tests that lazy evaluation can parse functions out of order.
64 TEST(BitReaderTest, MaterializeFunctionsOutOfOrder) {
65   SmallString<1024> Mem;
66   LLVMContext Context;
67   std::unique_ptr<Module> M = getLazyModuleFromAssembly(
68       Context, Mem, "define void @f() {\n"
69                     "  unreachable\n"
70                     "}\n"
71                     "define void @g() {\n"
72                     "  unreachable\n"
73                     "}\n"
74                     "define void @h() {\n"
75                     "  unreachable\n"
76                     "}\n"
77                     "define void @j() {\n"
78                     "  unreachable\n"
79                     "}\n");
80   EXPECT_FALSE(verifyModule(*M, &dbgs()));
81 
82   Function *F = M->getFunction("f");
83   Function *G = M->getFunction("g");
84   Function *H = M->getFunction("h");
85   Function *J = M->getFunction("j");
86 
87   // Initially all functions are not materialized (no basic blocks).
88   EXPECT_TRUE(F->empty());
89   EXPECT_TRUE(G->empty());
90   EXPECT_TRUE(H->empty());
91   EXPECT_TRUE(J->empty());
92   EXPECT_FALSE(verifyModule(*M, &dbgs()));
93 
94   // Materialize h.
95   ASSERT_FALSE(H->materialize());
96   EXPECT_TRUE(F->empty());
97   EXPECT_TRUE(G->empty());
98   EXPECT_FALSE(H->empty());
99   EXPECT_TRUE(J->empty());
100   EXPECT_FALSE(verifyModule(*M, &dbgs()));
101 
102   // Materialize g.
103   ASSERT_FALSE(G->materialize());
104   EXPECT_TRUE(F->empty());
105   EXPECT_FALSE(G->empty());
106   EXPECT_FALSE(H->empty());
107   EXPECT_TRUE(J->empty());
108   EXPECT_FALSE(verifyModule(*M, &dbgs()));
109 
110   // Materialize j.
111   ASSERT_FALSE(J->materialize());
112   EXPECT_TRUE(F->empty());
113   EXPECT_FALSE(G->empty());
114   EXPECT_FALSE(H->empty());
115   EXPECT_FALSE(J->empty());
116   EXPECT_FALSE(verifyModule(*M, &dbgs()));
117 
118   // Materialize f.
119   ASSERT_FALSE(F->materialize());
120   EXPECT_FALSE(F->empty());
121   EXPECT_FALSE(G->empty());
122   EXPECT_FALSE(H->empty());
123   EXPECT_FALSE(J->empty());
124   EXPECT_FALSE(verifyModule(*M, &dbgs()));
125 }
126 
127 TEST(BitReaderTest, MaterializeFunctionsStrictFP) {
128   SmallString<1024> Mem;
129 
130   LLVMContext Context;
131   std::unique_ptr<Module> M = getLazyModuleFromAssembly(
132       Context, Mem, "define double @foo(double %a) {\n"
133                     "  %result = call double @bar(double %a) strictfp\n"
134                     "  ret double %result\n"
135                     "}\n"
136                     "declare double @bar(double)\n");
137   Function *Foo = M->getFunction("foo");
138   ASSERT_FALSE(Foo->materialize());
139   EXPECT_FALSE(Foo->empty());
140 
141   for (auto &BB : *Foo) {
142     auto It = BB.begin();
143     while (It != BB.end()) {
144       Instruction &I = *It;
145       ++It;
146 
147       if (auto *Call = dyn_cast<CallBase>(&I)) {
148         EXPECT_FALSE(Call->isStrictFP());
149         EXPECT_TRUE(Call->isNoBuiltin());
150       }
151     }
152   }
153 
154   EXPECT_FALSE(verifyModule(*M, &dbgs()));
155 }
156 
157 TEST(BitReaderTest, MaterializeConstrainedFPStrictFP) {
158   SmallString<1024> Mem;
159 
160   LLVMContext Context;
161   std::unique_ptr<Module> M = getLazyModuleFromAssembly(
162       Context, Mem,
163       "define double @foo(double %a) strictfp {\n"
164       "  %result = call double @llvm.experimental.constrained.sqrt.f64(double "
165       "%a, metadata !\"round.tonearest\", metadata !\"fpexcept.strict\") "
166       "strictfp\n"
167       "  ret double %result\n"
168       "}\n"
169       "declare double @llvm.experimental.constrained.sqrt.f64(double, "
170       "metadata, metadata)\n");
171   Function *Foo = M->getFunction("foo");
172   ASSERT_FALSE(Foo->materialize());
173   EXPECT_FALSE(Foo->empty());
174 
175   for (auto &BB : *Foo) {
176     auto It = BB.begin();
177     while (It != BB.end()) {
178       Instruction &I = *It;
179       ++It;
180 
181       if (auto *Call = dyn_cast<CallBase>(&I)) {
182         EXPECT_TRUE(Call->isStrictFP());
183         EXPECT_FALSE(Call->isNoBuiltin());
184       }
185     }
186   }
187 
188   EXPECT_FALSE(verifyModule(*M, &dbgs()));
189 }
190 
191 TEST(BitReaderTest, MaterializeFunctionsForBlockAddr) { // PR11677
192   SmallString<1024> Mem;
193 
194   LLVMContext Context;
195   std::unique_ptr<Module> M = getLazyModuleFromAssembly(
196       Context, Mem, "@table = constant i8* blockaddress(@func, %bb)\n"
197                     "define void @func() {\n"
198                     "  unreachable\n"
199                     "bb:\n"
200                     "  unreachable\n"
201                     "}\n");
202   EXPECT_FALSE(verifyModule(*M, &dbgs()));
203   EXPECT_FALSE(M->getFunction("func")->empty());
204 }
205 
206 TEST(BitReaderTest, MaterializeFunctionsForBlockAddrInFunctionBefore) {
207   SmallString<1024> Mem;
208 
209   LLVMContext Context;
210   std::unique_ptr<Module> M = getLazyModuleFromAssembly(
211       Context, Mem, "define i8* @before() {\n"
212                     "  ret i8* blockaddress(@func, %bb)\n"
213                     "}\n"
214                     "define void @other() {\n"
215                     "  unreachable\n"
216                     "}\n"
217                     "define void @func() {\n"
218                     "  unreachable\n"
219                     "bb:\n"
220                     "  unreachable\n"
221                     "}\n");
222   EXPECT_TRUE(M->getFunction("before")->empty());
223   EXPECT_TRUE(M->getFunction("func")->empty());
224   EXPECT_FALSE(verifyModule(*M, &dbgs()));
225 
226   // Materialize @before, pulling in @func.
227   EXPECT_FALSE(M->getFunction("before")->materialize());
228   EXPECT_FALSE(M->getFunction("func")->empty());
229   EXPECT_TRUE(M->getFunction("other")->empty());
230   EXPECT_FALSE(verifyModule(*M, &dbgs()));
231 }
232 
233 TEST(BitReaderTest, MaterializeFunctionsForBlockAddrInFunctionAfter) {
234   SmallString<1024> Mem;
235 
236   LLVMContext Context;
237   std::unique_ptr<Module> M = getLazyModuleFromAssembly(
238       Context, Mem, "define void @func() {\n"
239                     "  unreachable\n"
240                     "bb:\n"
241                     "  unreachable\n"
242                     "}\n"
243                     "define void @other() {\n"
244                     "  unreachable\n"
245                     "}\n"
246                     "define i8* @after() {\n"
247                     "  ret i8* blockaddress(@func, %bb)\n"
248                     "}\n");
249   EXPECT_TRUE(M->getFunction("after")->empty());
250   EXPECT_TRUE(M->getFunction("func")->empty());
251   EXPECT_FALSE(verifyModule(*M, &dbgs()));
252 
253   // Materialize @after, pulling in @func.
254   EXPECT_FALSE(M->getFunction("after")->materialize());
255   EXPECT_FALSE(M->getFunction("func")->empty());
256   EXPECT_TRUE(M->getFunction("other")->empty());
257   EXPECT_FALSE(verifyModule(*M, &dbgs()));
258 }
259 
260 // Helper function to convert type metadata to a string for testing
261 static std::string mdToString(Metadata *MD) {
262   std::string S;
263   if (auto *VMD = dyn_cast<ValueAsMetadata>(MD)) {
264     if (VMD->getType()->isPointerTy()) {
265       S += "ptr";
266       return S;
267     }
268   }
269 
270   if (auto *TMD = dyn_cast<MDTuple>(MD)) {
271     S += "!{";
272     for (unsigned I = 0; I < TMD->getNumOperands(); I++) {
273       if (I != 0)
274         S += ", ";
275       S += mdToString(TMD->getOperand(I).get());
276     }
277     S += "}";
278   } else if (auto *SMD = dyn_cast<MDString>(MD)) {
279     S += "!'";
280     S += SMD->getString();
281     S += "'";
282   } else if (auto *I = mdconst::dyn_extract<ConstantInt>(MD)) {
283     S += std::to_string(I->getZExtValue());
284   } else if (auto *P = mdconst::dyn_extract<PoisonValue>(MD)) {
285     auto *Ty = P->getType();
286     if (Ty->isIntegerTy()) {
287       S += "i";
288       S += std::to_string(Ty->getIntegerBitWidth());
289     } else if (Ty->isStructTy()) {
290       S += "%";
291       S += Ty->getStructName();
292     } else {
293       llvm_unreachable("unhandled poison metadata");
294     }
295   } else {
296     llvm_unreachable("unhandled metadata");
297   }
298   return S;
299 }
300 
301 // Recursively look into a (pointer) type and the the type.
302 // For primitive types it's a poison value of the type, for a pointer it's a
303 // metadata tuple with the addrspace and the referenced type. For a function,
304 // it's a tuple where the first element is the string "function", the second
305 // element is the return type or the string "void" and the following elements
306 // are the argument types.
307 static Metadata *getTypeMetadataEntry(unsigned TypeID, LLVMContext &Context,
308                                       GetTypeByIDTy GetTypeByID,
309                                       GetContainedTypeIDTy GetContainedTypeID) {
310   Type *Ty = GetTypeByID(TypeID);
311   if (auto *FTy = dyn_cast<FunctionType>(Ty)) {
312     // Save the function signature as metadata
313     SmallVector<Metadata *> SignatureMD;
314     SignatureMD.push_back(MDString::get(Context, "function"));
315     // Return type
316     if (FTy->getReturnType()->isVoidTy())
317       SignatureMD.push_back(MDString::get(Context, "void"));
318     else
319       SignatureMD.push_back(getTypeMetadataEntry(GetContainedTypeID(TypeID, 0),
320                                                  Context, GetTypeByID,
321                                                  GetContainedTypeID));
322     // Arguments
323     for (unsigned I = 0; I != FTy->getNumParams(); ++I)
324       SignatureMD.push_back(
325           getTypeMetadataEntry(GetContainedTypeID(TypeID, I + 1), Context,
326                                GetTypeByID, GetContainedTypeID));
327 
328     return MDTuple::get(Context, SignatureMD);
329   }
330 
331   if (!Ty->isPointerTy())
332     return ConstantAsMetadata::get(PoisonValue::get(Ty));
333 
334   // Return !{<addrspace>, <inner>} for pointer
335   SmallVector<Metadata *, 2> MD;
336   MD.push_back(ConstantAsMetadata::get(ConstantInt::get(
337       Type::getInt32Ty(Context), Ty->getPointerAddressSpace())));
338   MD.push_back(getTypeMetadataEntry(GetContainedTypeID(TypeID, 0), Context,
339                                     GetTypeByID, GetContainedTypeID));
340   return MDTuple::get(Context, MD);
341 }
342 
343 // Test that when reading bitcode with typed pointers and upgrading them to
344 // opaque pointers, the type information of function signatures can be extracted
345 // and stored in metadata.
346 TEST(BitReaderTest, AccessFunctionTypeInfo) {
347   StringRef Bitcode(reinterpret_cast<const char *>(AccessFunctionTypeInfoBc),
348                     sizeof(AccessFunctionTypeInfoBc));
349 
350   LLVMContext Context;
351   ParserCallbacks Callbacks;
352   // Supply a callback that stores the signature of a function into metadata,
353   // so that the types behind pointers can be accessed.
354   // Each function gets a !types metadata, which is a tuple with one element
355   // for a non-void return type and every argument. For primitive types it's
356   // a poison value of the type, for a pointer it's a metadata tuple with
357   // the addrspace and the referenced type.
358   Callbacks.ValueType = [&](Value *V, unsigned TypeID,
359                             GetTypeByIDTy GetTypeByID,
360                             GetContainedTypeIDTy GetContainedTypeID) {
361     if (auto *F = dyn_cast<Function>(V)) {
362       auto *MD = getTypeMetadataEntry(TypeID, F->getContext(), GetTypeByID,
363                                       GetContainedTypeID);
364       F->setMetadata("types", cast<MDNode>(MD));
365     }
366   };
367 
368   Expected<std::unique_ptr<Module>> ModuleOrErr =
369       parseBitcodeFile(MemoryBufferRef(Bitcode, "test"), Context, Callbacks);
370 
371   if (!ModuleOrErr)
372     report_fatal_error("Could not parse bitcode module");
373   std::unique_ptr<Module> M = std::move(ModuleOrErr.get());
374 
375   EXPECT_EQ(mdToString(M->getFunction("func")->getMetadata("types")),
376             "!{!'function', !'void'}");
377   EXPECT_EQ(mdToString(M->getFunction("func_header")->getMetadata("types")),
378             "!{!'function', i32}");
379   EXPECT_EQ(mdToString(M->getFunction("ret_ptr")->getMetadata("types")),
380             "!{!'function', !{0, i8}}");
381   EXPECT_EQ(mdToString(M->getFunction("ret_and_arg_ptr")->getMetadata("types")),
382             "!{!'function', !{0, i8}, !{8, i32}}");
383   EXPECT_EQ(mdToString(M->getFunction("double_ptr")->getMetadata("types")),
384             "!{!'function', !{1, i8}, !{2, !{0, i32}}, !{0, !{0, !{0, i32}}}}");
385 }
386 
387 // Test that when reading bitcode with typed pointers and upgrading them to
388 // opaque pointers, the type information of pointers in metadata can be
389 // extracted and stored in metadata.
390 TEST(BitReaderTest, AccessMetadataTypeInfo) {
391   StringRef Bitcode(reinterpret_cast<const char *>(AccessMetadataTypeInfoBc),
392                     sizeof(AccessFunctionTypeInfoBc));
393 
394   LLVMContext Context;
395   ParserCallbacks Callbacks;
396   // Supply a callback that stores types from metadata,
397   // so that the types behind pointers can be accessed.
398   // Non-pointer entries are ignored. Values with a pointer type are
399   // replaced by a metadata tuple with {original value, type md}. We cannot
400   // save the metadata outside because after conversion to opaque pointers,
401   // entries are not distinguishable anymore (e.g. i32* and i8* are both
402   // upgraded to ptr).
403   Callbacks.MDType = [&](Metadata **Val, unsigned TypeID,
404                          GetTypeByIDTy GetTypeByID,
405                          GetContainedTypeIDTy GetContainedTypeID) {
406     auto *OrigVal = cast<ValueAsMetadata>(*Val);
407     if (OrigVal->getType()->isPointerTy()) {
408       // Ignore function references, their signature can be saved like
409       // in the test above
410       if (!isa<Function>(OrigVal->getValue())) {
411         SmallVector<Metadata *> Tuple;
412         Tuple.push_back(OrigVal);
413         Tuple.push_back(getTypeMetadataEntry(GetContainedTypeID(TypeID, 0),
414                                              OrigVal->getContext(), GetTypeByID,
415                                              GetContainedTypeID));
416         *Val = MDTuple::get(OrigVal->getContext(), Tuple);
417       }
418     }
419   };
420 
421   Expected<std::unique_ptr<Module>> ModuleOrErr =
422       parseBitcodeFile(MemoryBufferRef(Bitcode, "test"), Context, Callbacks);
423 
424   if (!ModuleOrErr)
425     report_fatal_error("Could not parse bitcode module");
426   std::unique_ptr<Module> M = std::move(ModuleOrErr.get());
427 
428   EXPECT_EQ(
429       mdToString(M->getNamedMetadata("md")->getOperand(0)),
430       "!{2, !{ptr, %dx.types.f32}, ptr, !{ptr, !{!'function', !'void'}}}");
431   EXPECT_EQ(mdToString(M->getNamedMetadata("md2")->getOperand(0)),
432             "!{!{ptr, !{!'function', !{0, i8}, !{2, !{0, i32}}}}, !{ptr, !{0, "
433             "!{0, i32}}}}");
434 }
435 
436 } // end namespace
437