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/CodeGen/CodeGenTargetMachineImpl.h"
12 #include "llvm/CodeGen/MachineFunction.h"
13 #include "llvm/CodeGen/MachineModuleInfo.h"
14 #include "llvm/CodeGen/TargetFrameLowering.h"
15 #include "llvm/CodeGen/TargetInstrInfo.h"
16 #include "llvm/CodeGen/TargetLowering.h"
17 #include "llvm/CodeGenTypes/LowLevelType.h"
18 #include "llvm/IR/Constants.h"
19 #include "llvm/IR/InstrTypes.h"
20 #include "llvm/IR/LLVMContext.h"
21 #include "llvm/IR/Module.h"
22 #include "llvm/IR/ModuleSlotTracker.h"
23 #include "llvm/MC/MCAsmInfo.h"
24 #include "llvm/MC/MCContext.h"
25 #include "llvm/MC/TargetRegistry.h"
26 #include "llvm/Support/raw_ostream.h"
27 #include "gtest/gtest.h"
33 // Include helper functions to ease the manipulation of MachineFunctions.
34 #include "MFCommon.inc"
36 TEST(MachineOperandTest
, ChangeToTargetIndexTest
) {
37 // Creating a MachineOperand to change it to TargetIndex
38 MachineOperand MO
= MachineOperand::CreateImm(50);
40 // Checking some precondition on the newly created
42 ASSERT_TRUE(MO
.isImm());
43 ASSERT_TRUE(MO
.getImm() == 50);
44 ASSERT_FALSE(MO
.isTargetIndex());
46 // Changing to TargetIndex with some arbitrary values
47 // for index, offset and flags.
48 MO
.ChangeToTargetIndex(74, 57, 12);
50 // Checking that the mutation to TargetIndex happened
52 ASSERT_TRUE(MO
.isTargetIndex());
53 ASSERT_TRUE(MO
.getIndex() == 74);
54 ASSERT_TRUE(MO
.getOffset() == 57);
55 ASSERT_TRUE(MO
.getTargetFlags() == 12);
58 TEST(MachineOperandTest
, PrintRegisterMask
) {
60 Module
Mod("Module", Ctx
);
61 auto MF
= createMachineFunction(Ctx
, Mod
);
63 uint32_t *Dummy
= MF
->allocateRegMask();
64 MachineOperand MO
= MachineOperand::CreateRegMask(Dummy
);
66 // Checking some preconditions on the newly created
68 ASSERT_TRUE(MO
.isRegMask());
69 ASSERT_TRUE(MO
.getRegMask() == Dummy
);
71 // Print a MachineOperand containing a RegMask. Here we check that without a
72 // TRI and IntrinsicInfo we still print a less detailed regmask.
74 raw_string_ostream
OS(str
);
75 MO
.print(OS
, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr);
76 ASSERT_TRUE(str
== "<regmask ...>");
79 TEST(MachineOperandTest
, PrintSubReg
) {
80 // Create a MachineOperand with RegNum=1 and SubReg=5.
81 MachineOperand MO
= MachineOperand::CreateReg(
82 /*Reg=*/1, /*isDef=*/false, /*isImp=*/false, /*isKill=*/false,
83 /*isDead=*/false, /*isUndef=*/false, /*isEarlyClobber=*/false,
84 /*SubReg=*/5, /*isDebug=*/false, /*isInternalRead=*/false);
86 // Checking some preconditions on the newly created
88 ASSERT_TRUE(MO
.isReg());
89 ASSERT_TRUE(MO
.getReg() == 1);
90 ASSERT_TRUE(MO
.getSubReg() == 5);
92 // Print a MachineOperand containing a SubReg. Here we check that without a
93 // TRI and IntrinsicInfo we can still print the subreg index.
95 raw_string_ostream
OS(str
);
96 MO
.print(OS
, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr);
97 ASSERT_TRUE(str
== "$physreg1.subreg5");
100 TEST(MachineOperandTest
, PrintCImm
) {
102 APInt
Int(128, UINT64_MAX
);
104 ConstantInt
*CImm
= ConstantInt::get(Context
, Int
);
105 // Create a MachineOperand with an Imm=(UINT64_MAX + 1)
106 MachineOperand MO
= MachineOperand::CreateCImm(CImm
);
108 // Checking some preconditions on the newly created
110 ASSERT_TRUE(MO
.isCImm());
111 ASSERT_TRUE(MO
.getCImm() == CImm
);
112 ASSERT_TRUE(MO
.getCImm()->getValue() == Int
);
114 // Print a MachineOperand containing a SubReg. Here we check that without a
115 // TRI and IntrinsicInfo we can still print the subreg index.
117 raw_string_ostream
OS(str
);
118 MO
.print(OS
, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr);
119 ASSERT_TRUE(str
== "i128 18446744073709551616");
122 TEST(MachineOperandTest
, PrintSubRegIndex
) {
123 // Create a MachineOperand with an immediate and print it as a subreg index.
124 MachineOperand MO
= MachineOperand::CreateImm(3);
126 // Checking some preconditions on the newly created
128 ASSERT_TRUE(MO
.isImm());
129 ASSERT_TRUE(MO
.getImm() == 3);
131 // Print a MachineOperand containing a SubRegIdx. Here we check that without a
132 // TRI and IntrinsicInfo we can print the operand as a subreg index.
134 raw_string_ostream
OS(str
);
135 MachineOperand::printSubRegIdx(OS
, MO
.getImm(), nullptr);
136 ASSERT_TRUE(str
== "%subreg.3");
139 TEST(MachineOperandTest
, PrintCPI
) {
140 // Create a MachineOperand with a constant pool index and print it.
141 MachineOperand MO
= MachineOperand::CreateCPI(0, 8);
143 // Checking some preconditions on the newly created
145 ASSERT_TRUE(MO
.isCPI());
146 ASSERT_TRUE(MO
.getIndex() == 0);
147 ASSERT_TRUE(MO
.getOffset() == 8);
149 // Print a MachineOperand containing a constant pool index and a positive
153 raw_string_ostream
OS(str
);
154 MO
.print(OS
, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr);
155 ASSERT_TRUE(str
== "%const.0 + 8");
162 // Print a MachineOperand containing a constant pool index and a negative
165 raw_string_ostream
OS(str
);
166 MO
.print(OS
, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr);
167 ASSERT_TRUE(str
== "%const.0 - 12");
171 TEST(MachineOperandTest
, PrintTargetIndexName
) {
172 // Create a MachineOperand with a target index and print it.
173 MachineOperand MO
= MachineOperand::CreateTargetIndex(0, 8);
175 // Checking some preconditions on the newly created
177 ASSERT_TRUE(MO
.isTargetIndex());
178 ASSERT_TRUE(MO
.getIndex() == 0);
179 ASSERT_TRUE(MO
.getOffset() == 8);
181 // Print a MachineOperand containing a target index and a positive offset.
184 raw_string_ostream
OS(str
);
185 MO
.print(OS
, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr);
186 ASSERT_TRUE(str
== "target-index(<unknown>) + 8");
193 // Print a MachineOperand containing a target index and a negative offset.
195 raw_string_ostream
OS(str
);
196 MO
.print(OS
, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr);
197 ASSERT_TRUE(str
== "target-index(<unknown>) - 12");
201 TEST(MachineOperandTest
, PrintJumpTableIndex
) {
202 // Create a MachineOperand with a jump-table index and print it.
203 MachineOperand MO
= MachineOperand::CreateJTI(3);
205 // Checking some preconditions on the newly created
207 ASSERT_TRUE(MO
.isJTI());
208 ASSERT_TRUE(MO
.getIndex() == 3);
210 // Print a MachineOperand containing a jump-table index.
212 raw_string_ostream
OS(str
);
213 MO
.print(OS
, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr);
214 ASSERT_TRUE(str
== "%jump-table.3");
217 TEST(MachineOperandTest
, PrintExternalSymbol
) {
218 // Create a MachineOperand with an external symbol and print it.
219 MachineOperand MO
= MachineOperand::CreateES("foo");
221 // Checking some preconditions on the newly created
223 ASSERT_TRUE(MO
.isSymbol());
224 ASSERT_TRUE(MO
.getSymbolName() == StringRef("foo"));
226 // Print a MachineOperand containing an external symbol and no offset.
229 raw_string_ostream
OS(str
);
230 MO
.print(OS
, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr);
231 ASSERT_TRUE(str
== "&foo");
237 // Print a MachineOperand containing an external symbol and a positive offset.
239 raw_string_ostream
OS(str
);
240 MO
.print(OS
, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr);
241 ASSERT_TRUE(str
== "&foo + 12");
247 // Print a MachineOperand containing an external symbol and a negative offset.
249 raw_string_ostream
OS(str
);
250 MO
.print(OS
, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr);
251 ASSERT_TRUE(str
== "&foo - 12");
255 TEST(MachineOperandTest
, PrintGlobalAddress
) {
257 Module
M("MachineOperandGVTest", Ctx
);
258 M
.getOrInsertGlobal("foo", Type::getInt32Ty(Ctx
));
260 GlobalValue
*GV
= M
.getNamedValue("foo");
262 // Create a MachineOperand with a global address and a positive offset and
264 MachineOperand MO
= MachineOperand::CreateGA(GV
, 12);
266 // Checking some preconditions on the newly created
268 ASSERT_TRUE(MO
.isGlobal());
269 ASSERT_TRUE(MO
.getGlobal() == GV
);
270 ASSERT_TRUE(MO
.getOffset() == 12);
273 // Print a MachineOperand containing a global address and a positive offset.
275 raw_string_ostream
OS(str
);
276 MO
.print(OS
, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr);
277 ASSERT_TRUE(str
== "@foo + 12");
283 // Print a MachineOperand containing a global address and a negative offset.
285 raw_string_ostream
OS(str
);
286 MO
.print(OS
, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr);
287 ASSERT_TRUE(str
== "@foo - 12");
291 TEST(MachineOperandTest
, PrintRegisterLiveOut
) {
292 // Create a MachineOperand with a register live out list and print it.
294 MachineOperand MO
= MachineOperand::CreateRegLiveOut(&Mask
);
296 // Checking some preconditions on the newly created
298 ASSERT_TRUE(MO
.isRegLiveOut());
299 ASSERT_TRUE(MO
.getRegLiveOut() == &Mask
);
302 // Print a MachineOperand containing a register live out list without a TRI.
303 raw_string_ostream
OS(str
);
304 MO
.print(OS
, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr);
305 ASSERT_TRUE(str
== "liveout(<unknown>)");
308 TEST(MachineOperandTest
, PrintMetadata
) {
310 Module
M("MachineOperandMDNodeTest", Ctx
);
311 NamedMDNode
*MD
= M
.getOrInsertNamedMetadata("namedmd");
312 ModuleSlotTracker
MST(&M
);
313 Metadata
*MDS
= MDString::get(Ctx
, "foo");
314 MDNode
*Node
= MDNode::get(Ctx
, MDS
);
315 MD
->addOperand(Node
);
317 // Create a MachineOperand with a metadata and print it.
318 MachineOperand MO
= MachineOperand::CreateMetadata(Node
);
320 // Checking some preconditions on the newly created
322 ASSERT_TRUE(MO
.isMetadata());
323 ASSERT_TRUE(MO
.getMetadata() == Node
);
326 // Print a MachineOperand containing a metadata node.
327 raw_string_ostream
OS(str
);
328 MO
.print(OS
, MST
, LLT
{}, /*OpIdx*/~0U, /*PrintDef=*/false, /*IsStandalone=*/false,
329 /*ShouldPrintRegisterTies=*/false, 0, /*TRI=*/nullptr,
330 /*IntrinsicInfo=*/nullptr);
331 ASSERT_TRUE(str
== "!0");
334 TEST(MachineOperandTest
, PrintMCSymbol
) {
336 Triple T
= Triple("unknown-unknown-unknown");
337 MCContext
Ctx(T
, &MAI
, /*MRI=*/nullptr, /*MSTI=*/nullptr);
338 MCSymbol
*Sym
= Ctx
.getOrCreateSymbol("foo");
340 // Create a MachineOperand with a metadata and print it.
341 MachineOperand MO
= MachineOperand::CreateMCSymbol(Sym
);
343 // Checking some preconditions on the newly created
345 ASSERT_TRUE(MO
.isMCSymbol());
346 ASSERT_TRUE(MO
.getMCSymbol() == Sym
);
349 // Print a MachineOperand containing a metadata node.
350 raw_string_ostream
OS(str
);
351 MO
.print(OS
, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr);
352 ASSERT_TRUE(str
== "<mcsymbol foo>");
355 TEST(MachineOperandTest
, PrintCFI
) {
356 // Create a MachineOperand with a CFI index but no function and print it.
357 MachineOperand MO
= MachineOperand::CreateCFIIndex(8);
359 // Checking some preconditions on the newly created
361 ASSERT_TRUE(MO
.isCFIIndex());
362 ASSERT_TRUE(MO
.getCFIIndex() == 8);
365 // Print a MachineOperand containing a CFI Index node but no machine function
367 raw_string_ostream
OS(str
);
368 MO
.print(OS
, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr);
369 ASSERT_TRUE(str
== "<cfi directive>");
372 TEST(MachineOperandTest
, PrintIntrinsicID
) {
373 // Create a MachineOperand with a generic intrinsic ID.
374 MachineOperand MO
= MachineOperand::CreateIntrinsicID(Intrinsic::bswap
);
376 // Checking some preconditions on the newly created
378 ASSERT_TRUE(MO
.isIntrinsicID());
379 ASSERT_TRUE(MO
.getIntrinsicID() == Intrinsic::bswap
);
383 // Print a MachineOperand containing a generic intrinsic ID.
384 raw_string_ostream
OS(str
);
385 MO
.print(OS
, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr);
386 ASSERT_TRUE(str
== "intrinsic(@llvm.bswap)");
390 // Set a target-specific intrinsic.
391 MO
= MachineOperand::CreateIntrinsicID((Intrinsic::ID
)-1);
393 // Print a MachineOperand containing a target-specific intrinsic ID but not
395 raw_string_ostream
OS(str
);
396 MO
.print(OS
, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr);
397 ASSERT_TRUE(str
== "intrinsic(4294967295)");
401 TEST(MachineOperandTest
, PrintPredicate
) {
402 // Create a MachineOperand with a generic intrinsic ID.
403 MachineOperand MO
= MachineOperand::CreatePredicate(CmpInst::ICMP_EQ
);
405 // Checking some preconditions on the newly created
407 ASSERT_TRUE(MO
.isPredicate());
408 ASSERT_TRUE(MO
.getPredicate() == CmpInst::ICMP_EQ
);
411 // Print a MachineOperand containing a int predicate ICMP_EQ.
412 raw_string_ostream
OS(str
);
413 MO
.print(OS
, /*TRI=*/nullptr, /*IntrinsicInfo=*/nullptr);
414 ASSERT_TRUE(str
== "intpred(eq)");
417 TEST(MachineOperandTest
, HashValue
) {
418 char SymName1
[] = "test";
419 char SymName2
[] = "test";
420 MachineOperand MO1
= MachineOperand::CreateES(SymName1
);
421 MachineOperand MO2
= MachineOperand::CreateES(SymName2
);
422 ASSERT_NE(SymName1
, SymName2
);
423 ASSERT_EQ(hash_value(MO1
), hash_value(MO2
));
424 ASSERT_TRUE(MO1
.isIdenticalTo(MO2
));