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
26using namespace llvm;
27
28namespace {
29
30std::unique_ptr<Module> parseAssembly(LLVMContext &Context,
31 const char *Assembly) {
32 SMDiagnostic Error;
33 std::unique_ptr<Module> M = parseAssemblyString(AsmString: Assembly, Err&: Error, Context);
34
35 std::string ErrMsg;
36 raw_string_ostream OS(ErrMsg);
37 Error.print(ProgName: "", S&: OS);
38
39 // A failure here means that the test itself is buggy.
40 if (!M)
41 report_fatal_error(reason: OS.str().c_str());
42
43 return M;
44}
45
46static void writeModuleToBuffer(std::unique_ptr<Module> Mod,
47 SmallVectorImpl<char> &Buffer) {
48 raw_svector_ostream OS(Buffer);
49 WriteBitcodeToFile(M: *Mod, Out&: OS);
50}
51
52static std::unique_ptr<Module> getLazyModuleFromAssembly(LLVMContext &Context,
53 SmallString<1024> &Mem,
54 const char *Assembly) {
55 writeModuleToBuffer(Mod: parseAssembly(Context, Assembly), Buffer&: Mem);
56 Expected<std::unique_ptr<Module>> ModuleOrErr =
57 getLazyBitcodeModule(Buffer: MemoryBufferRef(Mem.str(), "test"), Context);
58 if (!ModuleOrErr)
59 report_fatal_error(reason: "Could not parse bitcode module");
60 return std::move(ModuleOrErr.get());
61}
62
63// Tests that lazy evaluation can parse functions out of order.
64TEST(BitReaderTest, MaterializeFunctionsOutOfOrder) {
65 SmallString<1024> Mem;
66 LLVMContext Context;
67 std::unique_ptr<Module> M = getLazyModuleFromAssembly(
68 Context, Mem, Assembly: "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(Name: "f");
83 Function *G = M->getFunction(Name: "g");
84 Function *H = M->getFunction(Name: "h");
85 Function *J = M->getFunction(Name: "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
127TEST(BitReaderTest, MaterializeFunctionsStrictFP) {
128 SmallString<1024> Mem;
129
130 LLVMContext Context;
131 std::unique_ptr<Module> M = getLazyModuleFromAssembly(
132 Context, Mem, Assembly: "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(Name: "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>(Val: &I)) {
148 EXPECT_FALSE(Call->isStrictFP());
149 EXPECT_TRUE(Call->isNoBuiltin());
150 }
151 }
152 }
153
154 EXPECT_FALSE(verifyModule(*M, &dbgs()));
155}
156
157TEST(BitReaderTest, MaterializeConstrainedFPStrictFP) {
158 SmallString<1024> Mem;
159
160 LLVMContext Context;
161 std::unique_ptr<Module> M = getLazyModuleFromAssembly(
162 Context, Mem,
163 Assembly: "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(Name: "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>(Val: &I)) {
182 EXPECT_TRUE(Call->isStrictFP());
183 EXPECT_FALSE(Call->isNoBuiltin());
184 }
185 }
186 }
187
188 EXPECT_FALSE(verifyModule(*M, &dbgs()));
189}
190
191TEST(BitReaderTest, MaterializeFunctionsForBlockAddr) { // PR11677
192 SmallString<1024> Mem;
193
194 LLVMContext Context;
195 std::unique_ptr<Module> M = getLazyModuleFromAssembly(
196 Context, Mem, Assembly: "@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
206TEST(BitReaderTest, MaterializeFunctionsForBlockAddrInFunctionBefore) {
207 SmallString<1024> Mem;
208
209 LLVMContext Context;
210 std::unique_ptr<Module> M = getLazyModuleFromAssembly(
211 Context, Mem, Assembly: "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
233TEST(BitReaderTest, MaterializeFunctionsForBlockAddrInFunctionAfter) {
234 SmallString<1024> Mem;
235
236 LLVMContext Context;
237 std::unique_ptr<Module> M = getLazyModuleFromAssembly(
238 Context, Mem, Assembly: "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
261static std::string mdToString(Metadata *MD) {
262 std::string S;
263 if (auto *VMD = dyn_cast<ValueAsMetadata>(Val: MD)) {
264 if (VMD->getType()->isPointerTy()) {
265 S += "ptr";
266 return S;
267 }
268 }
269
270 if (auto *TMD = dyn_cast<MDTuple>(Val: MD)) {
271 S += "!{";
272 for (unsigned I = 0; I < TMD->getNumOperands(); I++) {
273 if (I != 0)
274 S += ", ";
275 S += mdToString(MD: TMD->getOperand(I).get());
276 }
277 S += "}";
278 } else if (auto *SMD = dyn_cast<MDString>(Val: MD)) {
279 S += "!'";
280 S += SMD->getString();
281 S += "'";
282 } else if (auto *I = mdconst::dyn_extract<ConstantInt>(MD)) {
283 S += std::to_string(val: 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(val: 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.
307static Metadata *getTypeMetadataEntry(unsigned TypeID, LLVMContext &Context,
308 GetTypeByIDTy GetTypeByID,
309 GetContainedTypeIDTy GetContainedTypeID) {
310 Type *Ty = GetTypeByID(TypeID);
311 if (auto *FTy = dyn_cast<FunctionType>(Val: Ty)) {
312 // Save the function signature as metadata
313 SmallVector<Metadata *> SignatureMD;
314 SignatureMD.push_back(Elt: MDString::get(Context, Str: "function"));
315 // Return type
316 if (FTy->getReturnType()->isVoidTy())
317 SignatureMD.push_back(Elt: MDString::get(Context, Str: "void"));
318 else
319 SignatureMD.push_back(Elt: getTypeMetadataEntry(TypeID: GetContainedTypeID(TypeID, 0),
320 Context, GetTypeByID,
321 GetContainedTypeID));
322 // Arguments
323 for (unsigned I = 0; I != FTy->getNumParams(); ++I)
324 SignatureMD.push_back(
325 Elt: getTypeMetadataEntry(TypeID: GetContainedTypeID(TypeID, I + 1), Context,
326 GetTypeByID, GetContainedTypeID));
327
328 return MDTuple::get(Context, MDs: SignatureMD);
329 }
330
331 if (!Ty->isPointerTy())
332 return ConstantAsMetadata::get(C: PoisonValue::get(T: Ty));
333
334 // Return !{<addrspace>, <inner>} for pointer
335 SmallVector<Metadata *, 2> MD;
336 MD.push_back(Elt: ConstantAsMetadata::get(C: ConstantInt::get(
337 Ty: Type::getInt32Ty(C&: Context), V: Ty->getPointerAddressSpace())));
338 MD.push_back(Elt: getTypeMetadataEntry(TypeID: GetContainedTypeID(TypeID, 0), Context,
339 GetTypeByID, GetContainedTypeID));
340 return MDTuple::get(Context, MDs: 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.
346TEST(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>(Val: V)) {
362 auto *MD = getTypeMetadataEntry(TypeID, Context&: F->getContext(), GetTypeByID,
363 GetContainedTypeID);
364 F->setMetadata(Kind: "types", Node: cast<MDNode>(Val: MD));
365 }
366 };
367
368 Expected<std::unique_ptr<Module>> ModuleOrErr =
369 parseBitcodeFile(Buffer: MemoryBufferRef(Bitcode, "test"), Context, Callbacks);
370
371 if (!ModuleOrErr)
372 report_fatal_error(reason: "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.
390TEST(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: *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>(Val: OrigVal->getValue())) {
411 SmallVector<Metadata *> Tuple;
412 Tuple.push_back(Elt: OrigVal);
413 Tuple.push_back(Elt: getTypeMetadataEntry(TypeID: GetContainedTypeID(TypeID, 0),
414 Context&: OrigVal->getContext(), GetTypeByID,
415 GetContainedTypeID));
416 *Val = MDTuple::get(Context&: OrigVal->getContext(), MDs: Tuple);
417 }
418 }
419 };
420
421 Expected<std::unique_ptr<Module>> ModuleOrErr =
422 parseBitcodeFile(Buffer: MemoryBufferRef(Bitcode, "test"), Context, Callbacks);
423
424 if (!ModuleOrErr)
425 report_fatal_error(reason: "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

source code of llvm/unittests/Bitcode/BitReaderTest.cpp