161f48ca3SMarcello Maggioni //===- MachineOperandTest.cpp ---------------------------------===//
261f48ca3SMarcello Maggioni //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
661f48ca3SMarcello Maggioni //
761f48ca3SMarcello Maggioni //===----------------------------------------------------------------------===//
861f48ca3SMarcello Maggioni 
961f48ca3SMarcello Maggioni #include "llvm/CodeGen/MachineOperand.h"
105df3bbf3SFrancis Visoiu Mistrih #include "llvm/ADT/ilist_node.h"
116c4ca713SFrancis Visoiu Mistrih #include "llvm/IR/Constants.h"
12cb2683d4SFrancis Visoiu Mistrih #include "llvm/IR/InstrTypes.h"
136c4ca713SFrancis Visoiu Mistrih #include "llvm/IR/LLVMContext.h"
145df3bbf3SFrancis Visoiu Mistrih #include "llvm/IR/Module.h"
15440f69c9SFrancis Visoiu Mistrih #include "llvm/IR/ModuleSlotTracker.h"
163c99371cSFrancis Visoiu Mistrih #include "llvm/MC/MCAsmInfo.h"
17*ed98c1b3Sserge-sans-paille #include "llvm/MC/MCContext.h"
18*ed98c1b3Sserge-sans-paille #include "llvm/Support/LowLevelTypeImpl.h"
19a8a83d15SFrancis Visoiu Mistrih #include "llvm/Support/raw_ostream.h"
2061f48ca3SMarcello Maggioni #include "gtest/gtest.h"
2161f48ca3SMarcello Maggioni 
2261f48ca3SMarcello Maggioni using namespace llvm;
2361f48ca3SMarcello Maggioni 
2461f48ca3SMarcello Maggioni namespace {
2561f48ca3SMarcello Maggioni 
TEST(MachineOperandTest,ChangeToTargetIndexTest)2661f48ca3SMarcello Maggioni TEST(MachineOperandTest, ChangeToTargetIndexTest) {
2761f48ca3SMarcello Maggioni   // Creating a MachineOperand to change it to TargetIndex
2861f48ca3SMarcello Maggioni   MachineOperand MO = MachineOperand::CreateImm(50);
2961f48ca3SMarcello Maggioni 
3061f48ca3SMarcello Maggioni   // Checking some precondition on the newly created
3161f48ca3SMarcello Maggioni   // MachineOperand.
3261f48ca3SMarcello Maggioni   ASSERT_TRUE(MO.isImm());
3361f48ca3SMarcello Maggioni   ASSERT_TRUE(MO.getImm() == 50);
3461f48ca3SMarcello Maggioni   ASSERT_FALSE(MO.isTargetIndex());
3561f48ca3SMarcello Maggioni 
3661f48ca3SMarcello Maggioni   // Changing to TargetIndex with some arbitrary values
3761f48ca3SMarcello Maggioni   // for index, offset and flags.
3861f48ca3SMarcello Maggioni   MO.ChangeToTargetIndex(74, 57, 12);
3961f48ca3SMarcello Maggioni 
4061f48ca3SMarcello Maggioni   // Checking that the mutation to TargetIndex happened
4161f48ca3SMarcello Maggioni   // correctly.
4261f48ca3SMarcello Maggioni   ASSERT_TRUE(MO.isTargetIndex());
4361f48ca3SMarcello Maggioni   ASSERT_TRUE(MO.getIndex() == 74);
4461f48ca3SMarcello Maggioni   ASSERT_TRUE(MO.getOffset() == 57);
4561f48ca3SMarcello Maggioni   ASSERT_TRUE(MO.getTargetFlags() == 12);
4661f48ca3SMarcello Maggioni }
4761f48ca3SMarcello Maggioni 
TEST(MachineOperandTest,PrintRegisterMask)48a8a83d15SFrancis Visoiu Mistrih TEST(MachineOperandTest, PrintRegisterMask) {
49a8a83d15SFrancis Visoiu Mistrih   uint32_t Dummy;
50a8a83d15SFrancis Visoiu Mistrih   MachineOperand MO = MachineOperand::CreateRegMask(&Dummy);
51a8a83d15SFrancis Visoiu Mistrih 
52a8a83d15SFrancis Visoiu Mistrih   // Checking some preconditions on the newly created
53a8a83d15SFrancis Visoiu Mistrih   // MachineOperand.
54a8a83d15SFrancis Visoiu Mistrih   ASSERT_TRUE(MO.isRegMask());
55a8a83d15SFrancis Visoiu Mistrih   ASSERT_TRUE(MO.getRegMask() == &Dummy);
56a8a83d15SFrancis Visoiu Mistrih 
57a8a83d15SFrancis Visoiu Mistrih   // Print a MachineOperand containing a RegMask. Here we check that without a
58a8a83d15SFrancis Visoiu Mistrih   // TRI and IntrinsicInfo we still print a less detailed regmask.
59a8a83d15SFrancis Visoiu Mistrih   std::string str;
60a8a83d15SFrancis Visoiu Mistrih   raw_string_ostream OS(str);
61a8a83d15SFrancis Visoiu Mistrih   MO.print(OS, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr);
62a8a83d15SFrancis Visoiu Mistrih   ASSERT_TRUE(OS.str() == "<regmask ...>");
63a8a83d15SFrancis Visoiu Mistrih }
64a8a83d15SFrancis Visoiu Mistrih 
TEST(MachineOperandTest,PrintSubReg)65a8a83d15SFrancis Visoiu Mistrih TEST(MachineOperandTest, PrintSubReg) {
66a8a83d15SFrancis Visoiu Mistrih   // Create a MachineOperand with RegNum=1 and SubReg=5.
67a8a83d15SFrancis Visoiu Mistrih   MachineOperand MO = MachineOperand::CreateReg(
68a8a83d15SFrancis Visoiu Mistrih       /*Reg=*/1, /*isDef=*/false, /*isImp=*/false, /*isKill=*/false,
69a8a83d15SFrancis Visoiu Mistrih       /*isDead=*/false, /*isUndef=*/false, /*isEarlyClobber=*/false,
70a8a83d15SFrancis Visoiu Mistrih       /*SubReg=*/5, /*isDebug=*/false, /*isInternalRead=*/false);
71a8a83d15SFrancis Visoiu Mistrih 
72a8a83d15SFrancis Visoiu Mistrih   // Checking some preconditions on the newly created
73a8a83d15SFrancis Visoiu Mistrih   // MachineOperand.
74a8a83d15SFrancis Visoiu Mistrih   ASSERT_TRUE(MO.isReg());
75a8a83d15SFrancis Visoiu Mistrih   ASSERT_TRUE(MO.getReg() == 1);
76a8a83d15SFrancis Visoiu Mistrih   ASSERT_TRUE(MO.getSubReg() == 5);
77a8a83d15SFrancis Visoiu Mistrih 
78a8a83d15SFrancis Visoiu Mistrih   // Print a MachineOperand containing a SubReg. Here we check that without a
79a8a83d15SFrancis Visoiu Mistrih   // TRI and IntrinsicInfo we can still print the subreg index.
80a8a83d15SFrancis Visoiu Mistrih   std::string str;
81a8a83d15SFrancis Visoiu Mistrih   raw_string_ostream OS(str);
82a8a83d15SFrancis Visoiu Mistrih   MO.print(OS, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr);
8343e94b15SPuyan Lotfi   ASSERT_TRUE(OS.str() == "$physreg1.subreg5");
84a8a83d15SFrancis Visoiu Mistrih }
85a8a83d15SFrancis Visoiu Mistrih 
TEST(MachineOperandTest,PrintCImm)866c4ca713SFrancis Visoiu Mistrih TEST(MachineOperandTest, PrintCImm) {
876c4ca713SFrancis Visoiu Mistrih   LLVMContext Context;
886c4ca713SFrancis Visoiu Mistrih   APInt Int(128, UINT64_MAX);
896c4ca713SFrancis Visoiu Mistrih   ++Int;
906c4ca713SFrancis Visoiu Mistrih   ConstantInt *CImm = ConstantInt::get(Context, Int);
916c4ca713SFrancis Visoiu Mistrih   // Create a MachineOperand with an Imm=(UINT64_MAX + 1)
926c4ca713SFrancis Visoiu Mistrih   MachineOperand MO = MachineOperand::CreateCImm(CImm);
936c4ca713SFrancis Visoiu Mistrih 
946c4ca713SFrancis Visoiu Mistrih   // Checking some preconditions on the newly created
956c4ca713SFrancis Visoiu Mistrih   // MachineOperand.
966c4ca713SFrancis Visoiu Mistrih   ASSERT_TRUE(MO.isCImm());
976c4ca713SFrancis Visoiu Mistrih   ASSERT_TRUE(MO.getCImm() == CImm);
986c4ca713SFrancis Visoiu Mistrih   ASSERT_TRUE(MO.getCImm()->getValue() == Int);
996c4ca713SFrancis Visoiu Mistrih 
1006c4ca713SFrancis Visoiu Mistrih   // Print a MachineOperand containing a SubReg. Here we check that without a
1016c4ca713SFrancis Visoiu Mistrih   // TRI and IntrinsicInfo we can still print the subreg index.
1026c4ca713SFrancis Visoiu Mistrih   std::string str;
1036c4ca713SFrancis Visoiu Mistrih   raw_string_ostream OS(str);
1046c4ca713SFrancis Visoiu Mistrih   MO.print(OS, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr);
1056c4ca713SFrancis Visoiu Mistrih   ASSERT_TRUE(OS.str() == "i128 18446744073709551616");
1066c4ca713SFrancis Visoiu Mistrih }
1076c4ca713SFrancis Visoiu Mistrih 
TEST(MachineOperandTest,PrintSubRegIndex)108440f69c9SFrancis Visoiu Mistrih TEST(MachineOperandTest, PrintSubRegIndex) {
109440f69c9SFrancis Visoiu Mistrih   // Create a MachineOperand with an immediate and print it as a subreg index.
110440f69c9SFrancis Visoiu Mistrih   MachineOperand MO = MachineOperand::CreateImm(3);
111440f69c9SFrancis Visoiu Mistrih 
112440f69c9SFrancis Visoiu Mistrih   // Checking some preconditions on the newly created
113440f69c9SFrancis Visoiu Mistrih   // MachineOperand.
114440f69c9SFrancis Visoiu Mistrih   ASSERT_TRUE(MO.isImm());
115440f69c9SFrancis Visoiu Mistrih   ASSERT_TRUE(MO.getImm() == 3);
116440f69c9SFrancis Visoiu Mistrih 
117440f69c9SFrancis Visoiu Mistrih   // Print a MachineOperand containing a SubRegIdx. Here we check that without a
118440f69c9SFrancis Visoiu Mistrih   // TRI and IntrinsicInfo we can print the operand as a subreg index.
119440f69c9SFrancis Visoiu Mistrih   std::string str;
120440f69c9SFrancis Visoiu Mistrih   raw_string_ostream OS(str);
121ecd0b833SFrancis Visoiu Mistrih   MachineOperand::printSubRegIdx(OS, MO.getImm(), nullptr);
122440f69c9SFrancis Visoiu Mistrih   ASSERT_TRUE(OS.str() == "%subreg.3");
123440f69c9SFrancis Visoiu Mistrih }
124440f69c9SFrancis Visoiu Mistrih 
TEST(MachineOperandTest,PrintCPI)12526ae8a65SFrancis Visoiu Mistrih TEST(MachineOperandTest, PrintCPI) {
12626ae8a65SFrancis Visoiu Mistrih   // Create a MachineOperand with a constant pool index and print it.
12726ae8a65SFrancis Visoiu Mistrih   MachineOperand MO = MachineOperand::CreateCPI(0, 8);
12826ae8a65SFrancis Visoiu Mistrih 
12926ae8a65SFrancis Visoiu Mistrih   // Checking some preconditions on the newly created
13026ae8a65SFrancis Visoiu Mistrih   // MachineOperand.
13126ae8a65SFrancis Visoiu Mistrih   ASSERT_TRUE(MO.isCPI());
13226ae8a65SFrancis Visoiu Mistrih   ASSERT_TRUE(MO.getIndex() == 0);
13326ae8a65SFrancis Visoiu Mistrih   ASSERT_TRUE(MO.getOffset() == 8);
13426ae8a65SFrancis Visoiu Mistrih 
13526ae8a65SFrancis Visoiu Mistrih   // Print a MachineOperand containing a constant pool index and a positive
13626ae8a65SFrancis Visoiu Mistrih   // offset.
13726ae8a65SFrancis Visoiu Mistrih   std::string str;
13826ae8a65SFrancis Visoiu Mistrih   {
13926ae8a65SFrancis Visoiu Mistrih     raw_string_ostream OS(str);
14026ae8a65SFrancis Visoiu Mistrih     MO.print(OS, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr);
14126ae8a65SFrancis Visoiu Mistrih     ASSERT_TRUE(OS.str() == "%const.0 + 8");
14226ae8a65SFrancis Visoiu Mistrih   }
14326ae8a65SFrancis Visoiu Mistrih 
14426ae8a65SFrancis Visoiu Mistrih   str.clear();
14526ae8a65SFrancis Visoiu Mistrih 
14626ae8a65SFrancis Visoiu Mistrih   MO.setOffset(-12);
14726ae8a65SFrancis Visoiu Mistrih 
14826ae8a65SFrancis Visoiu Mistrih   // Print a MachineOperand containing a constant pool index and a negative
14926ae8a65SFrancis Visoiu Mistrih   // offset.
15026ae8a65SFrancis Visoiu Mistrih   {
15126ae8a65SFrancis Visoiu Mistrih     raw_string_ostream OS(str);
15226ae8a65SFrancis Visoiu Mistrih     MO.print(OS, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr);
15326ae8a65SFrancis Visoiu Mistrih     ASSERT_TRUE(OS.str() == "%const.0 - 12");
15426ae8a65SFrancis Visoiu Mistrih   }
15526ae8a65SFrancis Visoiu Mistrih }
15626ae8a65SFrancis Visoiu Mistrih 
TEST(MachineOperandTest,PrintTargetIndexName)157b3a0d513SFrancis Visoiu Mistrih TEST(MachineOperandTest, PrintTargetIndexName) {
158b3a0d513SFrancis Visoiu Mistrih   // Create a MachineOperand with a target index and print it.
159b3a0d513SFrancis Visoiu Mistrih   MachineOperand MO = MachineOperand::CreateTargetIndex(0, 8);
160b3a0d513SFrancis Visoiu Mistrih 
161b3a0d513SFrancis Visoiu Mistrih   // Checking some preconditions on the newly created
162b3a0d513SFrancis Visoiu Mistrih   // MachineOperand.
163b3a0d513SFrancis Visoiu Mistrih   ASSERT_TRUE(MO.isTargetIndex());
164b3a0d513SFrancis Visoiu Mistrih   ASSERT_TRUE(MO.getIndex() == 0);
165b3a0d513SFrancis Visoiu Mistrih   ASSERT_TRUE(MO.getOffset() == 8);
166b3a0d513SFrancis Visoiu Mistrih 
167b3a0d513SFrancis Visoiu Mistrih   // Print a MachineOperand containing a target index and a positive offset.
168b3a0d513SFrancis Visoiu Mistrih   std::string str;
169b3a0d513SFrancis Visoiu Mistrih   {
170b3a0d513SFrancis Visoiu Mistrih     raw_string_ostream OS(str);
171b3a0d513SFrancis Visoiu Mistrih     MO.print(OS, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr);
172b3a0d513SFrancis Visoiu Mistrih     ASSERT_TRUE(OS.str() == "target-index(<unknown>) + 8");
173b3a0d513SFrancis Visoiu Mistrih   }
174b3a0d513SFrancis Visoiu Mistrih 
175b3a0d513SFrancis Visoiu Mistrih   str.clear();
176b3a0d513SFrancis Visoiu Mistrih 
177b3a0d513SFrancis Visoiu Mistrih   MO.setOffset(-12);
178b3a0d513SFrancis Visoiu Mistrih 
179b3a0d513SFrancis Visoiu Mistrih   // Print a MachineOperand containing a target index and a negative offset.
180b3a0d513SFrancis Visoiu Mistrih   {
181b3a0d513SFrancis Visoiu Mistrih     raw_string_ostream OS(str);
182b3a0d513SFrancis Visoiu Mistrih     MO.print(OS, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr);
183b3a0d513SFrancis Visoiu Mistrih     ASSERT_TRUE(OS.str() == "target-index(<unknown>) - 12");
184b3a0d513SFrancis Visoiu Mistrih   }
185b3a0d513SFrancis Visoiu Mistrih }
186b3a0d513SFrancis Visoiu Mistrih 
TEST(MachineOperandTest,PrintJumpTableIndex)187b41dbbe3SFrancis Visoiu Mistrih TEST(MachineOperandTest, PrintJumpTableIndex) {
188b41dbbe3SFrancis Visoiu Mistrih   // Create a MachineOperand with a jump-table index and print it.
189b41dbbe3SFrancis Visoiu Mistrih   MachineOperand MO = MachineOperand::CreateJTI(3);
190b41dbbe3SFrancis Visoiu Mistrih 
191b41dbbe3SFrancis Visoiu Mistrih   // Checking some preconditions on the newly created
192b41dbbe3SFrancis Visoiu Mistrih   // MachineOperand.
193b41dbbe3SFrancis Visoiu Mistrih   ASSERT_TRUE(MO.isJTI());
194b41dbbe3SFrancis Visoiu Mistrih   ASSERT_TRUE(MO.getIndex() == 3);
195b41dbbe3SFrancis Visoiu Mistrih 
196b41dbbe3SFrancis Visoiu Mistrih   // Print a MachineOperand containing a jump-table index.
197b41dbbe3SFrancis Visoiu Mistrih   std::string str;
198b41dbbe3SFrancis Visoiu Mistrih   raw_string_ostream OS(str);
199b41dbbe3SFrancis Visoiu Mistrih   MO.print(OS, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr);
200b41dbbe3SFrancis Visoiu Mistrih   ASSERT_TRUE(OS.str() == "%jump-table.3");
201b41dbbe3SFrancis Visoiu Mistrih }
202b41dbbe3SFrancis Visoiu Mistrih 
TEST(MachineOperandTest,PrintExternalSymbol)203e76c5fcdSFrancis Visoiu Mistrih TEST(MachineOperandTest, PrintExternalSymbol) {
204e76c5fcdSFrancis Visoiu Mistrih   // Create a MachineOperand with an external symbol and print it.
205e76c5fcdSFrancis Visoiu Mistrih   MachineOperand MO = MachineOperand::CreateES("foo");
206e76c5fcdSFrancis Visoiu Mistrih 
207e76c5fcdSFrancis Visoiu Mistrih   // Checking some preconditions on the newly created
208e76c5fcdSFrancis Visoiu Mistrih   // MachineOperand.
209e76c5fcdSFrancis Visoiu Mistrih   ASSERT_TRUE(MO.isSymbol());
210e76c5fcdSFrancis Visoiu Mistrih   ASSERT_TRUE(MO.getSymbolName() == StringRef("foo"));
211e76c5fcdSFrancis Visoiu Mistrih 
212e76c5fcdSFrancis Visoiu Mistrih   // Print a MachineOperand containing an external symbol and no offset.
213e76c5fcdSFrancis Visoiu Mistrih   std::string str;
214e76c5fcdSFrancis Visoiu Mistrih   {
215e76c5fcdSFrancis Visoiu Mistrih     raw_string_ostream OS(str);
216e76c5fcdSFrancis Visoiu Mistrih     MO.print(OS, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr);
217fe6c9cbbSPuyan Lotfi     ASSERT_TRUE(OS.str() == "&foo");
218e76c5fcdSFrancis Visoiu Mistrih   }
219e76c5fcdSFrancis Visoiu Mistrih 
220e76c5fcdSFrancis Visoiu Mistrih   str.clear();
221e76c5fcdSFrancis Visoiu Mistrih   MO.setOffset(12);
222e76c5fcdSFrancis Visoiu Mistrih 
223e76c5fcdSFrancis Visoiu Mistrih   // Print a MachineOperand containing an external symbol and a positive offset.
224e76c5fcdSFrancis Visoiu Mistrih   {
225e76c5fcdSFrancis Visoiu Mistrih     raw_string_ostream OS(str);
226e76c5fcdSFrancis Visoiu Mistrih     MO.print(OS, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr);
227fe6c9cbbSPuyan Lotfi     ASSERT_TRUE(OS.str() == "&foo + 12");
228e76c5fcdSFrancis Visoiu Mistrih   }
229e76c5fcdSFrancis Visoiu Mistrih 
230e76c5fcdSFrancis Visoiu Mistrih   str.clear();
231e76c5fcdSFrancis Visoiu Mistrih   MO.setOffset(-12);
232e76c5fcdSFrancis Visoiu Mistrih 
233e76c5fcdSFrancis Visoiu Mistrih   // Print a MachineOperand containing an external symbol and a negative offset.
234e76c5fcdSFrancis Visoiu Mistrih   {
235e76c5fcdSFrancis Visoiu Mistrih     raw_string_ostream OS(str);
236e76c5fcdSFrancis Visoiu Mistrih     MO.print(OS, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr);
237fe6c9cbbSPuyan Lotfi     ASSERT_TRUE(OS.str() == "&foo - 12");
238e76c5fcdSFrancis Visoiu Mistrih   }
239e76c5fcdSFrancis Visoiu Mistrih }
240e76c5fcdSFrancis Visoiu Mistrih 
TEST(MachineOperandTest,PrintGlobalAddress)2415df3bbf3SFrancis Visoiu Mistrih TEST(MachineOperandTest, PrintGlobalAddress) {
2425df3bbf3SFrancis Visoiu Mistrih   LLVMContext Ctx;
2435df3bbf3SFrancis Visoiu Mistrih   Module M("MachineOperandGVTest", Ctx);
2445df3bbf3SFrancis Visoiu Mistrih   M.getOrInsertGlobal("foo", Type::getInt32Ty(Ctx));
2455df3bbf3SFrancis Visoiu Mistrih 
2465df3bbf3SFrancis Visoiu Mistrih   GlobalValue *GV = M.getNamedValue("foo");
2475df3bbf3SFrancis Visoiu Mistrih 
2485df3bbf3SFrancis Visoiu Mistrih   // Create a MachineOperand with a global address and a positive offset and
2495df3bbf3SFrancis Visoiu Mistrih   // print it.
2505df3bbf3SFrancis Visoiu Mistrih   MachineOperand MO = MachineOperand::CreateGA(GV, 12);
2515df3bbf3SFrancis Visoiu Mistrih 
2525df3bbf3SFrancis Visoiu Mistrih   // Checking some preconditions on the newly created
2535df3bbf3SFrancis Visoiu Mistrih   // MachineOperand.
2545df3bbf3SFrancis Visoiu Mistrih   ASSERT_TRUE(MO.isGlobal());
2555df3bbf3SFrancis Visoiu Mistrih   ASSERT_TRUE(MO.getGlobal() == GV);
2565df3bbf3SFrancis Visoiu Mistrih   ASSERT_TRUE(MO.getOffset() == 12);
2575df3bbf3SFrancis Visoiu Mistrih 
2585df3bbf3SFrancis Visoiu Mistrih   std::string str;
2595df3bbf3SFrancis Visoiu Mistrih   // Print a MachineOperand containing a global address and a positive offset.
2605df3bbf3SFrancis Visoiu Mistrih   {
2615df3bbf3SFrancis Visoiu Mistrih     raw_string_ostream OS(str);
2625df3bbf3SFrancis Visoiu Mistrih     MO.print(OS, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr);
2635df3bbf3SFrancis Visoiu Mistrih     ASSERT_TRUE(OS.str() == "@foo + 12");
2645df3bbf3SFrancis Visoiu Mistrih   }
2655df3bbf3SFrancis Visoiu Mistrih 
2665df3bbf3SFrancis Visoiu Mistrih   str.clear();
2675df3bbf3SFrancis Visoiu Mistrih   MO.setOffset(-12);
2685df3bbf3SFrancis Visoiu Mistrih 
2695df3bbf3SFrancis Visoiu Mistrih   // Print a MachineOperand containing a global address and a negative offset.
2705df3bbf3SFrancis Visoiu Mistrih   {
2715df3bbf3SFrancis Visoiu Mistrih     raw_string_ostream OS(str);
2725df3bbf3SFrancis Visoiu Mistrih     MO.print(OS, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr);
2735df3bbf3SFrancis Visoiu Mistrih     ASSERT_TRUE(OS.str() == "@foo - 12");
2745df3bbf3SFrancis Visoiu Mistrih   }
2755df3bbf3SFrancis Visoiu Mistrih }
2765df3bbf3SFrancis Visoiu Mistrih 
TEST(MachineOperandTest,PrintRegisterLiveOut)277bdaf8bfaSFrancis Visoiu Mistrih TEST(MachineOperandTest, PrintRegisterLiveOut) {
278bdaf8bfaSFrancis Visoiu Mistrih   // Create a MachineOperand with a register live out list and print it.
279bdaf8bfaSFrancis Visoiu Mistrih   uint32_t Mask = 0;
280bdaf8bfaSFrancis Visoiu Mistrih   MachineOperand MO = MachineOperand::CreateRegLiveOut(&Mask);
281bdaf8bfaSFrancis Visoiu Mistrih 
282bdaf8bfaSFrancis Visoiu Mistrih   // Checking some preconditions on the newly created
283bdaf8bfaSFrancis Visoiu Mistrih   // MachineOperand.
284bdaf8bfaSFrancis Visoiu Mistrih   ASSERT_TRUE(MO.isRegLiveOut());
285bdaf8bfaSFrancis Visoiu Mistrih   ASSERT_TRUE(MO.getRegLiveOut() == &Mask);
286bdaf8bfaSFrancis Visoiu Mistrih 
287bdaf8bfaSFrancis Visoiu Mistrih   std::string str;
288bdaf8bfaSFrancis Visoiu Mistrih   // Print a MachineOperand containing a register live out list without a TRI.
289bdaf8bfaSFrancis Visoiu Mistrih   raw_string_ostream OS(str);
290bdaf8bfaSFrancis Visoiu Mistrih   MO.print(OS, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr);
291bdaf8bfaSFrancis Visoiu Mistrih   ASSERT_TRUE(OS.str() == "liveout(<unknown>)");
292bdaf8bfaSFrancis Visoiu Mistrih }
293bdaf8bfaSFrancis Visoiu Mistrih 
TEST(MachineOperandTest,PrintMetadata)2942db59382SFrancis Visoiu Mistrih TEST(MachineOperandTest, PrintMetadata) {
2952db59382SFrancis Visoiu Mistrih   LLVMContext Ctx;
2962db59382SFrancis Visoiu Mistrih   Module M("MachineOperandMDNodeTest", Ctx);
2972db59382SFrancis Visoiu Mistrih   NamedMDNode *MD = M.getOrInsertNamedMetadata("namedmd");
298378b5f3dSFrancis Visoiu Mistrih   ModuleSlotTracker MST(&M);
2992db59382SFrancis Visoiu Mistrih   Metadata *MDS = MDString::get(Ctx, "foo");
3002db59382SFrancis Visoiu Mistrih   MDNode *Node = MDNode::get(Ctx, MDS);
3012db59382SFrancis Visoiu Mistrih   MD->addOperand(Node);
3022db59382SFrancis Visoiu Mistrih 
3032db59382SFrancis Visoiu Mistrih   // Create a MachineOperand with a metadata and print it.
3042db59382SFrancis Visoiu Mistrih   MachineOperand MO = MachineOperand::CreateMetadata(Node);
3052db59382SFrancis Visoiu Mistrih 
3062db59382SFrancis Visoiu Mistrih   // Checking some preconditions on the newly created
3072db59382SFrancis Visoiu Mistrih   // MachineOperand.
3082db59382SFrancis Visoiu Mistrih   ASSERT_TRUE(MO.isMetadata());
3092db59382SFrancis Visoiu Mistrih   ASSERT_TRUE(MO.getMetadata() == Node);
3102db59382SFrancis Visoiu Mistrih 
3112db59382SFrancis Visoiu Mistrih   std::string str;
3122db59382SFrancis Visoiu Mistrih   // Print a MachineOperand containing a metadata node.
3132db59382SFrancis Visoiu Mistrih   raw_string_ostream OS(str);
314de3d0ee0SDaniel Sanders   MO.print(OS, MST, LLT{}, /*OpIdx*/~0U, /*PrintDef=*/false, /*IsStandalone=*/false,
315378b5f3dSFrancis Visoiu Mistrih            /*ShouldPrintRegisterTies=*/false, 0, /*TRI=*/nullptr,
3162db59382SFrancis Visoiu Mistrih            /*IntrinsicInfo=*/nullptr);
3172db59382SFrancis Visoiu Mistrih   ASSERT_TRUE(OS.str() == "!0");
3182db59382SFrancis Visoiu Mistrih }
3192db59382SFrancis Visoiu Mistrih 
TEST(MachineOperandTest,PrintMCSymbol)3203c99371cSFrancis Visoiu Mistrih TEST(MachineOperandTest, PrintMCSymbol) {
3213c99371cSFrancis Visoiu Mistrih   MCAsmInfo MAI;
322632ebc4aSPhilipp Krones   Triple T = Triple("unknown-unknown-unknown");
323c2f819afSPhilipp Krones   MCContext Ctx(T, &MAI, /*MRI=*/nullptr, /*MSTI=*/nullptr);
3243c99371cSFrancis Visoiu Mistrih   MCSymbol *Sym = Ctx.getOrCreateSymbol("foo");
3253c99371cSFrancis Visoiu Mistrih 
3263c99371cSFrancis Visoiu Mistrih   // Create a MachineOperand with a metadata and print it.
3273c99371cSFrancis Visoiu Mistrih   MachineOperand MO = MachineOperand::CreateMCSymbol(Sym);
3283c99371cSFrancis Visoiu Mistrih 
3293c99371cSFrancis Visoiu Mistrih   // Checking some preconditions on the newly created
3303c99371cSFrancis Visoiu Mistrih   // MachineOperand.
3313c99371cSFrancis Visoiu Mistrih   ASSERT_TRUE(MO.isMCSymbol());
3323c99371cSFrancis Visoiu Mistrih   ASSERT_TRUE(MO.getMCSymbol() == Sym);
3333c99371cSFrancis Visoiu Mistrih 
3343c99371cSFrancis Visoiu Mistrih   std::string str;
3353c99371cSFrancis Visoiu Mistrih   // Print a MachineOperand containing a metadata node.
3363c99371cSFrancis Visoiu Mistrih   raw_string_ostream OS(str);
3373c99371cSFrancis Visoiu Mistrih   MO.print(OS, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr);
3383c99371cSFrancis Visoiu Mistrih   ASSERT_TRUE(OS.str() == "<mcsymbol foo>");
3393c99371cSFrancis Visoiu Mistrih }
3403c99371cSFrancis Visoiu Mistrih 
TEST(MachineOperandTest,PrintCFI)341874ae6faSFrancis Visoiu Mistrih TEST(MachineOperandTest, PrintCFI) {
342874ae6faSFrancis Visoiu Mistrih   // Create a MachineOperand with a CFI index but no function and print it.
343874ae6faSFrancis Visoiu Mistrih   MachineOperand MO = MachineOperand::CreateCFIIndex(8);
344874ae6faSFrancis Visoiu Mistrih 
345874ae6faSFrancis Visoiu Mistrih   // Checking some preconditions on the newly created
346874ae6faSFrancis Visoiu Mistrih   // MachineOperand.
347874ae6faSFrancis Visoiu Mistrih   ASSERT_TRUE(MO.isCFIIndex());
348874ae6faSFrancis Visoiu Mistrih   ASSERT_TRUE(MO.getCFIIndex() == 8);
349874ae6faSFrancis Visoiu Mistrih 
350874ae6faSFrancis Visoiu Mistrih   std::string str;
351874ae6faSFrancis Visoiu Mistrih   // Print a MachineOperand containing a CFI Index node but no machine function
352874ae6faSFrancis Visoiu Mistrih   // attached to it.
353874ae6faSFrancis Visoiu Mistrih   raw_string_ostream OS(str);
354874ae6faSFrancis Visoiu Mistrih   MO.print(OS, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr);
355874ae6faSFrancis Visoiu Mistrih   ASSERT_TRUE(OS.str() == "<cfi directive>");
356874ae6faSFrancis Visoiu Mistrih }
357874ae6faSFrancis Visoiu Mistrih 
TEST(MachineOperandTest,PrintIntrinsicID)358bbd610aeSFrancis Visoiu Mistrih TEST(MachineOperandTest, PrintIntrinsicID) {
359bbd610aeSFrancis Visoiu Mistrih   // Create a MachineOperand with a generic intrinsic ID.
360bbd610aeSFrancis Visoiu Mistrih   MachineOperand MO = MachineOperand::CreateIntrinsicID(Intrinsic::bswap);
361bbd610aeSFrancis Visoiu Mistrih 
362bbd610aeSFrancis Visoiu Mistrih   // Checking some preconditions on the newly created
363bbd610aeSFrancis Visoiu Mistrih   // MachineOperand.
364bbd610aeSFrancis Visoiu Mistrih   ASSERT_TRUE(MO.isIntrinsicID());
365bbd610aeSFrancis Visoiu Mistrih   ASSERT_TRUE(MO.getIntrinsicID() == Intrinsic::bswap);
366bbd610aeSFrancis Visoiu Mistrih 
367bbd610aeSFrancis Visoiu Mistrih   std::string str;
368bbd610aeSFrancis Visoiu Mistrih   {
369bbd610aeSFrancis Visoiu Mistrih     // Print a MachineOperand containing a generic intrinsic ID.
370bbd610aeSFrancis Visoiu Mistrih     raw_string_ostream OS(str);
371bbd610aeSFrancis Visoiu Mistrih     MO.print(OS, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr);
372bbd610aeSFrancis Visoiu Mistrih     ASSERT_TRUE(OS.str() == "intrinsic(@llvm.bswap)");
373bbd610aeSFrancis Visoiu Mistrih   }
374bbd610aeSFrancis Visoiu Mistrih 
375bbd610aeSFrancis Visoiu Mistrih   str.clear();
376bbd610aeSFrancis Visoiu Mistrih   // Set a target-specific intrinsic.
377bbd610aeSFrancis Visoiu Mistrih   MO = MachineOperand::CreateIntrinsicID((Intrinsic::ID)-1);
378bbd610aeSFrancis Visoiu Mistrih   {
379bbd610aeSFrancis Visoiu Mistrih     // Print a MachineOperand containing a target-specific intrinsic ID but not
380bbd610aeSFrancis Visoiu Mistrih     // IntrinsicInfo.
381bbd610aeSFrancis Visoiu Mistrih     raw_string_ostream OS(str);
382bbd610aeSFrancis Visoiu Mistrih     MO.print(OS, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr);
383bbd610aeSFrancis Visoiu Mistrih     ASSERT_TRUE(OS.str() == "intrinsic(4294967295)");
384bbd610aeSFrancis Visoiu Mistrih   }
385bbd610aeSFrancis Visoiu Mistrih }
386bbd610aeSFrancis Visoiu Mistrih 
TEST(MachineOperandTest,PrintPredicate)387cb2683d4SFrancis Visoiu Mistrih TEST(MachineOperandTest, PrintPredicate) {
388cb2683d4SFrancis Visoiu Mistrih   // Create a MachineOperand with a generic intrinsic ID.
389cb2683d4SFrancis Visoiu Mistrih   MachineOperand MO = MachineOperand::CreatePredicate(CmpInst::ICMP_EQ);
390cb2683d4SFrancis Visoiu Mistrih 
391cb2683d4SFrancis Visoiu Mistrih   // Checking some preconditions on the newly created
392cb2683d4SFrancis Visoiu Mistrih   // MachineOperand.
393cb2683d4SFrancis Visoiu Mistrih   ASSERT_TRUE(MO.isPredicate());
394cb2683d4SFrancis Visoiu Mistrih   ASSERT_TRUE(MO.getPredicate() == CmpInst::ICMP_EQ);
395cb2683d4SFrancis Visoiu Mistrih 
396cb2683d4SFrancis Visoiu Mistrih   std::string str;
397cb2683d4SFrancis Visoiu Mistrih   // Print a MachineOperand containing a int predicate ICMP_EQ.
398cb2683d4SFrancis Visoiu Mistrih   raw_string_ostream OS(str);
399cb2683d4SFrancis Visoiu Mistrih   MO.print(OS, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr);
400cb2683d4SFrancis Visoiu Mistrih   ASSERT_TRUE(OS.str() == "intpred(eq)");
401cb2683d4SFrancis Visoiu Mistrih }
402cb2683d4SFrancis Visoiu Mistrih 
TEST(MachineOperandTest,HashValue)403d8e87227SEli Friedman TEST(MachineOperandTest, HashValue) {
404d8e87227SEli Friedman   char SymName1[] = "test";
405d8e87227SEli Friedman   char SymName2[] = "test";
406d8e87227SEli Friedman   MachineOperand MO1 = MachineOperand::CreateES(SymName1);
407d8e87227SEli Friedman   MachineOperand MO2 = MachineOperand::CreateES(SymName2);
408d8e87227SEli Friedman   ASSERT_NE(SymName1, SymName2);
409d8e87227SEli Friedman   ASSERT_EQ(hash_value(MO1), hash_value(MO2));
410d8e87227SEli Friedman   ASSERT_TRUE(MO1.isIdenticalTo(MO2));
411d8e87227SEli Friedman }
412d8e87227SEli Friedman 
41361f48ca3SMarcello Maggioni } // end namespace
414