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/LLVMContext.h"
13 #include "llvm/IR/Module.h"
14 #include "llvm/IR/ModuleSlotTracker.h"
15 #include "llvm/Support/SourceMgr.h"
16 #include "gtest/gtest.h"
17 using namespace llvm;
18 
19 namespace {
20 
21 TEST(ValueTest, UsedInBasicBlock) {
22   LLVMContext C;
23 
24   const char *ModuleString = "define void @f(i32 %x, i32 %y) {\n"
25                              "bb0:\n"
26                              "  %y1 = add i32 %y, 1\n"
27                              "  %y2 = add i32 %y, 1\n"
28                              "  %y3 = add i32 %y, 1\n"
29                              "  %y4 = add i32 %y, 1\n"
30                              "  %y5 = add i32 %y, 1\n"
31                              "  %y6 = add i32 %y, 1\n"
32                              "  %y7 = add i32 %y, 1\n"
33                              "  %y8 = add i32 %x, 1\n"
34                              "  ret void\n"
35                              "}\n";
36   SMDiagnostic Err;
37   std::unique_ptr<Module> M = parseAssemblyString(ModuleString, Err, C);
38 
39   Function *F = M->getFunction("f");
40 
41   EXPECT_FALSE(F->isUsedInBasicBlock(&F->front()));
42   EXPECT_TRUE(std::next(F->arg_begin())->isUsedInBasicBlock(&F->front()));
43   EXPECT_TRUE(F->arg_begin()->isUsedInBasicBlock(&F->front()));
44 }
45 
46 TEST(GlobalTest, CreateAddressSpace) {
47   LLVMContext Ctx;
48   std::unique_ptr<Module> M(new Module("TestModule", Ctx));
49   Type *Int8Ty = Type::getInt8Ty(Ctx);
50   Type *Int32Ty = Type::getInt32Ty(Ctx);
51 
52   GlobalVariable *Dummy0
53     = new GlobalVariable(*M,
54                          Int32Ty,
55                          true,
56                          GlobalValue::ExternalLinkage,
57                          Constant::getAllOnesValue(Int32Ty),
58                          "dummy",
59                          nullptr,
60                          GlobalVariable::NotThreadLocal,
61                          1);
62 
63   EXPECT_TRUE(Value::MaximumAlignment == 536870912U);
64   Dummy0->setAlignment(Align(536870912));
65   EXPECT_EQ(Dummy0->getAlignment(), 536870912U);
66 
67   // Make sure the address space isn't dropped when returning this.
68   Constant *Dummy1 = M->getOrInsertGlobal("dummy", Int32Ty);
69   EXPECT_EQ(Dummy0, Dummy1);
70   EXPECT_EQ(1u, Dummy1->getType()->getPointerAddressSpace());
71 
72 
73   // This one requires a bitcast, but the address space must also stay the same.
74   GlobalVariable *DummyCast0
75     = new GlobalVariable(*M,
76                          Int32Ty,
77                          true,
78                          GlobalValue::ExternalLinkage,
79                          Constant::getAllOnesValue(Int32Ty),
80                          "dummy_cast",
81                          nullptr,
82                          GlobalVariable::NotThreadLocal,
83                          1);
84 
85   // Make sure the address space isn't dropped when returning this.
86   Constant *DummyCast1 = M->getOrInsertGlobal("dummy_cast", Int8Ty);
87   EXPECT_EQ(1u, DummyCast1->getType()->getPointerAddressSpace());
88   EXPECT_NE(DummyCast0, DummyCast1) << *DummyCast1;
89 }
90 
91 #ifdef GTEST_HAS_DEATH_TEST
92 #ifndef NDEBUG
93 
94 TEST(GlobalTest, AlignDeath) {
95   LLVMContext Ctx;
96   std::unique_ptr<Module> M(new Module("TestModule", Ctx));
97   Type *Int32Ty = Type::getInt32Ty(Ctx);
98   GlobalVariable *Var =
99       new GlobalVariable(*M, Int32Ty, true, GlobalValue::ExternalLinkage,
100                          Constant::getAllOnesValue(Int32Ty), "var", nullptr,
101                          GlobalVariable::NotThreadLocal, 1);
102 
103   EXPECT_DEATH(Var->setAlignment(Align(1073741824U)),
104                "Alignment is greater than MaximumAlignment");
105 }
106 #endif
107 #endif
108 
109 TEST(ValueTest, printSlots) {
110   // Check that Value::print() and Value::printAsOperand() work with and
111   // without a slot tracker.
112   LLVMContext C;
113 
114   const char *ModuleString = "@g0 = external global %500\n"
115                              "@g1 = external global %900\n"
116                              "\n"
117                              "%900 = type { i32, i32 }\n"
118                              "%500 = type { i32 }\n"
119                              "\n"
120                              "define void @f(i32 %x, i32 %y) {\n"
121                              "entry:\n"
122                              "  %0 = add i32 %y, 1\n"
123                              "  %1 = add i32 %y, 1\n"
124                              "  ret void\n"
125                              "}\n";
126   SMDiagnostic Err;
127   std::unique_ptr<Module> M = parseAssemblyString(ModuleString, Err, C);
128 
129   Function *F = M->getFunction("f");
130   ASSERT_TRUE(F);
131   ASSERT_FALSE(F->empty());
132   BasicBlock &BB = F->getEntryBlock();
133   ASSERT_EQ(3u, BB.size());
134 
135   Instruction *I0 = &*BB.begin();
136   ASSERT_TRUE(I0);
137   Instruction *I1 = &*++BB.begin();
138   ASSERT_TRUE(I1);
139 
140   GlobalVariable *G0 = M->getGlobalVariable("g0");
141   ASSERT_TRUE(G0);
142   GlobalVariable *G1 = M->getGlobalVariable("g1");
143   ASSERT_TRUE(G1);
144 
145   ModuleSlotTracker MST(M.get());
146 
147 #define CHECK_PRINT(INST, STR)                                                 \
148   do {                                                                         \
149     {                                                                          \
150       std::string S;                                                           \
151       raw_string_ostream OS(S);                                                \
152       INST->print(OS);                                                         \
153       EXPECT_EQ(STR, OS.str());                                                \
154     }                                                                          \
155     {                                                                          \
156       std::string S;                                                           \
157       raw_string_ostream OS(S);                                                \
158       INST->print(OS, MST);                                                    \
159       EXPECT_EQ(STR, OS.str());                                                \
160     }                                                                          \
161   } while (false)
162   CHECK_PRINT(I0, "  %0 = add i32 %y, 1");
163   CHECK_PRINT(I1, "  %1 = add i32 %y, 1");
164 #undef CHECK_PRINT
165 
166 #define CHECK_PRINT_AS_OPERAND(INST, TYPE, STR)                                \
167   do {                                                                         \
168     {                                                                          \
169       std::string S;                                                           \
170       raw_string_ostream OS(S);                                                \
171       INST->printAsOperand(OS, TYPE);                                          \
172       EXPECT_EQ(StringRef(STR), StringRef(OS.str()));                          \
173     }                                                                          \
174     {                                                                          \
175       std::string S;                                                           \
176       raw_string_ostream OS(S);                                                \
177       INST->printAsOperand(OS, TYPE, MST);                                     \
178       EXPECT_EQ(StringRef(STR), StringRef(OS.str()));                          \
179     }                                                                          \
180   } while (false)
181   CHECK_PRINT_AS_OPERAND(I0, false, "%0");
182   CHECK_PRINT_AS_OPERAND(I1, false, "%1");
183   CHECK_PRINT_AS_OPERAND(I0, true, "i32 %0");
184   CHECK_PRINT_AS_OPERAND(I1, true, "i32 %1");
185   CHECK_PRINT_AS_OPERAND(G0, true, "%0* @g0");
186   CHECK_PRINT_AS_OPERAND(G1, true, "%1* @g1");
187 #undef CHECK_PRINT_AS_OPERAND
188 }
189 
190 TEST(ValueTest, getLocalSlots) {
191   // Verify that the getLocalSlot method returns the correct slot numbers.
192   LLVMContext C;
193   const char *ModuleString = "define void @f(i32 %x, i32 %y) {\n"
194                              "entry:\n"
195                              "  %0 = add i32 %y, 1\n"
196                              "  %1 = add i32 %y, 1\n"
197                              "  br label %2\n"
198                              "\n"
199                              "  ret void\n"
200                              "}\n";
201   SMDiagnostic Err;
202   std::unique_ptr<Module> M = parseAssemblyString(ModuleString, Err, C);
203 
204   Function *F = M->getFunction("f");
205   ASSERT_TRUE(F);
206   ASSERT_FALSE(F->empty());
207   BasicBlock &EntryBB = F->getEntryBlock();
208   ASSERT_EQ(3u, EntryBB.size());
209   BasicBlock *BB2 = &*++F->begin();
210   ASSERT_TRUE(BB2);
211 
212   Instruction *I0 = &*EntryBB.begin();
213   ASSERT_TRUE(I0);
214   Instruction *I1 = &*++EntryBB.begin();
215   ASSERT_TRUE(I1);
216 
217   ModuleSlotTracker MST(M.get());
218   MST.incorporateFunction(*F);
219   EXPECT_EQ(MST.getLocalSlot(I0), 0);
220   EXPECT_EQ(MST.getLocalSlot(I1), 1);
221   EXPECT_EQ(MST.getLocalSlot(&EntryBB), -1);
222   EXPECT_EQ(MST.getLocalSlot(BB2), 2);
223 }
224 
225 #if defined(GTEST_HAS_DEATH_TEST) && !defined(NDEBUG)
226 TEST(ValueTest, getLocalSlotDeath) {
227   LLVMContext C;
228   const char *ModuleString = "define void @f(i32 %x, i32 %y) {\n"
229                              "entry:\n"
230                              "  %0 = add i32 %y, 1\n"
231                              "  %1 = add i32 %y, 1\n"
232                              "  br label %2\n"
233                              "\n"
234                              "  ret void\n"
235                              "}\n";
236   SMDiagnostic Err;
237   std::unique_ptr<Module> M = parseAssemblyString(ModuleString, Err, C);
238 
239   Function *F = M->getFunction("f");
240   ASSERT_TRUE(F);
241   ASSERT_FALSE(F->empty());
242   BasicBlock *BB2 = &*++F->begin();
243   ASSERT_TRUE(BB2);
244 
245   ModuleSlotTracker MST(M.get());
246   EXPECT_DEATH(MST.getLocalSlot(BB2), "No function incorporated");
247 }
248 #endif
249 
250 } // end anonymous namespace
251