Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / llvm / unittests / CodeGen / AsmPrinterDwarfTest.cpp
blob32319f1e97587f2a29910529065b5e029fe599ea
1 //===- llvm/unittest/CodeGen/AsmPrinterDwarfTest.cpp ----------------------===//
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 "TestAsmPrinter.h"
10 #include "llvm/BinaryFormat/ELF.h"
11 #include "llvm/CodeGen/AsmPrinter.h"
12 #include "llvm/CodeGen/MachineModuleInfo.h"
13 #include "llvm/IR/LegacyPassManager.h"
14 #include "llvm/IR/Module.h"
15 #include "llvm/IR/PassManager.h"
16 #include "llvm/MC/MCContext.h"
17 #include "llvm/MC/MCSectionELF.h"
18 #include "llvm/Target/TargetMachine.h"
19 #include "llvm/Testing/Support/Error.h"
21 using namespace llvm;
22 using testing::_;
23 using testing::DoAll;
24 using testing::InSequence;
25 using testing::SaveArg;
27 namespace {
29 class AsmPrinterFixtureBase : public testing::Test {
30 void setupTestPrinter(const std::string &TripleStr, unsigned DwarfVersion,
31 dwarf::DwarfFormat DwarfFormat) {
32 auto ExpectedTestPrinter =
33 TestAsmPrinter::create(TripleStr, DwarfVersion, DwarfFormat);
34 ASSERT_THAT_EXPECTED(ExpectedTestPrinter, Succeeded());
35 TestPrinter = std::move(ExpectedTestPrinter.get());
38 protected:
39 bool init(const std::string &TripleStr, unsigned DwarfVersion,
40 dwarf::DwarfFormat DwarfFormat) {
41 setupTestPrinter(TripleStr, DwarfVersion, DwarfFormat);
42 return TestPrinter != nullptr;
45 std::unique_ptr<TestAsmPrinter> TestPrinter;
48 class AsmPrinterEmitDwarfSymbolReferenceTest : public AsmPrinterFixtureBase {
49 protected:
50 bool init(const std::string &TripleStr, unsigned DwarfVersion,
51 dwarf::DwarfFormat DwarfFormat) {
52 if (!AsmPrinterFixtureBase::init(TripleStr, DwarfVersion, DwarfFormat))
53 return false;
55 // AsmPrinter::emitDwarfSymbolReference(Label, true) gets the associated
56 // section from `Label` to find its BeginSymbol.
57 // Prepare the test symbol `Val` accordingly.
59 Val = TestPrinter->getCtx().createTempSymbol();
60 MCSection *Sec =
61 TestPrinter->getCtx().getELFSection(".tst", ELF::SHT_PROGBITS, 0);
62 SecBeginSymbol = Sec->getBeginSymbol();
63 TestPrinter->getMS().switchSection(Sec);
64 Val->setFragment(&Sec->getDummyFragment());
66 return true;
69 MCSymbol *Val = nullptr;
70 MCSymbol *SecBeginSymbol = nullptr;
73 TEST_F(AsmPrinterEmitDwarfSymbolReferenceTest, COFF) {
74 if (!init("x86_64-pc-windows", /*DwarfVersion=*/4, dwarf::DWARF32))
75 GTEST_SKIP();
77 EXPECT_CALL(TestPrinter->getMS(), emitCOFFSecRel32(Val, 0));
78 TestPrinter->getAP()->emitDwarfSymbolReference(Val, false);
81 TEST_F(AsmPrinterEmitDwarfSymbolReferenceTest, COFFForceOffset) {
82 if (!init("x86_64-pc-windows", /*DwarfVersion=*/4, dwarf::DWARF32))
83 GTEST_SKIP();
85 EXPECT_CALL(TestPrinter->getMS(),
86 emitAbsoluteSymbolDiff(Val, SecBeginSymbol, 4));
87 TestPrinter->getAP()->emitDwarfSymbolReference(Val, true);
90 TEST_F(AsmPrinterEmitDwarfSymbolReferenceTest, ELFDWARF32) {
91 if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF32))
92 GTEST_SKIP();
94 const MCExpr *Arg0 = nullptr;
95 EXPECT_CALL(TestPrinter->getMS(), emitValueImpl(_, 4, _))
96 .WillOnce(SaveArg<0>(&Arg0));
97 TestPrinter->getAP()->emitDwarfSymbolReference(Val, false);
99 const MCSymbolRefExpr *ActualArg0 = dyn_cast_or_null<MCSymbolRefExpr>(Arg0);
100 ASSERT_NE(ActualArg0, nullptr);
101 EXPECT_EQ(&(ActualArg0->getSymbol()), Val);
104 TEST_F(AsmPrinterEmitDwarfSymbolReferenceTest, ELFDWARF32ForceOffset) {
105 if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF32))
106 GTEST_SKIP();
108 EXPECT_CALL(TestPrinter->getMS(),
109 emitAbsoluteSymbolDiff(Val, SecBeginSymbol, 4));
110 TestPrinter->getAP()->emitDwarfSymbolReference(Val, true);
113 TEST_F(AsmPrinterEmitDwarfSymbolReferenceTest, ELFDWARF64) {
114 if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF64))
115 GTEST_SKIP();
117 const MCExpr *Arg0 = nullptr;
118 EXPECT_CALL(TestPrinter->getMS(), emitValueImpl(_, 8, _))
119 .WillOnce(SaveArg<0>(&Arg0));
120 TestPrinter->getAP()->emitDwarfSymbolReference(Val, false);
122 const MCSymbolRefExpr *ActualArg0 = dyn_cast_or_null<MCSymbolRefExpr>(Arg0);
123 ASSERT_NE(ActualArg0, nullptr);
124 EXPECT_EQ(&(ActualArg0->getSymbol()), Val);
127 TEST_F(AsmPrinterEmitDwarfSymbolReferenceTest, ELFDWARF64ForceOffset) {
128 if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF64))
129 GTEST_SKIP();
131 EXPECT_CALL(TestPrinter->getMS(),
132 emitAbsoluteSymbolDiff(Val, SecBeginSymbol, 8));
133 TestPrinter->getAP()->emitDwarfSymbolReference(Val, true);
136 class AsmPrinterEmitDwarfStringOffsetTest : public AsmPrinterFixtureBase {
137 protected:
138 bool init(const std::string &TripleStr, unsigned DwarfVersion,
139 dwarf::DwarfFormat DwarfFormat) {
140 if (!AsmPrinterFixtureBase::init(TripleStr, DwarfVersion, DwarfFormat))
141 return false;
143 Val.Index = DwarfStringPoolEntry::NotIndexed;
144 Val.Symbol = TestPrinter->getCtx().createTempSymbol();
145 Val.Offset = 42;
146 return true;
149 DwarfStringPoolEntry Val;
152 TEST_F(AsmPrinterEmitDwarfStringOffsetTest, DWARF32) {
153 if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF32))
154 GTEST_SKIP();
156 const MCExpr *Arg0 = nullptr;
157 EXPECT_CALL(TestPrinter->getMS(), emitValueImpl(_, 4, _))
158 .WillOnce(SaveArg<0>(&Arg0));
159 TestPrinter->getAP()->emitDwarfStringOffset(Val);
161 const MCSymbolRefExpr *ActualArg0 = dyn_cast_or_null<MCSymbolRefExpr>(Arg0);
162 ASSERT_NE(ActualArg0, nullptr);
163 EXPECT_EQ(&(ActualArg0->getSymbol()), Val.Symbol);
166 TEST_F(AsmPrinterEmitDwarfStringOffsetTest,
167 DWARF32NoRelocationsAcrossSections) {
168 if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF32))
169 GTEST_SKIP();
171 TestPrinter->setDwarfUsesRelocationsAcrossSections(false);
172 EXPECT_CALL(TestPrinter->getMS(), emitIntValue(Val.Offset, 4));
173 TestPrinter->getAP()->emitDwarfStringOffset(Val);
176 TEST_F(AsmPrinterEmitDwarfStringOffsetTest, DWARF64) {
177 if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF64))
178 GTEST_SKIP();
180 const MCExpr *Arg0 = nullptr;
181 EXPECT_CALL(TestPrinter->getMS(), emitValueImpl(_, 8, _))
182 .WillOnce(SaveArg<0>(&Arg0));
183 TestPrinter->getAP()->emitDwarfStringOffset(Val);
185 const MCSymbolRefExpr *ActualArg0 = dyn_cast_or_null<MCSymbolRefExpr>(Arg0);
186 ASSERT_NE(ActualArg0, nullptr);
187 EXPECT_EQ(&(ActualArg0->getSymbol()), Val.Symbol);
190 TEST_F(AsmPrinterEmitDwarfStringOffsetTest,
191 DWARF64NoRelocationsAcrossSections) {
192 if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF64))
193 GTEST_SKIP();
195 TestPrinter->setDwarfUsesRelocationsAcrossSections(false);
196 EXPECT_CALL(TestPrinter->getMS(), emitIntValue(Val.Offset, 8));
197 TestPrinter->getAP()->emitDwarfStringOffset(Val);
200 class AsmPrinterEmitDwarfOffsetTest : public AsmPrinterFixtureBase {
201 protected:
202 bool init(const std::string &TripleStr, unsigned DwarfVersion,
203 dwarf::DwarfFormat DwarfFormat) {
204 if (!AsmPrinterFixtureBase::init(TripleStr, DwarfVersion, DwarfFormat))
205 return false;
207 Label = TestPrinter->getCtx().createTempSymbol();
208 return true;
211 MCSymbol *Label = nullptr;
212 uint64_t Offset = 42;
215 TEST_F(AsmPrinterEmitDwarfOffsetTest, DWARF32) {
216 if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF32))
217 GTEST_SKIP();
219 const MCExpr *Arg0 = nullptr;
220 EXPECT_CALL(TestPrinter->getMS(), emitValueImpl(_, 4, _))
221 .WillOnce(SaveArg<0>(&Arg0));
222 TestPrinter->getAP()->emitDwarfOffset(Label, Offset);
224 const MCBinaryExpr *ActualArg0 = dyn_cast_or_null<MCBinaryExpr>(Arg0);
225 ASSERT_NE(ActualArg0, nullptr);
226 EXPECT_EQ(ActualArg0->getOpcode(), MCBinaryExpr::Add);
228 const MCSymbolRefExpr *ActualLHS =
229 dyn_cast_or_null<MCSymbolRefExpr>(ActualArg0->getLHS());
230 ASSERT_NE(ActualLHS, nullptr);
231 EXPECT_EQ(&(ActualLHS->getSymbol()), Label);
233 const MCConstantExpr *ActualRHS =
234 dyn_cast_or_null<MCConstantExpr>(ActualArg0->getRHS());
235 ASSERT_NE(ActualRHS, nullptr);
236 EXPECT_EQ(static_cast<uint64_t>(ActualRHS->getValue()), Offset);
239 TEST_F(AsmPrinterEmitDwarfOffsetTest, DWARF64) {
240 if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF64))
241 GTEST_SKIP();
243 const MCExpr *Arg0 = nullptr;
244 EXPECT_CALL(TestPrinter->getMS(), emitValueImpl(_, 8, _))
245 .WillOnce(SaveArg<0>(&Arg0));
246 TestPrinter->getAP()->emitDwarfOffset(Label, Offset);
248 const MCBinaryExpr *ActualArg0 = dyn_cast_or_null<MCBinaryExpr>(Arg0);
249 ASSERT_NE(ActualArg0, nullptr);
250 EXPECT_EQ(ActualArg0->getOpcode(), MCBinaryExpr::Add);
252 const MCSymbolRefExpr *ActualLHS =
253 dyn_cast_or_null<MCSymbolRefExpr>(ActualArg0->getLHS());
254 ASSERT_NE(ActualLHS, nullptr);
255 EXPECT_EQ(&(ActualLHS->getSymbol()), Label);
257 const MCConstantExpr *ActualRHS =
258 dyn_cast_or_null<MCConstantExpr>(ActualArg0->getRHS());
259 ASSERT_NE(ActualRHS, nullptr);
260 EXPECT_EQ(static_cast<uint64_t>(ActualRHS->getValue()), Offset);
263 class AsmPrinterEmitDwarfLengthOrOffsetTest : public AsmPrinterFixtureBase {
264 protected:
265 uint64_t Val = 42;
268 TEST_F(AsmPrinterEmitDwarfLengthOrOffsetTest, DWARF32) {
269 if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF32))
270 GTEST_SKIP();
272 EXPECT_CALL(TestPrinter->getMS(), emitIntValue(Val, 4));
273 TestPrinter->getAP()->emitDwarfLengthOrOffset(Val);
276 TEST_F(AsmPrinterEmitDwarfLengthOrOffsetTest, DWARF64) {
277 if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF64))
278 GTEST_SKIP();
280 EXPECT_CALL(TestPrinter->getMS(), emitIntValue(Val, 8));
281 TestPrinter->getAP()->emitDwarfLengthOrOffset(Val);
284 class AsmPrinterGetUnitLengthFieldByteSizeTest : public AsmPrinterFixtureBase {
287 TEST_F(AsmPrinterGetUnitLengthFieldByteSizeTest, DWARF32) {
288 if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF32))
289 GTEST_SKIP();
291 EXPECT_EQ(TestPrinter->getAP()->getUnitLengthFieldByteSize(), 4u);
294 TEST_F(AsmPrinterGetUnitLengthFieldByteSizeTest, DWARF64) {
295 if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF64))
296 GTEST_SKIP();
298 EXPECT_EQ(TestPrinter->getAP()->getUnitLengthFieldByteSize(), 12u);
301 class AsmPrinterEmitDwarfUnitLengthAsIntTest : public AsmPrinterFixtureBase {
302 protected:
303 uint64_t Val = 42;
306 TEST_F(AsmPrinterEmitDwarfUnitLengthAsIntTest, DWARF32) {
307 if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF32))
308 GTEST_SKIP();
310 EXPECT_CALL(TestPrinter->getMS(), emitIntValue(Val, 4));
311 TestPrinter->getAP()->emitDwarfUnitLength(Val, "");
314 TEST_F(AsmPrinterEmitDwarfUnitLengthAsIntTest, DWARF64) {
315 if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF64))
316 GTEST_SKIP();
318 InSequence S;
319 EXPECT_CALL(TestPrinter->getMS(), emitIntValue(dwarf::DW_LENGTH_DWARF64, 4));
320 EXPECT_CALL(TestPrinter->getMS(), emitIntValue(Val, 8));
322 TestPrinter->getAP()->emitDwarfUnitLength(Val, "");
325 class AsmPrinterEmitDwarfUnitLengthAsHiLoDiffTest
326 : public AsmPrinterFixtureBase {
327 protected:
328 bool init(const std::string &TripleStr, unsigned DwarfVersion,
329 dwarf::DwarfFormat DwarfFormat) {
330 if (!AsmPrinterFixtureBase::init(TripleStr, DwarfVersion, DwarfFormat))
331 return false;
333 return true;
337 TEST_F(AsmPrinterEmitDwarfUnitLengthAsHiLoDiffTest, DWARF32) {
338 if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF32))
339 GTEST_SKIP();
341 InSequence S;
342 const MCSymbol *Hi = nullptr;
343 const MCSymbol *Lo = nullptr;
344 EXPECT_CALL(TestPrinter->getMS(), emitAbsoluteSymbolDiff(_, _, 4))
345 .WillOnce(DoAll(SaveArg<0>(&Hi), SaveArg<1>(&Lo)));
346 MCSymbol *LTmp = nullptr;
347 EXPECT_CALL(TestPrinter->getMS(), emitLabel(_, _))
348 .WillOnce(SaveArg<0>(&LTmp));
350 MCSymbol *HTmp = TestPrinter->getAP()->emitDwarfUnitLength("", "");
351 EXPECT_NE(Lo, nullptr);
352 EXPECT_EQ(Lo, LTmp);
353 EXPECT_NE(Hi, nullptr);
354 EXPECT_EQ(Hi, HTmp);
357 TEST_F(AsmPrinterEmitDwarfUnitLengthAsHiLoDiffTest, DWARF64) {
358 if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF64))
359 GTEST_SKIP();
361 InSequence S;
362 const MCSymbol *Hi = nullptr;
363 const MCSymbol *Lo = nullptr;
364 EXPECT_CALL(TestPrinter->getMS(), emitIntValue(dwarf::DW_LENGTH_DWARF64, 4));
365 EXPECT_CALL(TestPrinter->getMS(), emitAbsoluteSymbolDiff(_, _, 8))
366 .WillOnce(DoAll(SaveArg<0>(&Hi), SaveArg<1>(&Lo)));
367 MCSymbol *LTmp = nullptr;
368 EXPECT_CALL(TestPrinter->getMS(), emitLabel(_, _))
369 .WillOnce(SaveArg<0>(&LTmp));
371 MCSymbol *HTmp = TestPrinter->getAP()->emitDwarfUnitLength("", "");
372 EXPECT_NE(Lo, nullptr);
373 EXPECT_EQ(Lo, LTmp);
374 EXPECT_NE(Hi, nullptr);
375 EXPECT_EQ(Hi, HTmp);
378 class AsmPrinterHandlerTest : public AsmPrinterFixtureBase {
379 class TestHandler : public AsmPrinterHandler {
380 AsmPrinterHandlerTest &Test;
382 public:
383 TestHandler(AsmPrinterHandlerTest &Test) : Test(Test) {}
384 virtual ~TestHandler() {}
385 virtual void setSymbolSize(const MCSymbol *Sym, uint64_t Size) override {}
386 virtual void beginModule(Module *M) override { Test.BeginCount++; }
387 virtual void endModule() override { Test.EndCount++; }
388 virtual void beginFunction(const MachineFunction *MF) override {}
389 virtual void endFunction(const MachineFunction *MF) override {}
390 virtual void beginInstruction(const MachineInstr *MI) override {}
391 virtual void endInstruction() override {}
394 protected:
395 bool init(const std::string &TripleStr, unsigned DwarfVersion,
396 dwarf::DwarfFormat DwarfFormat) {
397 if (!AsmPrinterFixtureBase::init(TripleStr, DwarfVersion, DwarfFormat))
398 return false;
400 auto *AP = TestPrinter->getAP();
401 AP->addAsmPrinterHandler(AsmPrinter::HandlerInfo(
402 std::unique_ptr<AsmPrinterHandler>(new TestHandler(*this)),
403 "TestTimerName", "TestTimerDesc", "TestGroupName", "TestGroupDesc"));
404 LLVMTargetMachine *LLVMTM = static_cast<LLVMTargetMachine *>(&AP->TM);
405 legacy::PassManager PM;
406 PM.add(new MachineModuleInfoWrapperPass(LLVMTM));
407 PM.add(TestPrinter->releaseAP()); // Takes ownership of destroying AP
408 LLVMContext Context;
409 std::unique_ptr<Module> M(new Module("TestModule", Context));
410 M->setDataLayout(LLVMTM->createDataLayout());
411 PM.run(*M);
412 // Now check that we can run it twice.
413 AP->addAsmPrinterHandler(AsmPrinter::HandlerInfo(
414 std::unique_ptr<AsmPrinterHandler>(new TestHandler(*this)),
415 "TestTimerName", "TestTimerDesc", "TestGroupName", "TestGroupDesc"));
416 PM.run(*M);
417 return true;
420 int BeginCount = 0;
421 int EndCount = 0;
424 TEST_F(AsmPrinterHandlerTest, Basic) {
425 if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF32))
426 GTEST_SKIP();
428 ASSERT_EQ(BeginCount, 3);
429 ASSERT_EQ(EndCount, 3);
432 } // end namespace