xref: /llvm-project/llvm/unittests/IR/ValueTest.cpp (revision 4259198d65c1454b5cb5e60a46b2cce2544f1ca5)
1 //===- llvm/unittest/IR/ValueTest.cpp - Value unit tests ------------------===//
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 "llvm/IR/Value.h"
10 #include "llvm/AsmParser/Parser.h"
11 #include "llvm/IR/Function.h"
12 #include "llvm/IR/IntrinsicInst.h"
13 #include "llvm/IR/LLVMContext.h"
14 #include "llvm/IR/Module.h"
15 #include "llvm/IR/ModuleSlotTracker.h"
16 #include "llvm/Support/SourceMgr.h"
17 #include "gtest/gtest.h"
18 using namespace llvm;
19 
20 extern cl::opt<bool> UseNewDbgInfoFormat;
21 
22 namespace {
23 
24 TEST(ValueTest, UsedInBasicBlock) {
25   LLVMContext C;
26 
27   const char *ModuleString = "define void @f(i32 %x, i32 %y) {\n"
28                              "bb0:\n"
29                              "  %y1 = add i32 %y, 1\n"
30                              "  %y2 = add i32 %y, 1\n"
31                              "  %y3 = add i32 %y, 1\n"
32                              "  %y4 = add i32 %y, 1\n"
33                              "  %y5 = add i32 %y, 1\n"
34                              "  %y6 = add i32 %y, 1\n"
35                              "  %y7 = add i32 %y, 1\n"
36                              "  %y8 = add i32 %x, 1\n"
37                              "  ret void\n"
38                              "}\n";
39   SMDiagnostic Err;
40   std::unique_ptr<Module> M = parseAssemblyString(ModuleString, Err, C);
41 
42   Function *F = M->getFunction("f");
43 
44   EXPECT_FALSE(F->isUsedInBasicBlock(&F->front()));
45   EXPECT_TRUE(std::next(F->arg_begin())->isUsedInBasicBlock(&F->front()));
46   EXPECT_TRUE(F->arg_begin()->isUsedInBasicBlock(&F->front()));
47 }
48 
49 TEST(GlobalTest, CreateAddressSpace) {
50   LLVMContext Ctx;
51   std::unique_ptr<Module> M(new Module("TestModule", Ctx));
52   Type *Int8Ty = Type::getInt8Ty(Ctx);
53   Type *Int32Ty = Type::getInt32Ty(Ctx);
54 
55   GlobalVariable *Dummy0
56     = new GlobalVariable(*M,
57                          Int32Ty,
58                          true,
59                          GlobalValue::ExternalLinkage,
60                          Constant::getAllOnesValue(Int32Ty),
61                          "dummy",
62                          nullptr,
63                          GlobalVariable::NotThreadLocal,
64                          1);
65 
66   const Align kMaxAlignment(Value::MaximumAlignment);
67   EXPECT_TRUE(kMaxAlignment.value() == 4294967296ULL);
68   Dummy0->setAlignment(kMaxAlignment);
69   EXPECT_TRUE(Dummy0->getAlign());
70   EXPECT_EQ(*Dummy0->getAlign(), kMaxAlignment);
71 
72   // Make sure the address space isn't dropped when returning this.
73   Constant *Dummy1 = M->getOrInsertGlobal("dummy", Int32Ty);
74   EXPECT_EQ(Dummy0, Dummy1);
75   EXPECT_EQ(1u, Dummy1->getType()->getPointerAddressSpace());
76 
77 
78   // This one requires a bitcast, but the address space must also stay the same.
79   GlobalVariable *DummyCast0
80     = new GlobalVariable(*M,
81                          Int32Ty,
82                          true,
83                          GlobalValue::ExternalLinkage,
84                          Constant::getAllOnesValue(Int32Ty),
85                          "dummy_cast",
86                          nullptr,
87                          GlobalVariable::NotThreadLocal,
88                          1);
89 
90   // Make sure the address space isn't dropped when returning this.
91   Constant *DummyCast1 = M->getOrInsertGlobal("dummy_cast", Int8Ty);
92   EXPECT_EQ(DummyCast0, DummyCast1);
93   EXPECT_EQ(1u, DummyCast1->getType()->getPointerAddressSpace());
94 }
95 
96 #ifdef GTEST_HAS_DEATH_TEST
97 #ifndef NDEBUG
98 
99 TEST(GlobalTest, AlignDeath) {
100   LLVMContext Ctx;
101   std::unique_ptr<Module> M(new Module("TestModule", Ctx));
102   Type *Int32Ty = Type::getInt32Ty(Ctx);
103   GlobalVariable *Var =
104       new GlobalVariable(*M, Int32Ty, true, GlobalValue::ExternalLinkage,
105                          Constant::getAllOnesValue(Int32Ty), "var", nullptr,
106                          GlobalVariable::NotThreadLocal, 1);
107 
108   EXPECT_DEATH(Var->setAlignment(Align(8589934592ULL)),
109                "Alignment is greater than MaximumAlignment");
110 }
111 #endif
112 #endif
113 
114 TEST(ValueTest, printSlots) {
115   // Check that Value::print() and Value::printAsOperand() work with and
116   // without a slot tracker.
117   LLVMContext C;
118 
119   const char *ModuleString = "@g0 = external global %500\n"
120                              "@g1 = external global %900\n"
121                              "\n"
122                              "%900 = type { i32, i32 }\n"
123                              "%500 = type { i32 }\n"
124                              "\n"
125                              "define void @f(i32 %x, i32 %y) {\n"
126                              "entry:\n"
127                              "  %0 = add i32 %y, 1\n"
128                              "  %1 = add i32 %y, 1\n"
129                              "  ret void\n"
130                              "}\n";
131   SMDiagnostic Err;
132   std::unique_ptr<Module> M = parseAssemblyString(ModuleString, Err, C);
133 
134   Function *F = M->getFunction("f");
135   ASSERT_TRUE(F);
136   ASSERT_FALSE(F->empty());
137   BasicBlock &BB = F->getEntryBlock();
138   ASSERT_EQ(3u, BB.size());
139 
140   Instruction *I0 = &*BB.begin();
141   ASSERT_TRUE(I0);
142   Instruction *I1 = &*++BB.begin();
143   ASSERT_TRUE(I1);
144 
145   GlobalVariable *G0 = M->getGlobalVariable("g0");
146   ASSERT_TRUE(G0);
147   GlobalVariable *G1 = M->getGlobalVariable("g1");
148   ASSERT_TRUE(G1);
149 
150   ModuleSlotTracker MST(M.get());
151 
152 #define CHECK_PRINT(INST, STR)                                                 \
153   do {                                                                         \
154     {                                                                          \
155       std::string S;                                                           \
156       raw_string_ostream OS(S);                                                \
157       INST->print(OS);                                                         \
158       EXPECT_EQ(STR, OS.str());                                                \
159     }                                                                          \
160     {                                                                          \
161       std::string S;                                                           \
162       raw_string_ostream OS(S);                                                \
163       INST->print(OS, MST);                                                    \
164       EXPECT_EQ(STR, OS.str());                                                \
165     }                                                                          \
166   } while (false)
167   CHECK_PRINT(I0, "  %0 = add i32 %y, 1");
168   CHECK_PRINT(I1, "  %1 = add i32 %y, 1");
169 #undef CHECK_PRINT
170 
171 #define CHECK_PRINT_AS_OPERAND(INST, TYPE, STR)                                \
172   do {                                                                         \
173     {                                                                          \
174       std::string S;                                                           \
175       raw_string_ostream OS(S);                                                \
176       INST->printAsOperand(OS, TYPE);                                          \
177       EXPECT_EQ(StringRef(STR), StringRef(OS.str()));                          \
178     }                                                                          \
179     {                                                                          \
180       std::string S;                                                           \
181       raw_string_ostream OS(S);                                                \
182       INST->printAsOperand(OS, TYPE, MST);                                     \
183       EXPECT_EQ(StringRef(STR), StringRef(OS.str()));                          \
184     }                                                                          \
185   } while (false)
186   CHECK_PRINT_AS_OPERAND(I0, false, "%0");
187   CHECK_PRINT_AS_OPERAND(I1, false, "%1");
188   CHECK_PRINT_AS_OPERAND(I0, true, "i32 %0");
189   CHECK_PRINT_AS_OPERAND(I1, true, "i32 %1");
190   CHECK_PRINT_AS_OPERAND(G0, true, "ptr @g0");
191   CHECK_PRINT_AS_OPERAND(G1, true, "ptr @g1");
192 #undef CHECK_PRINT_AS_OPERAND
193 }
194 
195 TEST(ValueTest, getLocalSlots) {
196   // Verify that the getLocalSlot method returns the correct slot numbers.
197   LLVMContext C;
198   const char *ModuleString = "define void @f(i32 %x, i32 %y) {\n"
199                              "entry:\n"
200                              "  %0 = add i32 %y, 1\n"
201                              "  %1 = add i32 %y, 1\n"
202                              "  br label %2\n"
203                              "\n"
204                              "  ret void\n"
205                              "}\n";
206   SMDiagnostic Err;
207   std::unique_ptr<Module> M = parseAssemblyString(ModuleString, Err, C);
208 
209   Function *F = M->getFunction("f");
210   ASSERT_TRUE(F);
211   ASSERT_FALSE(F->empty());
212   BasicBlock &EntryBB = F->getEntryBlock();
213   ASSERT_EQ(3u, EntryBB.size());
214   BasicBlock *BB2 = &*++F->begin();
215   ASSERT_TRUE(BB2);
216 
217   Instruction *I0 = &*EntryBB.begin();
218   ASSERT_TRUE(I0);
219   Instruction *I1 = &*++EntryBB.begin();
220   ASSERT_TRUE(I1);
221 
222   ModuleSlotTracker MST(M.get());
223   MST.incorporateFunction(*F);
224   EXPECT_EQ(MST.getLocalSlot(I0), 0);
225   EXPECT_EQ(MST.getLocalSlot(I1), 1);
226   EXPECT_EQ(MST.getLocalSlot(&EntryBB), -1);
227   EXPECT_EQ(MST.getLocalSlot(BB2), 2);
228 }
229 
230 #if defined(GTEST_HAS_DEATH_TEST) && !defined(NDEBUG)
231 TEST(ValueTest, getLocalSlotDeath) {
232   LLVMContext C;
233   const char *ModuleString = "define void @f(i32 %x, i32 %y) {\n"
234                              "entry:\n"
235                              "  %0 = add i32 %y, 1\n"
236                              "  %1 = add i32 %y, 1\n"
237                              "  br label %2\n"
238                              "\n"
239                              "  ret void\n"
240                              "}\n";
241   SMDiagnostic Err;
242   std::unique_ptr<Module> M = parseAssemblyString(ModuleString, Err, C);
243 
244   Function *F = M->getFunction("f");
245   ASSERT_TRUE(F);
246   ASSERT_FALSE(F->empty());
247   BasicBlock *BB2 = &*++F->begin();
248   ASSERT_TRUE(BB2);
249 
250   ModuleSlotTracker MST(M.get());
251   EXPECT_DEATH(MST.getLocalSlot(BB2), "No function incorporated");
252 }
253 #endif
254 
255 TEST(ValueTest, replaceUsesOutsideBlock) {
256   // Check that Value::replaceUsesOutsideBlock(New, BB) replaces uses outside
257   // BB, including dbg.* uses of MetadataAsValue(ValueAsMetadata(this)).
258   const auto *IR = R"(
259     define i32 @f() !dbg !6 {
260     entry:
261       %a = add i32 0, 1, !dbg !15
262       %b = add i32 0, 2, !dbg !15
263       %c = add i32 %a, 2, !dbg !15
264       call void @llvm.dbg.value(metadata i32 %a, metadata !9, metadata !DIExpression()), !dbg !15
265       br label %exit, !dbg !15
266 
267     exit:
268       call void @llvm.dbg.value(metadata i32 %a, metadata !11, metadata !DIExpression()), !dbg !16
269       ret i32 %a, !dbg !16
270     }
271 
272     declare void @llvm.dbg.value(metadata, metadata, metadata)
273 
274     !llvm.dbg.cu = !{!0}
275     !llvm.module.flags = !{!5}
276 
277     !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
278     !1 = !DIFile(filename: "test.ll", directory: "/")
279     !2 = !{}
280     !5 = !{i32 2, !"Debug Info Version", i32 3}
281     !6 = distinct !DISubprogram(name: "f", linkageName: "f", scope: null, file: !1, line: 1, type: !7, isLocal: false, isDefinition: true, scopeLine: 1, isOptimized: true, unit: !0, retainedNodes: !8)
282     !7 = !DISubroutineType(types: !2)
283     !8 = !{!9, !11}
284     !9 = !DILocalVariable(name: "1", scope: !6, file: !1, line: 1, type: !10)
285     !10 = !DIBasicType(name: "ty32", size: 32, encoding: DW_ATE_signed)
286     !11 = !DILocalVariable(name: "2", scope: !6, file: !1, line: 2, type: !12)
287     !12 = !DIBasicType(name: "ty64", size: 64, encoding: DW_ATE_signed)
288     !15 = !DILocation(line: 1, column: 1, scope: !6)
289     !16 = !DILocation(line: 5, column: 1, scope: !6)
290   )";
291   LLVMContext Ctx;
292   SMDiagnostic Err;
293   std::unique_ptr<Module> M = parseAssemblyString(IR, Err, Ctx);
294   if (!M)
295     Err.print("ValueTest", errs());
296 
297   auto GetNext = [](auto *I) { return &*++I->getIterator(); };
298 
299   Function *F = M->getFunction("f");
300   // Entry.
301   BasicBlock *Entry = &F->front();
302   Instruction *A = &Entry->front();
303   Instruction *B = GetNext(A);
304   Instruction *C = GetNext(B);
305   auto *EntryDbg = cast<DbgValueInst>(GetNext(C));
306   // Exit.
307   BasicBlock *Exit = GetNext(Entry);
308   auto *ExitDbg = cast<DbgValueInst>(&Exit->front());
309   Instruction *Ret = GetNext(ExitDbg);
310 
311   A->replaceUsesOutsideBlock(B, Entry);
312   // These users are in Entry so shouldn't be changed.
313   ASSERT_TRUE(C->getOperand(0) == cast<Value>(A));
314   ASSERT_TRUE(EntryDbg->getValue(0) == cast<Value>(A));
315   // These users are outside Entry so should be changed.
316   ASSERT_TRUE(ExitDbg->getValue(0) == cast<Value>(B));
317   ASSERT_TRUE(Ret->getOperand(0) == cast<Value>(B));
318 }
319 
320 TEST(ValueTest, replaceUsesOutsideBlockDPValue) {
321   // Check that Value::replaceUsesOutsideBlock(New, BB) replaces uses outside
322   // BB, including DPValues.
323   const auto *IR = R"(
324     define i32 @f() !dbg !6 {
325     entry:
326       %a = add i32 0, 1, !dbg !15
327       %b = add i32 0, 2, !dbg !15
328       %c = add i32 %a, 2, !dbg !15
329       call void @llvm.dbg.value(metadata i32 %a, metadata !9, metadata !DIExpression()), !dbg !15
330       br label %exit, !dbg !15
331 
332     exit:
333       call void @llvm.dbg.value(metadata i32 %a, metadata !11, metadata !DIExpression()), !dbg !16
334       ret i32 %a, !dbg !16
335     }
336 
337     declare void @llvm.dbg.value(metadata, metadata, metadata)
338 
339     !llvm.dbg.cu = !{!0}
340     !llvm.module.flags = !{!5}
341 
342     !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
343     !1 = !DIFile(filename: "test.ll", directory: "/")
344     !2 = !{}
345     !5 = !{i32 2, !"Debug Info Version", i32 3}
346     !6 = distinct !DISubprogram(name: "f", linkageName: "f", scope: null, file: !1, line: 1, type: !7, isLocal: false, isDefinition: true, scopeLine: 1, isOptimized: true, unit: !0, retainedNodes: !8)
347     !7 = !DISubroutineType(types: !2)
348     !8 = !{!9, !11}
349     !9 = !DILocalVariable(name: "1", scope: !6, file: !1, line: 1, type: !10)
350     !10 = !DIBasicType(name: "ty32", size: 32, encoding: DW_ATE_signed)
351     !11 = !DILocalVariable(name: "2", scope: !6, file: !1, line: 2, type: !12)
352     !12 = !DIBasicType(name: "ty64", size: 64, encoding: DW_ATE_signed)
353     !15 = !DILocation(line: 1, column: 1, scope: !6)
354     !16 = !DILocation(line: 5, column: 1, scope: !6)
355   )";
356   LLVMContext Ctx;
357   SMDiagnostic Err;
358   std::unique_ptr<Module> M = parseAssemblyString(IR, Err, Ctx);
359   if (!M)
360     Err.print("ValueTest", errs());
361 
362   bool OldDbgValueMode = UseNewDbgInfoFormat;
363   UseNewDbgInfoFormat = true;
364   M->convertToNewDbgValues();
365 
366   auto GetNext = [](auto *I) { return &*++I->getIterator(); };
367 
368   Function *F = M->getFunction("f");
369   // Entry.
370   BasicBlock *Entry = &F->front();
371   Instruction *A = &Entry->front();
372   Instruction *B = GetNext(A);
373   Instruction *C = GetNext(B);
374   Instruction *Branch = GetNext(C);
375   // Exit.
376   BasicBlock *Exit = GetNext(Entry);
377   Instruction *Ret = &Exit->front();
378 
379   EXPECT_TRUE(Branch->hasDbgValues());
380   EXPECT_TRUE(Ret->hasDbgValues());
381 
382   DPValue *DPV1 = &*Branch->getDbgValueRange().begin();
383   DPValue *DPV2 = &*Ret->getDbgValueRange().begin();
384 
385   A->replaceUsesOutsideBlock(B, Entry);
386   // These users are in Entry so shouldn't be changed.
387   EXPECT_TRUE(DPV1->getVariableLocationOp(0) == cast<Value>(A));
388   // These users are outside Entry so should be changed.
389   EXPECT_TRUE(DPV2->getVariableLocationOp(0) == cast<Value>(B));
390   UseNewDbgInfoFormat = OldDbgValueMode;
391 }
392 
393 } // end anonymous namespace
394