1 //===- llvm/unittest/Bitcode/BitReaderTest.cpp - Tests for BitReader ------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "llvm/ADT/STLExtras.h"
10 #include "llvm/ADT/SmallString.h"
11 #include "llvm/AsmParser/Parser.h"
12 #include "llvm/Bitcode/BitcodeReader.h"
13 #include "llvm/Bitcode/BitcodeWriter.h"
14 #include "llvm/IR/InstrTypes.h"
15 #include "llvm/IR/LLVMContext.h"
16 #include "llvm/IR/Module.h"
17 #include "llvm/IR/Verifier.h"
18 #include "llvm/Support/Debug.h"
19 #include "llvm/Support/Error.h"
20 #include "llvm/Support/MemoryBuffer.h"
21 #include "llvm/Support/SourceMgr.h"
22 #include "gtest/gtest.h"
28 std::unique_ptr
<Module
> parseAssembly(LLVMContext
&Context
,
29 const char *Assembly
) {
31 std::unique_ptr
<Module
> M
= parseAssemblyString(Assembly
, Error
, Context
);
34 raw_string_ostream
OS(ErrMsg
);
37 // A failure here means that the test itself is buggy.
39 report_fatal_error(OS
.str().c_str());
44 static void writeModuleToBuffer(std::unique_ptr
<Module
> Mod
,
45 SmallVectorImpl
<char> &Buffer
) {
46 raw_svector_ostream
OS(Buffer
);
47 WriteBitcodeToFile(*Mod
, OS
);
50 static std::unique_ptr
<Module
> getLazyModuleFromAssembly(LLVMContext
&Context
,
51 SmallString
<1024> &Mem
,
52 const char *Assembly
) {
53 writeModuleToBuffer(parseAssembly(Context
, Assembly
), Mem
);
54 Expected
<std::unique_ptr
<Module
>> ModuleOrErr
=
55 getLazyBitcodeModule(MemoryBufferRef(Mem
.str(), "test"), Context
);
57 report_fatal_error("Could not parse bitcode module");
58 return std::move(ModuleOrErr
.get());
61 // Tests that lazy evaluation can parse functions out of order.
62 TEST(BitReaderTest
, MaterializeFunctionsOutOfOrder
) {
63 SmallString
<1024> Mem
;
65 std::unique_ptr
<Module
> M
= getLazyModuleFromAssembly(
66 Context
, Mem
, "define void @f() {\n"
69 "define void @g() {\n"
72 "define void @h() {\n"
75 "define void @j() {\n"
78 EXPECT_FALSE(verifyModule(*M
, &dbgs()));
80 Function
*F
= M
->getFunction("f");
81 Function
*G
= M
->getFunction("g");
82 Function
*H
= M
->getFunction("h");
83 Function
*J
= M
->getFunction("j");
85 // Initially all functions are not materialized (no basic blocks).
86 EXPECT_TRUE(F
->empty());
87 EXPECT_TRUE(G
->empty());
88 EXPECT_TRUE(H
->empty());
89 EXPECT_TRUE(J
->empty());
90 EXPECT_FALSE(verifyModule(*M
, &dbgs()));
93 ASSERT_FALSE(H
->materialize());
94 EXPECT_TRUE(F
->empty());
95 EXPECT_TRUE(G
->empty());
96 EXPECT_FALSE(H
->empty());
97 EXPECT_TRUE(J
->empty());
98 EXPECT_FALSE(verifyModule(*M
, &dbgs()));
101 ASSERT_FALSE(G
->materialize());
102 EXPECT_TRUE(F
->empty());
103 EXPECT_FALSE(G
->empty());
104 EXPECT_FALSE(H
->empty());
105 EXPECT_TRUE(J
->empty());
106 EXPECT_FALSE(verifyModule(*M
, &dbgs()));
109 ASSERT_FALSE(J
->materialize());
110 EXPECT_TRUE(F
->empty());
111 EXPECT_FALSE(G
->empty());
112 EXPECT_FALSE(H
->empty());
113 EXPECT_FALSE(J
->empty());
114 EXPECT_FALSE(verifyModule(*M
, &dbgs()));
117 ASSERT_FALSE(F
->materialize());
118 EXPECT_FALSE(F
->empty());
119 EXPECT_FALSE(G
->empty());
120 EXPECT_FALSE(H
->empty());
121 EXPECT_FALSE(J
->empty());
122 EXPECT_FALSE(verifyModule(*M
, &dbgs()));
125 TEST(BitReaderTest
, MaterializeFunctionsStrictFP
) {
126 SmallString
<1024> Mem
;
129 std::unique_ptr
<Module
> M
= getLazyModuleFromAssembly(
130 Context
, Mem
, "define double @foo(double %a) {\n"
131 " %result = call double @bar(double %a) strictfp\n"
132 " ret double %result\n"
134 "declare double @bar(double)\n");
135 Function
*Foo
= M
->getFunction("foo");
136 ASSERT_FALSE(Foo
->materialize());
137 EXPECT_FALSE(Foo
->empty());
139 for (auto &BB
: *Foo
) {
140 auto It
= BB
.begin();
141 while (It
!= BB
.end()) {
142 Instruction
&I
= *It
;
145 if (auto *Call
= dyn_cast
<CallBase
>(&I
)) {
146 EXPECT_FALSE(Call
->isStrictFP());
147 EXPECT_TRUE(Call
->isNoBuiltin());
152 EXPECT_FALSE(verifyModule(*M
, &dbgs()));
155 TEST(BitReaderTest
, MaterializeConstrainedFPStrictFP
) {
156 SmallString
<1024> Mem
;
159 std::unique_ptr
<Module
> M
= getLazyModuleFromAssembly(
161 "define double @foo(double %a) {\n"
162 " %result = call double @llvm.experimental.constrained.sqrt.f64(double "
163 "%a, metadata !\"round.tonearest\", metadata !\"fpexcept.strict\") "
165 " ret double %result\n"
167 "declare double @llvm.experimental.constrained.sqrt.f64(double, "
168 "metadata, metadata)\n");
169 Function
*Foo
= M
->getFunction("foo");
170 ASSERT_FALSE(Foo
->materialize());
171 EXPECT_FALSE(Foo
->empty());
173 for (auto &BB
: *Foo
) {
174 auto It
= BB
.begin();
175 while (It
!= BB
.end()) {
176 Instruction
&I
= *It
;
179 if (auto *Call
= dyn_cast
<CallBase
>(&I
)) {
180 EXPECT_TRUE(Call
->isStrictFP());
181 EXPECT_FALSE(Call
->isNoBuiltin());
186 EXPECT_FALSE(verifyModule(*M
, &dbgs()));
189 TEST(BitReaderTest
, MaterializeFunctionsForBlockAddr
) { // PR11677
190 SmallString
<1024> Mem
;
193 std::unique_ptr
<Module
> M
= getLazyModuleFromAssembly(
194 Context
, Mem
, "@table = constant i8* blockaddress(@func, %bb)\n"
195 "define void @func() {\n"
200 EXPECT_FALSE(verifyModule(*M
, &dbgs()));
201 EXPECT_FALSE(M
->getFunction("func")->empty());
204 TEST(BitReaderTest
, MaterializeFunctionsForBlockAddrInFunctionBefore
) {
205 SmallString
<1024> Mem
;
208 std::unique_ptr
<Module
> M
= getLazyModuleFromAssembly(
209 Context
, Mem
, "define i8* @before() {\n"
210 " ret i8* blockaddress(@func, %bb)\n"
212 "define void @other() {\n"
215 "define void @func() {\n"
220 EXPECT_TRUE(M
->getFunction("before")->empty());
221 EXPECT_TRUE(M
->getFunction("func")->empty());
222 EXPECT_FALSE(verifyModule(*M
, &dbgs()));
224 // Materialize @before, pulling in @func.
225 EXPECT_FALSE(M
->getFunction("before")->materialize());
226 EXPECT_FALSE(M
->getFunction("func")->empty());
227 EXPECT_TRUE(M
->getFunction("other")->empty());
228 EXPECT_FALSE(verifyModule(*M
, &dbgs()));
231 TEST(BitReaderTest
, MaterializeFunctionsForBlockAddrInFunctionAfter
) {
232 SmallString
<1024> Mem
;
235 std::unique_ptr
<Module
> M
= getLazyModuleFromAssembly(
236 Context
, Mem
, "define void @func() {\n"
241 "define void @other() {\n"
244 "define i8* @after() {\n"
245 " ret i8* blockaddress(@func, %bb)\n"
247 EXPECT_TRUE(M
->getFunction("after")->empty());
248 EXPECT_TRUE(M
->getFunction("func")->empty());
249 EXPECT_FALSE(verifyModule(*M
, &dbgs()));
251 // Materialize @after, pulling in @func.
252 EXPECT_FALSE(M
->getFunction("after")->materialize());
253 EXPECT_FALSE(M
->getFunction("func")->empty());
254 EXPECT_TRUE(M
->getFunction("other")->empty());
255 EXPECT_FALSE(verifyModule(*M
, &dbgs()));