blob: 1ab4cd7048240ce0ae683435198b461e38c50f56 [file] [log] [blame]
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001//===-- llvm/CodeGen/GlobalISel/MachineIRBuilder.h - MIBuilder --*- C++ -*-===//
2//
Andrew Walbran16937d02019-10-22 13:54:20 +01003// 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
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01006//
7//===----------------------------------------------------------------------===//
8/// \file
9/// This file declares the MachineIRBuilder class.
10/// This is a helper class to build MachineInstr.
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_CODEGEN_GLOBALISEL_MACHINEIRBUILDER_H
14#define LLVM_CODEGEN_GLOBALISEL_MACHINEIRBUILDER_H
15
Andrew Walbran16937d02019-10-22 13:54:20 +010016#include "llvm/CodeGen/GlobalISel/CSEInfo.h"
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010017#include "llvm/CodeGen/LowLevelType.h"
18#include "llvm/CodeGen/MachineBasicBlock.h"
19#include "llvm/CodeGen/MachineInstrBuilder.h"
20#include "llvm/CodeGen/MachineRegisterInfo.h"
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020021#include "llvm/CodeGen/TargetOpcodes.h"
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010022#include "llvm/IR/Constants.h"
23#include "llvm/IR/DebugLoc.h"
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020024#include "llvm/IR/Module.h"
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010025
26namespace llvm {
27
28// Forward declarations.
29class MachineFunction;
30class MachineInstr;
31class TargetInstrInfo;
Andrew Walbran16937d02019-10-22 13:54:20 +010032class GISelChangeObserver;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010033
Andrew Scullcdfcccc2018-10-05 20:58:37 +010034/// Class which stores all the state required in a MachineIRBuilder.
35/// Since MachineIRBuilders will only store state in this object, it allows
36/// to transfer BuilderState between different kinds of MachineIRBuilders.
37struct MachineIRBuilderState {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010038 /// MachineFunction under construction.
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020039 MachineFunction *MF = nullptr;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010040 /// Information used to access the description of the opcodes.
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020041 const TargetInstrInfo *TII = nullptr;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010042 /// Information used to verify types are consistent and to create virtual registers.
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020043 MachineRegisterInfo *MRI = nullptr;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010044 /// Debug location to be set to any instruction we create.
45 DebugLoc DL;
46
47 /// \name Fields describing the insertion point.
48 /// @{
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020049 MachineBasicBlock *MBB = nullptr;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010050 MachineBasicBlock::iterator II;
51 /// @}
52
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020053 GISelChangeObserver *Observer = nullptr;
Andrew Walbran16937d02019-10-22 13:54:20 +010054
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020055 GISelCSEInfo *CSEInfo = nullptr;
Andrew Scullcdfcccc2018-10-05 20:58:37 +010056};
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010057
Andrew Walbran16937d02019-10-22 13:54:20 +010058class DstOp {
59 union {
60 LLT LLTTy;
Andrew Walbran3d2c1972020-04-07 12:24:26 +010061 Register Reg;
Andrew Walbran16937d02019-10-22 13:54:20 +010062 const TargetRegisterClass *RC;
63 };
64
65public:
66 enum class DstType { Ty_LLT, Ty_Reg, Ty_RC };
67 DstOp(unsigned R) : Reg(R), Ty(DstType::Ty_Reg) {}
Andrew Walbran3d2c1972020-04-07 12:24:26 +010068 DstOp(Register R) : Reg(R), Ty(DstType::Ty_Reg) {}
Andrew Walbran16937d02019-10-22 13:54:20 +010069 DstOp(const MachineOperand &Op) : Reg(Op.getReg()), Ty(DstType::Ty_Reg) {}
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020070 DstOp(const LLT T) : LLTTy(T), Ty(DstType::Ty_LLT) {}
Andrew Walbran16937d02019-10-22 13:54:20 +010071 DstOp(const TargetRegisterClass *TRC) : RC(TRC), Ty(DstType::Ty_RC) {}
72
73 void addDefToMIB(MachineRegisterInfo &MRI, MachineInstrBuilder &MIB) const {
74 switch (Ty) {
75 case DstType::Ty_Reg:
76 MIB.addDef(Reg);
77 break;
78 case DstType::Ty_LLT:
79 MIB.addDef(MRI.createGenericVirtualRegister(LLTTy));
80 break;
81 case DstType::Ty_RC:
82 MIB.addDef(MRI.createVirtualRegister(RC));
83 break;
84 }
85 }
86
87 LLT getLLTTy(const MachineRegisterInfo &MRI) const {
88 switch (Ty) {
89 case DstType::Ty_RC:
90 return LLT{};
91 case DstType::Ty_LLT:
92 return LLTTy;
93 case DstType::Ty_Reg:
94 return MRI.getType(Reg);
95 }
96 llvm_unreachable("Unrecognised DstOp::DstType enum");
97 }
98
Andrew Walbran3d2c1972020-04-07 12:24:26 +010099 Register getReg() const {
Andrew Walbran16937d02019-10-22 13:54:20 +0100100 assert(Ty == DstType::Ty_Reg && "Not a register");
101 return Reg;
102 }
103
104 const TargetRegisterClass *getRegClass() const {
105 switch (Ty) {
106 case DstType::Ty_RC:
107 return RC;
108 default:
109 llvm_unreachable("Not a RC Operand");
110 }
111 }
112
113 DstType getDstOpKind() const { return Ty; }
114
115private:
116 DstType Ty;
117};
118
119class SrcOp {
120 union {
121 MachineInstrBuilder SrcMIB;
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100122 Register Reg;
Andrew Walbran16937d02019-10-22 13:54:20 +0100123 CmpInst::Predicate Pred;
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200124 int64_t Imm;
Andrew Walbran16937d02019-10-22 13:54:20 +0100125 };
126
127public:
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200128 enum class SrcType { Ty_Reg, Ty_MIB, Ty_Predicate, Ty_Imm };
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100129 SrcOp(Register R) : Reg(R), Ty(SrcType::Ty_Reg) {}
Andrew Walbran16937d02019-10-22 13:54:20 +0100130 SrcOp(const MachineOperand &Op) : Reg(Op.getReg()), Ty(SrcType::Ty_Reg) {}
131 SrcOp(const MachineInstrBuilder &MIB) : SrcMIB(MIB), Ty(SrcType::Ty_MIB) {}
132 SrcOp(const CmpInst::Predicate P) : Pred(P), Ty(SrcType::Ty_Predicate) {}
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200133 /// Use of registers held in unsigned integer variables (or more rarely signed
134 /// integers) is no longer permitted to avoid ambiguity with upcoming support
135 /// for immediates.
136 SrcOp(unsigned) = delete;
137 SrcOp(int) = delete;
138 SrcOp(uint64_t V) : Imm(V), Ty(SrcType::Ty_Imm) {}
139 SrcOp(int64_t V) : Imm(V), Ty(SrcType::Ty_Imm) {}
Andrew Walbran16937d02019-10-22 13:54:20 +0100140
141 void addSrcToMIB(MachineInstrBuilder &MIB) const {
142 switch (Ty) {
143 case SrcType::Ty_Predicate:
144 MIB.addPredicate(Pred);
145 break;
146 case SrcType::Ty_Reg:
147 MIB.addUse(Reg);
148 break;
149 case SrcType::Ty_MIB:
150 MIB.addUse(SrcMIB->getOperand(0).getReg());
151 break;
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200152 case SrcType::Ty_Imm:
153 MIB.addImm(Imm);
154 break;
Andrew Walbran16937d02019-10-22 13:54:20 +0100155 }
156 }
157
158 LLT getLLTTy(const MachineRegisterInfo &MRI) const {
159 switch (Ty) {
160 case SrcType::Ty_Predicate:
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200161 case SrcType::Ty_Imm:
Andrew Walbran16937d02019-10-22 13:54:20 +0100162 llvm_unreachable("Not a register operand");
163 case SrcType::Ty_Reg:
164 return MRI.getType(Reg);
165 case SrcType::Ty_MIB:
166 return MRI.getType(SrcMIB->getOperand(0).getReg());
167 }
168 llvm_unreachable("Unrecognised SrcOp::SrcType enum");
169 }
170
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100171 Register getReg() const {
Andrew Walbran16937d02019-10-22 13:54:20 +0100172 switch (Ty) {
173 case SrcType::Ty_Predicate:
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200174 case SrcType::Ty_Imm:
Andrew Walbran16937d02019-10-22 13:54:20 +0100175 llvm_unreachable("Not a register operand");
176 case SrcType::Ty_Reg:
177 return Reg;
178 case SrcType::Ty_MIB:
179 return SrcMIB->getOperand(0).getReg();
180 }
181 llvm_unreachable("Unrecognised SrcOp::SrcType enum");
182 }
183
184 CmpInst::Predicate getPredicate() const {
185 switch (Ty) {
186 case SrcType::Ty_Predicate:
187 return Pred;
188 default:
189 llvm_unreachable("Not a register operand");
190 }
191 }
192
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200193 int64_t getImm() const {
194 switch (Ty) {
195 case SrcType::Ty_Imm:
196 return Imm;
197 default:
198 llvm_unreachable("Not an immediate");
199 }
200 }
201
Andrew Walbran16937d02019-10-22 13:54:20 +0100202 SrcType getSrcOpKind() const { return Ty; }
203
204private:
205 SrcType Ty;
206};
207
208class FlagsOp {
209 Optional<unsigned> Flags;
210
211public:
212 explicit FlagsOp(unsigned F) : Flags(F) {}
213 FlagsOp() : Flags(None) {}
214 Optional<unsigned> getFlags() const { return Flags; }
215};
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100216/// Helper class to build MachineInstr.
217/// It keeps internally the insertion point and debug location for all
218/// the new instructions we want to create.
219/// This information can be modify via the related setters.
Andrew Walbran16937d02019-10-22 13:54:20 +0100220class MachineIRBuilder {
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100221
222 MachineIRBuilderState State;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100223
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100224protected:
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200225 void validateTruncExt(const LLT Dst, const LLT Src, bool IsExtend);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100226
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200227 void validateUnaryOp(const LLT Res, const LLT Op0);
228 void validateBinaryOp(const LLT Res, const LLT Op0, const LLT Op1);
229 void validateShiftOp(const LLT Res, const LLT Op0, const LLT Op1);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100230
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200231 void validateSelectOp(const LLT ResTy, const LLT TstTy, const LLT Op0Ty,
232 const LLT Op1Ty);
233
234 void recordInsertion(MachineInstr *InsertedInstr) const {
235 if (State.Observer)
236 State.Observer->createdInstr(*InsertedInstr);
237 }
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100238
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100239public:
240 /// Some constructors for easy use.
Andrew Walbran16937d02019-10-22 13:54:20 +0100241 MachineIRBuilder() = default;
242 MachineIRBuilder(MachineFunction &MF) { setMF(MF); }
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200243
244 MachineIRBuilder(MachineBasicBlock &MBB, MachineBasicBlock::iterator InsPt) {
245 setMF(*MBB.getParent());
246 setInsertPt(MBB, InsPt);
247 }
248
249 MachineIRBuilder(MachineInstr &MI) :
250 MachineIRBuilder(*MI.getParent(), MI.getIterator()) {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100251 setInstr(MI);
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200252 setDebugLoc(MI.getDebugLoc());
253 }
254
255 MachineIRBuilder(MachineInstr &MI, GISelChangeObserver &Observer) :
256 MachineIRBuilder(MI) {
257 setChangeObserver(Observer);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100258 }
259
Andrew Walbran16937d02019-10-22 13:54:20 +0100260 virtual ~MachineIRBuilder() = default;
261
262 MachineIRBuilder(const MachineIRBuilderState &BState) : State(BState) {}
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100263
Andrew Scull0372a572018-11-16 15:47:06 +0000264 const TargetInstrInfo &getTII() {
265 assert(State.TII && "TargetInstrInfo is not set");
266 return *State.TII;
267 }
268
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100269 /// Getter for the function we currently build.
270 MachineFunction &getMF() {
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100271 assert(State.MF && "MachineFunction is not set");
272 return *State.MF;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100273 }
274
Andrew Walbran16937d02019-10-22 13:54:20 +0100275 const MachineFunction &getMF() const {
276 assert(State.MF && "MachineFunction is not set");
277 return *State.MF;
278 }
279
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100280 const DataLayout &getDataLayout() const {
281 return getMF().getFunction().getParent()->getDataLayout();
282 }
283
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100284 /// Getter for DebugLoc
285 const DebugLoc &getDL() { return State.DL; }
286
287 /// Getter for MRI
288 MachineRegisterInfo *getMRI() { return State.MRI; }
Andrew Walbran16937d02019-10-22 13:54:20 +0100289 const MachineRegisterInfo *getMRI() const { return State.MRI; }
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100290
291 /// Getter for the State
292 MachineIRBuilderState &getState() { return State; }
293
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100294 /// Getter for the basic block we currently build.
Andrew Walbran16937d02019-10-22 13:54:20 +0100295 const MachineBasicBlock &getMBB() const {
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100296 assert(State.MBB && "MachineBasicBlock is not set");
297 return *State.MBB;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100298 }
299
Andrew Walbran16937d02019-10-22 13:54:20 +0100300 MachineBasicBlock &getMBB() {
301 return const_cast<MachineBasicBlock &>(
302 const_cast<const MachineIRBuilder *>(this)->getMBB());
303 }
304
305 GISelCSEInfo *getCSEInfo() { return State.CSEInfo; }
306 const GISelCSEInfo *getCSEInfo() const { return State.CSEInfo; }
307
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100308 /// Current insertion point for new instructions.
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100309 MachineBasicBlock::iterator getInsertPt() { return State.II; }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100310
311 /// Set the insertion point before the specified position.
312 /// \pre MBB must be in getMF().
313 /// \pre II must be a valid iterator in MBB.
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200314 void setInsertPt(MachineBasicBlock &MBB, MachineBasicBlock::iterator II) {
315 assert(MBB.getParent() == &getMF() &&
316 "Basic block is in a different function");
317 State.MBB = &MBB;
318 State.II = II;
319 }
320
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100321 /// @}
322
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200323 void setCSEInfo(GISelCSEInfo *Info) { State.CSEInfo = Info; }
Andrew Walbran16937d02019-10-22 13:54:20 +0100324
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100325 /// \name Setters for the insertion point.
326 /// @{
327 /// Set the MachineFunction where to build instructions.
Andrew Walbran16937d02019-10-22 13:54:20 +0100328 void setMF(MachineFunction &MF);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100329
330 /// Set the insertion point to the end of \p MBB.
331 /// \pre \p MBB must be contained by getMF().
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200332 void setMBB(MachineBasicBlock &MBB) {
333 State.MBB = &MBB;
334 State.II = MBB.end();
335 assert(&getMF() == MBB.getParent() &&
336 "Basic block is in a different function");
337 }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100338
339 /// Set the insertion point to before MI.
340 /// \pre MI must be in getMF().
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200341 void setInstr(MachineInstr &MI) {
342 assert(MI.getParent() && "Instruction is not part of a basic block");
343 setMBB(*MI.getParent());
344 State.II = MI.getIterator();
345 }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100346 /// @}
347
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200348 /// Set the insertion point to before MI, and set the debug loc to MI's loc.
349 /// \pre MI must be in getMF().
350 void setInstrAndDebugLoc(MachineInstr &MI) {
351 setInstr(MI);
352 setDebugLoc(MI.getDebugLoc());
353 }
354
355 void setChangeObserver(GISelChangeObserver &Observer) {
356 State.Observer = &Observer;
357 }
358
359 void stopObservingChanges() { State.Observer = nullptr; }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100360 /// @}
361
362 /// Set the debug location to \p DL for all the next build instructions.
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100363 void setDebugLoc(const DebugLoc &DL) { this->State.DL = DL; }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100364
365 /// Get the current instruction's debug location.
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100366 DebugLoc getDebugLoc() { return State.DL; }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100367
368 /// Build and insert <empty> = \p Opcode <empty>.
369 /// The insertion point is the one set by the last call of either
370 /// setBasicBlock or setMI.
371 ///
372 /// \pre setBasicBlock or setMI must have been called.
373 ///
374 /// \return a MachineInstrBuilder for the newly created instruction.
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200375 MachineInstrBuilder buildInstr(unsigned Opcode) {
376 return insertInstr(buildInstrNoInsert(Opcode));
377 }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100378
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100379 /// Build but don't insert <empty> = \p Opcode <empty>.
380 ///
381 /// \pre setMF, setBasicBlock or setMI must have been called.
382 ///
383 /// \return a MachineInstrBuilder for the newly created instruction.
384 MachineInstrBuilder buildInstrNoInsert(unsigned Opcode);
385
386 /// Insert an existing instruction at the insertion point.
387 MachineInstrBuilder insertInstr(MachineInstrBuilder MIB);
388
389 /// Build and insert a DBG_VALUE instruction expressing the fact that the
390 /// associated \p Variable lives in \p Reg (suitably modified by \p Expr).
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100391 MachineInstrBuilder buildDirectDbgValue(Register Reg, const MDNode *Variable,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100392 const MDNode *Expr);
393
394 /// Build and insert a DBG_VALUE instruction expressing the fact that the
395 /// associated \p Variable lives in memory at \p Reg (suitably modified by \p
396 /// Expr).
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100397 MachineInstrBuilder buildIndirectDbgValue(Register Reg,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100398 const MDNode *Variable,
399 const MDNode *Expr);
400
401 /// Build and insert a DBG_VALUE instruction expressing the fact that the
402 /// associated \p Variable lives in the stack slot specified by \p FI
403 /// (suitably modified by \p Expr).
404 MachineInstrBuilder buildFIDbgValue(int FI, const MDNode *Variable,
405 const MDNode *Expr);
406
407 /// Build and insert a DBG_VALUE instructions specifying that \p Variable is
408 /// given by \p C (suitably modified by \p Expr).
409 MachineInstrBuilder buildConstDbgValue(const Constant &C,
410 const MDNode *Variable,
411 const MDNode *Expr);
412
Andrew Scull0372a572018-11-16 15:47:06 +0000413 /// Build and insert a DBG_LABEL instructions specifying that \p Label is
414 /// given. Convert "llvm.dbg.label Label" to "DBG_LABEL Label".
415 MachineInstrBuilder buildDbgLabel(const MDNode *Label);
416
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200417 /// Build and insert \p Res = G_DYN_STACKALLOC \p Size, \p Align
418 ///
419 /// G_DYN_STACKALLOC does a dynamic stack allocation and writes the address of
420 /// the allocated memory into \p Res.
421 /// \pre setBasicBlock or setMI must have been called.
422 /// \pre \p Res must be a generic virtual register with pointer type.
423 ///
424 /// \return a MachineInstrBuilder for the newly created instruction.
425 MachineInstrBuilder buildDynStackAlloc(const DstOp &Res, const SrcOp &Size,
426 Align Alignment);
427
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100428 /// Build and insert \p Res = G_FRAME_INDEX \p Idx
429 ///
430 /// G_FRAME_INDEX materializes the address of an alloca value or other
431 /// stack-based object.
432 ///
433 /// \pre setBasicBlock or setMI must have been called.
434 /// \pre \p Res must be a generic virtual register with pointer type.
435 ///
436 /// \return a MachineInstrBuilder for the newly created instruction.
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100437 MachineInstrBuilder buildFrameIndex(const DstOp &Res, int Idx);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100438
439 /// Build and insert \p Res = G_GLOBAL_VALUE \p GV
440 ///
441 /// G_GLOBAL_VALUE materializes the address of the specified global
442 /// into \p Res.
443 ///
444 /// \pre setBasicBlock or setMI must have been called.
445 /// \pre \p Res must be a generic virtual register with pointer type
446 /// in the same address space as \p GV.
447 ///
448 /// \return a MachineInstrBuilder for the newly created instruction.
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100449 MachineInstrBuilder buildGlobalValue(const DstOp &Res, const GlobalValue *GV);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100450
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200451 /// Build and insert \p Res = G_PTR_ADD \p Op0, \p Op1
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100452 ///
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200453 /// G_PTR_ADD adds \p Op1 addressible units to the pointer specified by \p Op0,
454 /// storing the resulting pointer in \p Res. Addressible units are typically
455 /// bytes but this can vary between targets.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100456 ///
457 /// \pre setBasicBlock or setMI must have been called.
458 /// \pre \p Res and \p Op0 must be generic virtual registers with pointer
459 /// type.
460 /// \pre \p Op1 must be a generic virtual register with scalar type.
461 ///
462 /// \return a MachineInstrBuilder for the newly created instruction.
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200463 MachineInstrBuilder buildPtrAdd(const DstOp &Res, const SrcOp &Op0,
464 const SrcOp &Op1);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100465
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200466 /// Materialize and insert \p Res = G_PTR_ADD \p Op0, (G_CONSTANT \p Value)
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100467 ///
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200468 /// G_PTR_ADD adds \p Value bytes to the pointer specified by \p Op0,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100469 /// storing the resulting pointer in \p Res. If \p Value is zero then no
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200470 /// G_PTR_ADD or G_CONSTANT will be created and \pre Op0 will be assigned to
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100471 /// \p Res.
472 ///
473 /// \pre setBasicBlock or setMI must have been called.
474 /// \pre \p Op0 must be a generic virtual register with pointer type.
475 /// \pre \p ValueTy must be a scalar type.
476 /// \pre \p Res must be 0. This is to detect confusion between
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200477 /// materializePtrAdd() and buildPtrAdd().
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100478 /// \post \p Res will either be a new generic virtual register of the same
479 /// type as \p Op0 or \p Op0 itself.
480 ///
481 /// \return a MachineInstrBuilder for the newly created instruction.
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200482 Optional<MachineInstrBuilder> materializePtrAdd(Register &Res, Register Op0,
483 const LLT ValueTy,
484 uint64_t Value);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100485
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200486 /// Build and insert \p Res = G_PTRMASK \p Op0, \p Op1
487 MachineInstrBuilder buildPtrMask(const DstOp &Res, const SrcOp &Op0,
488 const SrcOp &Op1) {
489 return buildInstr(TargetOpcode::G_PTRMASK, {Res}, {Op0, Op1});
490 }
491
492 /// Build and insert \p Res = G_PTRMASK \p Op0, \p G_CONSTANT (1 << NumBits) - 1
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100493 ///
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200494 /// This clears the low bits of a pointer operand without destroying its
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100495 /// pointer properties. This has the effect of rounding the address *down* to
496 /// a specified alignment in bits.
497 ///
498 /// \pre setBasicBlock or setMI must have been called.
499 /// \pre \p Res and \p Op0 must be generic virtual registers with pointer
500 /// type.
501 /// \pre \p NumBits must be an integer representing the number of low bits to
502 /// be cleared in \p Op0.
503 ///
504 /// \return a MachineInstrBuilder for the newly created instruction.
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200505 MachineInstrBuilder buildMaskLowPtrBits(const DstOp &Res, const SrcOp &Op0,
506 uint32_t NumBits);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100507
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100508 /// Build and insert \p Res, \p CarryOut = G_UADDO \p Op0, \p Op1
509 ///
510 /// G_UADDO sets \p Res to \p Op0 + \p Op1 (truncated to the bit width) and
511 /// sets \p CarryOut to 1 if the result overflowed in unsigned arithmetic.
512 ///
513 /// \pre setBasicBlock or setMI must have been called.
514 /// \pre \p Res, \p Op0 and \p Op1 must be generic virtual registers with the
515 /// same scalar type.
516 ////\pre \p CarryOut must be generic virtual register with scalar type
517 ///(typically s1)
518 ///
519 /// \return The newly created instruction.
520 MachineInstrBuilder buildUAddo(const DstOp &Res, const DstOp &CarryOut,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200521 const SrcOp &Op0, const SrcOp &Op1) {
522 return buildInstr(TargetOpcode::G_UADDO, {Res, CarryOut}, {Op0, Op1});
523 }
524
525 /// Build and insert \p Res, \p CarryOut = G_USUBO \p Op0, \p Op1
526 MachineInstrBuilder buildUSubo(const DstOp &Res, const DstOp &CarryOut,
527 const SrcOp &Op0, const SrcOp &Op1) {
528 return buildInstr(TargetOpcode::G_USUBO, {Res, CarryOut}, {Op0, Op1});
529 }
530
531 /// Build and insert \p Res, \p CarryOut = G_SADDO \p Op0, \p Op1
532 MachineInstrBuilder buildSAddo(const DstOp &Res, const DstOp &CarryOut,
533 const SrcOp &Op0, const SrcOp &Op1) {
534 return buildInstr(TargetOpcode::G_SADDO, {Res, CarryOut}, {Op0, Op1});
535 }
536
537 /// Build and insert \p Res, \p CarryOut = G_SUBO \p Op0, \p Op1
538 MachineInstrBuilder buildSSubo(const DstOp &Res, const DstOp &CarryOut,
539 const SrcOp &Op0, const SrcOp &Op1) {
540 return buildInstr(TargetOpcode::G_SSUBO, {Res, CarryOut}, {Op0, Op1});
541 }
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100542
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100543 /// Build and insert \p Res, \p CarryOut = G_UADDE \p Op0,
544 /// \p Op1, \p CarryIn
545 ///
546 /// G_UADDE sets \p Res to \p Op0 + \p Op1 + \p CarryIn (truncated to the bit
547 /// width) and sets \p CarryOut to 1 if the result overflowed in unsigned
548 /// arithmetic.
549 ///
550 /// \pre setBasicBlock or setMI must have been called.
551 /// \pre \p Res, \p Op0 and \p Op1 must be generic virtual registers
552 /// with the same scalar type.
553 /// \pre \p CarryOut and \p CarryIn must be generic virtual
554 /// registers with the same scalar type (typically s1)
555 ///
556 /// \return The newly created instruction.
Andrew Walbran16937d02019-10-22 13:54:20 +0100557 MachineInstrBuilder buildUAdde(const DstOp &Res, const DstOp &CarryOut,
558 const SrcOp &Op0, const SrcOp &Op1,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200559 const SrcOp &CarryIn) {
560 return buildInstr(TargetOpcode::G_UADDE, {Res, CarryOut},
561 {Op0, Op1, CarryIn});
562 }
563
564 /// Build and insert \p Res, \p CarryOut = G_USUBE \p Op0, \p Op1, \p CarryInp
565 MachineInstrBuilder buildUSube(const DstOp &Res, const DstOp &CarryOut,
566 const SrcOp &Op0, const SrcOp &Op1,
567 const SrcOp &CarryIn) {
568 return buildInstr(TargetOpcode::G_USUBE, {Res, CarryOut},
569 {Op0, Op1, CarryIn});
570 }
571
572 /// Build and insert \p Res, \p CarryOut = G_SADDE \p Op0, \p Op1, \p CarryInp
573 MachineInstrBuilder buildSAdde(const DstOp &Res, const DstOp &CarryOut,
574 const SrcOp &Op0, const SrcOp &Op1,
575 const SrcOp &CarryIn) {
576 return buildInstr(TargetOpcode::G_SADDE, {Res, CarryOut},
577 {Op0, Op1, CarryIn});
578 }
579
580 /// Build and insert \p Res, \p CarryOut = G_SSUBE \p Op0, \p Op1, \p CarryInp
581 MachineInstrBuilder buildSSube(const DstOp &Res, const DstOp &CarryOut,
582 const SrcOp &Op0, const SrcOp &Op1,
583 const SrcOp &CarryIn) {
584 return buildInstr(TargetOpcode::G_SSUBE, {Res, CarryOut},
585 {Op0, Op1, CarryIn});
586 }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100587
588 /// Build and insert \p Res = G_ANYEXT \p Op0
589 ///
590 /// G_ANYEXT produces a register of the specified width, with bits 0 to
591 /// sizeof(\p Ty) * 8 set to \p Op. The remaining bits are unspecified
592 /// (i.e. this is neither zero nor sign-extension). For a vector register,
593 /// each element is extended individually.
594 ///
595 /// \pre setBasicBlock or setMI must have been called.
596 /// \pre \p Res must be a generic virtual register with scalar or vector type.
597 /// \pre \p Op must be a generic virtual register with scalar or vector type.
598 /// \pre \p Op must be smaller than \p Res
599 ///
600 /// \return The newly created instruction.
601
Andrew Walbran16937d02019-10-22 13:54:20 +0100602 MachineInstrBuilder buildAnyExt(const DstOp &Res, const SrcOp &Op);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100603
604 /// Build and insert \p Res = G_SEXT \p Op
605 ///
606 /// G_SEXT produces a register of the specified width, with bits 0 to
607 /// sizeof(\p Ty) * 8 set to \p Op. The remaining bits are duplicated from the
608 /// high bit of \p Op (i.e. 2s-complement sign extended).
609 ///
610 /// \pre setBasicBlock or setMI must have been called.
611 /// \pre \p Res must be a generic virtual register with scalar or vector type.
612 /// \pre \p Op must be a generic virtual register with scalar or vector type.
613 /// \pre \p Op must be smaller than \p Res
614 ///
615 /// \return The newly created instruction.
Andrew Walbran16937d02019-10-22 13:54:20 +0100616 MachineInstrBuilder buildSExt(const DstOp &Res, const SrcOp &Op);
617
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200618 /// Build and insert \p Res = G_SEXT_INREG \p Op, ImmOp
619 MachineInstrBuilder buildSExtInReg(const DstOp &Res, const SrcOp &Op, int64_t ImmOp) {
620 return buildInstr(TargetOpcode::G_SEXT_INREG, {Res}, {Op, SrcOp(ImmOp)});
621 }
622
623 /// Build and insert \p Res = G_FPEXT \p Op
624 MachineInstrBuilder buildFPExt(const DstOp &Res, const SrcOp &Op,
625 Optional<unsigned> Flags = None) {
626 return buildInstr(TargetOpcode::G_FPEXT, {Res}, {Op}, Flags);
627 }
628
629
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100630 /// Build and insert a G_PTRTOINT instruction.
631 MachineInstrBuilder buildPtrToInt(const DstOp &Dst, const SrcOp &Src) {
632 return buildInstr(TargetOpcode::G_PTRTOINT, {Dst}, {Src});
633 }
634
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200635 /// Build and insert a G_INTTOPTR instruction.
636 MachineInstrBuilder buildIntToPtr(const DstOp &Dst, const SrcOp &Src) {
637 return buildInstr(TargetOpcode::G_INTTOPTR, {Dst}, {Src});
638 }
639
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100640 /// Build and insert \p Dst = G_BITCAST \p Src
641 MachineInstrBuilder buildBitcast(const DstOp &Dst, const SrcOp &Src) {
642 return buildInstr(TargetOpcode::G_BITCAST, {Dst}, {Src});
643 }
644
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200645 /// Build and insert \p Dst = G_ADDRSPACE_CAST \p Src
646 MachineInstrBuilder buildAddrSpaceCast(const DstOp &Dst, const SrcOp &Src) {
647 return buildInstr(TargetOpcode::G_ADDRSPACE_CAST, {Dst}, {Src});
648 }
649
Andrew Walbran16937d02019-10-22 13:54:20 +0100650 /// \return The opcode of the extension the target wants to use for boolean
651 /// values.
652 unsigned getBoolExtOp(bool IsVec, bool IsFP) const;
653
654 // Build and insert \p Res = G_ANYEXT \p Op, \p Res = G_SEXT \p Op, or \p Res
655 // = G_ZEXT \p Op depending on how the target wants to extend boolean values.
656 MachineInstrBuilder buildBoolExt(const DstOp &Res, const SrcOp &Op,
657 bool IsFP);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100658
659 /// Build and insert \p Res = G_ZEXT \p Op
660 ///
661 /// G_ZEXT produces a register of the specified width, with bits 0 to
662 /// sizeof(\p Ty) * 8 set to \p Op. The remaining bits are 0. For a vector
663 /// register, each element is extended individually.
664 ///
665 /// \pre setBasicBlock or setMI must have been called.
666 /// \pre \p Res must be a generic virtual register with scalar or vector type.
667 /// \pre \p Op must be a generic virtual register with scalar or vector type.
668 /// \pre \p Op must be smaller than \p Res
669 ///
670 /// \return The newly created instruction.
Andrew Walbran16937d02019-10-22 13:54:20 +0100671 MachineInstrBuilder buildZExt(const DstOp &Res, const SrcOp &Op);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100672
673 /// Build and insert \p Res = G_SEXT \p Op, \p Res = G_TRUNC \p Op, or
674 /// \p Res = COPY \p Op depending on the differing sizes of \p Res and \p Op.
675 /// ///
676 /// \pre setBasicBlock or setMI must have been called.
677 /// \pre \p Res must be a generic virtual register with scalar or vector type.
678 /// \pre \p Op must be a generic virtual register with scalar or vector type.
679 ///
680 /// \return The newly created instruction.
Andrew Walbran16937d02019-10-22 13:54:20 +0100681 MachineInstrBuilder buildSExtOrTrunc(const DstOp &Res, const SrcOp &Op);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100682
683 /// Build and insert \p Res = G_ZEXT \p Op, \p Res = G_TRUNC \p Op, or
684 /// \p Res = COPY \p Op depending on the differing sizes of \p Res and \p Op.
685 /// ///
686 /// \pre setBasicBlock or setMI must have been called.
687 /// \pre \p Res must be a generic virtual register with scalar or vector type.
688 /// \pre \p Op must be a generic virtual register with scalar or vector type.
689 ///
690 /// \return The newly created instruction.
Andrew Walbran16937d02019-10-22 13:54:20 +0100691 MachineInstrBuilder buildZExtOrTrunc(const DstOp &Res, const SrcOp &Op);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100692
693 // Build and insert \p Res = G_ANYEXT \p Op, \p Res = G_TRUNC \p Op, or
694 /// \p Res = COPY \p Op depending on the differing sizes of \p Res and \p Op.
695 /// ///
696 /// \pre setBasicBlock or setMI must have been called.
697 /// \pre \p Res must be a generic virtual register with scalar or vector type.
698 /// \pre \p Op must be a generic virtual register with scalar or vector type.
699 ///
700 /// \return The newly created instruction.
Andrew Walbran16937d02019-10-22 13:54:20 +0100701 MachineInstrBuilder buildAnyExtOrTrunc(const DstOp &Res, const SrcOp &Op);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100702
703 /// Build and insert \p Res = \p ExtOpc, \p Res = G_TRUNC \p
704 /// Op, or \p Res = COPY \p Op depending on the differing sizes of \p Res and
705 /// \p Op.
706 /// ///
707 /// \pre setBasicBlock or setMI must have been called.
708 /// \pre \p Res must be a generic virtual register with scalar or vector type.
709 /// \pre \p Op must be a generic virtual register with scalar or vector type.
710 ///
711 /// \return The newly created instruction.
Andrew Walbran16937d02019-10-22 13:54:20 +0100712 MachineInstrBuilder buildExtOrTrunc(unsigned ExtOpc, const DstOp &Res,
713 const SrcOp &Op);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100714
715 /// Build and insert an appropriate cast between two registers of equal size.
Andrew Walbran16937d02019-10-22 13:54:20 +0100716 MachineInstrBuilder buildCast(const DstOp &Dst, const SrcOp &Src);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100717
718 /// Build and insert G_BR \p Dest
719 ///
720 /// G_BR is an unconditional branch to \p Dest.
721 ///
722 /// \pre setBasicBlock or setMI must have been called.
723 ///
724 /// \return a MachineInstrBuilder for the newly created instruction.
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100725 MachineInstrBuilder buildBr(MachineBasicBlock &Dest);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100726
727 /// Build and insert G_BRCOND \p Tst, \p Dest
728 ///
729 /// G_BRCOND is a conditional branch to \p Dest.
730 ///
731 /// \pre setBasicBlock or setMI must have been called.
732 /// \pre \p Tst must be a generic virtual register with scalar
733 /// type. At the beginning of legalization, this will be a single
734 /// bit (s1). Targets with interesting flags registers may change
735 /// this. For a wider type, whether the branch is taken must only
736 /// depend on bit 0 (for now).
737 ///
738 /// \return The newly created instruction.
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200739 MachineInstrBuilder buildBrCond(const SrcOp &Tst, MachineBasicBlock &Dest);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100740
741 /// Build and insert G_BRINDIRECT \p Tgt
742 ///
743 /// G_BRINDIRECT is an indirect branch to \p Tgt.
744 ///
745 /// \pre setBasicBlock or setMI must have been called.
746 /// \pre \p Tgt must be a generic virtual register with pointer type.
747 ///
748 /// \return a MachineInstrBuilder for the newly created instruction.
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100749 MachineInstrBuilder buildBrIndirect(Register Tgt);
750
751 /// Build and insert G_BRJT \p TablePtr, \p JTI, \p IndexReg
752 ///
753 /// G_BRJT is a jump table branch using a table base pointer \p TablePtr,
754 /// jump table index \p JTI and index \p IndexReg
755 ///
756 /// \pre setBasicBlock or setMI must have been called.
757 /// \pre \p TablePtr must be a generic virtual register with pointer type.
758 /// \pre \p JTI must be be a jump table index.
759 /// \pre \p IndexReg must be a generic virtual register with pointer type.
760 ///
761 /// \return a MachineInstrBuilder for the newly created instruction.
762 MachineInstrBuilder buildBrJT(Register TablePtr, unsigned JTI,
763 Register IndexReg);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100764
765 /// Build and insert \p Res = G_CONSTANT \p Val
766 ///
767 /// G_CONSTANT is an integer constant with the specified size and value. \p
768 /// Val will be extended or truncated to the size of \p Reg.
769 ///
770 /// \pre setBasicBlock or setMI must have been called.
771 /// \pre \p Res must be a generic virtual register with scalar or pointer
772 /// type.
773 ///
774 /// \return The newly created instruction.
Andrew Walbran16937d02019-10-22 13:54:20 +0100775 virtual MachineInstrBuilder buildConstant(const DstOp &Res,
776 const ConstantInt &Val);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100777
778 /// Build and insert \p Res = G_CONSTANT \p Val
779 ///
780 /// G_CONSTANT is an integer constant with the specified size and value.
781 ///
782 /// \pre setBasicBlock or setMI must have been called.
783 /// \pre \p Res must be a generic virtual register with scalar type.
784 ///
785 /// \return The newly created instruction.
Andrew Walbran16937d02019-10-22 13:54:20 +0100786 MachineInstrBuilder buildConstant(const DstOp &Res, int64_t Val);
787 MachineInstrBuilder buildConstant(const DstOp &Res, const APInt &Val);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100788
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100789 /// Build and insert \p Res = G_FCONSTANT \p Val
790 ///
791 /// G_FCONSTANT is a floating-point constant with the specified size and
792 /// value.
793 ///
794 /// \pre setBasicBlock or setMI must have been called.
795 /// \pre \p Res must be a generic virtual register with scalar type.
796 ///
797 /// \return The newly created instruction.
Andrew Walbran16937d02019-10-22 13:54:20 +0100798 virtual MachineInstrBuilder buildFConstant(const DstOp &Res,
799 const ConstantFP &Val);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100800
Andrew Walbran16937d02019-10-22 13:54:20 +0100801 MachineInstrBuilder buildFConstant(const DstOp &Res, double Val);
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100802 MachineInstrBuilder buildFConstant(const DstOp &Res, const APFloat &Val);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100803
804 /// Build and insert \p Res = COPY Op
805 ///
806 /// Register-to-register COPY sets \p Res to \p Op.
807 ///
808 /// \pre setBasicBlock or setMI must have been called.
809 ///
810 /// \return a MachineInstrBuilder for the newly created instruction.
Andrew Walbran16937d02019-10-22 13:54:20 +0100811 MachineInstrBuilder buildCopy(const DstOp &Res, const SrcOp &Op);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100812
813 /// Build and insert `Res = G_LOAD Addr, MMO`.
814 ///
815 /// Loads the value stored at \p Addr. Puts the result in \p Res.
816 ///
817 /// \pre setBasicBlock or setMI must have been called.
818 /// \pre \p Res must be a generic virtual register.
819 /// \pre \p Addr must be a generic virtual register with pointer type.
820 ///
821 /// \return a MachineInstrBuilder for the newly created instruction.
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100822 MachineInstrBuilder buildLoad(const DstOp &Res, const SrcOp &Addr,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200823 MachineMemOperand &MMO) {
824 return buildLoadInstr(TargetOpcode::G_LOAD, Res, Addr, MMO);
825 }
826
827 /// Build and insert a G_LOAD instruction, while constructing the
828 /// MachineMemOperand.
829 MachineInstrBuilder
830 buildLoad(const DstOp &Res, const SrcOp &Addr, MachinePointerInfo PtrInfo,
831 Align Alignment,
832 MachineMemOperand::Flags MMOFlags = MachineMemOperand::MONone,
833 const AAMDNodes &AAInfo = AAMDNodes());
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100834
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100835 /// Build and insert `Res = <opcode> Addr, MMO`.
836 ///
837 /// Loads the value stored at \p Addr. Puts the result in \p Res.
838 ///
839 /// \pre setBasicBlock or setMI must have been called.
840 /// \pre \p Res must be a generic virtual register.
841 /// \pre \p Addr must be a generic virtual register with pointer type.
842 ///
843 /// \return a MachineInstrBuilder for the newly created instruction.
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100844 MachineInstrBuilder buildLoadInstr(unsigned Opcode, const DstOp &Res,
845 const SrcOp &Addr, MachineMemOperand &MMO);
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100846
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200847 /// Helper to create a load from a constant offset given a base address. Load
848 /// the type of \p Dst from \p Offset from the given base address and memory
849 /// operand.
850 MachineInstrBuilder buildLoadFromOffset(const DstOp &Dst,
851 const SrcOp &BasePtr,
852 MachineMemOperand &BaseMMO,
853 int64_t Offset);
854
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100855 /// Build and insert `G_STORE Val, Addr, MMO`.
856 ///
857 /// Stores the value \p Val to \p Addr.
858 ///
859 /// \pre setBasicBlock or setMI must have been called.
860 /// \pre \p Val must be a generic virtual register.
861 /// \pre \p Addr must be a generic virtual register with pointer type.
862 ///
863 /// \return a MachineInstrBuilder for the newly created instruction.
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100864 MachineInstrBuilder buildStore(const SrcOp &Val, const SrcOp &Addr,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100865 MachineMemOperand &MMO);
866
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200867 /// Build and insert a G_STORE instruction, while constructing the
868 /// MachineMemOperand.
869 MachineInstrBuilder
870 buildStore(const SrcOp &Val, const SrcOp &Addr, MachinePointerInfo PtrInfo,
871 Align Alignment,
872 MachineMemOperand::Flags MMOFlags = MachineMemOperand::MONone,
873 const AAMDNodes &AAInfo = AAMDNodes());
874
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100875 /// Build and insert `Res0, ... = G_EXTRACT Src, Idx0`.
876 ///
877 /// \pre setBasicBlock or setMI must have been called.
878 /// \pre \p Res and \p Src must be generic virtual registers.
879 ///
880 /// \return a MachineInstrBuilder for the newly created instruction.
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100881 MachineInstrBuilder buildExtract(const DstOp &Res, const SrcOp &Src, uint64_t Index);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100882
883 /// Build and insert \p Res = IMPLICIT_DEF.
Andrew Walbran16937d02019-10-22 13:54:20 +0100884 MachineInstrBuilder buildUndef(const DstOp &Res);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100885
886 /// Build and insert instructions to put \p Ops together at the specified p
887 /// Indices to form a larger register.
888 ///
889 /// If the types of the input registers are uniform and cover the entirity of
890 /// \p Res then a G_MERGE_VALUES will be produced. Otherwise an IMPLICIT_DEF
891 /// followed by a sequence of G_INSERT instructions.
892 ///
893 /// \pre setBasicBlock or setMI must have been called.
894 /// \pre The final element of the sequence must not extend past the end of the
895 /// destination register.
896 /// \pre The bits defined by each Op (derived from index and scalar size) must
897 /// not overlap.
898 /// \pre \p Indices must be in ascending order of bit position.
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100899 void buildSequence(Register Res, ArrayRef<Register> Ops,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100900 ArrayRef<uint64_t> Indices);
901
902 /// Build and insert \p Res = G_MERGE_VALUES \p Op0, ...
903 ///
904 /// G_MERGE_VALUES combines the input elements contiguously into a larger
905 /// register.
906 ///
907 /// \pre setBasicBlock or setMI must have been called.
908 /// \pre The entire register \p Res (and no more) must be covered by the input
909 /// registers.
910 /// \pre The type of all \p Ops registers must be identical.
911 ///
912 /// \return a MachineInstrBuilder for the newly created instruction.
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100913 MachineInstrBuilder buildMerge(const DstOp &Res, ArrayRef<Register> Ops);
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200914 MachineInstrBuilder buildMerge(const DstOp &Res,
915 std::initializer_list<SrcOp> Ops);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100916
917 /// Build and insert \p Res0, ... = G_UNMERGE_VALUES \p Op
918 ///
919 /// G_UNMERGE_VALUES splits contiguous bits of the input into multiple
920 ///
921 /// \pre setBasicBlock or setMI must have been called.
922 /// \pre The entire register \p Res (and no more) must be covered by the input
923 /// registers.
924 /// \pre The type of all \p Res registers must be identical.
925 ///
926 /// \return a MachineInstrBuilder for the newly created instruction.
Andrew Walbran16937d02019-10-22 13:54:20 +0100927 MachineInstrBuilder buildUnmerge(ArrayRef<LLT> Res, const SrcOp &Op);
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100928 MachineInstrBuilder buildUnmerge(ArrayRef<Register> Res, const SrcOp &Op);
929
930 /// Build and insert an unmerge of \p Res sized pieces to cover \p Op
931 MachineInstrBuilder buildUnmerge(LLT Res, const SrcOp &Op);
Andrew Walbran16937d02019-10-22 13:54:20 +0100932
933 /// Build and insert \p Res = G_BUILD_VECTOR \p Op0, ...
934 ///
935 /// G_BUILD_VECTOR creates a vector value from multiple scalar registers.
936 /// \pre setBasicBlock or setMI must have been called.
937 /// \pre The entire register \p Res (and no more) must be covered by the
938 /// input scalar registers.
939 /// \pre The type of all \p Ops registers must be identical.
940 ///
941 /// \return a MachineInstrBuilder for the newly created instruction.
942 MachineInstrBuilder buildBuildVector(const DstOp &Res,
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100943 ArrayRef<Register> Ops);
Andrew Walbran16937d02019-10-22 13:54:20 +0100944
945 /// Build and insert \p Res = G_BUILD_VECTOR with \p Src replicated to fill
946 /// the number of elements
947 MachineInstrBuilder buildSplatVector(const DstOp &Res,
948 const SrcOp &Src);
949
950 /// Build and insert \p Res = G_BUILD_VECTOR_TRUNC \p Op0, ...
951 ///
952 /// G_BUILD_VECTOR_TRUNC creates a vector value from multiple scalar registers
953 /// which have types larger than the destination vector element type, and
954 /// truncates the values to fit.
955 ///
956 /// If the operands given are already the same size as the vector elt type,
957 /// then this method will instead create a G_BUILD_VECTOR instruction.
958 ///
959 /// \pre setBasicBlock or setMI must have been called.
960 /// \pre The type of all \p Ops registers must be identical.
961 ///
962 /// \return a MachineInstrBuilder for the newly created instruction.
963 MachineInstrBuilder buildBuildVectorTrunc(const DstOp &Res,
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100964 ArrayRef<Register> Ops);
Andrew Walbran16937d02019-10-22 13:54:20 +0100965
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200966 /// Build and insert a vector splat of a scalar \p Src using a
967 /// G_INSERT_VECTOR_ELT and G_SHUFFLE_VECTOR idiom.
968 ///
969 /// \pre setBasicBlock or setMI must have been called.
970 /// \pre \p Src must have the same type as the element type of \p Dst
971 ///
972 /// \return a MachineInstrBuilder for the newly created instruction.
973 MachineInstrBuilder buildShuffleSplat(const DstOp &Res, const SrcOp &Src);
974
975 /// Build and insert \p Res = G_SHUFFLE_VECTOR \p Src1, \p Src2, \p Mask
976 ///
977 /// \pre setBasicBlock or setMI must have been called.
978 ///
979 /// \return a MachineInstrBuilder for the newly created instruction.
980 MachineInstrBuilder buildShuffleVector(const DstOp &Res, const SrcOp &Src1,
981 const SrcOp &Src2, ArrayRef<int> Mask);
982
Andrew Walbran16937d02019-10-22 13:54:20 +0100983 /// Build and insert \p Res = G_CONCAT_VECTORS \p Op0, ...
984 ///
985 /// G_CONCAT_VECTORS creates a vector from the concatenation of 2 or more
986 /// vectors.
987 ///
988 /// \pre setBasicBlock or setMI must have been called.
989 /// \pre The entire register \p Res (and no more) must be covered by the input
990 /// registers.
991 /// \pre The type of all source operands must be identical.
992 ///
993 /// \return a MachineInstrBuilder for the newly created instruction.
994 MachineInstrBuilder buildConcatVectors(const DstOp &Res,
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100995 ArrayRef<Register> Ops);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100996
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200997 MachineInstrBuilder buildInsert(const DstOp &Res, const SrcOp &Src,
998 const SrcOp &Op, unsigned Index);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100999
1000 /// Build and insert either a G_INTRINSIC (if \p HasSideEffects is false) or
1001 /// G_INTRINSIC_W_SIDE_EFFECTS instruction. Its first operand will be the
1002 /// result register definition unless \p Reg is NoReg (== 0). The second
1003 /// operand will be the intrinsic's ID.
1004 ///
1005 /// Callers are expected to add the required definitions and uses afterwards.
1006 ///
1007 /// \pre setBasicBlock or setMI must have been called.
1008 ///
1009 /// \return a MachineInstrBuilder for the newly created instruction.
Andrew Walbran3d2c1972020-04-07 12:24:26 +01001010 MachineInstrBuilder buildIntrinsic(Intrinsic::ID ID, ArrayRef<Register> Res,
1011 bool HasSideEffects);
1012 MachineInstrBuilder buildIntrinsic(Intrinsic::ID ID, ArrayRef<DstOp> Res,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001013 bool HasSideEffects);
1014
1015 /// Build and insert \p Res = G_FPTRUNC \p Op
1016 ///
1017 /// G_FPTRUNC converts a floating-point value into one with a smaller type.
1018 ///
1019 /// \pre setBasicBlock or setMI must have been called.
1020 /// \pre \p Res must be a generic virtual register with scalar or vector type.
1021 /// \pre \p Op must be a generic virtual register with scalar or vector type.
1022 /// \pre \p Res must be smaller than \p Op
1023 ///
1024 /// \return The newly created instruction.
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02001025 MachineInstrBuilder buildFPTrunc(const DstOp &Res, const SrcOp &Op,
1026 Optional<unsigned> Flags = None);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001027
1028 /// Build and insert \p Res = G_TRUNC \p Op
1029 ///
1030 /// G_TRUNC extracts the low bits of a type. For a vector type each element is
1031 /// truncated independently before being packed into the destination.
1032 ///
1033 /// \pre setBasicBlock or setMI must have been called.
1034 /// \pre \p Res must be a generic virtual register with scalar or vector type.
1035 /// \pre \p Op must be a generic virtual register with scalar or vector type.
1036 /// \pre \p Res must be smaller than \p Op
1037 ///
1038 /// \return The newly created instruction.
Andrew Walbran16937d02019-10-22 13:54:20 +01001039 MachineInstrBuilder buildTrunc(const DstOp &Res, const SrcOp &Op);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001040
1041 /// Build and insert a \p Res = G_ICMP \p Pred, \p Op0, \p Op1
1042 ///
1043 /// \pre setBasicBlock or setMI must have been called.
1044
1045 /// \pre \p Res must be a generic virtual register with scalar or
1046 /// vector type. Typically this starts as s1 or <N x s1>.
1047 /// \pre \p Op0 and Op1 must be generic virtual registers with the
1048 /// same number of elements as \p Res. If \p Res is a scalar,
1049 /// \p Op0 must be either a scalar or pointer.
1050 /// \pre \p Pred must be an integer predicate.
1051 ///
1052 /// \return a MachineInstrBuilder for the newly created instruction.
Andrew Walbran16937d02019-10-22 13:54:20 +01001053 MachineInstrBuilder buildICmp(CmpInst::Predicate Pred, const DstOp &Res,
1054 const SrcOp &Op0, const SrcOp &Op1);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001055
1056 /// Build and insert a \p Res = G_FCMP \p Pred\p Op0, \p Op1
1057 ///
1058 /// \pre setBasicBlock or setMI must have been called.
1059
1060 /// \pre \p Res must be a generic virtual register with scalar or
1061 /// vector type. Typically this starts as s1 or <N x s1>.
1062 /// \pre \p Op0 and Op1 must be generic virtual registers with the
1063 /// same number of elements as \p Res (or scalar, if \p Res is
1064 /// scalar).
1065 /// \pre \p Pred must be a floating-point predicate.
1066 ///
1067 /// \return a MachineInstrBuilder for the newly created instruction.
Andrew Walbran16937d02019-10-22 13:54:20 +01001068 MachineInstrBuilder buildFCmp(CmpInst::Predicate Pred, const DstOp &Res,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02001069 const SrcOp &Op0, const SrcOp &Op1,
1070 Optional<unsigned> Flags = None);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001071
1072 /// Build and insert a \p Res = G_SELECT \p Tst, \p Op0, \p Op1
1073 ///
1074 /// \pre setBasicBlock or setMI must have been called.
1075 /// \pre \p Res, \p Op0 and \p Op1 must be generic virtual registers
1076 /// with the same type.
1077 /// \pre \p Tst must be a generic virtual register with scalar, pointer or
1078 /// vector type. If vector then it must have the same number of
1079 /// elements as the other parameters.
1080 ///
1081 /// \return a MachineInstrBuilder for the newly created instruction.
Andrew Walbran16937d02019-10-22 13:54:20 +01001082 MachineInstrBuilder buildSelect(const DstOp &Res, const SrcOp &Tst,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02001083 const SrcOp &Op0, const SrcOp &Op1,
1084 Optional<unsigned> Flags = None);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001085
1086 /// Build and insert \p Res = G_INSERT_VECTOR_ELT \p Val,
1087 /// \p Elt, \p Idx
1088 ///
1089 /// \pre setBasicBlock or setMI must have been called.
1090 /// \pre \p Res and \p Val must be a generic virtual register
1091 // with the same vector type.
1092 /// \pre \p Elt and \p Idx must be a generic virtual register
1093 /// with scalar type.
1094 ///
1095 /// \return The newly created instruction.
Andrew Walbran16937d02019-10-22 13:54:20 +01001096 MachineInstrBuilder buildInsertVectorElement(const DstOp &Res,
1097 const SrcOp &Val,
1098 const SrcOp &Elt,
1099 const SrcOp &Idx);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001100
1101 /// Build and insert \p Res = G_EXTRACT_VECTOR_ELT \p Val, \p Idx
1102 ///
1103 /// \pre setBasicBlock or setMI must have been called.
1104 /// \pre \p Res must be a generic virtual register with scalar type.
1105 /// \pre \p Val must be a generic virtual register with vector type.
1106 /// \pre \p Idx must be a generic virtual register with scalar type.
1107 ///
1108 /// \return The newly created instruction.
Andrew Walbran16937d02019-10-22 13:54:20 +01001109 MachineInstrBuilder buildExtractVectorElement(const DstOp &Res,
1110 const SrcOp &Val,
1111 const SrcOp &Idx);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001112
Andrew Scullcdfcccc2018-10-05 20:58:37 +01001113 /// Build and insert `OldValRes<def>, SuccessRes<def> =
1114 /// G_ATOMIC_CMPXCHG_WITH_SUCCESS Addr, CmpVal, NewVal, MMO`.
1115 ///
1116 /// Atomically replace the value at \p Addr with \p NewVal if it is currently
1117 /// \p CmpVal otherwise leaves it unchanged. Puts the original value from \p
1118 /// Addr in \p Res, along with an s1 indicating whether it was replaced.
1119 ///
1120 /// \pre setBasicBlock or setMI must have been called.
1121 /// \pre \p OldValRes must be a generic virtual register of scalar type.
1122 /// \pre \p SuccessRes must be a generic virtual register of scalar type. It
1123 /// will be assigned 0 on failure and 1 on success.
1124 /// \pre \p Addr must be a generic virtual register with pointer type.
1125 /// \pre \p OldValRes, \p CmpVal, and \p NewVal must be generic virtual
1126 /// registers of the same type.
1127 ///
1128 /// \return a MachineInstrBuilder for the newly created instruction.
1129 MachineInstrBuilder
Andrew Walbran3d2c1972020-04-07 12:24:26 +01001130 buildAtomicCmpXchgWithSuccess(Register OldValRes, Register SuccessRes,
1131 Register Addr, Register CmpVal, Register NewVal,
Andrew Scullcdfcccc2018-10-05 20:58:37 +01001132 MachineMemOperand &MMO);
1133
1134 /// Build and insert `OldValRes<def> = G_ATOMIC_CMPXCHG Addr, CmpVal, NewVal,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001135 /// MMO`.
1136 ///
1137 /// Atomically replace the value at \p Addr with \p NewVal if it is currently
1138 /// \p CmpVal otherwise leaves it unchanged. Puts the original value from \p
1139 /// Addr in \p Res.
1140 ///
1141 /// \pre setBasicBlock or setMI must have been called.
1142 /// \pre \p OldValRes must be a generic virtual register of scalar type.
1143 /// \pre \p Addr must be a generic virtual register with pointer type.
1144 /// \pre \p OldValRes, \p CmpVal, and \p NewVal must be generic virtual
1145 /// registers of the same type.
1146 ///
1147 /// \return a MachineInstrBuilder for the newly created instruction.
Andrew Walbran3d2c1972020-04-07 12:24:26 +01001148 MachineInstrBuilder buildAtomicCmpXchg(Register OldValRes, Register Addr,
1149 Register CmpVal, Register NewVal,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001150 MachineMemOperand &MMO);
Andrew Scullcdfcccc2018-10-05 20:58:37 +01001151
1152 /// Build and insert `OldValRes<def> = G_ATOMICRMW_<Opcode> Addr, Val, MMO`.
1153 ///
1154 /// Atomically read-modify-update the value at \p Addr with \p Val. Puts the
1155 /// original value from \p Addr in \p OldValRes. The modification is
1156 /// determined by the opcode.
1157 ///
1158 /// \pre setBasicBlock or setMI must have been called.
1159 /// \pre \p OldValRes must be a generic virtual register.
1160 /// \pre \p Addr must be a generic virtual register with pointer type.
1161 /// \pre \p OldValRes, and \p Val must be generic virtual registers of the
1162 /// same type.
1163 ///
1164 /// \return a MachineInstrBuilder for the newly created instruction.
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02001165 MachineInstrBuilder buildAtomicRMW(unsigned Opcode, const DstOp &OldValRes,
1166 const SrcOp &Addr, const SrcOp &Val,
Andrew Scullcdfcccc2018-10-05 20:58:37 +01001167 MachineMemOperand &MMO);
1168
1169 /// Build and insert `OldValRes<def> = G_ATOMICRMW_XCHG Addr, Val, MMO`.
1170 ///
1171 /// Atomically replace the value at \p Addr with \p Val. Puts the original
1172 /// value from \p Addr in \p OldValRes.
1173 ///
1174 /// \pre setBasicBlock or setMI must have been called.
1175 /// \pre \p OldValRes must be a generic virtual register.
1176 /// \pre \p Addr must be a generic virtual register with pointer type.
1177 /// \pre \p OldValRes, and \p Val must be generic virtual registers of the
1178 /// same type.
1179 ///
1180 /// \return a MachineInstrBuilder for the newly created instruction.
Andrew Walbran3d2c1972020-04-07 12:24:26 +01001181 MachineInstrBuilder buildAtomicRMWXchg(Register OldValRes, Register Addr,
1182 Register Val, MachineMemOperand &MMO);
Andrew Scullcdfcccc2018-10-05 20:58:37 +01001183
1184 /// Build and insert `OldValRes<def> = G_ATOMICRMW_ADD Addr, Val, MMO`.
1185 ///
1186 /// Atomically replace the value at \p Addr with the addition of \p Val and
1187 /// the original value. Puts the original value from \p Addr in \p OldValRes.
1188 ///
1189 /// \pre setBasicBlock or setMI must have been called.
1190 /// \pre \p OldValRes must be a generic virtual register.
1191 /// \pre \p Addr must be a generic virtual register with pointer type.
1192 /// \pre \p OldValRes, and \p Val must be generic virtual registers of the
1193 /// same type.
1194 ///
1195 /// \return a MachineInstrBuilder for the newly created instruction.
Andrew Walbran3d2c1972020-04-07 12:24:26 +01001196 MachineInstrBuilder buildAtomicRMWAdd(Register OldValRes, Register Addr,
1197 Register Val, MachineMemOperand &MMO);
Andrew Scullcdfcccc2018-10-05 20:58:37 +01001198
1199 /// Build and insert `OldValRes<def> = G_ATOMICRMW_SUB Addr, Val, MMO`.
1200 ///
1201 /// Atomically replace the value at \p Addr with the subtraction of \p Val and
1202 /// the original value. Puts the original value from \p Addr in \p OldValRes.
1203 ///
1204 /// \pre setBasicBlock or setMI must have been called.
1205 /// \pre \p OldValRes must be a generic virtual register.
1206 /// \pre \p Addr must be a generic virtual register with pointer type.
1207 /// \pre \p OldValRes, and \p Val must be generic virtual registers of the
1208 /// same type.
1209 ///
1210 /// \return a MachineInstrBuilder for the newly created instruction.
Andrew Walbran3d2c1972020-04-07 12:24:26 +01001211 MachineInstrBuilder buildAtomicRMWSub(Register OldValRes, Register Addr,
1212 Register Val, MachineMemOperand &MMO);
Andrew Scullcdfcccc2018-10-05 20:58:37 +01001213
1214 /// Build and insert `OldValRes<def> = G_ATOMICRMW_AND Addr, Val, MMO`.
1215 ///
1216 /// Atomically replace the value at \p Addr with the bitwise and of \p Val and
1217 /// the original value. Puts the original value from \p Addr in \p OldValRes.
1218 ///
1219 /// \pre setBasicBlock or setMI must have been called.
1220 /// \pre \p OldValRes must be a generic virtual register.
1221 /// \pre \p Addr must be a generic virtual register with pointer type.
1222 /// \pre \p OldValRes, and \p Val must be generic virtual registers of the
1223 /// same type.
1224 ///
1225 /// \return a MachineInstrBuilder for the newly created instruction.
Andrew Walbran3d2c1972020-04-07 12:24:26 +01001226 MachineInstrBuilder buildAtomicRMWAnd(Register OldValRes, Register Addr,
1227 Register Val, MachineMemOperand &MMO);
Andrew Scullcdfcccc2018-10-05 20:58:37 +01001228
1229 /// Build and insert `OldValRes<def> = G_ATOMICRMW_NAND Addr, Val, MMO`.
1230 ///
1231 /// Atomically replace the value at \p Addr with the bitwise nand of \p Val
1232 /// and the original value. Puts the original value from \p Addr in \p
1233 /// OldValRes.
1234 ///
1235 /// \pre setBasicBlock or setMI must have been called.
1236 /// \pre \p OldValRes must be a generic virtual register.
1237 /// \pre \p Addr must be a generic virtual register with pointer type.
1238 /// \pre \p OldValRes, and \p Val must be generic virtual registers of the
1239 /// same type.
1240 ///
1241 /// \return a MachineInstrBuilder for the newly created instruction.
Andrew Walbran3d2c1972020-04-07 12:24:26 +01001242 MachineInstrBuilder buildAtomicRMWNand(Register OldValRes, Register Addr,
1243 Register Val, MachineMemOperand &MMO);
Andrew Scullcdfcccc2018-10-05 20:58:37 +01001244
1245 /// Build and insert `OldValRes<def> = G_ATOMICRMW_OR Addr, Val, MMO`.
1246 ///
1247 /// Atomically replace the value at \p Addr with the bitwise or of \p Val and
1248 /// the original value. Puts the original value from \p Addr in \p OldValRes.
1249 ///
1250 /// \pre setBasicBlock or setMI must have been called.
1251 /// \pre \p OldValRes must be a generic virtual register.
1252 /// \pre \p Addr must be a generic virtual register with pointer type.
1253 /// \pre \p OldValRes, and \p Val must be generic virtual registers of the
1254 /// same type.
1255 ///
1256 /// \return a MachineInstrBuilder for the newly created instruction.
Andrew Walbran3d2c1972020-04-07 12:24:26 +01001257 MachineInstrBuilder buildAtomicRMWOr(Register OldValRes, Register Addr,
1258 Register Val, MachineMemOperand &MMO);
Andrew Scullcdfcccc2018-10-05 20:58:37 +01001259
1260 /// Build and insert `OldValRes<def> = G_ATOMICRMW_XOR Addr, Val, MMO`.
1261 ///
1262 /// Atomically replace the value at \p Addr with the bitwise xor of \p Val and
1263 /// the original value. Puts the original value from \p Addr in \p OldValRes.
1264 ///
1265 /// \pre setBasicBlock or setMI must have been called.
1266 /// \pre \p OldValRes must be a generic virtual register.
1267 /// \pre \p Addr must be a generic virtual register with pointer type.
1268 /// \pre \p OldValRes, and \p Val must be generic virtual registers of the
1269 /// same type.
1270 ///
1271 /// \return a MachineInstrBuilder for the newly created instruction.
Andrew Walbran3d2c1972020-04-07 12:24:26 +01001272 MachineInstrBuilder buildAtomicRMWXor(Register OldValRes, Register Addr,
1273 Register Val, MachineMemOperand &MMO);
Andrew Scullcdfcccc2018-10-05 20:58:37 +01001274
1275 /// Build and insert `OldValRes<def> = G_ATOMICRMW_MAX Addr, Val, MMO`.
1276 ///
1277 /// Atomically replace the value at \p Addr with the signed maximum of \p
1278 /// Val and the original value. Puts the original value from \p Addr in \p
1279 /// OldValRes.
1280 ///
1281 /// \pre setBasicBlock or setMI must have been called.
1282 /// \pre \p OldValRes must be a generic virtual register.
1283 /// \pre \p Addr must be a generic virtual register with pointer type.
1284 /// \pre \p OldValRes, and \p Val must be generic virtual registers of the
1285 /// same type.
1286 ///
1287 /// \return a MachineInstrBuilder for the newly created instruction.
Andrew Walbran3d2c1972020-04-07 12:24:26 +01001288 MachineInstrBuilder buildAtomicRMWMax(Register OldValRes, Register Addr,
1289 Register Val, MachineMemOperand &MMO);
Andrew Scullcdfcccc2018-10-05 20:58:37 +01001290
1291 /// Build and insert `OldValRes<def> = G_ATOMICRMW_MIN Addr, Val, MMO`.
1292 ///
1293 /// Atomically replace the value at \p Addr with the signed minimum of \p
1294 /// Val and the original value. Puts the original value from \p Addr in \p
1295 /// OldValRes.
1296 ///
1297 /// \pre setBasicBlock or setMI must have been called.
1298 /// \pre \p OldValRes must be a generic virtual register.
1299 /// \pre \p Addr must be a generic virtual register with pointer type.
1300 /// \pre \p OldValRes, and \p Val must be generic virtual registers of the
1301 /// same type.
1302 ///
1303 /// \return a MachineInstrBuilder for the newly created instruction.
Andrew Walbran3d2c1972020-04-07 12:24:26 +01001304 MachineInstrBuilder buildAtomicRMWMin(Register OldValRes, Register Addr,
1305 Register Val, MachineMemOperand &MMO);
Andrew Scullcdfcccc2018-10-05 20:58:37 +01001306
1307 /// Build and insert `OldValRes<def> = G_ATOMICRMW_UMAX Addr, Val, MMO`.
1308 ///
1309 /// Atomically replace the value at \p Addr with the unsigned maximum of \p
1310 /// Val and the original value. Puts the original value from \p Addr in \p
1311 /// OldValRes.
1312 ///
1313 /// \pre setBasicBlock or setMI must have been called.
1314 /// \pre \p OldValRes must be a generic virtual register.
1315 /// \pre \p Addr must be a generic virtual register with pointer type.
1316 /// \pre \p OldValRes, and \p Val must be generic virtual registers of the
1317 /// same type.
1318 ///
1319 /// \return a MachineInstrBuilder for the newly created instruction.
Andrew Walbran3d2c1972020-04-07 12:24:26 +01001320 MachineInstrBuilder buildAtomicRMWUmax(Register OldValRes, Register Addr,
1321 Register Val, MachineMemOperand &MMO);
Andrew Scullcdfcccc2018-10-05 20:58:37 +01001322
1323 /// Build and insert `OldValRes<def> = G_ATOMICRMW_UMIN Addr, Val, MMO`.
1324 ///
1325 /// Atomically replace the value at \p Addr with the unsigned minimum of \p
1326 /// Val and the original value. Puts the original value from \p Addr in \p
1327 /// OldValRes.
1328 ///
1329 /// \pre setBasicBlock or setMI must have been called.
1330 /// \pre \p OldValRes must be a generic virtual register.
1331 /// \pre \p Addr must be a generic virtual register with pointer type.
1332 /// \pre \p OldValRes, and \p Val must be generic virtual registers of the
1333 /// same type.
1334 ///
1335 /// \return a MachineInstrBuilder for the newly created instruction.
Andrew Walbran3d2c1972020-04-07 12:24:26 +01001336 MachineInstrBuilder buildAtomicRMWUmin(Register OldValRes, Register Addr,
1337 Register Val, MachineMemOperand &MMO);
1338
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02001339 /// Build and insert `OldValRes<def> = G_ATOMICRMW_FADD Addr, Val, MMO`.
1340 MachineInstrBuilder buildAtomicRMWFAdd(
1341 const DstOp &OldValRes, const SrcOp &Addr, const SrcOp &Val,
1342 MachineMemOperand &MMO);
1343
1344 /// Build and insert `OldValRes<def> = G_ATOMICRMW_FSUB Addr, Val, MMO`.
1345 MachineInstrBuilder buildAtomicRMWFSub(
1346 const DstOp &OldValRes, const SrcOp &Addr, const SrcOp &Val,
1347 MachineMemOperand &MMO);
1348
Andrew Walbran3d2c1972020-04-07 12:24:26 +01001349 /// Build and insert `G_FENCE Ordering, Scope`.
1350 MachineInstrBuilder buildFence(unsigned Ordering, unsigned Scope);
Andrew Scullcdfcccc2018-10-05 20:58:37 +01001351
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02001352 /// Build and insert \p Dst = G_FREEZE \p Src
1353 MachineInstrBuilder buildFreeze(const DstOp &Dst, const SrcOp &Src) {
1354 return buildInstr(TargetOpcode::G_FREEZE, {Dst}, {Src});
1355 }
1356
Andrew Scullcdfcccc2018-10-05 20:58:37 +01001357 /// Build and insert \p Res = G_BLOCK_ADDR \p BA
1358 ///
1359 /// G_BLOCK_ADDR computes the address of a basic block.
1360 ///
1361 /// \pre setBasicBlock or setMI must have been called.
1362 /// \pre \p Res must be a generic virtual register of a pointer type.
1363 ///
1364 /// \return The newly created instruction.
Andrew Walbran3d2c1972020-04-07 12:24:26 +01001365 MachineInstrBuilder buildBlockAddress(Register Res, const BlockAddress *BA);
Andrew Scullcdfcccc2018-10-05 20:58:37 +01001366
Andrew Scullcdfcccc2018-10-05 20:58:37 +01001367 /// Build and insert \p Res = G_ADD \p Op0, \p Op1
1368 ///
1369 /// G_ADD sets \p Res to the sum of integer parameters \p Op0 and \p Op1,
1370 /// truncated to their width.
1371 ///
1372 /// \pre setBasicBlock or setMI must have been called.
1373 /// \pre \p Res, \p Op0 and \p Op1 must be generic virtual registers
1374 /// with the same (scalar or vector) type).
1375 ///
1376 /// \return a MachineInstrBuilder for the newly created instruction.
1377
Andrew Walbran16937d02019-10-22 13:54:20 +01001378 MachineInstrBuilder buildAdd(const DstOp &Dst, const SrcOp &Src0,
1379 const SrcOp &Src1,
1380 Optional<unsigned> Flags = None) {
1381 return buildInstr(TargetOpcode::G_ADD, {Dst}, {Src0, Src1}, Flags);
Andrew Scullcdfcccc2018-10-05 20:58:37 +01001382 }
1383
1384 /// Build and insert \p Res = G_SUB \p Op0, \p Op1
1385 ///
1386 /// G_SUB sets \p Res to the sum of integer parameters \p Op0 and \p Op1,
1387 /// truncated to their width.
1388 ///
1389 /// \pre setBasicBlock or setMI must have been called.
1390 /// \pre \p Res, \p Op0 and \p Op1 must be generic virtual registers
1391 /// with the same (scalar or vector) type).
1392 ///
1393 /// \return a MachineInstrBuilder for the newly created instruction.
1394
Andrew Walbran16937d02019-10-22 13:54:20 +01001395 MachineInstrBuilder buildSub(const DstOp &Dst, const SrcOp &Src0,
1396 const SrcOp &Src1,
1397 Optional<unsigned> Flags = None) {
1398 return buildInstr(TargetOpcode::G_SUB, {Dst}, {Src0, Src1}, Flags);
Andrew Scullcdfcccc2018-10-05 20:58:37 +01001399 }
1400
1401 /// Build and insert \p Res = G_MUL \p Op0, \p Op1
1402 ///
1403 /// G_MUL sets \p Res to the sum of integer parameters \p Op0 and \p Op1,
1404 /// truncated to their width.
1405 ///
1406 /// \pre setBasicBlock or setMI must have been called.
1407 /// \pre \p Res, \p Op0 and \p Op1 must be generic virtual registers
1408 /// with the same (scalar or vector) type).
1409 ///
1410 /// \return a MachineInstrBuilder for the newly created instruction.
Andrew Walbran16937d02019-10-22 13:54:20 +01001411 MachineInstrBuilder buildMul(const DstOp &Dst, const SrcOp &Src0,
1412 const SrcOp &Src1,
1413 Optional<unsigned> Flags = None) {
1414 return buildInstr(TargetOpcode::G_MUL, {Dst}, {Src0, Src1}, Flags);
Andrew Scullcdfcccc2018-10-05 20:58:37 +01001415 }
Andrew Walbran16937d02019-10-22 13:54:20 +01001416
1417 MachineInstrBuilder buildUMulH(const DstOp &Dst, const SrcOp &Src0,
1418 const SrcOp &Src1,
1419 Optional<unsigned> Flags = None) {
1420 return buildInstr(TargetOpcode::G_UMULH, {Dst}, {Src0, Src1}, Flags);
1421 }
1422
1423 MachineInstrBuilder buildSMulH(const DstOp &Dst, const SrcOp &Src0,
1424 const SrcOp &Src1,
1425 Optional<unsigned> Flags = None) {
1426 return buildInstr(TargetOpcode::G_SMULH, {Dst}, {Src0, Src1}, Flags);
1427 }
1428
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02001429 MachineInstrBuilder buildFMul(const DstOp &Dst, const SrcOp &Src0,
1430 const SrcOp &Src1,
1431 Optional<unsigned> Flags = None) {
1432 return buildInstr(TargetOpcode::G_FMUL, {Dst}, {Src0, Src1}, Flags);
1433 }
1434
1435 MachineInstrBuilder buildFMinNum(const DstOp &Dst, const SrcOp &Src0,
1436 const SrcOp &Src1,
1437 Optional<unsigned> Flags = None) {
1438 return buildInstr(TargetOpcode::G_FMINNUM, {Dst}, {Src0, Src1}, Flags);
1439 }
1440
1441 MachineInstrBuilder buildFMaxNum(const DstOp &Dst, const SrcOp &Src0,
1442 const SrcOp &Src1,
1443 Optional<unsigned> Flags = None) {
1444 return buildInstr(TargetOpcode::G_FMAXNUM, {Dst}, {Src0, Src1}, Flags);
1445 }
1446
1447 MachineInstrBuilder buildFMinNumIEEE(const DstOp &Dst, const SrcOp &Src0,
1448 const SrcOp &Src1,
1449 Optional<unsigned> Flags = None) {
1450 return buildInstr(TargetOpcode::G_FMINNUM_IEEE, {Dst}, {Src0, Src1}, Flags);
1451 }
1452
1453 MachineInstrBuilder buildFMaxNumIEEE(const DstOp &Dst, const SrcOp &Src0,
1454 const SrcOp &Src1,
1455 Optional<unsigned> Flags = None) {
1456 return buildInstr(TargetOpcode::G_FMAXNUM_IEEE, {Dst}, {Src0, Src1}, Flags);
1457 }
1458
Andrew Walbran16937d02019-10-22 13:54:20 +01001459 MachineInstrBuilder buildShl(const DstOp &Dst, const SrcOp &Src0,
1460 const SrcOp &Src1,
1461 Optional<unsigned> Flags = None) {
1462 return buildInstr(TargetOpcode::G_SHL, {Dst}, {Src0, Src1}, Flags);
1463 }
1464
1465 MachineInstrBuilder buildLShr(const DstOp &Dst, const SrcOp &Src0,
1466 const SrcOp &Src1,
1467 Optional<unsigned> Flags = None) {
1468 return buildInstr(TargetOpcode::G_LSHR, {Dst}, {Src0, Src1}, Flags);
1469 }
1470
1471 MachineInstrBuilder buildAShr(const DstOp &Dst, const SrcOp &Src0,
1472 const SrcOp &Src1,
1473 Optional<unsigned> Flags = None) {
1474 return buildInstr(TargetOpcode::G_ASHR, {Dst}, {Src0, Src1}, Flags);
Andrew Scullcdfcccc2018-10-05 20:58:37 +01001475 }
1476
1477 /// Build and insert \p Res = G_AND \p Op0, \p Op1
1478 ///
1479 /// G_AND sets \p Res to the bitwise and of integer parameters \p Op0 and \p
1480 /// Op1.
1481 ///
1482 /// \pre setBasicBlock or setMI must have been called.
1483 /// \pre \p Res, \p Op0 and \p Op1 must be generic virtual registers
1484 /// with the same (scalar or vector) type).
1485 ///
1486 /// \return a MachineInstrBuilder for the newly created instruction.
1487
Andrew Walbran16937d02019-10-22 13:54:20 +01001488 MachineInstrBuilder buildAnd(const DstOp &Dst, const SrcOp &Src0,
1489 const SrcOp &Src1) {
1490 return buildInstr(TargetOpcode::G_AND, {Dst}, {Src0, Src1});
Andrew Scullcdfcccc2018-10-05 20:58:37 +01001491 }
1492
1493 /// Build and insert \p Res = G_OR \p Op0, \p Op1
1494 ///
1495 /// G_OR sets \p Res to the bitwise or of integer parameters \p Op0 and \p
1496 /// Op1.
1497 ///
1498 /// \pre setBasicBlock or setMI must have been called.
1499 /// \pre \p Res, \p Op0 and \p Op1 must be generic virtual registers
1500 /// with the same (scalar or vector) type).
1501 ///
1502 /// \return a MachineInstrBuilder for the newly created instruction.
Andrew Walbran16937d02019-10-22 13:54:20 +01001503 MachineInstrBuilder buildOr(const DstOp &Dst, const SrcOp &Src0,
1504 const SrcOp &Src1) {
1505 return buildInstr(TargetOpcode::G_OR, {Dst}, {Src0, Src1});
Andrew Scullcdfcccc2018-10-05 20:58:37 +01001506 }
Andrew Scullcdfcccc2018-10-05 20:58:37 +01001507
Andrew Walbran3d2c1972020-04-07 12:24:26 +01001508 /// Build and insert \p Res = G_XOR \p Op0, \p Op1
1509 MachineInstrBuilder buildXor(const DstOp &Dst, const SrcOp &Src0,
1510 const SrcOp &Src1) {
1511 return buildInstr(TargetOpcode::G_XOR, {Dst}, {Src0, Src1});
1512 }
1513
1514 /// Build and insert a bitwise not,
1515 /// \p NegOne = G_CONSTANT -1
1516 /// \p Res = G_OR \p Op0, NegOne
1517 MachineInstrBuilder buildNot(const DstOp &Dst, const SrcOp &Src0) {
1518 auto NegOne = buildConstant(Dst.getLLTTy(*getMRI()), -1);
1519 return buildInstr(TargetOpcode::G_XOR, {Dst}, {Src0, NegOne});
1520 }
1521
1522 /// Build and insert \p Res = G_CTPOP \p Op0, \p Src0
1523 MachineInstrBuilder buildCTPOP(const DstOp &Dst, const SrcOp &Src0) {
1524 return buildInstr(TargetOpcode::G_CTPOP, {Dst}, {Src0});
1525 }
1526
1527 /// Build and insert \p Res = G_CTLZ \p Op0, \p Src0
1528 MachineInstrBuilder buildCTLZ(const DstOp &Dst, const SrcOp &Src0) {
1529 return buildInstr(TargetOpcode::G_CTLZ, {Dst}, {Src0});
1530 }
1531
1532 /// Build and insert \p Res = G_CTLZ_ZERO_UNDEF \p Op0, \p Src0
1533 MachineInstrBuilder buildCTLZ_ZERO_UNDEF(const DstOp &Dst, const SrcOp &Src0) {
1534 return buildInstr(TargetOpcode::G_CTLZ_ZERO_UNDEF, {Dst}, {Src0});
1535 }
1536
1537 /// Build and insert \p Res = G_CTTZ \p Op0, \p Src0
1538 MachineInstrBuilder buildCTTZ(const DstOp &Dst, const SrcOp &Src0) {
1539 return buildInstr(TargetOpcode::G_CTTZ, {Dst}, {Src0});
1540 }
1541
1542 /// Build and insert \p Res = G_CTTZ_ZERO_UNDEF \p Op0, \p Src0
1543 MachineInstrBuilder buildCTTZ_ZERO_UNDEF(const DstOp &Dst, const SrcOp &Src0) {
1544 return buildInstr(TargetOpcode::G_CTTZ_ZERO_UNDEF, {Dst}, {Src0});
1545 }
1546
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02001547 /// Build and insert \p Dst = G_BSWAP \p Src0
1548 MachineInstrBuilder buildBSwap(const DstOp &Dst, const SrcOp &Src0) {
1549 return buildInstr(TargetOpcode::G_BSWAP, {Dst}, {Src0});
1550 }
1551
Andrew Walbran3d2c1972020-04-07 12:24:26 +01001552 /// Build and insert \p Res = G_FADD \p Op0, \p Op1
1553 MachineInstrBuilder buildFAdd(const DstOp &Dst, const SrcOp &Src0,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02001554 const SrcOp &Src1,
1555 Optional<unsigned> Flags = None) {
1556 return buildInstr(TargetOpcode::G_FADD, {Dst}, {Src0, Src1}, Flags);
Andrew Walbran3d2c1972020-04-07 12:24:26 +01001557 }
1558
1559 /// Build and insert \p Res = G_FSUB \p Op0, \p Op1
1560 MachineInstrBuilder buildFSub(const DstOp &Dst, const SrcOp &Src0,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02001561 const SrcOp &Src1,
1562 Optional<unsigned> Flags = None) {
1563 return buildInstr(TargetOpcode::G_FSUB, {Dst}, {Src0, Src1}, Flags);
1564 }
1565
1566 /// Build and insert \p Res = G_FDIV \p Op0, \p Op1
1567 MachineInstrBuilder buildFDiv(const DstOp &Dst, const SrcOp &Src0,
1568 const SrcOp &Src1,
1569 Optional<unsigned> Flags = None) {
1570 return buildInstr(TargetOpcode::G_FDIV, {Dst}, {Src0, Src1}, Flags);
Andrew Walbran3d2c1972020-04-07 12:24:26 +01001571 }
1572
1573 /// Build and insert \p Res = G_FMA \p Op0, \p Op1, \p Op2
1574 MachineInstrBuilder buildFMA(const DstOp &Dst, const SrcOp &Src0,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02001575 const SrcOp &Src1, const SrcOp &Src2,
1576 Optional<unsigned> Flags = None) {
1577 return buildInstr(TargetOpcode::G_FMA, {Dst}, {Src0, Src1, Src2}, Flags);
1578 }
1579
1580 /// Build and insert \p Res = G_FMAD \p Op0, \p Op1, \p Op2
1581 MachineInstrBuilder buildFMAD(const DstOp &Dst, const SrcOp &Src0,
1582 const SrcOp &Src1, const SrcOp &Src2,
1583 Optional<unsigned> Flags = None) {
1584 return buildInstr(TargetOpcode::G_FMAD, {Dst}, {Src0, Src1, Src2}, Flags);
Andrew Walbran3d2c1972020-04-07 12:24:26 +01001585 }
1586
1587 /// Build and insert \p Res = G_FNEG \p Op0
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02001588 MachineInstrBuilder buildFNeg(const DstOp &Dst, const SrcOp &Src0,
1589 Optional<unsigned> Flags = None) {
1590 return buildInstr(TargetOpcode::G_FNEG, {Dst}, {Src0}, Flags);
Andrew Walbran3d2c1972020-04-07 12:24:26 +01001591 }
1592
1593 /// Build and insert \p Res = G_FABS \p Op0
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02001594 MachineInstrBuilder buildFAbs(const DstOp &Dst, const SrcOp &Src0,
1595 Optional<unsigned> Flags = None) {
1596 return buildInstr(TargetOpcode::G_FABS, {Dst}, {Src0}, Flags);
1597 }
1598
1599 /// Build and insert \p Dst = G_FCANONICALIZE \p Src0
1600 MachineInstrBuilder buildFCanonicalize(const DstOp &Dst, const SrcOp &Src0,
1601 Optional<unsigned> Flags = None) {
1602 return buildInstr(TargetOpcode::G_FCANONICALIZE, {Dst}, {Src0}, Flags);
1603 }
1604
1605 /// Build and insert \p Dst = G_INTRINSIC_TRUNC \p Src0
1606 MachineInstrBuilder buildIntrinsicTrunc(const DstOp &Dst, const SrcOp &Src0,
1607 Optional<unsigned> Flags = None) {
1608 return buildInstr(TargetOpcode::G_INTRINSIC_TRUNC, {Dst}, {Src0}, Flags);
1609 }
1610
1611 /// Build and insert \p Res = GFFLOOR \p Op0, \p Op1
1612 MachineInstrBuilder buildFFloor(const DstOp &Dst, const SrcOp &Src0,
1613 Optional<unsigned> Flags = None) {
1614 return buildInstr(TargetOpcode::G_FFLOOR, {Dst}, {Src0}, Flags);
1615 }
1616
1617 /// Build and insert \p Dst = G_FLOG \p Src
1618 MachineInstrBuilder buildFLog(const DstOp &Dst, const SrcOp &Src,
1619 Optional<unsigned> Flags = None) {
1620 return buildInstr(TargetOpcode::G_FLOG, {Dst}, {Src}, Flags);
1621 }
1622
1623 /// Build and insert \p Dst = G_FLOG2 \p Src
1624 MachineInstrBuilder buildFLog2(const DstOp &Dst, const SrcOp &Src,
1625 Optional<unsigned> Flags = None) {
1626 return buildInstr(TargetOpcode::G_FLOG2, {Dst}, {Src}, Flags);
1627 }
1628
1629 /// Build and insert \p Dst = G_FEXP2 \p Src
1630 MachineInstrBuilder buildFExp2(const DstOp &Dst, const SrcOp &Src,
1631 Optional<unsigned> Flags = None) {
1632 return buildInstr(TargetOpcode::G_FEXP2, {Dst}, {Src}, Flags);
1633 }
1634
1635 /// Build and insert \p Dst = G_FPOW \p Src0, \p Src1
1636 MachineInstrBuilder buildFPow(const DstOp &Dst, const SrcOp &Src0,
1637 const SrcOp &Src1,
1638 Optional<unsigned> Flags = None) {
1639 return buildInstr(TargetOpcode::G_FPOW, {Dst}, {Src0, Src1}, Flags);
Andrew Walbran3d2c1972020-04-07 12:24:26 +01001640 }
1641
1642 /// Build and insert \p Res = G_FCOPYSIGN \p Op0, \p Op1
1643 MachineInstrBuilder buildFCopysign(const DstOp &Dst, const SrcOp &Src0,
1644 const SrcOp &Src1) {
1645 return buildInstr(TargetOpcode::G_FCOPYSIGN, {Dst}, {Src0, Src1});
1646 }
1647
1648 /// Build and insert \p Res = G_UITOFP \p Src0
1649 MachineInstrBuilder buildUITOFP(const DstOp &Dst, const SrcOp &Src0) {
1650 return buildInstr(TargetOpcode::G_UITOFP, {Dst}, {Src0});
1651 }
1652
1653 /// Build and insert \p Res = G_SITOFP \p Src0
1654 MachineInstrBuilder buildSITOFP(const DstOp &Dst, const SrcOp &Src0) {
1655 return buildInstr(TargetOpcode::G_SITOFP, {Dst}, {Src0});
1656 }
1657
1658 /// Build and insert \p Res = G_FPTOUI \p Src0
1659 MachineInstrBuilder buildFPTOUI(const DstOp &Dst, const SrcOp &Src0) {
1660 return buildInstr(TargetOpcode::G_FPTOUI, {Dst}, {Src0});
1661 }
1662
1663 /// Build and insert \p Res = G_FPTOSI \p Src0
1664 MachineInstrBuilder buildFPTOSI(const DstOp &Dst, const SrcOp &Src0) {
1665 return buildInstr(TargetOpcode::G_FPTOSI, {Dst}, {Src0});
1666 }
1667
1668 /// Build and insert \p Res = G_SMIN \p Op0, \p Op1
1669 MachineInstrBuilder buildSMin(const DstOp &Dst, const SrcOp &Src0,
1670 const SrcOp &Src1) {
1671 return buildInstr(TargetOpcode::G_SMIN, {Dst}, {Src0, Src1});
1672 }
1673
1674 /// Build and insert \p Res = G_SMAX \p Op0, \p Op1
1675 MachineInstrBuilder buildSMax(const DstOp &Dst, const SrcOp &Src0,
1676 const SrcOp &Src1) {
1677 return buildInstr(TargetOpcode::G_SMAX, {Dst}, {Src0, Src1});
1678 }
1679
1680 /// Build and insert \p Res = G_UMIN \p Op0, \p Op1
1681 MachineInstrBuilder buildUMin(const DstOp &Dst, const SrcOp &Src0,
1682 const SrcOp &Src1) {
1683 return buildInstr(TargetOpcode::G_UMIN, {Dst}, {Src0, Src1});
1684 }
1685
1686 /// Build and insert \p Res = G_UMAX \p Op0, \p Op1
1687 MachineInstrBuilder buildUMax(const DstOp &Dst, const SrcOp &Src0,
1688 const SrcOp &Src1) {
1689 return buildInstr(TargetOpcode::G_UMAX, {Dst}, {Src0, Src1});
1690 }
1691
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02001692 /// Build and insert \p Dst = G_ABS \p Src
1693 MachineInstrBuilder buildAbs(const DstOp &Dst, const SrcOp &Src) {
1694 return buildInstr(TargetOpcode::G_ABS, {Dst}, {Src});
1695 }
1696
Andrew Walbran3d2c1972020-04-07 12:24:26 +01001697 /// Build and insert \p Res = G_JUMP_TABLE \p JTI
1698 ///
1699 /// G_JUMP_TABLE sets \p Res to the address of the jump table specified by
1700 /// the jump table index \p JTI.
1701 ///
1702 /// \return a MachineInstrBuilder for the newly created instruction.
1703 MachineInstrBuilder buildJumpTable(const LLT PtrTy, unsigned JTI);
1704
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02001705 /// Build and insert \p Res = G_VECREDUCE_SEQ_FADD \p ScalarIn, \p VecIn
1706 ///
1707 /// \p ScalarIn is the scalar accumulator input to start the sequential
1708 /// reduction operation of \p VecIn.
1709 MachineInstrBuilder buildVecReduceSeqFAdd(const DstOp &Dst,
1710 const SrcOp &ScalarIn,
1711 const SrcOp &VecIn) {
1712 return buildInstr(TargetOpcode::G_VECREDUCE_SEQ_FADD, {Dst},
1713 {ScalarIn, {VecIn}});
1714 }
1715
1716 /// Build and insert \p Res = G_VECREDUCE_SEQ_FMUL \p ScalarIn, \p VecIn
1717 ///
1718 /// \p ScalarIn is the scalar accumulator input to start the sequential
1719 /// reduction operation of \p VecIn.
1720 MachineInstrBuilder buildVecReduceSeqFMul(const DstOp &Dst,
1721 const SrcOp &ScalarIn,
1722 const SrcOp &VecIn) {
1723 return buildInstr(TargetOpcode::G_VECREDUCE_SEQ_FMUL, {Dst},
1724 {ScalarIn, {VecIn}});
1725 }
1726
1727 /// Build and insert \p Res = G_VECREDUCE_FADD \p Src
1728 ///
1729 /// \p ScalarIn is the scalar accumulator input to the reduction operation of
1730 /// \p VecIn.
1731 MachineInstrBuilder buildVecReduceFAdd(const DstOp &Dst,
1732 const SrcOp &ScalarIn,
1733 const SrcOp &VecIn) {
1734 return buildInstr(TargetOpcode::G_VECREDUCE_FADD, {Dst}, {ScalarIn, VecIn});
1735 }
1736
1737 /// Build and insert \p Res = G_VECREDUCE_FMUL \p Src
1738 ///
1739 /// \p ScalarIn is the scalar accumulator input to the reduction operation of
1740 /// \p VecIn.
1741 MachineInstrBuilder buildVecReduceFMul(const DstOp &Dst,
1742 const SrcOp &ScalarIn,
1743 const SrcOp &VecIn) {
1744 return buildInstr(TargetOpcode::G_VECREDUCE_FMUL, {Dst}, {ScalarIn, VecIn});
1745 }
1746
1747 /// Build and insert \p Res = G_VECREDUCE_FMAX \p Src
1748 MachineInstrBuilder buildVecReduceFMax(const DstOp &Dst, const SrcOp &Src) {
1749 return buildInstr(TargetOpcode::G_VECREDUCE_FMAX, {Dst}, {Src});
1750 }
1751
1752 /// Build and insert \p Res = G_VECREDUCE_FMIN \p Src
1753 MachineInstrBuilder buildVecReduceFMin(const DstOp &Dst, const SrcOp &Src) {
1754 return buildInstr(TargetOpcode::G_VECREDUCE_FMIN, {Dst}, {Src});
1755 }
1756 /// Build and insert \p Res = G_VECREDUCE_ADD \p Src
1757 MachineInstrBuilder buildVecReduceAdd(const DstOp &Dst, const SrcOp &Src) {
1758 return buildInstr(TargetOpcode::G_VECREDUCE_ADD, {Dst}, {Src});
1759 }
1760
1761 /// Build and insert \p Res = G_VECREDUCE_MUL \p Src
1762 MachineInstrBuilder buildVecReduceMul(const DstOp &Dst, const SrcOp &Src) {
1763 return buildInstr(TargetOpcode::G_VECREDUCE_MUL, {Dst}, {Src});
1764 }
1765
1766 /// Build and insert \p Res = G_VECREDUCE_AND \p Src
1767 MachineInstrBuilder buildVecReduceAnd(const DstOp &Dst, const SrcOp &Src) {
1768 return buildInstr(TargetOpcode::G_VECREDUCE_AND, {Dst}, {Src});
1769 }
1770
1771 /// Build and insert \p Res = G_VECREDUCE_OR \p Src
1772 MachineInstrBuilder buildVecReduceOr(const DstOp &Dst, const SrcOp &Src) {
1773 return buildInstr(TargetOpcode::G_VECREDUCE_OR, {Dst}, {Src});
1774 }
1775
1776 /// Build and insert \p Res = G_VECREDUCE_XOR \p Src
1777 MachineInstrBuilder buildVecReduceXor(const DstOp &Dst, const SrcOp &Src) {
1778 return buildInstr(TargetOpcode::G_VECREDUCE_XOR, {Dst}, {Src});
1779 }
1780
1781 /// Build and insert \p Res = G_VECREDUCE_SMAX \p Src
1782 MachineInstrBuilder buildVecReduceSMax(const DstOp &Dst, const SrcOp &Src) {
1783 return buildInstr(TargetOpcode::G_VECREDUCE_SMAX, {Dst}, {Src});
1784 }
1785
1786 /// Build and insert \p Res = G_VECREDUCE_SMIN \p Src
1787 MachineInstrBuilder buildVecReduceSMin(const DstOp &Dst, const SrcOp &Src) {
1788 return buildInstr(TargetOpcode::G_VECREDUCE_SMIN, {Dst}, {Src});
1789 }
1790
1791 /// Build and insert \p Res = G_VECREDUCE_UMAX \p Src
1792 MachineInstrBuilder buildVecReduceUMax(const DstOp &Dst, const SrcOp &Src) {
1793 return buildInstr(TargetOpcode::G_VECREDUCE_UMAX, {Dst}, {Src});
1794 }
1795
1796 /// Build and insert \p Res = G_VECREDUCE_UMIN \p Src
1797 MachineInstrBuilder buildVecReduceUMin(const DstOp &Dst, const SrcOp &Src) {
1798 return buildInstr(TargetOpcode::G_VECREDUCE_UMIN, {Dst}, {Src});
1799 }
Andrew Walbran16937d02019-10-22 13:54:20 +01001800 virtual MachineInstrBuilder buildInstr(unsigned Opc, ArrayRef<DstOp> DstOps,
1801 ArrayRef<SrcOp> SrcOps,
1802 Optional<unsigned> Flags = None);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001803};
1804
1805} // End namespace llvm.
1806#endif // LLVM_CODEGEN_GLOBALISEL_MACHINEIRBUILDER_H