xref: /llvm-project/llvm/unittests/MIR/MachineMetadata.cpp (revision bb3f5e1fed7c6ba733b7f273e93f5d3930976185)
1b9c05affSMichael Liao //===- MachineInstrBundleIteratorTest.cpp ---------------------------------===//
2b9c05affSMichael Liao //
3b9c05affSMichael Liao // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4b9c05affSMichael Liao // See https://llvm.org/LICENSE.txt for license information.
5b9c05affSMichael Liao // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6b9c05affSMichael Liao //
7b9c05affSMichael Liao //===----------------------------------------------------------------------===//
8b9c05affSMichael Liao 
9aba43035SDmitri Gribenko #include "llvm/ADT/STLExtras.h"
10b9c05affSMichael Liao #include "llvm/CodeGen/MIRParser/MIRParser.h"
11b9c05affSMichael Liao #include "llvm/CodeGen/MIRPrinter.h"
12b9c05affSMichael Liao #include "llvm/CodeGen/MachineFunction.h"
13b9c05affSMichael Liao #include "llvm/CodeGen/MachineMemOperand.h"
14b9c05affSMichael Liao #include "llvm/CodeGen/MachineModuleInfo.h"
15b9c05affSMichael Liao #include "llvm/CodeGen/MachineModuleSlotTracker.h"
16b9c05affSMichael Liao #include "llvm/CodeGen/MachineOperand.h"
17b9c05affSMichael Liao #include "llvm/CodeGen/TargetFrameLowering.h"
18b9c05affSMichael Liao #include "llvm/CodeGen/TargetInstrInfo.h"
19b9c05affSMichael Liao #include "llvm/CodeGen/TargetLowering.h"
20b9c05affSMichael Liao #include "llvm/CodeGen/TargetSubtargetInfo.h"
21b9c05affSMichael Liao #include "llvm/FileCheck/FileCheck.h"
22b9c05affSMichael Liao #include "llvm/IR/MDBuilder.h"
234169338eSNikita Popov #include "llvm/IR/Module.h"
24b9c05affSMichael Liao #include "llvm/IR/ModuleSlotTracker.h"
25b9c05affSMichael Liao #include "llvm/MC/MCAsmInfo.h"
2689b57061SReid Kleckner #include "llvm/MC/TargetRegistry.h"
27b9c05affSMichael Liao #include "llvm/Support/SourceMgr.h"
28b9c05affSMichael Liao #include "llvm/Support/TargetSelect.h"
29b9c05affSMichael Liao #include "llvm/Target/TargetMachine.h"
30b9c05affSMichael Liao #include "gtest/gtest.h"
31b9c05affSMichael Liao 
32b9c05affSMichael Liao using namespace llvm;
33b9c05affSMichael Liao 
34b9c05affSMichael Liao class MachineMetadataTest : public testing::Test {
35b9c05affSMichael Liao public:
36b9c05affSMichael Liao   MachineMetadataTest() {}
37b9c05affSMichael Liao 
38b9c05affSMichael Liao protected:
39b9c05affSMichael Liao   LLVMContext Context;
40b9c05affSMichael Liao   std::unique_ptr<Module> M;
41b9c05affSMichael Liao   std::unique_ptr<MIRParser> MIR;
42b9c05affSMichael Liao 
43b9c05affSMichael Liao   static void SetUpTestCase() {
44b9c05affSMichael Liao     InitializeAllTargetInfos();
45b9c05affSMichael Liao     InitializeAllTargets();
46b9c05affSMichael Liao     InitializeAllTargetMCs();
47b9c05affSMichael Liao   }
48b9c05affSMichael Liao 
49b9c05affSMichael Liao   void SetUp() override { M = std::make_unique<Module>("Dummy", Context); }
50b9c05affSMichael Liao 
51b9c05affSMichael Liao   void addHooks(ModuleSlotTracker &MST, const MachineOperand &MO) {
52b9c05affSMichael Liao     // Setup hooks to assign slot numbers for the specified machine metadata.
53b9c05affSMichael Liao     MST.setProcessHook([&MO](AbstractSlotTrackerStorage *AST, const Module *M,
54b9c05affSMichael Liao                              bool ShouldInitializeAllMetadata) {
55b9c05affSMichael Liao       if (ShouldInitializeAllMetadata) {
56b9c05affSMichael Liao         if (MO.isMetadata())
57b9c05affSMichael Liao           AST->createMetadataSlot(MO.getMetadata());
58b9c05affSMichael Liao       }
59b9c05affSMichael Liao     });
60b9c05affSMichael Liao     MST.setProcessHook([&MO](AbstractSlotTrackerStorage *AST, const Function *F,
61b9c05affSMichael Liao                              bool ShouldInitializeAllMetadata) {
62b9c05affSMichael Liao       if (!ShouldInitializeAllMetadata) {
63b9c05affSMichael Liao         if (MO.isMetadata())
64b9c05affSMichael Liao           AST->createMetadataSlot(MO.getMetadata());
65b9c05affSMichael Liao       }
66b9c05affSMichael Liao     });
67b9c05affSMichael Liao   }
68b9c05affSMichael Liao 
69*bb3f5e1fSMatin Raayai   std::unique_ptr<TargetMachine>
70b9c05affSMichael Liao   createTargetMachine(std::string TT, StringRef CPU, StringRef FS) {
71b9c05affSMichael Liao     std::string Error;
72b9c05affSMichael Liao     const Target *T = TargetRegistry::lookupTarget(TT, Error);
73b9c05affSMichael Liao     if (!T)
74b9c05affSMichael Liao       return nullptr;
75b9c05affSMichael Liao     TargetOptions Options;
76*bb3f5e1fSMatin Raayai     return std::unique_ptr<TargetMachine>(T->createTargetMachine(
77*bb3f5e1fSMatin Raayai         TT, CPU, FS, Options, std::nullopt, std::nullopt));
78b9c05affSMichael Liao   }
79b9c05affSMichael Liao 
80b9c05affSMichael Liao   std::unique_ptr<Module> parseMIR(const TargetMachine &TM, StringRef MIRCode,
8138c3855cSKyungwoo Lee                                    MachineModuleInfo &MMI) {
82b9c05affSMichael Liao     SMDiagnostic Diagnostic;
83b9c05affSMichael Liao     std::unique_ptr<MemoryBuffer> MBuffer = MemoryBuffer::getMemBuffer(MIRCode);
84b9c05affSMichael Liao     MIR = createMIRParser(std::move(MBuffer), Context);
85b9c05affSMichael Liao     if (!MIR)
86b9c05affSMichael Liao       return nullptr;
87b9c05affSMichael Liao 
88b9c05affSMichael Liao     std::unique_ptr<Module> Mod = MIR->parseIRModule();
89b9c05affSMichael Liao     if (!Mod)
90b9c05affSMichael Liao       return nullptr;
91b9c05affSMichael Liao 
92b9c05affSMichael Liao     Mod->setDataLayout(TM.createDataLayout());
93b9c05affSMichael Liao 
94b9c05affSMichael Liao     if (MIR->parseMachineFunctions(*Mod, MMI)) {
95b9c05affSMichael Liao       M.reset();
96b9c05affSMichael Liao       return nullptr;
97b9c05affSMichael Liao     }
98b9c05affSMichael Liao 
99b9c05affSMichael Liao     return Mod;
100b9c05affSMichael Liao   }
101b9c05affSMichael Liao };
102b9c05affSMichael Liao 
103b9c05affSMichael Liao // Helper to dump the printer output into a string.
104b9c05affSMichael Liao static std::string print(std::function<void(raw_ostream &OS)> PrintFn) {
105b9c05affSMichael Liao   std::string Str;
106b9c05affSMichael Liao   raw_string_ostream OS(Str);
107b9c05affSMichael Liao   PrintFn(OS);
108b9c05affSMichael Liao   return Str;
109b9c05affSMichael Liao }
110b9c05affSMichael Liao 
111b9c05affSMichael Liao TEST_F(MachineMetadataTest, TrivialHook) {
112b9c05affSMichael Liao   // Verify that post-process hook is invoked to assign slot numbers for
113b9c05affSMichael Liao   // machine metadata.
114b9c05affSMichael Liao   ASSERT_TRUE(M);
115b9c05affSMichael Liao 
116b9c05affSMichael Liao   // Create a MachineOperand with a metadata and print it.
117b9c05affSMichael Liao   Metadata *MDS = MDString::get(Context, "foo");
118b9c05affSMichael Liao   MDNode *Node = MDNode::get(Context, MDS);
119b9c05affSMichael Liao   MachineOperand MO = MachineOperand::CreateMetadata(Node);
120b9c05affSMichael Liao 
121b9c05affSMichael Liao   // Checking some preconditions on the newly created
122b9c05affSMichael Liao   // MachineOperand.
123b9c05affSMichael Liao   ASSERT_TRUE(MO.isMetadata());
124b9c05affSMichael Liao   ASSERT_EQ(MO.getMetadata(), Node);
125b9c05affSMichael Liao 
126b9c05affSMichael Liao   ModuleSlotTracker MST(M.get());
127b9c05affSMichael Liao   addHooks(MST, MO);
128b9c05affSMichael Liao 
129b9c05affSMichael Liao   // Print a MachineOperand containing a metadata node.
130b9c05affSMichael Liao   EXPECT_EQ("!0", print([&](raw_ostream &OS) {
131b9c05affSMichael Liao               MO.print(OS, MST, LLT{}, /*OpIdx*/ ~0U, /*PrintDef=*/false,
132b9c05affSMichael Liao                        /*IsStandalone=*/false,
133b9c05affSMichael Liao                        /*ShouldPrintRegisterTies=*/false, /*TiedOperandIdx=*/0,
134b9c05affSMichael Liao                        /*TRI=*/nullptr,
135b9c05affSMichael Liao                        /*IntrinsicInfo=*/nullptr);
136b9c05affSMichael Liao             }));
137b9c05affSMichael Liao   // Print the definition of that metadata node.
138b9c05affSMichael Liao   EXPECT_EQ("!0 = !{!\"foo\"}",
139b9c05affSMichael Liao             print([&](raw_ostream &OS) { Node->print(OS, MST); }));
140b9c05affSMichael Liao }
141b9c05affSMichael Liao 
142b9c05affSMichael Liao TEST_F(MachineMetadataTest, BasicHook) {
143b9c05affSMichael Liao   // Verify that post-process hook is invoked to assign slot numbers for
144b9c05affSMichael Liao   // machine metadata. When both LLVM IR and machine IR contain metadata,
145b9c05affSMichael Liao   // ensure that machine metadata is always assigned after LLVM IR.
146b9c05affSMichael Liao   ASSERT_TRUE(M);
147b9c05affSMichael Liao 
148b9c05affSMichael Liao   // Create a MachineOperand with a metadata and print it.
149b9c05affSMichael Liao   Metadata *MachineMDS = MDString::get(Context, "foo");
150b9c05affSMichael Liao   MDNode *MachineNode = MDNode::get(Context, MachineMDS);
151b9c05affSMichael Liao   MachineOperand MO = MachineOperand::CreateMetadata(MachineNode);
152b9c05affSMichael Liao 
153b9c05affSMichael Liao   // Checking some preconditions on the newly created
154b9c05affSMichael Liao   // MachineOperand.
155b9c05affSMichael Liao   ASSERT_TRUE(MO.isMetadata());
156b9c05affSMichael Liao   ASSERT_EQ(MO.getMetadata(), MachineNode);
157b9c05affSMichael Liao 
158b9c05affSMichael Liao   // Create metadata in LLVM IR.
159b9c05affSMichael Liao   NamedMDNode *MD = M->getOrInsertNamedMetadata("namedmd");
160b9c05affSMichael Liao   Metadata *MDS = MDString::get(Context, "bar");
161b9c05affSMichael Liao   MDNode *Node = MDNode::get(Context, MDS);
162b9c05affSMichael Liao   MD->addOperand(Node);
163b9c05affSMichael Liao 
164b9c05affSMichael Liao   ModuleSlotTracker MST(M.get());
165b9c05affSMichael Liao   addHooks(MST, MO);
166b9c05affSMichael Liao 
167b9c05affSMichael Liao   // Print a MachineOperand containing a metadata node.
168b9c05affSMichael Liao   EXPECT_EQ("!1", print([&](raw_ostream &OS) {
169b9c05affSMichael Liao               MO.print(OS, MST, LLT{}, /*OpIdx*/ ~0U, /*PrintDef=*/false,
170b9c05affSMichael Liao                        /*IsStandalone=*/false,
171b9c05affSMichael Liao                        /*ShouldPrintRegisterTies=*/false, /*TiedOperandIdx=*/0,
172b9c05affSMichael Liao                        /*TRI=*/nullptr,
173b9c05affSMichael Liao                        /*IntrinsicInfo=*/nullptr);
174b9c05affSMichael Liao             }));
175b9c05affSMichael Liao   // Print the definition of these unnamed metadata nodes.
176b9c05affSMichael Liao   EXPECT_EQ("!0 = !{!\"bar\"}",
177b9c05affSMichael Liao             print([&](raw_ostream &OS) { Node->print(OS, MST); }));
178b9c05affSMichael Liao   EXPECT_EQ("!1 = !{!\"foo\"}",
179b9c05affSMichael Liao             print([&](raw_ostream &OS) { MachineNode->print(OS, MST); }));
180b9c05affSMichael Liao }
181b9c05affSMichael Liao 
182b9c05affSMichael Liao static bool checkOutput(std::string CheckString, std::string Output) {
183b9c05affSMichael Liao   auto CheckBuffer = MemoryBuffer::getMemBuffer(CheckString, "");
184b9c05affSMichael Liao   auto OutputBuffer = MemoryBuffer::getMemBuffer(Output, "Output", false);
185b9c05affSMichael Liao 
186b9c05affSMichael Liao   SmallString<4096> CheckFileBuffer;
187b9c05affSMichael Liao   FileCheckRequest Req;
188b9c05affSMichael Liao   FileCheck FC(Req);
18975bc20ffSKazu Hirata   StringRef CheckFileText = FC.CanonicalizeFile(*CheckBuffer, CheckFileBuffer);
190b9c05affSMichael Liao 
191b9c05affSMichael Liao   SourceMgr SM;
192b9c05affSMichael Liao   SM.AddNewSourceBuffer(MemoryBuffer::getMemBuffer(CheckFileText, "CheckFile"),
193b9c05affSMichael Liao                         SMLoc());
194261b4710SNikita Popov   if (FC.readCheckFile(SM, CheckFileText))
195b9c05affSMichael Liao     return false;
196b9c05affSMichael Liao 
197b9c05affSMichael Liao   auto OutBuffer = OutputBuffer->getBuffer();
198b9c05affSMichael Liao   SM.AddNewSourceBuffer(std::move(OutputBuffer), SMLoc());
199b9c05affSMichael Liao   return FC.checkInput(SM, OutBuffer);
200b9c05affSMichael Liao }
201b9c05affSMichael Liao 
202b9c05affSMichael Liao TEST_F(MachineMetadataTest, MMSlotTrackerAArch64) {
203b9c05affSMichael Liao   auto TM = createTargetMachine(Triple::normalize("aarch64--"), "", "");
204b9c05affSMichael Liao   if (!TM)
205b9c05affSMichael Liao     GTEST_SKIP();
206b9c05affSMichael Liao 
207b9c05affSMichael Liao   StringRef MIRString = R"MIR(
208b9c05affSMichael Liao --- |
209b9c05affSMichael Liao   define i32 @test0(i32* %p) {
210b9c05affSMichael Liao     %r = load i32, i32* %p, align 4
211b9c05affSMichael Liao     ret i32 %r
212b9c05affSMichael Liao   }
213b9c05affSMichael Liao ...
214b9c05affSMichael Liao ---
215b9c05affSMichael Liao name:            test0
216b9c05affSMichael Liao liveins:
217b9c05affSMichael Liao   - { reg: '$x0', virtual-reg: '%0' }
218b9c05affSMichael Liao body:             |
219b9c05affSMichael Liao   bb.0 (%ir-block.0):
220b9c05affSMichael Liao     liveins: $x0
221b9c05affSMichael Liao 
222b9c05affSMichael Liao   %0:gpr64common = COPY $x0
223fae05692SMatt Arsenault   %1:gpr32 = LDRWui %0, 0 :: (load (s32) from %ir.p)
224b9c05affSMichael Liao ...
225b9c05affSMichael Liao )MIR";
226b9c05affSMichael Liao 
227b9c05affSMichael Liao   MachineModuleInfo MMI(TM.get());
22838c3855cSKyungwoo Lee   M = parseMIR(*TM, MIRString, MMI);
229b9c05affSMichael Liao   ASSERT_TRUE(M);
230b9c05affSMichael Liao 
231b9c05affSMichael Liao   auto *MF = MMI.getMachineFunction(*M->getFunction("test0"));
232b9c05affSMichael Liao   auto *MBB = MF->getBlockNumbered(0);
233b9c05affSMichael Liao 
234b9c05affSMichael Liao   auto &MI = MBB->back();
235b9c05affSMichael Liao   ASSERT_TRUE(MI.hasOneMemOperand());
236b9c05affSMichael Liao 
237b9c05affSMichael Liao   // Create and attached scoped AA metadata on that instruction with one MMO.
238b9c05affSMichael Liao   MDBuilder MDB(Context);
239b9c05affSMichael Liao   MDNode *Domain = MDB.createAnonymousAliasScopeDomain("domain");
240b9c05affSMichael Liao   MDNode *Scope0 = MDB.createAnonymousAliasScope(Domain, "scope0");
241b9c05affSMichael Liao   MDNode *Scope1 = MDB.createAnonymousAliasScope(Domain, "scope1");
242b9c05affSMichael Liao   MDNode *Set0 = MDNode::get(Context, {Scope0});
243b9c05affSMichael Liao   MDNode *Set1 = MDNode::get(Context, {Scope1});
244b9c05affSMichael Liao 
245b9c05affSMichael Liao   AAMDNodes AAInfo;
246b9c05affSMichael Liao   AAInfo.TBAA = AAInfo.TBAAStruct = nullptr;
247b9c05affSMichael Liao   AAInfo.Scope = Set0;
248b9c05affSMichael Liao   AAInfo.NoAlias = Set1;
249b9c05affSMichael Liao 
250b9c05affSMichael Liao   auto *OldMMO = MI.memoperands().front();
251b9c05affSMichael Liao   auto *NewMMO = MF->getMachineMemOperand(OldMMO, AAInfo);
252b9c05affSMichael Liao   MI.setMemRefs(*MF, NewMMO);
253b9c05affSMichael Liao 
2549a258664SMatt Arsenault   MachineModuleSlotTracker MST(MMI, MF);
255b9c05affSMichael Liao   // Print that MI with new machine metadata, which slot numbers should be
256b9c05affSMichael Liao   // assigned.
257fae05692SMatt Arsenault   EXPECT_EQ("%1:gpr32 = LDRWui %0, 0 :: (load (s32) from %ir.p, "
258b9c05affSMichael Liao             "!alias.scope !0, !noalias !3)",
259b9c05affSMichael Liao             print([&](raw_ostream &OS) {
260b9c05affSMichael Liao               MI.print(OS, MST, /*IsStandalone=*/false, /*SkipOpers=*/false,
261b9c05affSMichael Liao                        /*SkipDebugLoc=*/false, /*AddNewLine=*/false);
262b9c05affSMichael Liao             }));
263b9c05affSMichael Liao 
264b9c05affSMichael Liao   std::vector<const MDNode *> Generated{Domain, Scope0, Scope1, Set0, Set1};
265b9c05affSMichael Liao   // Examine machine metadata collected. They should match ones
266b9c05affSMichael Liao   // afore-generated.
267b9c05affSMichael Liao   std::vector<const MDNode *> Collected;
268b9c05affSMichael Liao   MachineModuleSlotTracker::MachineMDNodeListType MDList;
269b9c05affSMichael Liao   MST.collectMachineMDNodes(MDList);
270b9c05affSMichael Liao   for (auto &MD : MDList)
271b9c05affSMichael Liao     Collected.push_back(MD.second);
272b9c05affSMichael Liao 
273aba43035SDmitri Gribenko   llvm::sort(Generated);
274aba43035SDmitri Gribenko   llvm::sort(Collected);
275b9c05affSMichael Liao   EXPECT_EQ(Collected, Generated);
276b9c05affSMichael Liao 
277b9c05affSMichael Liao   // FileCheck the output from MIR printer.
2789a258664SMatt Arsenault   std::string Output = print([&](raw_ostream &OS) { printMIR(OS, MMI, *MF); });
279b9c05affSMichael Liao   std::string CheckString = R"(
280b9c05affSMichael Liao CHECK: machineMetadataNodes:
281b9c05affSMichael Liao CHECK-DAG: ![[MMDOMAIN:[0-9]+]] = distinct !{!{{[0-9]+}}, !"domain"}
282b9c05affSMichael Liao CHECK-DAG: ![[MMSCOPE0:[0-9]+]] = distinct !{!{{[0-9]+}}, ![[MMDOMAIN]], !"scope0"}
283b9c05affSMichael Liao CHECK-DAG: ![[MMSCOPE1:[0-9]+]] = distinct !{!{{[0-9]+}}, ![[MMDOMAIN]], !"scope1"}
284b9c05affSMichael Liao CHECK-DAG: ![[MMSET0:[0-9]+]] = !{![[MMSCOPE0]]}
285b9c05affSMichael Liao CHECK-DAG: ![[MMSET1:[0-9]+]] = !{![[MMSCOPE1]]}
286b9c05affSMichael Liao CHECK: body:
287fae05692SMatt Arsenault CHECK: %1:gpr32 = LDRWui %0, 0 :: (load (s32) from %ir.p, !alias.scope ![[MMSET0]], !noalias ![[MMSET1]])
288b9c05affSMichael Liao )";
289b9c05affSMichael Liao   EXPECT_TRUE(checkOutput(CheckString, Output));
290b9c05affSMichael Liao }
291b9c05affSMichael Liao 
292edff0070SShengchen Kan TEST_F(MachineMetadataTest, isMetaInstruction) {
293edff0070SShengchen Kan   auto TM = createTargetMachine(Triple::normalize("x86_64--"), "", "");
294edff0070SShengchen Kan   if (!TM)
295edff0070SShengchen Kan     GTEST_SKIP();
296edff0070SShengchen Kan 
297edff0070SShengchen Kan   StringRef MIRString = R"MIR(
298edff0070SShengchen Kan --- |
299edff0070SShengchen Kan   define void @test0(i32 %b) {
300edff0070SShengchen Kan     ret void
301edff0070SShengchen Kan   }
302edff0070SShengchen Kan   !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
303edff0070SShengchen Kan   !1 = !DIFile(filename: "a.c", directory: "/tmp")
304edff0070SShengchen Kan   !2 = !{i32 7, !"Dwarf Version", i32 4}
305edff0070SShengchen Kan   !3 = !{i32 2, !"Debug Info Version", i32 3}
306edff0070SShengchen Kan   !4 = !{i32 1, !"wchar_size", i32 4}
307edff0070SShengchen Kan   !5 = !{i32 7, !"uwtable", i32 1}
308edff0070SShengchen Kan   !6 = !{i32 7, !"frame-pointer", i32 2}
309edff0070SShengchen Kan   !7 = !{!""}
310edff0070SShengchen Kan   !8 = distinct !DISubprogram(name: "test0", scope: !1, file: !1, line: 1, type: !9, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !12)
311edff0070SShengchen Kan   !9 = !DISubroutineType(types: !10)
312edff0070SShengchen Kan   !10 = !{null, !11}
313edff0070SShengchen Kan   !11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
314edff0070SShengchen Kan   !12 = !{}
315edff0070SShengchen Kan   !13 = !DILocalVariable(name: "b", arg: 1, scope: !8, file: !1, line: 1, type: !11)
316edff0070SShengchen Kan   !14 = !DILocation(line: 1, column: 16, scope: !8)
317edff0070SShengchen Kan ...
318edff0070SShengchen Kan ---
319edff0070SShengchen Kan name:            test0
320edff0070SShengchen Kan machineFunctionInfo
321edff0070SShengchen Kan body:             |
322edff0070SShengchen Kan   bb.0:
323edff0070SShengchen Kan   $rdi = IMPLICIT_DEF
324edff0070SShengchen Kan   KILL $rsi
325edff0070SShengchen Kan   CFI_INSTRUCTION undefined $rax
326edff0070SShengchen Kan   EH_LABEL 0
327edff0070SShengchen Kan   GC_LABEL 0
328edff0070SShengchen Kan   DBG_VALUE $rax, $noreg, !13, !DIExpression(), debug-location !14
329edff0070SShengchen Kan   DBG_LABEL 0
330edff0070SShengchen Kan   LIFETIME_START 0
331edff0070SShengchen Kan   LIFETIME_END 0
332edff0070SShengchen Kan   PSEUDO_PROBE 6699318081062747564, 1, 0, 0
333edff0070SShengchen Kan   $xmm0 = ARITH_FENCE $xmm0
334eb442269SPhilip Reames   MEMBARRIER
335edff0070SShengchen Kan ...
336edff0070SShengchen Kan )MIR";
337edff0070SShengchen Kan 
338edff0070SShengchen Kan   MachineModuleInfo MMI(TM.get());
33938c3855cSKyungwoo Lee   M = parseMIR(*TM, MIRString, MMI);
340edff0070SShengchen Kan   ASSERT_TRUE(M);
341edff0070SShengchen Kan 
342edff0070SShengchen Kan   auto *MF = MMI.getMachineFunction(*M->getFunction("test0"));
343edff0070SShengchen Kan   auto *MBB = MF->getBlockNumbered(0);
344edff0070SShengchen Kan 
345edff0070SShengchen Kan   for (auto It = MBB->begin(); It != MBB->end(); ++It) {
346edff0070SShengchen Kan     MachineInstr &MI = *It;
347edff0070SShengchen Kan     ASSERT_TRUE(MI.isMetaInstruction());
348edff0070SShengchen Kan   }
349edff0070SShengchen Kan }
350edff0070SShengchen Kan 
351b9c05affSMichael Liao TEST_F(MachineMetadataTest, MMSlotTrackerX64) {
352b9c05affSMichael Liao   auto TM = createTargetMachine(Triple::normalize("x86_64--"), "", "");
353b9c05affSMichael Liao   if (!TM)
354b9c05affSMichael Liao     GTEST_SKIP();
355b9c05affSMichael Liao 
356b9c05affSMichael Liao   StringRef MIRString = R"MIR(
357b9c05affSMichael Liao --- |
358b9c05affSMichael Liao   define i32 @test0(i32* %p) {
359b9c05affSMichael Liao     %r = load i32, i32* %p, align 4
360b9c05affSMichael Liao     ret i32 %r
361b9c05affSMichael Liao   }
362b9c05affSMichael Liao ...
363b9c05affSMichael Liao ---
364b9c05affSMichael Liao name:            test0
365b9c05affSMichael Liao liveins:
366b9c05affSMichael Liao   - { reg: '$rdi', virtual-reg: '%0' }
367b9c05affSMichael Liao body:             |
368b9c05affSMichael Liao   bb.0 (%ir-block.0):
369b9c05affSMichael Liao     liveins: $rdi
370b9c05affSMichael Liao 
371b9c05affSMichael Liao   %0:gr64 = COPY $rdi
372fae05692SMatt Arsenault   %1:gr32 = MOV32rm %0, 1, $noreg, 0, $noreg :: (load (s32) from %ir.p)
373b9c05affSMichael Liao ...
374b9c05affSMichael Liao )MIR";
375b9c05affSMichael Liao 
376b9c05affSMichael Liao   MachineModuleInfo MMI(TM.get());
37738c3855cSKyungwoo Lee   M = parseMIR(*TM, MIRString, MMI);
378b9c05affSMichael Liao   ASSERT_TRUE(M);
379b9c05affSMichael Liao 
380b9c05affSMichael Liao   auto *MF = MMI.getMachineFunction(*M->getFunction("test0"));
381b9c05affSMichael Liao   auto *MBB = MF->getBlockNumbered(0);
382b9c05affSMichael Liao 
383b9c05affSMichael Liao   auto &MI = MBB->back();
384b9c05affSMichael Liao   ASSERT_FALSE(MI.memoperands_empty());
385b9c05affSMichael Liao   ASSERT_TRUE(MI.hasOneMemOperand());
386b9c05affSMichael Liao 
387b9c05affSMichael Liao   // Create and attached scoped AA metadata on that instruction with one MMO.
388b9c05affSMichael Liao   MDBuilder MDB(Context);
389b9c05affSMichael Liao   MDNode *Domain = MDB.createAnonymousAliasScopeDomain("domain");
390b9c05affSMichael Liao   MDNode *Scope0 = MDB.createAnonymousAliasScope(Domain, "scope0");
391b9c05affSMichael Liao   MDNode *Scope1 = MDB.createAnonymousAliasScope(Domain, "scope1");
392b9c05affSMichael Liao   MDNode *Set0 = MDNode::get(Context, {Scope0});
393b9c05affSMichael Liao   MDNode *Set1 = MDNode::get(Context, {Scope1});
394b9c05affSMichael Liao 
395b9c05affSMichael Liao   AAMDNodes AAInfo;
396b9c05affSMichael Liao   AAInfo.TBAA = AAInfo.TBAAStruct = nullptr;
397b9c05affSMichael Liao   AAInfo.Scope = Set0;
398b9c05affSMichael Liao   AAInfo.NoAlias = Set1;
399b9c05affSMichael Liao 
400b9c05affSMichael Liao   auto *OldMMO = MI.memoperands().front();
401b9c05affSMichael Liao   auto *NewMMO = MF->getMachineMemOperand(OldMMO, AAInfo);
402b9c05affSMichael Liao   MI.setMemRefs(*MF, NewMMO);
403b9c05affSMichael Liao 
4049a258664SMatt Arsenault   MachineModuleSlotTracker MST(MMI, MF);
405b9c05affSMichael Liao   // Print that MI with new machine metadata, which slot numbers should be
406b9c05affSMichael Liao   // assigned.
407fae05692SMatt Arsenault   EXPECT_EQ("%1:gr32 = MOV32rm %0, 1, $noreg, 0, $noreg :: (load (s32) from %ir.p, "
408b9c05affSMichael Liao             "!alias.scope !0, !noalias !3)",
409b9c05affSMichael Liao             print([&](raw_ostream &OS) {
410b9c05affSMichael Liao               MI.print(OS, MST, /*IsStandalone=*/false, /*SkipOpers=*/false,
411b9c05affSMichael Liao                        /*SkipDebugLoc=*/false, /*AddNewLine=*/false);
412b9c05affSMichael Liao             }));
413b9c05affSMichael Liao 
414b9c05affSMichael Liao   std::vector<const MDNode *> Generated{Domain, Scope0, Scope1, Set0, Set1};
415b9c05affSMichael Liao   // Examine machine metadata collected. They should match ones
416b9c05affSMichael Liao   // afore-generated.
417b9c05affSMichael Liao   std::vector<const MDNode *> Collected;
418b9c05affSMichael Liao   MachineModuleSlotTracker::MachineMDNodeListType MDList;
419b9c05affSMichael Liao   MST.collectMachineMDNodes(MDList);
420b9c05affSMichael Liao   for (auto &MD : MDList)
421b9c05affSMichael Liao     Collected.push_back(MD.second);
422b9c05affSMichael Liao 
423aba43035SDmitri Gribenko   llvm::sort(Generated);
424aba43035SDmitri Gribenko   llvm::sort(Collected);
425b9c05affSMichael Liao   EXPECT_EQ(Collected, Generated);
426b9c05affSMichael Liao 
427b9c05affSMichael Liao   // FileCheck the output from MIR printer.
4289a258664SMatt Arsenault   std::string Output = print([&](raw_ostream &OS) { printMIR(OS, MMI, *MF); });
429b9c05affSMichael Liao   std::string CheckString = R"(
430b9c05affSMichael Liao CHECK: machineMetadataNodes:
431b9c05affSMichael Liao CHECK-DAG: ![[MMDOMAIN:[0-9]+]] = distinct !{!{{[0-9]+}}, !"domain"}
432b9c05affSMichael Liao CHECK-DAG: ![[MMSCOPE0:[0-9]+]] = distinct !{!{{[0-9]+}}, ![[MMDOMAIN]], !"scope0"}
433b9c05affSMichael Liao CHECK-DAG: ![[MMSCOPE1:[0-9]+]] = distinct !{!{{[0-9]+}}, ![[MMDOMAIN]], !"scope1"}
434b9c05affSMichael Liao CHECK-DAG: ![[MMSET0:[0-9]+]] = !{![[MMSCOPE0]]}
435b9c05affSMichael Liao CHECK-DAG: ![[MMSET1:[0-9]+]] = !{![[MMSCOPE1]]}
436b9c05affSMichael Liao CHECK: body:
437fae05692SMatt Arsenault CHECK: %1:gr32 = MOV32rm %0, 1, $noreg, 0, $noreg :: (load (s32) from %ir.p, !alias.scope ![[MMSET0]], !noalias ![[MMSET1]])
438b9c05affSMichael Liao )";
439b9c05affSMichael Liao   EXPECT_TRUE(checkOutput(CheckString, Output));
440b9c05affSMichael Liao }
441b9c05affSMichael Liao 
442b9c05affSMichael Liao TEST_F(MachineMetadataTest, MMSlotTrackerAMDGPU) {
443b9c05affSMichael Liao   auto TM = createTargetMachine(Triple::normalize("amdgcn-amd-amdhsa"),
444b9c05affSMichael Liao                                 "gfx1010", "");
445b9c05affSMichael Liao   if (!TM)
446b9c05affSMichael Liao     GTEST_SKIP();
447b9c05affSMichael Liao 
448b9c05affSMichael Liao   StringRef MIRString = R"MIR(
449b9c05affSMichael Liao --- |
450b9c05affSMichael Liao   define i32 @test0(i32* %p) {
451b9c05affSMichael Liao     %r = load i32, i32* %p, align 4
452b9c05affSMichael Liao     ret i32 %r
453b9c05affSMichael Liao   }
454b9c05affSMichael Liao ...
455b9c05affSMichael Liao ---
456b9c05affSMichael Liao name:            test0
457b9c05affSMichael Liao liveins:
458b9c05affSMichael Liao   - { reg: '$vgpr0', virtual-reg: '%0' }
459b9c05affSMichael Liao   - { reg: '$vgpr1', virtual-reg: '%1' }
460b9c05affSMichael Liao   - { reg: '$sgpr30_sgpr31', virtual-reg: '%2' }
461b9c05affSMichael Liao body:             |
462b9c05affSMichael Liao   bb.0 (%ir-block.0):
463b9c05affSMichael Liao     liveins: $vgpr0, $vgpr1, $sgpr30_sgpr31
464b9c05affSMichael Liao 
465b9c05affSMichael Liao     %2:sreg_64 = COPY $sgpr30_sgpr31
466b9c05affSMichael Liao     %1:vgpr_32 = COPY $vgpr1
467b9c05affSMichael Liao     %0:vgpr_32 = COPY $vgpr0
468b9c05affSMichael Liao     %8:vreg_64 = REG_SEQUENCE %0, %subreg.sub0, %1, %subreg.sub1
469b9c05affSMichael Liao     %6:vreg_64 = COPY %8
470fae05692SMatt Arsenault     %5:vgpr_32 = FLAT_LOAD_DWORD killed %6, 0, 0, implicit $exec, implicit $flat_scr :: (load (s32) from %ir.p)
471b9c05affSMichael Liao ...
472b9c05affSMichael Liao )MIR";
473b9c05affSMichael Liao 
474b9c05affSMichael Liao   MachineModuleInfo MMI(TM.get());
47538c3855cSKyungwoo Lee   M = parseMIR(*TM, MIRString, MMI);
476b9c05affSMichael Liao   ASSERT_TRUE(M);
477b9c05affSMichael Liao 
478b9c05affSMichael Liao   auto *MF = MMI.getMachineFunction(*M->getFunction("test0"));
479b9c05affSMichael Liao   auto *MBB = MF->getBlockNumbered(0);
480b9c05affSMichael Liao 
481b9c05affSMichael Liao   auto &MI = MBB->back();
482b9c05affSMichael Liao   ASSERT_FALSE(MI.memoperands_empty());
483b9c05affSMichael Liao   ASSERT_TRUE(MI.hasOneMemOperand());
484b9c05affSMichael Liao 
485b9c05affSMichael Liao   // Create and attached scoped AA metadata on that instruction with one MMO.
486b9c05affSMichael Liao   MDBuilder MDB(Context);
487b9c05affSMichael Liao   MDNode *Domain = MDB.createAnonymousAliasScopeDomain("domain");
488b9c05affSMichael Liao   MDNode *Scope0 = MDB.createAnonymousAliasScope(Domain, "scope0");
489b9c05affSMichael Liao   MDNode *Scope1 = MDB.createAnonymousAliasScope(Domain, "scope1");
490b9c05affSMichael Liao   MDNode *Set0 = MDNode::get(Context, {Scope0});
491b9c05affSMichael Liao   MDNode *Set1 = MDNode::get(Context, {Scope1});
492b9c05affSMichael Liao 
493b9c05affSMichael Liao   AAMDNodes AAInfo;
494b9c05affSMichael Liao   AAInfo.TBAA = AAInfo.TBAAStruct = nullptr;
495b9c05affSMichael Liao   AAInfo.Scope = Set0;
496b9c05affSMichael Liao   AAInfo.NoAlias = Set1;
497b9c05affSMichael Liao 
498b9c05affSMichael Liao   auto *OldMMO = MI.memoperands().front();
499b9c05affSMichael Liao   auto *NewMMO = MF->getMachineMemOperand(OldMMO, AAInfo);
500b9c05affSMichael Liao   MI.setMemRefs(*MF, NewMMO);
501b9c05affSMichael Liao 
5029a258664SMatt Arsenault   MachineModuleSlotTracker MST(MMI, MF);
503b9c05affSMichael Liao   // Print that MI with new machine metadata, which slot numbers should be
504b9c05affSMichael Liao   // assigned.
505b9c05affSMichael Liao   EXPECT_EQ(
506b9c05affSMichael Liao       "%5:vgpr_32 = FLAT_LOAD_DWORD killed %4, 0, 0, implicit $exec, implicit "
507fae05692SMatt Arsenault       "$flat_scr :: (load (s32) from %ir.p, !alias.scope !0, !noalias !3)",
508b9c05affSMichael Liao       print([&](raw_ostream &OS) {
509b9c05affSMichael Liao         MI.print(OS, MST, /*IsStandalone=*/false, /*SkipOpers=*/false,
510b9c05affSMichael Liao                  /*SkipDebugLoc=*/false, /*AddNewLine=*/false);
511b9c05affSMichael Liao       }));
512b9c05affSMichael Liao 
513b9c05affSMichael Liao   std::vector<const MDNode *> Generated{Domain, Scope0, Scope1, Set0, Set1};
514b9c05affSMichael Liao   // Examine machine metadata collected. They should match ones
515b9c05affSMichael Liao   // afore-generated.
516b9c05affSMichael Liao   std::vector<const MDNode *> Collected;
517b9c05affSMichael Liao   MachineModuleSlotTracker::MachineMDNodeListType MDList;
518b9c05affSMichael Liao   MST.collectMachineMDNodes(MDList);
519b9c05affSMichael Liao   for (auto &MD : MDList)
520b9c05affSMichael Liao     Collected.push_back(MD.second);
521b9c05affSMichael Liao 
522aba43035SDmitri Gribenko   llvm::sort(Generated);
523aba43035SDmitri Gribenko   llvm::sort(Collected);
524b9c05affSMichael Liao   EXPECT_EQ(Collected, Generated);
525b9c05affSMichael Liao 
526b9c05affSMichael Liao   // FileCheck the output from MIR printer.
5279a258664SMatt Arsenault   std::string Output = print([&](raw_ostream &OS) { printMIR(OS, MMI, *MF); });
528b9c05affSMichael Liao   std::string CheckString = R"(
529b9c05affSMichael Liao CHECK: machineMetadataNodes:
530b9c05affSMichael Liao CHECK-DAG: ![[MMDOMAIN:[0-9]+]] = distinct !{!{{[0-9]+}}, !"domain"}
531b9c05affSMichael Liao CHECK-DAG: ![[MMSCOPE0:[0-9]+]] = distinct !{!{{[0-9]+}}, ![[MMDOMAIN]], !"scope0"}
532b9c05affSMichael Liao CHECK-DAG: ![[MMSCOPE1:[0-9]+]] = distinct !{!{{[0-9]+}}, ![[MMDOMAIN]], !"scope1"}
533b9c05affSMichael Liao CHECK-DAG: ![[MMSET0:[0-9]+]] = !{![[MMSCOPE0]]}
534b9c05affSMichael Liao CHECK-DAG: ![[MMSET1:[0-9]+]] = !{![[MMSCOPE1]]}
535b9c05affSMichael Liao CHECK: body:
536fae05692SMatt Arsenault CHECK: %5:vgpr_32 = FLAT_LOAD_DWORD killed %4, 0, 0, implicit $exec, implicit $flat_scr :: (load (s32) from %ir.p, !alias.scope ![[MMSET0]], !noalias ![[MMSET1]])
537b9c05affSMichael Liao )";
538b9c05affSMichael Liao   EXPECT_TRUE(checkOutput(CheckString, Output));
539b9c05affSMichael Liao }
540b206ee69SKai Luo 
541b206ee69SKai Luo TEST_F(MachineMetadataTest, TiedOpsRewritten) {
542b206ee69SKai Luo   auto TM = createTargetMachine(Triple::normalize("powerpc64--"), "", "");
543b206ee69SKai Luo   if (!TM)
544b206ee69SKai Luo     GTEST_SKIP();
545b206ee69SKai Luo   StringRef MIRString = R"MIR(
546b206ee69SKai Luo ---
547b206ee69SKai Luo name:            foo
548b206ee69SKai Luo alignment:       16
549b206ee69SKai Luo tracksRegLiveness: true
550b206ee69SKai Luo frameInfo:
551b206ee69SKai Luo   maxAlignment:    16
552b206ee69SKai Luo machineFunctionInfo: {}
553b206ee69SKai Luo body:             |
554b206ee69SKai Luo   bb.0:
555b206ee69SKai Luo     liveins: $r3
556b206ee69SKai Luo     %0:gprc = COPY $r3
557b206ee69SKai Luo     %0 = RLWIMI killed %0, $r3, 1, 0, 30
558b206ee69SKai Luo     $r3 = COPY %0
559b206ee69SKai Luo     BLR8 implicit $r3, implicit $lr8, implicit $rm
560b206ee69SKai Luo 
561b206ee69SKai Luo ...
562b206ee69SKai Luo )MIR";
563b206ee69SKai Luo   MachineModuleInfo MMI(TM.get());
56438c3855cSKyungwoo Lee   M = parseMIR(*TM, MIRString, MMI);
565b206ee69SKai Luo   ASSERT_TRUE(M);
566b206ee69SKai Luo   auto *MF = MMI.getMachineFunction(*M->getFunction("foo"));
567b206ee69SKai Luo   MachineFunctionProperties &Properties = MF->getProperties();
568b206ee69SKai Luo   ASSERT_TRUE(Properties.hasProperty(
569b206ee69SKai Luo       MachineFunctionProperties::Property::TiedOpsRewritten));
570b206ee69SKai Luo }
571b206ee69SKai Luo 
572b206ee69SKai Luo TEST_F(MachineMetadataTest, NoTiedOpsRewritten) {
573b206ee69SKai Luo   auto TM = createTargetMachine(Triple::normalize("powerpc64--"), "", "");
574b206ee69SKai Luo   if (!TM)
575b206ee69SKai Luo     GTEST_SKIP();
576b206ee69SKai Luo   StringRef MIRString = R"MIR(
577b206ee69SKai Luo ---
578b206ee69SKai Luo name:            foo
579b206ee69SKai Luo alignment:       16
580b206ee69SKai Luo tracksRegLiveness: true
581b206ee69SKai Luo frameInfo:
582b206ee69SKai Luo   maxAlignment:    16
583b206ee69SKai Luo machineFunctionInfo: {}
584b206ee69SKai Luo body:             |
585b206ee69SKai Luo   bb.0:
586b206ee69SKai Luo     liveins: $r3
587b206ee69SKai Luo     %0:gprc = COPY $r3
588b206ee69SKai Luo     %1:gprc = RLWIMI killed %0, $r3, 1, 0, 30
589b206ee69SKai Luo     $r3 = COPY %1
590b206ee69SKai Luo     BLR8 implicit $r3, implicit $lr8, implicit $rm
591b206ee69SKai Luo 
592b206ee69SKai Luo ...
593b206ee69SKai Luo )MIR";
594b206ee69SKai Luo   MachineModuleInfo MMI(TM.get());
59538c3855cSKyungwoo Lee   M = parseMIR(*TM, MIRString, MMI);
596b206ee69SKai Luo   ASSERT_TRUE(M);
597b206ee69SKai Luo   auto *MF = MMI.getMachineFunction(*M->getFunction("foo"));
598b206ee69SKai Luo   MachineFunctionProperties &Properties = MF->getProperties();
599b206ee69SKai Luo   ASSERT_FALSE(Properties.hasProperty(
600b206ee69SKai Luo       MachineFunctionProperties::Property::TiedOpsRewritten));
601b206ee69SKai Luo }
602