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