1 //===-- llvm/CodeGen/GlobalISel/MachineIRBuilder.cpp - MIBuilder--*- C++ -*-==//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 /// This file implements the MachineIRBuidler class.
11 //===----------------------------------------------------------------------===//
12 #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
14 #include "llvm/CodeGen/MachineFunction.h"
15 #include "llvm/CodeGen/MachineInstr.h"
16 #include "llvm/CodeGen/MachineInstrBuilder.h"
17 #include "llvm/CodeGen/MachineRegisterInfo.h"
18 #include "llvm/CodeGen/TargetInstrInfo.h"
19 #include "llvm/CodeGen/TargetOpcodes.h"
20 #include "llvm/CodeGen/TargetSubtargetInfo.h"
21 #include "llvm/IR/DebugInfo.h"
25 void MachineIRBuilderBase::setMF(MachineFunction
&MF
) {
28 State
.MRI
= &MF
.getRegInfo();
29 State
.TII
= MF
.getSubtarget().getInstrInfo();
30 State
.DL
= DebugLoc();
31 State
.II
= MachineBasicBlock::iterator();
32 State
.InsertedInstr
= nullptr;
35 void MachineIRBuilderBase::setMBB(MachineBasicBlock
&MBB
) {
38 assert(&getMF() == MBB
.getParent() &&
39 "Basic block is in a different function");
42 void MachineIRBuilderBase::setInstr(MachineInstr
&MI
) {
43 assert(MI
.getParent() && "Instruction is not part of a basic block");
44 setMBB(*MI
.getParent());
45 State
.II
= MI
.getIterator();
48 void MachineIRBuilderBase::setInsertPt(MachineBasicBlock
&MBB
,
49 MachineBasicBlock::iterator II
) {
50 assert(MBB
.getParent() == &getMF() &&
51 "Basic block is in a different function");
56 void MachineIRBuilderBase::recordInsertion(MachineInstr
*InsertedInstr
) const {
57 if (State
.InsertedInstr
)
58 State
.InsertedInstr(InsertedInstr
);
61 void MachineIRBuilderBase::recordInsertions(
62 std::function
<void(MachineInstr
*)> Inserted
) {
63 State
.InsertedInstr
= std::move(Inserted
);
66 void MachineIRBuilderBase::stopRecordingInsertions() {
67 State
.InsertedInstr
= nullptr;
70 //------------------------------------------------------------------------------
71 // Build instruction variants.
72 //------------------------------------------------------------------------------
74 MachineInstrBuilder
MachineIRBuilderBase::buildInstr(unsigned Opcode
) {
75 return insertInstr(buildInstrNoInsert(Opcode
));
78 MachineInstrBuilder
MachineIRBuilderBase::buildInstrNoInsert(unsigned Opcode
) {
79 MachineInstrBuilder MIB
= BuildMI(getMF(), getDL(), getTII().get(Opcode
));
83 MachineInstrBuilder
MachineIRBuilderBase::insertInstr(MachineInstrBuilder MIB
) {
84 getMBB().insert(getInsertPt(), MIB
);
90 MachineIRBuilderBase::buildDirectDbgValue(unsigned Reg
, const MDNode
*Variable
,
92 assert(isa
<DILocalVariable
>(Variable
) && "not a variable");
93 assert(cast
<DIExpression
>(Expr
)->isValid() && "not an expression");
95 cast
<DILocalVariable
>(Variable
)->isValidLocationForIntrinsic(getDL()) &&
96 "Expected inlined-at fields to agree");
97 return insertInstr(BuildMI(getMF(), getDL(),
98 getTII().get(TargetOpcode::DBG_VALUE
),
99 /*IsIndirect*/ false, Reg
, Variable
, Expr
));
102 MachineInstrBuilder
MachineIRBuilderBase::buildIndirectDbgValue(
103 unsigned Reg
, const MDNode
*Variable
, const MDNode
*Expr
) {
104 assert(isa
<DILocalVariable
>(Variable
) && "not a variable");
105 assert(cast
<DIExpression
>(Expr
)->isValid() && "not an expression");
107 cast
<DILocalVariable
>(Variable
)->isValidLocationForIntrinsic(getDL()) &&
108 "Expected inlined-at fields to agree");
109 return insertInstr(BuildMI(getMF(), getDL(),
110 getTII().get(TargetOpcode::DBG_VALUE
),
111 /*IsIndirect*/ true, Reg
, Variable
, Expr
));
115 MachineIRBuilderBase::buildFIDbgValue(int FI
, const MDNode
*Variable
,
116 const MDNode
*Expr
) {
117 assert(isa
<DILocalVariable
>(Variable
) && "not a variable");
118 assert(cast
<DIExpression
>(Expr
)->isValid() && "not an expression");
120 cast
<DILocalVariable
>(Variable
)->isValidLocationForIntrinsic(getDL()) &&
121 "Expected inlined-at fields to agree");
122 return buildInstr(TargetOpcode::DBG_VALUE
)
125 .addMetadata(Variable
)
129 MachineInstrBuilder
MachineIRBuilderBase::buildConstDbgValue(
130 const Constant
&C
, const MDNode
*Variable
, const MDNode
*Expr
) {
131 assert(isa
<DILocalVariable
>(Variable
) && "not a variable");
132 assert(cast
<DIExpression
>(Expr
)->isValid() && "not an expression");
134 cast
<DILocalVariable
>(Variable
)->isValidLocationForIntrinsic(getDL()) &&
135 "Expected inlined-at fields to agree");
136 auto MIB
= buildInstr(TargetOpcode::DBG_VALUE
);
137 if (auto *CI
= dyn_cast
<ConstantInt
>(&C
)) {
138 if (CI
->getBitWidth() > 64)
141 MIB
.addImm(CI
->getZExtValue());
142 } else if (auto *CFP
= dyn_cast
<ConstantFP
>(&C
)) {
145 // Insert %noreg if we didn't find a usable constant and had to drop it.
149 return MIB
.addImm(0).addMetadata(Variable
).addMetadata(Expr
);
152 MachineInstrBuilder
MachineIRBuilderBase::buildDbgLabel(const MDNode
*Label
) {
153 assert(isa
<DILabel
>(Label
) && "not a label");
154 assert(cast
<DILabel
>(Label
)->isValidLocationForIntrinsic(State
.DL
) &&
155 "Expected inlined-at fields to agree");
156 auto MIB
= buildInstr(TargetOpcode::DBG_LABEL
);
158 return MIB
.addMetadata(Label
);
161 MachineInstrBuilder
MachineIRBuilderBase::buildFrameIndex(unsigned Res
,
163 assert(getMRI()->getType(Res
).isPointer() && "invalid operand type");
164 return buildInstr(TargetOpcode::G_FRAME_INDEX
)
170 MachineIRBuilderBase::buildGlobalValue(unsigned Res
, const GlobalValue
*GV
) {
171 assert(getMRI()->getType(Res
).isPointer() && "invalid operand type");
172 assert(getMRI()->getType(Res
).getAddressSpace() ==
173 GV
->getType()->getAddressSpace() &&
174 "address space mismatch");
176 return buildInstr(TargetOpcode::G_GLOBAL_VALUE
)
178 .addGlobalAddress(GV
);
181 void MachineIRBuilderBase::validateBinaryOp(unsigned Res
, unsigned Op0
,
183 assert((getMRI()->getType(Res
).isScalar() ||
184 getMRI()->getType(Res
).isVector()) &&
185 "invalid operand type");
186 assert(getMRI()->getType(Res
) == getMRI()->getType(Op0
) &&
187 getMRI()->getType(Res
) == getMRI()->getType(Op1
) && "type mismatch");
190 MachineInstrBuilder
MachineIRBuilderBase::buildGEP(unsigned Res
, unsigned Op0
,
192 assert(getMRI()->getType(Res
).isPointer() &&
193 getMRI()->getType(Res
) == getMRI()->getType(Op0
) && "type mismatch");
194 assert(getMRI()->getType(Op1
).isScalar() && "invalid offset type");
196 return buildInstr(TargetOpcode::G_GEP
)
202 Optional
<MachineInstrBuilder
>
203 MachineIRBuilderBase::materializeGEP(unsigned &Res
, unsigned Op0
,
204 const LLT
&ValueTy
, uint64_t Value
) {
205 assert(Res
== 0 && "Res is a result argument");
206 assert(ValueTy
.isScalar() && "invalid offset type");
213 Res
= getMRI()->createGenericVirtualRegister(getMRI()->getType(Op0
));
214 unsigned TmpReg
= getMRI()->createGenericVirtualRegister(ValueTy
);
216 buildConstant(TmpReg
, Value
);
217 return buildGEP(Res
, Op0
, TmpReg
);
220 MachineInstrBuilder
MachineIRBuilderBase::buildPtrMask(unsigned Res
,
223 assert(getMRI()->getType(Res
).isPointer() &&
224 getMRI()->getType(Res
) == getMRI()->getType(Op0
) && "type mismatch");
226 return buildInstr(TargetOpcode::G_PTR_MASK
)
232 MachineInstrBuilder
MachineIRBuilderBase::buildBr(MachineBasicBlock
&Dest
) {
233 return buildInstr(TargetOpcode::G_BR
).addMBB(&Dest
);
236 MachineInstrBuilder
MachineIRBuilderBase::buildBrIndirect(unsigned Tgt
) {
237 assert(getMRI()->getType(Tgt
).isPointer() && "invalid branch destination");
238 return buildInstr(TargetOpcode::G_BRINDIRECT
).addUse(Tgt
);
241 MachineInstrBuilder
MachineIRBuilderBase::buildCopy(unsigned Res
, unsigned Op
) {
242 assert(getMRI()->getType(Res
) == LLT() || getMRI()->getType(Op
) == LLT() ||
243 getMRI()->getType(Res
) == getMRI()->getType(Op
));
244 return buildInstr(TargetOpcode::COPY
).addDef(Res
).addUse(Op
);
248 MachineIRBuilderBase::buildConstant(unsigned Res
, const ConstantInt
&Val
) {
249 LLT Ty
= getMRI()->getType(Res
);
251 assert((Ty
.isScalar() || Ty
.isPointer()) && "invalid operand type");
253 const ConstantInt
*NewVal
= &Val
;
254 if (Ty
.getSizeInBits() != Val
.getBitWidth())
255 NewVal
= ConstantInt::get(getMF().getFunction().getContext(),
256 Val
.getValue().sextOrTrunc(Ty
.getSizeInBits()));
258 return buildInstr(TargetOpcode::G_CONSTANT
).addDef(Res
).addCImm(NewVal
);
261 MachineInstrBuilder
MachineIRBuilderBase::buildConstant(unsigned Res
,
263 auto IntN
= IntegerType::get(getMF().getFunction().getContext(),
264 getMRI()->getType(Res
).getSizeInBits());
265 ConstantInt
*CI
= ConstantInt::get(IntN
, Val
, true);
266 return buildConstant(Res
, *CI
);
270 MachineIRBuilderBase::buildFConstant(unsigned Res
, const ConstantFP
&Val
) {
271 assert(getMRI()->getType(Res
).isScalar() && "invalid operand type");
273 return buildInstr(TargetOpcode::G_FCONSTANT
).addDef(Res
).addFPImm(&Val
);
276 MachineInstrBuilder
MachineIRBuilderBase::buildFConstant(unsigned Res
,
278 LLT DstTy
= getMRI()->getType(Res
);
279 auto &Ctx
= getMF().getFunction().getContext();
281 ConstantFP::get(Ctx
, getAPFloatFromSize(Val
, DstTy
.getSizeInBits()));
282 return buildFConstant(Res
, *CFP
);
285 MachineInstrBuilder
MachineIRBuilderBase::buildBrCond(unsigned Tst
,
286 MachineBasicBlock
&Dest
) {
287 assert(getMRI()->getType(Tst
).isScalar() && "invalid operand type");
289 return buildInstr(TargetOpcode::G_BRCOND
).addUse(Tst
).addMBB(&Dest
);
292 MachineInstrBuilder
MachineIRBuilderBase::buildLoad(unsigned Res
, unsigned Addr
,
293 MachineMemOperand
&MMO
) {
294 return buildLoadInstr(TargetOpcode::G_LOAD
, Res
, Addr
, MMO
);
298 MachineIRBuilderBase::buildLoadInstr(unsigned Opcode
, unsigned Res
,
299 unsigned Addr
, MachineMemOperand
&MMO
) {
300 assert(getMRI()->getType(Res
).isValid() && "invalid operand type");
301 assert(getMRI()->getType(Addr
).isPointer() && "invalid operand type");
303 return buildInstr(Opcode
)
306 .addMemOperand(&MMO
);
309 MachineInstrBuilder
MachineIRBuilderBase::buildStore(unsigned Val
,
311 MachineMemOperand
&MMO
) {
312 assert(getMRI()->getType(Val
).isValid() && "invalid operand type");
313 assert(getMRI()->getType(Addr
).isPointer() && "invalid operand type");
315 return buildInstr(TargetOpcode::G_STORE
)
318 .addMemOperand(&MMO
);
321 MachineInstrBuilder
MachineIRBuilderBase::buildUAdde(unsigned Res
,
323 unsigned Op0
, unsigned Op1
,
325 assert(getMRI()->getType(Res
).isScalar() && "invalid operand type");
326 assert(getMRI()->getType(Res
) == getMRI()->getType(Op0
) &&
327 getMRI()->getType(Res
) == getMRI()->getType(Op1
) && "type mismatch");
328 assert(getMRI()->getType(CarryOut
).isScalar() && "invalid operand type");
329 assert(getMRI()->getType(CarryOut
) == getMRI()->getType(CarryIn
) &&
332 return buildInstr(TargetOpcode::G_UADDE
)
340 MachineInstrBuilder
MachineIRBuilderBase::buildAnyExt(unsigned Res
,
342 validateTruncExt(Res
, Op
, true);
343 return buildInstr(TargetOpcode::G_ANYEXT
).addDef(Res
).addUse(Op
);
346 MachineInstrBuilder
MachineIRBuilderBase::buildSExt(unsigned Res
, unsigned Op
) {
347 validateTruncExt(Res
, Op
, true);
348 return buildInstr(TargetOpcode::G_SEXT
).addDef(Res
).addUse(Op
);
351 MachineInstrBuilder
MachineIRBuilderBase::buildZExt(unsigned Res
, unsigned Op
) {
352 validateTruncExt(Res
, Op
, true);
353 return buildInstr(TargetOpcode::G_ZEXT
).addDef(Res
).addUse(Op
);
356 MachineInstrBuilder
MachineIRBuilderBase::buildExtOrTrunc(unsigned ExtOpc
,
359 assert((TargetOpcode::G_ANYEXT
== ExtOpc
|| TargetOpcode::G_ZEXT
== ExtOpc
||
360 TargetOpcode::G_SEXT
== ExtOpc
) &&
361 "Expecting Extending Opc");
362 assert(getMRI()->getType(Res
).isScalar() ||
363 getMRI()->getType(Res
).isVector());
364 assert(getMRI()->getType(Res
).isScalar() == getMRI()->getType(Op
).isScalar());
366 unsigned Opcode
= TargetOpcode::COPY
;
367 if (getMRI()->getType(Res
).getSizeInBits() >
368 getMRI()->getType(Op
).getSizeInBits())
370 else if (getMRI()->getType(Res
).getSizeInBits() <
371 getMRI()->getType(Op
).getSizeInBits())
372 Opcode
= TargetOpcode::G_TRUNC
;
374 assert(getMRI()->getType(Res
) == getMRI()->getType(Op
));
376 return buildInstr(Opcode
).addDef(Res
).addUse(Op
);
379 MachineInstrBuilder
MachineIRBuilderBase::buildSExtOrTrunc(unsigned Res
,
381 return buildExtOrTrunc(TargetOpcode::G_SEXT
, Res
, Op
);
384 MachineInstrBuilder
MachineIRBuilderBase::buildZExtOrTrunc(unsigned Res
,
386 return buildExtOrTrunc(TargetOpcode::G_ZEXT
, Res
, Op
);
389 MachineInstrBuilder
MachineIRBuilderBase::buildAnyExtOrTrunc(unsigned Res
,
391 return buildExtOrTrunc(TargetOpcode::G_ANYEXT
, Res
, Op
);
394 MachineInstrBuilder
MachineIRBuilderBase::buildCast(unsigned Dst
,
396 LLT SrcTy
= getMRI()->getType(Src
);
397 LLT DstTy
= getMRI()->getType(Dst
);
399 return buildCopy(Dst
, Src
);
402 if (SrcTy
.isPointer() && DstTy
.isScalar())
403 Opcode
= TargetOpcode::G_PTRTOINT
;
404 else if (DstTy
.isPointer() && SrcTy
.isScalar())
405 Opcode
= TargetOpcode::G_INTTOPTR
;
407 assert(!SrcTy
.isPointer() && !DstTy
.isPointer() && "n G_ADDRCAST yet");
408 Opcode
= TargetOpcode::G_BITCAST
;
411 return buildInstr(Opcode
).addDef(Dst
).addUse(Src
);
415 MachineIRBuilderBase::buildExtract(unsigned Res
, unsigned Src
, uint64_t Index
) {
417 assert(getMRI()->getType(Src
).isValid() && "invalid operand type");
418 assert(getMRI()->getType(Res
).isValid() && "invalid operand type");
419 assert(Index
+ getMRI()->getType(Res
).getSizeInBits() <=
420 getMRI()->getType(Src
).getSizeInBits() &&
421 "extracting off end of register");
424 if (getMRI()->getType(Res
).getSizeInBits() ==
425 getMRI()->getType(Src
).getSizeInBits()) {
426 assert(Index
== 0 && "insertion past the end of a register");
427 return buildCast(Res
, Src
);
430 return buildInstr(TargetOpcode::G_EXTRACT
)
436 void MachineIRBuilderBase::buildSequence(unsigned Res
, ArrayRef
<unsigned> Ops
,
437 ArrayRef
<uint64_t> Indices
) {
439 assert(Ops
.size() == Indices
.size() && "incompatible args");
440 assert(!Ops
.empty() && "invalid trivial sequence");
441 assert(std::is_sorted(Indices
.begin(), Indices
.end()) &&
442 "sequence offsets must be in ascending order");
444 assert(getMRI()->getType(Res
).isValid() && "invalid operand type");
446 assert(getMRI()->getType(Op
).isValid() && "invalid operand type");
449 LLT ResTy
= getMRI()->getType(Res
);
450 LLT OpTy
= getMRI()->getType(Ops
[0]);
451 unsigned OpSize
= OpTy
.getSizeInBits();
452 bool MaybeMerge
= true;
453 for (unsigned i
= 0; i
< Ops
.size(); ++i
) {
454 if (getMRI()->getType(Ops
[i
]) != OpTy
|| Indices
[i
] != i
* OpSize
) {
460 if (MaybeMerge
&& Ops
.size() * OpSize
== ResTy
.getSizeInBits()) {
461 buildMerge(Res
, Ops
);
465 unsigned ResIn
= getMRI()->createGenericVirtualRegister(ResTy
);
468 for (unsigned i
= 0; i
< Ops
.size(); ++i
) {
469 unsigned ResOut
= i
+ 1 == Ops
.size()
471 : getMRI()->createGenericVirtualRegister(ResTy
);
472 buildInsert(ResOut
, ResIn
, Ops
[i
], Indices
[i
]);
477 MachineInstrBuilder
MachineIRBuilderBase::buildUndef(unsigned Res
) {
478 return buildInstr(TargetOpcode::G_IMPLICIT_DEF
).addDef(Res
);
481 MachineInstrBuilder
MachineIRBuilderBase::buildMerge(unsigned Res
,
482 ArrayRef
<unsigned> Ops
) {
485 assert(!Ops
.empty() && "invalid trivial sequence");
486 LLT Ty
= getMRI()->getType(Ops
[0]);
488 assert(getMRI()->getType(Reg
) == Ty
&& "type mismatch in input list");
489 assert(Ops
.size() * getMRI()->getType(Ops
[0]).getSizeInBits() ==
490 getMRI()->getType(Res
).getSizeInBits() &&
491 "input operands do not cover output register");
495 return buildCast(Res
, Ops
[0]);
497 MachineInstrBuilder MIB
= buildInstr(TargetOpcode::G_MERGE_VALUES
);
499 for (unsigned i
= 0; i
< Ops
.size(); ++i
)
504 MachineInstrBuilder
MachineIRBuilderBase::buildUnmerge(ArrayRef
<unsigned> Res
,
508 assert(!Res
.empty() && "invalid trivial sequence");
509 LLT Ty
= getMRI()->getType(Res
[0]);
511 assert(getMRI()->getType(Reg
) == Ty
&& "type mismatch in input list");
512 assert(Res
.size() * getMRI()->getType(Res
[0]).getSizeInBits() ==
513 getMRI()->getType(Op
).getSizeInBits() &&
514 "input operands do not cover output register");
517 MachineInstrBuilder MIB
= buildInstr(TargetOpcode::G_UNMERGE_VALUES
);
518 for (unsigned i
= 0; i
< Res
.size(); ++i
)
524 MachineInstrBuilder
MachineIRBuilderBase::buildInsert(unsigned Res
,
525 unsigned Src
, unsigned Op
,
527 assert(Index
+ getMRI()->getType(Op
).getSizeInBits() <=
528 getMRI()->getType(Res
).getSizeInBits() &&
529 "insertion past the end of a register");
531 if (getMRI()->getType(Res
).getSizeInBits() ==
532 getMRI()->getType(Op
).getSizeInBits()) {
533 return buildCast(Res
, Op
);
536 return buildInstr(TargetOpcode::G_INSERT
)
543 MachineInstrBuilder
MachineIRBuilderBase::buildIntrinsic(Intrinsic::ID ID
,
545 bool HasSideEffects
) {
547 buildInstr(HasSideEffects
? TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS
548 : TargetOpcode::G_INTRINSIC
);
551 MIB
.addIntrinsicID(ID
);
555 MachineInstrBuilder
MachineIRBuilderBase::buildTrunc(unsigned Res
,
557 validateTruncExt(Res
, Op
, false);
558 return buildInstr(TargetOpcode::G_TRUNC
).addDef(Res
).addUse(Op
);
561 MachineInstrBuilder
MachineIRBuilderBase::buildFPTrunc(unsigned Res
,
563 validateTruncExt(Res
, Op
, false);
564 return buildInstr(TargetOpcode::G_FPTRUNC
).addDef(Res
).addUse(Op
);
567 MachineInstrBuilder
MachineIRBuilderBase::buildICmp(CmpInst::Predicate Pred
,
568 unsigned Res
, unsigned Op0
,
571 assert(getMRI()->getType(Op0
) == getMRI()->getType(Op0
) && "type mismatch");
572 assert(CmpInst::isIntPredicate(Pred
) && "invalid predicate");
573 if (getMRI()->getType(Op0
).isScalar() || getMRI()->getType(Op0
).isPointer())
574 assert(getMRI()->getType(Res
).isScalar() && "type mismatch");
576 assert(getMRI()->getType(Res
).isVector() &&
577 getMRI()->getType(Res
).getNumElements() ==
578 getMRI()->getType(Op0
).getNumElements() &&
582 return buildInstr(TargetOpcode::G_ICMP
)
589 MachineInstrBuilder
MachineIRBuilderBase::buildFCmp(CmpInst::Predicate Pred
,
590 unsigned Res
, unsigned Op0
,
593 assert((getMRI()->getType(Op0
).isScalar() ||
594 getMRI()->getType(Op0
).isVector()) &&
595 "invalid operand type");
596 assert(getMRI()->getType(Op0
) == getMRI()->getType(Op1
) && "type mismatch");
597 assert(CmpInst::isFPPredicate(Pred
) && "invalid predicate");
598 if (getMRI()->getType(Op0
).isScalar())
599 assert(getMRI()->getType(Res
).isScalar() && "type mismatch");
601 assert(getMRI()->getType(Res
).isVector() &&
602 getMRI()->getType(Res
).getNumElements() ==
603 getMRI()->getType(Op0
).getNumElements() &&
607 return buildInstr(TargetOpcode::G_FCMP
)
614 MachineInstrBuilder
MachineIRBuilderBase::buildSelect(unsigned Res
,
619 LLT ResTy
= getMRI()->getType(Res
);
620 assert((ResTy
.isScalar() || ResTy
.isVector() || ResTy
.isPointer()) &&
621 "invalid operand type");
622 assert(ResTy
== getMRI()->getType(Op0
) && ResTy
== getMRI()->getType(Op1
) &&
624 if (ResTy
.isScalar() || ResTy
.isPointer())
625 assert(getMRI()->getType(Tst
).isScalar() && "type mismatch");
627 assert((getMRI()->getType(Tst
).isScalar() ||
628 (getMRI()->getType(Tst
).isVector() &&
629 getMRI()->getType(Tst
).getNumElements() ==
630 getMRI()->getType(Op0
).getNumElements())) &&
634 return buildInstr(TargetOpcode::G_SELECT
)
642 MachineIRBuilderBase::buildInsertVectorElement(unsigned Res
, unsigned Val
,
643 unsigned Elt
, unsigned Idx
) {
645 LLT ResTy
= getMRI()->getType(Res
);
646 LLT ValTy
= getMRI()->getType(Val
);
647 LLT EltTy
= getMRI()->getType(Elt
);
648 LLT IdxTy
= getMRI()->getType(Idx
);
649 assert(ResTy
.isVector() && ValTy
.isVector() && "invalid operand type");
650 assert(IdxTy
.isScalar() && "invalid operand type");
651 assert(ResTy
.getNumElements() == ValTy
.getNumElements() && "type mismatch");
652 assert(ResTy
.getElementType() == EltTy
&& "type mismatch");
655 return buildInstr(TargetOpcode::G_INSERT_VECTOR_ELT
)
663 MachineIRBuilderBase::buildExtractVectorElement(unsigned Res
, unsigned Val
,
666 LLT ResTy
= getMRI()->getType(Res
);
667 LLT ValTy
= getMRI()->getType(Val
);
668 LLT IdxTy
= getMRI()->getType(Idx
);
669 assert(ValTy
.isVector() && "invalid operand type");
670 assert((ResTy
.isScalar() || ResTy
.isPointer()) && "invalid operand type");
671 assert(IdxTy
.isScalar() && "invalid operand type");
672 assert(ValTy
.getElementType() == ResTy
&& "type mismatch");
675 return buildInstr(TargetOpcode::G_EXTRACT_VECTOR_ELT
)
681 MachineInstrBuilder
MachineIRBuilderBase::buildAtomicCmpXchgWithSuccess(
682 unsigned OldValRes
, unsigned SuccessRes
, unsigned Addr
, unsigned CmpVal
,
683 unsigned NewVal
, MachineMemOperand
&MMO
) {
685 LLT OldValResTy
= getMRI()->getType(OldValRes
);
686 LLT SuccessResTy
= getMRI()->getType(SuccessRes
);
687 LLT AddrTy
= getMRI()->getType(Addr
);
688 LLT CmpValTy
= getMRI()->getType(CmpVal
);
689 LLT NewValTy
= getMRI()->getType(NewVal
);
690 assert(OldValResTy
.isScalar() && "invalid operand type");
691 assert(SuccessResTy
.isScalar() && "invalid operand type");
692 assert(AddrTy
.isPointer() && "invalid operand type");
693 assert(CmpValTy
.isValid() && "invalid operand type");
694 assert(NewValTy
.isValid() && "invalid operand type");
695 assert(OldValResTy
== CmpValTy
&& "type mismatch");
696 assert(OldValResTy
== NewValTy
&& "type mismatch");
699 return buildInstr(TargetOpcode::G_ATOMIC_CMPXCHG_WITH_SUCCESS
)
705 .addMemOperand(&MMO
);
709 MachineIRBuilderBase::buildAtomicCmpXchg(unsigned OldValRes
, unsigned Addr
,
710 unsigned CmpVal
, unsigned NewVal
,
711 MachineMemOperand
&MMO
) {
713 LLT OldValResTy
= getMRI()->getType(OldValRes
);
714 LLT AddrTy
= getMRI()->getType(Addr
);
715 LLT CmpValTy
= getMRI()->getType(CmpVal
);
716 LLT NewValTy
= getMRI()->getType(NewVal
);
717 assert(OldValResTy
.isScalar() && "invalid operand type");
718 assert(AddrTy
.isPointer() && "invalid operand type");
719 assert(CmpValTy
.isValid() && "invalid operand type");
720 assert(NewValTy
.isValid() && "invalid operand type");
721 assert(OldValResTy
== CmpValTy
&& "type mismatch");
722 assert(OldValResTy
== NewValTy
&& "type mismatch");
725 return buildInstr(TargetOpcode::G_ATOMIC_CMPXCHG
)
730 .addMemOperand(&MMO
);
734 MachineIRBuilderBase::buildAtomicRMW(unsigned Opcode
, unsigned OldValRes
,
735 unsigned Addr
, unsigned Val
,
736 MachineMemOperand
&MMO
) {
738 LLT OldValResTy
= getMRI()->getType(OldValRes
);
739 LLT AddrTy
= getMRI()->getType(Addr
);
740 LLT ValTy
= getMRI()->getType(Val
);
741 assert(OldValResTy
.isScalar() && "invalid operand type");
742 assert(AddrTy
.isPointer() && "invalid operand type");
743 assert(ValTy
.isValid() && "invalid operand type");
744 assert(OldValResTy
== ValTy
&& "type mismatch");
747 return buildInstr(Opcode
)
751 .addMemOperand(&MMO
);
755 MachineIRBuilderBase::buildAtomicRMWXchg(unsigned OldValRes
, unsigned Addr
,
756 unsigned Val
, MachineMemOperand
&MMO
) {
757 return buildAtomicRMW(TargetOpcode::G_ATOMICRMW_XCHG
, OldValRes
, Addr
, Val
,
761 MachineIRBuilderBase::buildAtomicRMWAdd(unsigned OldValRes
, unsigned Addr
,
762 unsigned Val
, MachineMemOperand
&MMO
) {
763 return buildAtomicRMW(TargetOpcode::G_ATOMICRMW_ADD
, OldValRes
, Addr
, Val
,
767 MachineIRBuilderBase::buildAtomicRMWSub(unsigned OldValRes
, unsigned Addr
,
768 unsigned Val
, MachineMemOperand
&MMO
) {
769 return buildAtomicRMW(TargetOpcode::G_ATOMICRMW_SUB
, OldValRes
, Addr
, Val
,
773 MachineIRBuilderBase::buildAtomicRMWAnd(unsigned OldValRes
, unsigned Addr
,
774 unsigned Val
, MachineMemOperand
&MMO
) {
775 return buildAtomicRMW(TargetOpcode::G_ATOMICRMW_AND
, OldValRes
, Addr
, Val
,
779 MachineIRBuilderBase::buildAtomicRMWNand(unsigned OldValRes
, unsigned Addr
,
780 unsigned Val
, MachineMemOperand
&MMO
) {
781 return buildAtomicRMW(TargetOpcode::G_ATOMICRMW_NAND
, OldValRes
, Addr
, Val
,
785 MachineIRBuilderBase::buildAtomicRMWOr(unsigned OldValRes
, unsigned Addr
,
786 unsigned Val
, MachineMemOperand
&MMO
) {
787 return buildAtomicRMW(TargetOpcode::G_ATOMICRMW_OR
, OldValRes
, Addr
, Val
,
791 MachineIRBuilderBase::buildAtomicRMWXor(unsigned OldValRes
, unsigned Addr
,
792 unsigned Val
, MachineMemOperand
&MMO
) {
793 return buildAtomicRMW(TargetOpcode::G_ATOMICRMW_XOR
, OldValRes
, Addr
, Val
,
797 MachineIRBuilderBase::buildAtomicRMWMax(unsigned OldValRes
, unsigned Addr
,
798 unsigned Val
, MachineMemOperand
&MMO
) {
799 return buildAtomicRMW(TargetOpcode::G_ATOMICRMW_MAX
, OldValRes
, Addr
, Val
,
803 MachineIRBuilderBase::buildAtomicRMWMin(unsigned OldValRes
, unsigned Addr
,
804 unsigned Val
, MachineMemOperand
&MMO
) {
805 return buildAtomicRMW(TargetOpcode::G_ATOMICRMW_MIN
, OldValRes
, Addr
, Val
,
809 MachineIRBuilderBase::buildAtomicRMWUmax(unsigned OldValRes
, unsigned Addr
,
810 unsigned Val
, MachineMemOperand
&MMO
) {
811 return buildAtomicRMW(TargetOpcode::G_ATOMICRMW_UMAX
, OldValRes
, Addr
, Val
,
815 MachineIRBuilderBase::buildAtomicRMWUmin(unsigned OldValRes
, unsigned Addr
,
816 unsigned Val
, MachineMemOperand
&MMO
) {
817 return buildAtomicRMW(TargetOpcode::G_ATOMICRMW_UMIN
, OldValRes
, Addr
, Val
,
822 MachineIRBuilderBase::buildBlockAddress(unsigned Res
, const BlockAddress
*BA
) {
824 assert(getMRI()->getType(Res
).isPointer() && "invalid res type");
827 return buildInstr(TargetOpcode::G_BLOCK_ADDR
).addDef(Res
).addBlockAddress(BA
);
830 void MachineIRBuilderBase::validateTruncExt(unsigned Dst
, unsigned Src
,
833 LLT SrcTy
= getMRI()->getType(Src
);
834 LLT DstTy
= getMRI()->getType(Dst
);
836 if (DstTy
.isVector()) {
837 assert(SrcTy
.isVector() && "mismatched cast between vector and non-vector");
838 assert(SrcTy
.getNumElements() == DstTy
.getNumElements() &&
839 "different number of elements in a trunc/ext");
841 assert(DstTy
.isScalar() && SrcTy
.isScalar() && "invalid extend/trunc");
844 assert(DstTy
.getSizeInBits() > SrcTy
.getSizeInBits() &&
845 "invalid narrowing extend");
847 assert(DstTy
.getSizeInBits() < SrcTy
.getSizeInBits() &&
848 "invalid widening trunc");