xref: /llvm-project/llvm/unittests/IR/AsmWriterTest.cpp (revision 402f90045c3c9a65fd842a2101bd3d9c4d654240)
1 //===- llvm/unittest/IR/AsmWriter.cpp - AsmWriter 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 #include "llvm/BinaryFormat/Dwarf.h"
9 #include "llvm/IR/DebugInfoMetadata.h"
10 #include "llvm/IR/Function.h"
11 #include "llvm/IR/IRBuilder.h"
12 #include "llvm/IR/LLVMContext.h"
13 #include "llvm/IR/MDBuilder.h"
14 #include "llvm/IR/Module.h"
15 #include "gmock/gmock.h"
16 #include "gtest/gtest.h"
17 
18 using namespace llvm;
19 using ::testing::HasSubstr;
20 
21 namespace {
22 
23 TEST(AsmWriterTest, DebugPrintDetachedInstruction) {
24 
25   // PR24852: Ensure that an instruction can be printed even when it
26   // has metadata attached but no parent.
27   LLVMContext Ctx;
28   auto Ty = Type::getInt32Ty(Ctx);
29   auto Poison = PoisonValue::get(Ty);
30   std::unique_ptr<BinaryOperator> Add(BinaryOperator::CreateAdd(Poison, Poison));
31   Add->setMetadata(
32       "", MDNode::get(Ctx, {ConstantAsMetadata::get(ConstantInt::get(Ty, 1))}));
33   std::string S;
34   raw_string_ostream OS(S);
35   Add->print(OS);
36   EXPECT_THAT(OS.str(),
37               HasSubstr("<badref> = add i32 poison, poison, !<empty"));
38 }
39 
40 TEST(AsmWriterTest, DebugPrintDetachedArgument) {
41   LLVMContext Ctx;
42   auto Ty = Type::getInt32Ty(Ctx);
43   auto Arg = new Argument(Ty);
44 
45   std::string S;
46   raw_string_ostream OS(S);
47   Arg->print(OS);
48   EXPECT_EQ(S, "i32 <badref>");
49   delete Arg;
50 }
51 
52 TEST(AsmWriterTest, DumpDIExpression) {
53   LLVMContext Ctx;
54   uint64_t Ops[] = {
55     dwarf::DW_OP_constu, 4,
56     dwarf::DW_OP_minus,
57     dwarf::DW_OP_deref,
58   };
59   DIExpression *Expr = DIExpression::get(Ctx, Ops);
60   std::string S;
61   raw_string_ostream OS(S);
62   Expr->print(OS);
63   EXPECT_EQ("!DIExpression(DW_OP_constu, 4, DW_OP_minus, DW_OP_deref)",
64             OS.str());
65 }
66 
67 TEST(AsmWriterTest, PrintAddrspaceWithNullOperand) {
68   LLVMContext Ctx;
69   Module M("test module", Ctx);
70   SmallVector<Type *, 3> FArgTypes;
71   FArgTypes.push_back(Type::getInt64Ty(Ctx));
72   FunctionType *FTy = FunctionType::get(Type::getVoidTy(Ctx), FArgTypes, false);
73   Function *F = Function::Create(FTy, Function::ExternalLinkage, "", &M);
74   Argument *Arg0 = F->getArg(0);
75   Value *Args[] = {Arg0};
76   std::unique_ptr<CallInst> Call(CallInst::Create(F, Args));
77   // This will make Call's operand null.
78   Call->dropAllReferences();
79 
80   std::string S;
81   raw_string_ostream OS(S);
82   Call->print(OS);
83   EXPECT_THAT(OS.str(), HasSubstr("<cannot get addrspace!>"));
84 }
85 
86 TEST(AsmWriterTest, PrintNullOperandBundle) {
87   LLVMContext C;
88   Type *Int32Ty = Type::getInt32Ty(C);
89   FunctionType *FnTy = FunctionType::get(Int32Ty, Int32Ty, /*isVarArg=*/false);
90   Value *Callee = Constant::getNullValue(FnTy->getPointerTo());
91   Value *Args[] = {ConstantInt::get(Int32Ty, 42)};
92   std::unique_ptr<BasicBlock> NormalDest(BasicBlock::Create(C));
93   std::unique_ptr<BasicBlock> UnwindDest(BasicBlock::Create(C));
94   OperandBundleDef Bundle("bundle", UndefValue::get(Int32Ty));
95   std::unique_ptr<InvokeInst> Invoke(
96       InvokeInst::Create(FnTy, Callee, NormalDest.get(), UnwindDest.get(), Args,
97                          Bundle, "result"));
98   // Makes the operand bundle null.
99   Invoke->dropAllReferences();
100   Invoke->setNormalDest(NormalDest.get());
101   Invoke->setUnwindDest(UnwindDest.get());
102 
103   std::string S;
104   raw_string_ostream OS(S);
105   Invoke->print(OS);
106   EXPECT_THAT(OS.str(), HasSubstr("<null operand bundle!>"));
107 }
108 }
109