1 //===- MachineOperandTest.cpp ---------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "llvm/CodeGen/MachineOperand.h"
10 #include "llvm/ADT/ilist_node.h"
11 #include "llvm/IR/Constants.h"
12 #include "llvm/IR/InstrTypes.h"
13 #include "llvm/IR/LLVMContext.h"
14 #include "llvm/IR/Module.h"
15 #include "llvm/IR/ModuleSlotTracker.h"
16 #include "llvm/MC/MCContext.h"
17 #include "llvm/MC/MCAsmInfo.h"
18 #include "llvm/Support/raw_ostream.h"
19 #include "gtest/gtest.h"
25 TEST(MachineOperandTest
, ChangeToTargetIndexTest
) {
26 // Creating a MachineOperand to change it to TargetIndex
27 MachineOperand MO
= MachineOperand::CreateImm(50);
29 // Checking some precondition on the newly created
31 ASSERT_TRUE(MO
.isImm());
32 ASSERT_TRUE(MO
.getImm() == 50);
33 ASSERT_FALSE(MO
.isTargetIndex());
35 // Changing to TargetIndex with some arbitrary values
36 // for index, offset and flags.
37 MO
.ChangeToTargetIndex(74, 57, 12);
39 // Checking that the mutation to TargetIndex happened
41 ASSERT_TRUE(MO
.isTargetIndex());
42 ASSERT_TRUE(MO
.getIndex() == 74);
43 ASSERT_TRUE(MO
.getOffset() == 57);
44 ASSERT_TRUE(MO
.getTargetFlags() == 12);
47 TEST(MachineOperandTest
, PrintRegisterMask
) {
49 MachineOperand MO
= MachineOperand::CreateRegMask(&Dummy
);
51 // Checking some preconditions on the newly created
53 ASSERT_TRUE(MO
.isRegMask());
54 ASSERT_TRUE(MO
.getRegMask() == &Dummy
);
56 // Print a MachineOperand containing a RegMask. Here we check that without a
57 // TRI and IntrinsicInfo we still print a less detailed regmask.
59 raw_string_ostream
OS(str
);
60 MO
.print(OS
, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr);
61 ASSERT_TRUE(OS
.str() == "<regmask ...>");
64 TEST(MachineOperandTest
, PrintSubReg
) {
65 // Create a MachineOperand with RegNum=1 and SubReg=5.
66 MachineOperand MO
= MachineOperand::CreateReg(
67 /*Reg=*/1, /*isDef=*/false, /*isImp=*/false, /*isKill=*/false,
68 /*isDead=*/false, /*isUndef=*/false, /*isEarlyClobber=*/false,
69 /*SubReg=*/5, /*isDebug=*/false, /*isInternalRead=*/false);
71 // Checking some preconditions on the newly created
73 ASSERT_TRUE(MO
.isReg());
74 ASSERT_TRUE(MO
.getReg() == 1);
75 ASSERT_TRUE(MO
.getSubReg() == 5);
77 // Print a MachineOperand containing a SubReg. Here we check that without a
78 // TRI and IntrinsicInfo we can still print the subreg index.
80 raw_string_ostream
OS(str
);
81 MO
.print(OS
, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr);
82 ASSERT_TRUE(OS
.str() == "$physreg1.subreg5");
85 TEST(MachineOperandTest
, PrintCImm
) {
87 APInt
Int(128, UINT64_MAX
);
89 ConstantInt
*CImm
= ConstantInt::get(Context
, Int
);
90 // Create a MachineOperand with an Imm=(UINT64_MAX + 1)
91 MachineOperand MO
= MachineOperand::CreateCImm(CImm
);
93 // Checking some preconditions on the newly created
95 ASSERT_TRUE(MO
.isCImm());
96 ASSERT_TRUE(MO
.getCImm() == CImm
);
97 ASSERT_TRUE(MO
.getCImm()->getValue() == Int
);
99 // Print a MachineOperand containing a SubReg. Here we check that without a
100 // TRI and IntrinsicInfo we can still print the subreg index.
102 raw_string_ostream
OS(str
);
103 MO
.print(OS
, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr);
104 ASSERT_TRUE(OS
.str() == "i128 18446744073709551616");
107 TEST(MachineOperandTest
, PrintSubRegIndex
) {
108 // Create a MachineOperand with an immediate and print it as a subreg index.
109 MachineOperand MO
= MachineOperand::CreateImm(3);
111 // Checking some preconditions on the newly created
113 ASSERT_TRUE(MO
.isImm());
114 ASSERT_TRUE(MO
.getImm() == 3);
116 // Print a MachineOperand containing a SubRegIdx. Here we check that without a
117 // TRI and IntrinsicInfo we can print the operand as a subreg index.
119 raw_string_ostream
OS(str
);
120 MachineOperand::printSubRegIdx(OS
, MO
.getImm(), nullptr);
121 ASSERT_TRUE(OS
.str() == "%subreg.3");
124 TEST(MachineOperandTest
, PrintCPI
) {
125 // Create a MachineOperand with a constant pool index and print it.
126 MachineOperand MO
= MachineOperand::CreateCPI(0, 8);
128 // Checking some preconditions on the newly created
130 ASSERT_TRUE(MO
.isCPI());
131 ASSERT_TRUE(MO
.getIndex() == 0);
132 ASSERT_TRUE(MO
.getOffset() == 8);
134 // Print a MachineOperand containing a constant pool index and a positive
138 raw_string_ostream
OS(str
);
139 MO
.print(OS
, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr);
140 ASSERT_TRUE(OS
.str() == "%const.0 + 8");
147 // Print a MachineOperand containing a constant pool index and a negative
150 raw_string_ostream
OS(str
);
151 MO
.print(OS
, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr);
152 ASSERT_TRUE(OS
.str() == "%const.0 - 12");
156 TEST(MachineOperandTest
, PrintTargetIndexName
) {
157 // Create a MachineOperand with a target index and print it.
158 MachineOperand MO
= MachineOperand::CreateTargetIndex(0, 8);
160 // Checking some preconditions on the newly created
162 ASSERT_TRUE(MO
.isTargetIndex());
163 ASSERT_TRUE(MO
.getIndex() == 0);
164 ASSERT_TRUE(MO
.getOffset() == 8);
166 // Print a MachineOperand containing a target index and a positive offset.
169 raw_string_ostream
OS(str
);
170 MO
.print(OS
, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr);
171 ASSERT_TRUE(OS
.str() == "target-index(<unknown>) + 8");
178 // Print a MachineOperand containing a target index and a negative offset.
180 raw_string_ostream
OS(str
);
181 MO
.print(OS
, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr);
182 ASSERT_TRUE(OS
.str() == "target-index(<unknown>) - 12");
186 TEST(MachineOperandTest
, PrintJumpTableIndex
) {
187 // Create a MachineOperand with a jump-table index and print it.
188 MachineOperand MO
= MachineOperand::CreateJTI(3);
190 // Checking some preconditions on the newly created
192 ASSERT_TRUE(MO
.isJTI());
193 ASSERT_TRUE(MO
.getIndex() == 3);
195 // Print a MachineOperand containing a jump-table index.
197 raw_string_ostream
OS(str
);
198 MO
.print(OS
, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr);
199 ASSERT_TRUE(OS
.str() == "%jump-table.3");
202 TEST(MachineOperandTest
, PrintExternalSymbol
) {
203 // Create a MachineOperand with an external symbol and print it.
204 MachineOperand MO
= MachineOperand::CreateES("foo");
206 // Checking some preconditions on the newly created
208 ASSERT_TRUE(MO
.isSymbol());
209 ASSERT_TRUE(MO
.getSymbolName() == StringRef("foo"));
211 // Print a MachineOperand containing an external symbol and no offset.
214 raw_string_ostream
OS(str
);
215 MO
.print(OS
, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr);
216 ASSERT_TRUE(OS
.str() == "&foo");
222 // Print a MachineOperand containing an external symbol and a positive offset.
224 raw_string_ostream
OS(str
);
225 MO
.print(OS
, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr);
226 ASSERT_TRUE(OS
.str() == "&foo + 12");
232 // Print a MachineOperand containing an external symbol and a negative offset.
234 raw_string_ostream
OS(str
);
235 MO
.print(OS
, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr);
236 ASSERT_TRUE(OS
.str() == "&foo - 12");
240 TEST(MachineOperandTest
, PrintGlobalAddress
) {
242 Module
M("MachineOperandGVTest", Ctx
);
243 M
.getOrInsertGlobal("foo", Type::getInt32Ty(Ctx
));
245 GlobalValue
*GV
= M
.getNamedValue("foo");
247 // Create a MachineOperand with a global address and a positive offset and
249 MachineOperand MO
= MachineOperand::CreateGA(GV
, 12);
251 // Checking some preconditions on the newly created
253 ASSERT_TRUE(MO
.isGlobal());
254 ASSERT_TRUE(MO
.getGlobal() == GV
);
255 ASSERT_TRUE(MO
.getOffset() == 12);
258 // Print a MachineOperand containing a global address and a positive offset.
260 raw_string_ostream
OS(str
);
261 MO
.print(OS
, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr);
262 ASSERT_TRUE(OS
.str() == "@foo + 12");
268 // Print a MachineOperand containing a global address and a negative offset.
270 raw_string_ostream
OS(str
);
271 MO
.print(OS
, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr);
272 ASSERT_TRUE(OS
.str() == "@foo - 12");
276 TEST(MachineOperandTest
, PrintRegisterLiveOut
) {
277 // Create a MachineOperand with a register live out list and print it.
279 MachineOperand MO
= MachineOperand::CreateRegLiveOut(&Mask
);
281 // Checking some preconditions on the newly created
283 ASSERT_TRUE(MO
.isRegLiveOut());
284 ASSERT_TRUE(MO
.getRegLiveOut() == &Mask
);
287 // Print a MachineOperand containing a register live out list without a TRI.
288 raw_string_ostream
OS(str
);
289 MO
.print(OS
, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr);
290 ASSERT_TRUE(OS
.str() == "liveout(<unknown>)");
293 TEST(MachineOperandTest
, PrintMetadata
) {
295 Module
M("MachineOperandMDNodeTest", Ctx
);
296 NamedMDNode
*MD
= M
.getOrInsertNamedMetadata("namedmd");
297 ModuleSlotTracker
MST(&M
);
298 Metadata
*MDS
= MDString::get(Ctx
, "foo");
299 MDNode
*Node
= MDNode::get(Ctx
, MDS
);
300 MD
->addOperand(Node
);
302 // Create a MachineOperand with a metadata and print it.
303 MachineOperand MO
= MachineOperand::CreateMetadata(Node
);
305 // Checking some preconditions on the newly created
307 ASSERT_TRUE(MO
.isMetadata());
308 ASSERT_TRUE(MO
.getMetadata() == Node
);
311 // Print a MachineOperand containing a metadata node.
312 raw_string_ostream
OS(str
);
313 MO
.print(OS
, MST
, LLT
{}, /*PrintDef=*/false, /*IsStandalone=*/false,
314 /*ShouldPrintRegisterTies=*/false, 0, /*TRI=*/nullptr,
315 /*IntrinsicInfo=*/nullptr);
316 ASSERT_TRUE(OS
.str() == "!0");
319 TEST(MachineOperandTest
, PrintMCSymbol
) {
321 MCContext
Ctx(&MAI
, /*MRI=*/nullptr, /*MOFI=*/nullptr);
322 MCSymbol
*Sym
= Ctx
.getOrCreateSymbol("foo");
324 // Create a MachineOperand with a metadata and print it.
325 MachineOperand MO
= MachineOperand::CreateMCSymbol(Sym
);
327 // Checking some preconditions on the newly created
329 ASSERT_TRUE(MO
.isMCSymbol());
330 ASSERT_TRUE(MO
.getMCSymbol() == Sym
);
333 // Print a MachineOperand containing a metadata node.
334 raw_string_ostream
OS(str
);
335 MO
.print(OS
, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr);
336 ASSERT_TRUE(OS
.str() == "<mcsymbol foo>");
339 TEST(MachineOperandTest
, PrintCFI
) {
340 // Create a MachineOperand with a CFI index but no function and print it.
341 MachineOperand MO
= MachineOperand::CreateCFIIndex(8);
343 // Checking some preconditions on the newly created
345 ASSERT_TRUE(MO
.isCFIIndex());
346 ASSERT_TRUE(MO
.getCFIIndex() == 8);
349 // Print a MachineOperand containing a CFI Index node but no machine function
351 raw_string_ostream
OS(str
);
352 MO
.print(OS
, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr);
353 ASSERT_TRUE(OS
.str() == "<cfi directive>");
356 TEST(MachineOperandTest
, PrintIntrinsicID
) {
357 // Create a MachineOperand with a generic intrinsic ID.
358 MachineOperand MO
= MachineOperand::CreateIntrinsicID(Intrinsic::bswap
);
360 // Checking some preconditions on the newly created
362 ASSERT_TRUE(MO
.isIntrinsicID());
363 ASSERT_TRUE(MO
.getIntrinsicID() == Intrinsic::bswap
);
367 // Print a MachineOperand containing a generic intrinsic ID.
368 raw_string_ostream
OS(str
);
369 MO
.print(OS
, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr);
370 ASSERT_TRUE(OS
.str() == "intrinsic(@llvm.bswap)");
374 // Set a target-specific intrinsic.
375 MO
= MachineOperand::CreateIntrinsicID((Intrinsic::ID
)-1);
377 // Print a MachineOperand containing a target-specific intrinsic ID but not
379 raw_string_ostream
OS(str
);
380 MO
.print(OS
, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr);
381 ASSERT_TRUE(OS
.str() == "intrinsic(4294967295)");
385 TEST(MachineOperandTest
, PrintPredicate
) {
386 // Create a MachineOperand with a generic intrinsic ID.
387 MachineOperand MO
= MachineOperand::CreatePredicate(CmpInst::ICMP_EQ
);
389 // Checking some preconditions on the newly created
391 ASSERT_TRUE(MO
.isPredicate());
392 ASSERT_TRUE(MO
.getPredicate() == CmpInst::ICMP_EQ
);
395 // Print a MachineOperand containing a int predicate ICMP_EQ.
396 raw_string_ostream
OS(str
);
397 MO
.print(OS
, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr);
398 ASSERT_TRUE(OS
.str() == "intpred(eq)");
401 TEST(MachineOperandTest
, HashValue
) {
402 char SymName1
[] = "test";
403 char SymName2
[] = "test";
404 MachineOperand MO1
= MachineOperand::CreateES(SymName1
);
405 MachineOperand MO2
= MachineOperand::CreateES(SymName2
);
406 ASSERT_NE(SymName1
, SymName2
);
407 ASSERT_EQ(hash_value(MO1
), hash_value(MO2
));
408 ASSERT_TRUE(MO1
.isIdenticalTo(MO2
));