Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / llvm / unittests / IR / VerifierTest.cpp
blob2e14bfc42670eb69f515bdc40067ca9e821fd9f1
1 //===- llvm/unittest/IR/VerifierTest.cpp - Verifier unit tests --*- C++ -*-===//
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 //===----------------------------------------------------------------------===//
9 #include "llvm/IR/Verifier.h"
10 #include "llvm/IR/Constants.h"
11 #include "llvm/IR/DIBuilder.h"
12 #include "llvm/IR/DerivedTypes.h"
13 #include "llvm/IR/Function.h"
14 #include "llvm/IR/GlobalAlias.h"
15 #include "llvm/IR/GlobalVariable.h"
16 #include "llvm/IR/IRBuilder.h"
17 #include "llvm/IR/Instructions.h"
18 #include "llvm/IR/LLVMContext.h"
19 #include "llvm/IR/Module.h"
20 #include "gtest/gtest.h"
22 namespace llvm {
23 namespace {
25 TEST(VerifierTest, Branch_i1) {
26 LLVMContext C;
27 Module M("M", C);
28 FunctionType *FTy = FunctionType::get(Type::getVoidTy(C), /*isVarArg=*/false);
29 Function *F = Function::Create(FTy, Function::ExternalLinkage, "foo", M);
30 BasicBlock *Entry = BasicBlock::Create(C, "entry", F);
31 BasicBlock *Exit = BasicBlock::Create(C, "exit", F);
32 ReturnInst::Create(C, Exit);
34 // To avoid triggering an assertion in BranchInst::Create, we first create
35 // a branch with an 'i1' condition ...
37 Constant *False = ConstantInt::getFalse(C);
38 BranchInst *BI = BranchInst::Create(Exit, Exit, False, Entry);
40 // ... then use setOperand to redirect it to a value of different type.
42 Constant *Zero32 = ConstantInt::get(IntegerType::get(C, 32), 0);
43 BI->setOperand(0, Zero32);
45 EXPECT_TRUE(verifyFunction(*F));
48 TEST(VerifierTest, Freeze) {
49 LLVMContext C;
50 Module M("M", C);
51 FunctionType *FTy = FunctionType::get(Type::getVoidTy(C), /*isVarArg=*/false);
52 Function *F = Function::Create(FTy, Function::ExternalLinkage, "foo", M);
53 BasicBlock *Entry = BasicBlock::Create(C, "entry", F);
54 ReturnInst *RI = ReturnInst::Create(C, Entry);
56 IntegerType *ITy = IntegerType::get(C, 32);
57 ConstantInt *CI = ConstantInt::get(ITy, 0);
59 // Valid type : freeze(<2 x i32>)
60 Constant *CV = ConstantVector::getSplat(ElementCount::getFixed(2), CI);
61 FreezeInst *FI_vec = new FreezeInst(CV);
62 FI_vec->insertBefore(RI);
64 EXPECT_FALSE(verifyFunction(*F));
66 FI_vec->eraseFromParent();
68 // Valid type : freeze(float)
69 Constant *CFP = ConstantFP::get(Type::getDoubleTy(C), 0.0);
70 FreezeInst *FI_dbl = new FreezeInst(CFP);
71 FI_dbl->insertBefore(RI);
73 EXPECT_FALSE(verifyFunction(*F));
75 FI_dbl->eraseFromParent();
77 // Valid type : freeze(i32*)
78 PointerType *PT = PointerType::get(ITy, 0);
79 ConstantPointerNull *CPN = ConstantPointerNull::get(PT);
80 FreezeInst *FI_ptr = new FreezeInst(CPN);
81 FI_ptr->insertBefore(RI);
83 EXPECT_FALSE(verifyFunction(*F));
85 FI_ptr->eraseFromParent();
87 // Valid type : freeze(int)
88 FreezeInst *FI = new FreezeInst(CI);
89 FI->insertBefore(RI);
91 EXPECT_FALSE(verifyFunction(*F));
93 FI->eraseFromParent();
96 TEST(VerifierTest, InvalidRetAttribute) {
97 LLVMContext C;
98 Module M("M", C);
99 FunctionType *FTy = FunctionType::get(Type::getInt32Ty(C), /*isVarArg=*/false);
100 Function *F = Function::Create(FTy, Function::ExternalLinkage, "foo", M);
101 AttributeList AS = F->getAttributes();
102 F->setAttributes(AS.addRetAttribute(
103 C, Attribute::getWithUWTableKind(C, UWTableKind::Default)));
105 std::string Error;
106 raw_string_ostream ErrorOS(Error);
107 EXPECT_TRUE(verifyModule(M, &ErrorOS));
108 EXPECT_TRUE(StringRef(ErrorOS.str()).startswith(
109 "Attribute 'uwtable' does not apply to function return values"));
112 /// Test the verifier rejects invalid nofpclass values that the assembler may
113 /// also choose to reject.
114 TEST(VerifierTest, InvalidNoFPClassAttribute) {
115 LLVMContext C;
117 const unsigned InvalidMasks[] = {0, fcAllFlags + 1};
119 for (unsigned InvalidMask : InvalidMasks) {
120 Module M("M", C);
121 FunctionType *FTy =
122 FunctionType::get(Type::getFloatTy(C), /*isVarArg=*/false);
123 Function *F = Function::Create(FTy, Function::ExternalLinkage, "foo", M);
124 AttributeList AS = F->getAttributes();
126 // Don't use getWithNoFPClass to avoid using out of bounds enum values here.
127 F->setAttributes(AS.addRetAttribute(
128 C, Attribute::get(C, Attribute::NoFPClass, InvalidMask)));
130 std::string Error;
131 raw_string_ostream ErrorOS(Error);
132 EXPECT_TRUE(verifyModule(M, &ErrorOS));
134 StringRef ErrMsg(ErrorOS.str());
136 if (InvalidMask == 0) {
137 EXPECT_TRUE(ErrMsg.startswith(
138 "Attribute 'nofpclass' must have at least one test bit set"))
139 << ErrMsg;
140 } else {
141 EXPECT_TRUE(ErrMsg.startswith("Invalid value for 'nofpclass' test mask"))
142 << ErrMsg;
147 TEST(VerifierTest, CrossModuleRef) {
148 LLVMContext C;
149 Module M1("M1", C);
150 Module M2("M2", C);
151 Module M3("M3", C);
152 FunctionType *FTy = FunctionType::get(Type::getInt32Ty(C), /*isVarArg=*/false);
153 Function *F1 = Function::Create(FTy, Function::ExternalLinkage, "foo1", M1);
154 Function *F2 = Function::Create(FTy, Function::ExternalLinkage, "foo2", M2);
155 Function *F3 = Function::Create(FTy, Function::ExternalLinkage, "foo3", M3);
157 BasicBlock *Entry1 = BasicBlock::Create(C, "entry", F1);
158 BasicBlock *Entry3 = BasicBlock::Create(C, "entry", F3);
160 // BAD: Referencing function in another module
161 CallInst::Create(F2,"call",Entry1);
163 // BAD: Referencing personality routine in another module
164 F3->setPersonalityFn(F2);
166 // Fill in the body
167 Constant *ConstZero = ConstantInt::get(Type::getInt32Ty(C), 0);
168 ReturnInst::Create(C, ConstZero, Entry1);
169 ReturnInst::Create(C, ConstZero, Entry3);
171 std::string Error;
172 raw_string_ostream ErrorOS(Error);
173 EXPECT_TRUE(verifyModule(M2, &ErrorOS));
174 EXPECT_TRUE(StringRef(ErrorOS.str())
175 .equals("Global is referenced in a different module!\n"
176 "ptr @foo2\n"
177 "; ModuleID = 'M2'\n"
178 " %call = call i32 @foo2()\n"
179 "ptr @foo1\n"
180 "; ModuleID = 'M1'\n"
181 "Global is used by function in a different module\n"
182 "ptr @foo2\n"
183 "; ModuleID = 'M2'\n"
184 "ptr @foo3\n"
185 "; ModuleID = 'M3'\n"));
187 Error.clear();
188 EXPECT_TRUE(verifyModule(M1, &ErrorOS));
189 EXPECT_TRUE(StringRef(ErrorOS.str()).equals(
190 "Referencing function in another module!\n"
191 " %call = call i32 @foo2()\n"
192 "; ModuleID = 'M1'\n"
193 "ptr @foo2\n"
194 "; ModuleID = 'M2'\n"));
196 Error.clear();
197 EXPECT_TRUE(verifyModule(M3, &ErrorOS));
198 EXPECT_TRUE(StringRef(ErrorOS.str()).startswith(
199 "Referencing personality function in another module!"));
201 // Erase bad methods to avoid triggering an assertion failure on destruction
202 F1->eraseFromParent();
203 F3->eraseFromParent();
206 TEST(VerifierTest, InvalidVariableLinkage) {
207 LLVMContext C;
208 Module M("M", C);
209 new GlobalVariable(M, Type::getInt8Ty(C), false,
210 GlobalValue::LinkOnceODRLinkage, nullptr, "Some Global");
211 std::string Error;
212 raw_string_ostream ErrorOS(Error);
213 EXPECT_TRUE(verifyModule(M, &ErrorOS));
214 EXPECT_TRUE(
215 StringRef(ErrorOS.str()).startswith("Global is external, but doesn't "
216 "have external or weak linkage!"));
219 TEST(VerifierTest, InvalidFunctionLinkage) {
220 LLVMContext C;
221 Module M("M", C);
223 FunctionType *FTy = FunctionType::get(Type::getVoidTy(C), /*isVarArg=*/false);
224 Function::Create(FTy, GlobalValue::LinkOnceODRLinkage, "foo", &M);
225 std::string Error;
226 raw_string_ostream ErrorOS(Error);
227 EXPECT_TRUE(verifyModule(M, &ErrorOS));
228 EXPECT_TRUE(
229 StringRef(ErrorOS.str()).startswith("Global is external, but doesn't "
230 "have external or weak linkage!"));
233 TEST(VerifierTest, DetectInvalidDebugInfo) {
235 LLVMContext C;
236 Module M("M", C);
237 DIBuilder DIB(M);
238 DIB.createCompileUnit(dwarf::DW_LANG_C89, DIB.createFile("broken.c", "/"),
239 "unittest", false, "", 0);
240 DIB.finalize();
241 EXPECT_FALSE(verifyModule(M));
243 // Now break it by inserting non-CU node to the list of CUs.
244 auto *File = DIB.createFile("not-a-CU.f", ".");
245 NamedMDNode *NMD = M.getOrInsertNamedMetadata("llvm.dbg.cu");
246 NMD->addOperand(File);
247 EXPECT_TRUE(verifyModule(M));
250 LLVMContext C;
251 Module M("M", C);
252 DIBuilder DIB(M);
253 auto *CU = DIB.createCompileUnit(dwarf::DW_LANG_C89,
254 DIB.createFile("broken.c", "/"),
255 "unittest", false, "", 0);
256 new GlobalVariable(M, Type::getInt8Ty(C), false,
257 GlobalValue::ExternalLinkage, nullptr, "g");
259 auto *F = Function::Create(FunctionType::get(Type::getVoidTy(C), false),
260 Function::ExternalLinkage, "f", M);
261 IRBuilder<> Builder(BasicBlock::Create(C, "", F));
262 Builder.CreateUnreachable();
263 F->setSubprogram(DIB.createFunction(
264 CU, "f", "f", DIB.createFile("broken.c", "/"), 1, nullptr, 1,
265 DINode::FlagZero,
266 DISubprogram::SPFlagLocalToUnit | DISubprogram::SPFlagDefinition));
267 DIB.finalize();
268 EXPECT_FALSE(verifyModule(M));
270 // Now break it by not listing the CU at all.
271 M.eraseNamedMetadata(M.getOrInsertNamedMetadata("llvm.dbg.cu"));
272 EXPECT_TRUE(verifyModule(M));
276 TEST(VerifierTest, MDNodeWrongContext) {
277 LLVMContext C1, C2;
278 auto *Node = MDNode::get(C1, std::nullopt);
280 Module M("M", C2);
281 auto *NamedNode = M.getOrInsertNamedMetadata("test");
282 NamedNode->addOperand(Node);
284 std::string Error;
285 raw_string_ostream ErrorOS(Error);
286 EXPECT_TRUE(verifyModule(M, &ErrorOS));
287 EXPECT_TRUE(StringRef(ErrorOS.str())
288 .startswith("MDNode context does not match Module context!"));
291 TEST(VerifierTest, AttributesWrongContext) {
292 LLVMContext C1, C2;
293 Module M1("M", C1);
294 FunctionType *FTy1 =
295 FunctionType::get(Type::getVoidTy(C1), /*isVarArg=*/false);
296 Function *F1 = Function::Create(FTy1, Function::ExternalLinkage, "foo", M1);
297 F1->setDoesNotReturn();
299 Module M2("M", C2);
300 FunctionType *FTy2 =
301 FunctionType::get(Type::getVoidTy(C2), /*isVarArg=*/false);
302 Function *F2 = Function::Create(FTy2, Function::ExternalLinkage, "foo", M2);
303 F2->copyAttributesFrom(F1);
305 EXPECT_TRUE(verifyFunction(*F2));
308 TEST(VerifierTest, SwitchInst) {
309 LLVMContext C;
310 Module M("M", C);
311 IntegerType *Int32Ty = Type::getInt32Ty(C);
312 FunctionType *FTy = FunctionType::get(Type::getVoidTy(C), {Int32Ty, Int32Ty},
313 /*isVarArg=*/false);
314 Function *F = Function::Create(FTy, Function::ExternalLinkage, "foo", M);
315 BasicBlock *Entry = BasicBlock::Create(C, "entry", F);
316 BasicBlock *Default = BasicBlock::Create(C, "default", F);
317 BasicBlock *OnOne = BasicBlock::Create(C, "on_one", F);
318 BasicBlock *OnTwo = BasicBlock::Create(C, "on_two", F);
320 BasicBlock *Exit = BasicBlock::Create(C, "exit", F);
322 BranchInst::Create(Exit, Default);
323 BranchInst::Create(Exit, OnTwo);
324 BranchInst::Create(Exit, OnOne);
325 ReturnInst::Create(C, Exit);
327 Value *Cond = F->getArg(0);
328 SwitchInst *Switch = SwitchInst::Create(Cond, Default, 2, Entry);
329 Switch->addCase(ConstantInt::get(Int32Ty, 1), OnOne);
330 Switch->addCase(ConstantInt::get(Int32Ty, 2), OnTwo);
332 EXPECT_FALSE(verifyFunction(*F));
333 // set one case value to function argument.
334 Switch->setOperand(2, F->getArg(1));
335 EXPECT_TRUE(verifyFunction(*F));
338 } // end anonymous namespace
339 } // end namespace llvm