blob: 9f9964078eafacf6defb7b3ad7d43c18b3cd6019 [file] [log] [blame]
Quentin Colombet2ad1f852016-02-11 17:44:59 +00001//===-- llvm/CodeGen/GlobalISel/MachineIRBuilder.cpp - MIBuilder--*- C++ -*-==//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9/// \file
10/// This file implements the MachineIRBuidler class.
11//===----------------------------------------------------------------------===//
12#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
Aditya Nandakumarf75d4f32018-12-05 20:14:52 +000013#include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h"
Quentin Colombet2ad1f852016-02-11 17:44:59 +000014
15#include "llvm/CodeGen/MachineFunction.h"
16#include "llvm/CodeGen/MachineInstr.h"
17#include "llvm/CodeGen/MachineInstrBuilder.h"
Tim Northover0f140c72016-09-09 11:46:34 +000018#include "llvm/CodeGen/MachineRegisterInfo.h"
David Blaikie3f833ed2017-11-08 01:01:31 +000019#include "llvm/CodeGen/TargetInstrInfo.h"
David Blaikieb3bde2e2017-11-17 01:07:10 +000020#include "llvm/CodeGen/TargetOpcodes.h"
21#include "llvm/CodeGen/TargetSubtargetInfo.h"
Tim Northover09aac4a2017-01-26 23:39:14 +000022#include "llvm/IR/DebugInfo.h"
Quentin Colombet2ad1f852016-02-11 17:44:59 +000023
24using namespace llvm;
25
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +000026void MachineIRBuilderBase::setMF(MachineFunction &MF) {
27 State.MF = &MF;
28 State.MBB = nullptr;
29 State.MRI = &MF.getRegInfo();
30 State.TII = MF.getSubtarget().getInstrInfo();
31 State.DL = DebugLoc();
32 State.II = MachineBasicBlock::iterator();
Aditya Nandakumarf75d4f32018-12-05 20:14:52 +000033 State.Observer = nullptr;
Quentin Colombet2ad1f852016-02-11 17:44:59 +000034}
35
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +000036void MachineIRBuilderBase::setMBB(MachineBasicBlock &MBB) {
37 State.MBB = &MBB;
38 State.II = MBB.end();
Quentin Colombet2ad1f852016-02-11 17:44:59 +000039 assert(&getMF() == MBB.getParent() &&
40 "Basic block is in a different function");
41}
42
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +000043void MachineIRBuilderBase::setInstr(MachineInstr &MI) {
Quentin Colombet2ad1f852016-02-11 17:44:59 +000044 assert(MI.getParent() && "Instruction is not part of a basic block");
Quentin Colombet91ebd712016-03-11 17:27:47 +000045 setMBB(*MI.getParent());
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +000046 State.II = MI.getIterator();
Quentin Colombet2ad1f852016-02-11 17:44:59 +000047}
48
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +000049void MachineIRBuilderBase::setInsertPt(MachineBasicBlock &MBB,
50 MachineBasicBlock::iterator II) {
Tim Northover05cc4852016-12-07 21:05:38 +000051 assert(MBB.getParent() == &getMF() &&
52 "Basic block is in a different function");
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +000053 State.MBB = &MBB;
54 State.II = II;
Quentin Colombet2ad1f852016-02-11 17:44:59 +000055}
56
Roman Tereshind5fa9fd2018-05-09 17:28:18 +000057void MachineIRBuilderBase::recordInsertion(MachineInstr *InsertedInstr) const {
Aditya Nandakumarf75d4f32018-12-05 20:14:52 +000058 if (State.Observer)
59 State.Observer->createdInstr(*InsertedInstr);
Roman Tereshind5fa9fd2018-05-09 17:28:18 +000060}
61
Aditya Nandakumarf75d4f32018-12-05 20:14:52 +000062void MachineIRBuilderBase::setChangeObserver(GISelChangeObserver &Observer) {
63 State.Observer = &Observer;
Tim Northover438c77c2016-08-25 17:37:32 +000064}
65
Aditya Nandakumarf75d4f32018-12-05 20:14:52 +000066void MachineIRBuilderBase::stopObservingChanges() { State.Observer = nullptr; }
Tim Northover438c77c2016-08-25 17:37:32 +000067
Quentin Colombetf9b49342016-03-11 17:27:58 +000068//------------------------------------------------------------------------------
69// Build instruction variants.
70//------------------------------------------------------------------------------
Tim Northovercc5f7622016-07-26 16:45:26 +000071
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +000072MachineInstrBuilder MachineIRBuilderBase::buildInstr(unsigned Opcode) {
Tim Northovera5e38fa2016-09-22 13:49:25 +000073 return insertInstr(buildInstrNoInsert(Opcode));
74}
75
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +000076MachineInstrBuilder MachineIRBuilderBase::buildInstrNoInsert(unsigned Opcode) {
77 MachineInstrBuilder MIB = BuildMI(getMF(), getDL(), getTII().get(Opcode));
Tim Northovera5e38fa2016-09-22 13:49:25 +000078 return MIB;
79}
80
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +000081MachineInstrBuilder MachineIRBuilderBase::insertInstr(MachineInstrBuilder MIB) {
Tim Northovera51575f2016-07-29 17:43:52 +000082 getMBB().insert(getInsertPt(), MIB);
Roman Tereshind5fa9fd2018-05-09 17:28:18 +000083 recordInsertion(MIB);
Tim Northovera51575f2016-07-29 17:43:52 +000084 return MIB;
Quentin Colombet74d7d2f2016-02-11 18:53:28 +000085}
86
Adrian Prantlaac78ce2017-08-01 22:37:35 +000087MachineInstrBuilder
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +000088MachineIRBuilderBase::buildDirectDbgValue(unsigned Reg, const MDNode *Variable,
89 const MDNode *Expr) {
Tim Northover09aac4a2017-01-26 23:39:14 +000090 assert(isa<DILocalVariable>(Variable) && "not a variable");
91 assert(cast<DIExpression>(Expr)->isValid() && "not an expression");
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +000092 assert(
93 cast<DILocalVariable>(Variable)->isValidLocationForIntrinsic(getDL()) &&
94 "Expected inlined-at fields to agree");
95 return insertInstr(BuildMI(getMF(), getDL(),
96 getTII().get(TargetOpcode::DBG_VALUE),
Adrian Prantlaac78ce2017-08-01 22:37:35 +000097 /*IsIndirect*/ false, Reg, Variable, Expr));
Tim Northover09aac4a2017-01-26 23:39:14 +000098}
99
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000100MachineInstrBuilder MachineIRBuilderBase::buildIndirectDbgValue(
101 unsigned Reg, const MDNode *Variable, const MDNode *Expr) {
Tim Northover09aac4a2017-01-26 23:39:14 +0000102 assert(isa<DILocalVariable>(Variable) && "not a variable");
103 assert(cast<DIExpression>(Expr)->isValid() && "not an expression");
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000104 assert(
105 cast<DILocalVariable>(Variable)->isValidLocationForIntrinsic(getDL()) &&
106 "Expected inlined-at fields to agree");
107 return insertInstr(BuildMI(getMF(), getDL(),
108 getTII().get(TargetOpcode::DBG_VALUE),
Adrian Prantlaac78ce2017-08-01 22:37:35 +0000109 /*IsIndirect*/ true, Reg, Variable, Expr));
Tim Northover09aac4a2017-01-26 23:39:14 +0000110}
111
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000112MachineInstrBuilder
113MachineIRBuilderBase::buildFIDbgValue(int FI, const MDNode *Variable,
114 const MDNode *Expr) {
Tim Northover09aac4a2017-01-26 23:39:14 +0000115 assert(isa<DILocalVariable>(Variable) && "not a variable");
116 assert(cast<DIExpression>(Expr)->isValid() && "not an expression");
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000117 assert(
118 cast<DILocalVariable>(Variable)->isValidLocationForIntrinsic(getDL()) &&
119 "Expected inlined-at fields to agree");
Tim Northover09aac4a2017-01-26 23:39:14 +0000120 return buildInstr(TargetOpcode::DBG_VALUE)
121 .addFrameIndex(FI)
122 .addImm(0)
123 .addMetadata(Variable)
124 .addMetadata(Expr);
125}
126
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000127MachineInstrBuilder MachineIRBuilderBase::buildConstDbgValue(
128 const Constant &C, const MDNode *Variable, const MDNode *Expr) {
Tim Northover09aac4a2017-01-26 23:39:14 +0000129 assert(isa<DILocalVariable>(Variable) && "not a variable");
130 assert(cast<DIExpression>(Expr)->isValid() && "not an expression");
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000131 assert(
132 cast<DILocalVariable>(Variable)->isValidLocationForIntrinsic(getDL()) &&
133 "Expected inlined-at fields to agree");
Tim Northover09aac4a2017-01-26 23:39:14 +0000134 auto MIB = buildInstr(TargetOpcode::DBG_VALUE);
135 if (auto *CI = dyn_cast<ConstantInt>(&C)) {
136 if (CI->getBitWidth() > 64)
137 MIB.addCImm(CI);
138 else
139 MIB.addImm(CI->getZExtValue());
Ahmed Bougacha4826bae2017-03-07 20:34:20 +0000140 } else if (auto *CFP = dyn_cast<ConstantFP>(&C)) {
Ahmed Bougachaadce3ee2017-03-07 20:52:57 +0000141 MIB.addFPImm(CFP);
Ahmed Bougacha4826bae2017-03-07 20:34:20 +0000142 } else {
143 // Insert %noreg if we didn't find a usable constant and had to drop it.
144 MIB.addReg(0U);
145 }
Tim Northover09aac4a2017-01-26 23:39:14 +0000146
Adrian Prantld92ac5a2017-07-28 22:46:20 +0000147 return MIB.addImm(0).addMetadata(Variable).addMetadata(Expr);
Tim Northover09aac4a2017-01-26 23:39:14 +0000148}
149
Hsiangkai Wang2532ac82018-08-17 15:22:04 +0000150MachineInstrBuilder MachineIRBuilderBase::buildDbgLabel(const MDNode *Label) {
151 assert(isa<DILabel>(Label) && "not a label");
152 assert(cast<DILabel>(Label)->isValidLocationForIntrinsic(State.DL) &&
153 "Expected inlined-at fields to agree");
154 auto MIB = buildInstr(TargetOpcode::DBG_LABEL);
155
156 return MIB.addMetadata(Label);
157}
158
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000159MachineInstrBuilder MachineIRBuilderBase::buildFrameIndex(unsigned Res,
160 int Idx) {
161 assert(getMRI()->getType(Res).isPointer() && "invalid operand type");
Tim Northover0f140c72016-09-09 11:46:34 +0000162 return buildInstr(TargetOpcode::G_FRAME_INDEX)
Tim Northovera51575f2016-07-29 17:43:52 +0000163 .addDef(Res)
164 .addFrameIndex(Idx);
Tim Northoverbd505462016-07-22 16:59:52 +0000165}
Tim Northover33b07d62016-07-22 20:03:43 +0000166
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000167MachineInstrBuilder
168MachineIRBuilderBase::buildGlobalValue(unsigned Res, const GlobalValue *GV) {
169 assert(getMRI()->getType(Res).isPointer() && "invalid operand type");
170 assert(getMRI()->getType(Res).getAddressSpace() ==
Tim Northover032548f2016-09-12 12:10:41 +0000171 GV->getType()->getAddressSpace() &&
172 "address space mismatch");
173
174 return buildInstr(TargetOpcode::G_GLOBAL_VALUE)
175 .addDef(Res)
176 .addGlobalAddress(GV);
177}
178
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000179void MachineIRBuilderBase::validateBinaryOp(unsigned Res, unsigned Op0,
180 unsigned Op1) {
181 assert((getMRI()->getType(Res).isScalar() ||
182 getMRI()->getType(Res).isVector()) &&
Tim Northover1f8b1db2016-09-09 11:46:58 +0000183 "invalid operand type");
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000184 assert(getMRI()->getType(Res) == getMRI()->getType(Op0) &&
185 getMRI()->getType(Res) == getMRI()->getType(Op1) && "type mismatch");
Tim Northover33b07d62016-07-22 20:03:43 +0000186}
187
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000188MachineInstrBuilder MachineIRBuilderBase::buildGEP(unsigned Res, unsigned Op0,
189 unsigned Op1) {
190 assert(getMRI()->getType(Res).isPointer() &&
191 getMRI()->getType(Res) == getMRI()->getType(Op0) && "type mismatch");
192 assert(getMRI()->getType(Op1).isScalar() && "invalid offset type");
Tim Northovera7653b32016-09-12 11:20:22 +0000193
194 return buildInstr(TargetOpcode::G_GEP)
195 .addDef(Res)
196 .addUse(Op0)
197 .addUse(Op1);
198}
199
Daniel Sanders4e523662017-06-13 23:42:32 +0000200Optional<MachineInstrBuilder>
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000201MachineIRBuilderBase::materializeGEP(unsigned &Res, unsigned Op0,
202 const LLT &ValueTy, uint64_t Value) {
Daniel Sanders4e523662017-06-13 23:42:32 +0000203 assert(Res == 0 && "Res is a result argument");
204 assert(ValueTy.isScalar() && "invalid offset type");
205
206 if (Value == 0) {
207 Res = Op0;
208 return None;
209 }
210
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000211 Res = getMRI()->createGenericVirtualRegister(getMRI()->getType(Op0));
212 unsigned TmpReg = getMRI()->createGenericVirtualRegister(ValueTy);
Daniel Sanders4e523662017-06-13 23:42:32 +0000213
214 buildConstant(TmpReg, Value);
215 return buildGEP(Res, Op0, TmpReg);
216}
217
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000218MachineInstrBuilder MachineIRBuilderBase::buildPtrMask(unsigned Res,
219 unsigned Op0,
220 uint32_t NumBits) {
221 assert(getMRI()->getType(Res).isPointer() &&
222 getMRI()->getType(Res) == getMRI()->getType(Op0) && "type mismatch");
Tim Northoverc2f89562017-02-14 20:56:18 +0000223
224 return buildInstr(TargetOpcode::G_PTR_MASK)
225 .addDef(Res)
226 .addUse(Op0)
227 .addImm(NumBits);
228}
229
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000230MachineInstrBuilder MachineIRBuilderBase::buildBr(MachineBasicBlock &Dest) {
Tim Northover0f140c72016-09-09 11:46:34 +0000231 return buildInstr(TargetOpcode::G_BR).addMBB(&Dest);
Tim Northovercc5f7622016-07-26 16:45:26 +0000232}
233
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000234MachineInstrBuilder MachineIRBuilderBase::buildBrIndirect(unsigned Tgt) {
235 assert(getMRI()->getType(Tgt).isPointer() && "invalid branch destination");
Kristof Beyls65a12c02017-01-30 09:13:18 +0000236 return buildInstr(TargetOpcode::G_BRINDIRECT).addUse(Tgt);
237}
238
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000239MachineInstrBuilder MachineIRBuilderBase::buildCopy(unsigned Res, unsigned Op) {
240 assert(getMRI()->getType(Res) == LLT() || getMRI()->getType(Op) == LLT() ||
241 getMRI()->getType(Res) == getMRI()->getType(Op));
Tim Northovera51575f2016-07-29 17:43:52 +0000242 return buildInstr(TargetOpcode::COPY).addDef(Res).addUse(Op);
Tim Northover756eca32016-07-26 16:45:30 +0000243}
244
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000245MachineInstrBuilder
246MachineIRBuilderBase::buildConstant(unsigned Res, const ConstantInt &Val) {
247 LLT Ty = getMRI()->getType(Res);
Tim Northover1f8b1db2016-09-09 11:46:58 +0000248
Sam McCall03435f52016-12-06 10:14:36 +0000249 assert((Ty.isScalar() || Ty.isPointer()) && "invalid operand type");
Tim Northover9267ac52016-12-05 21:47:07 +0000250
251 const ConstantInt *NewVal = &Val;
252 if (Ty.getSizeInBits() != Val.getBitWidth())
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000253 NewVal = ConstantInt::get(getMF().getFunction().getContext(),
Tim Northover9267ac52016-12-05 21:47:07 +0000254 Val.getValue().sextOrTrunc(Ty.getSizeInBits()));
255
256 return buildInstr(TargetOpcode::G_CONSTANT).addDef(Res).addCImm(NewVal);
257}
258
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000259MachineInstrBuilder MachineIRBuilderBase::buildConstant(unsigned Res,
260 int64_t Val) {
261 auto IntN = IntegerType::get(getMF().getFunction().getContext(),
262 getMRI()->getType(Res).getSizeInBits());
Tim Northover9267ac52016-12-05 21:47:07 +0000263 ConstantInt *CI = ConstantInt::get(IntN, Val, true);
264 return buildConstant(Res, *CI);
Tim Northover9656f142016-08-04 20:54:13 +0000265}
266
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000267MachineInstrBuilder
268MachineIRBuilderBase::buildFConstant(unsigned Res, const ConstantFP &Val) {
269 assert(getMRI()->getType(Res).isScalar() && "invalid operand type");
Tim Northover1f8b1db2016-09-09 11:46:58 +0000270
Tim Northover0f140c72016-09-09 11:46:34 +0000271 return buildInstr(TargetOpcode::G_FCONSTANT).addDef(Res).addFPImm(&Val);
Tim Northoverb16734f2016-08-19 20:09:15 +0000272}
273
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000274MachineInstrBuilder MachineIRBuilderBase::buildFConstant(unsigned Res,
275 double Val) {
276 LLT DstTy = getMRI()->getType(Res);
277 auto &Ctx = getMF().getFunction().getContext();
Aditya Nandakumar91fc4e02018-03-09 17:31:51 +0000278 auto *CFP =
279 ConstantFP::get(Ctx, getAPFloatFromSize(Val, DstTy.getSizeInBits()));
280 return buildFConstant(Res, *CFP);
281}
282
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000283MachineInstrBuilder MachineIRBuilderBase::buildBrCond(unsigned Tst,
284 MachineBasicBlock &Dest) {
285 assert(getMRI()->getType(Tst).isScalar() && "invalid operand type");
Tim Northover1f8b1db2016-09-09 11:46:58 +0000286
Tim Northover0f140c72016-09-09 11:46:34 +0000287 return buildInstr(TargetOpcode::G_BRCOND).addUse(Tst).addMBB(&Dest);
Tim Northover69c2ba52016-07-29 17:58:00 +0000288}
289
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000290MachineInstrBuilder MachineIRBuilderBase::buildLoad(unsigned Res, unsigned Addr,
291 MachineMemOperand &MMO) {
Daniel Sanders5eb9f582018-04-28 18:14:50 +0000292 return buildLoadInstr(TargetOpcode::G_LOAD, Res, Addr, MMO);
293}
294
295MachineInstrBuilder
296MachineIRBuilderBase::buildLoadInstr(unsigned Opcode, unsigned Res,
297 unsigned Addr, MachineMemOperand &MMO) {
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000298 assert(getMRI()->getType(Res).isValid() && "invalid operand type");
299 assert(getMRI()->getType(Addr).isPointer() && "invalid operand type");
Tim Northover1f8b1db2016-09-09 11:46:58 +0000300
Daniel Sanders5eb9f582018-04-28 18:14:50 +0000301 return buildInstr(Opcode)
Tim Northovera51575f2016-07-29 17:43:52 +0000302 .addDef(Res)
303 .addUse(Addr)
304 .addMemOperand(&MMO);
Tim Northoverad2b7172016-07-26 20:23:26 +0000305}
306
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000307MachineInstrBuilder MachineIRBuilderBase::buildStore(unsigned Val,
308 unsigned Addr,
309 MachineMemOperand &MMO) {
310 assert(getMRI()->getType(Val).isValid() && "invalid operand type");
311 assert(getMRI()->getType(Addr).isPointer() && "invalid operand type");
Tim Northover1f8b1db2016-09-09 11:46:58 +0000312
Tim Northover0f140c72016-09-09 11:46:34 +0000313 return buildInstr(TargetOpcode::G_STORE)
Tim Northovera51575f2016-07-29 17:43:52 +0000314 .addUse(Val)
315 .addUse(Addr)
316 .addMemOperand(&MMO);
Tim Northoverad2b7172016-07-26 20:23:26 +0000317}
318
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000319MachineInstrBuilder MachineIRBuilderBase::buildUAdde(unsigned Res,
320 unsigned CarryOut,
321 unsigned Op0, unsigned Op1,
322 unsigned CarryIn) {
323 assert(getMRI()->getType(Res).isScalar() && "invalid operand type");
324 assert(getMRI()->getType(Res) == getMRI()->getType(Op0) &&
325 getMRI()->getType(Res) == getMRI()->getType(Op1) && "type mismatch");
326 assert(getMRI()->getType(CarryOut).isScalar() && "invalid operand type");
327 assert(getMRI()->getType(CarryOut) == getMRI()->getType(CarryIn) &&
328 "type mismatch");
Tim Northover1f8b1db2016-09-09 11:46:58 +0000329
Tim Northover0f140c72016-09-09 11:46:34 +0000330 return buildInstr(TargetOpcode::G_UADDE)
Tim Northover9656f142016-08-04 20:54:13 +0000331 .addDef(Res)
332 .addDef(CarryOut)
333 .addUse(Op0)
334 .addUse(Op1)
335 .addUse(CarryIn);
336}
337
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000338MachineInstrBuilder MachineIRBuilderBase::buildAnyExt(unsigned Res,
339 unsigned Op) {
Tim Northover0f140c72016-09-09 11:46:34 +0000340 validateTruncExt(Res, Op, true);
341 return buildInstr(TargetOpcode::G_ANYEXT).addDef(Res).addUse(Op);
Tim Northover32335812016-08-04 18:35:11 +0000342}
343
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000344MachineInstrBuilder MachineIRBuilderBase::buildSExt(unsigned Res, unsigned Op) {
Tim Northover0f140c72016-09-09 11:46:34 +0000345 validateTruncExt(Res, Op, true);
346 return buildInstr(TargetOpcode::G_SEXT).addDef(Res).addUse(Op);
Tim Northover6cd4b232016-08-23 21:01:26 +0000347}
348
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000349MachineInstrBuilder MachineIRBuilderBase::buildZExt(unsigned Res, unsigned Op) {
Tim Northover0f140c72016-09-09 11:46:34 +0000350 validateTruncExt(Res, Op, true);
351 return buildInstr(TargetOpcode::G_ZEXT).addDef(Res).addUse(Op);
Tim Northover6cd4b232016-08-23 21:01:26 +0000352}
353
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000354MachineInstrBuilder MachineIRBuilderBase::buildExtOrTrunc(unsigned ExtOpc,
355 unsigned Res,
356 unsigned Op) {
Aditya Nandakumar892979e2017-08-25 04:57:27 +0000357 assert((TargetOpcode::G_ANYEXT == ExtOpc || TargetOpcode::G_ZEXT == ExtOpc ||
358 TargetOpcode::G_SEXT == ExtOpc) &&
359 "Expecting Extending Opc");
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000360 assert(getMRI()->getType(Res).isScalar() ||
361 getMRI()->getType(Res).isVector());
362 assert(getMRI()->getType(Res).isScalar() == getMRI()->getType(Op).isScalar());
Tim Northoverc9902362017-06-27 22:45:35 +0000363
Tim Northovera7653b32016-09-12 11:20:22 +0000364 unsigned Opcode = TargetOpcode::COPY;
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000365 if (getMRI()->getType(Res).getSizeInBits() >
366 getMRI()->getType(Op).getSizeInBits())
Aditya Nandakumar892979e2017-08-25 04:57:27 +0000367 Opcode = ExtOpc;
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000368 else if (getMRI()->getType(Res).getSizeInBits() <
369 getMRI()->getType(Op).getSizeInBits())
Tim Northovera7653b32016-09-12 11:20:22 +0000370 Opcode = TargetOpcode::G_TRUNC;
Tim Northoverc9902362017-06-27 22:45:35 +0000371 else
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000372 assert(getMRI()->getType(Res) == getMRI()->getType(Op));
Tim Northovera7653b32016-09-12 11:20:22 +0000373
374 return buildInstr(Opcode).addDef(Res).addUse(Op);
375}
376
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000377MachineInstrBuilder MachineIRBuilderBase::buildSExtOrTrunc(unsigned Res,
378 unsigned Op) {
Aditya Nandakumar892979e2017-08-25 04:57:27 +0000379 return buildExtOrTrunc(TargetOpcode::G_SEXT, Res, Op);
380}
381
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000382MachineInstrBuilder MachineIRBuilderBase::buildZExtOrTrunc(unsigned Res,
383 unsigned Op) {
Aditya Nandakumar892979e2017-08-25 04:57:27 +0000384 return buildExtOrTrunc(TargetOpcode::G_ZEXT, Res, Op);
385}
Tim Northoverc9902362017-06-27 22:45:35 +0000386
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000387MachineInstrBuilder MachineIRBuilderBase::buildAnyExtOrTrunc(unsigned Res,
388 unsigned Op) {
Aditya Nandakumar892979e2017-08-25 04:57:27 +0000389 return buildExtOrTrunc(TargetOpcode::G_ANYEXT, Res, Op);
Tim Northoverc3e3f592017-02-03 18:22:45 +0000390}
391
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000392MachineInstrBuilder MachineIRBuilderBase::buildCast(unsigned Dst,
393 unsigned Src) {
394 LLT SrcTy = getMRI()->getType(Src);
395 LLT DstTy = getMRI()->getType(Dst);
Tim Northover95b6d5f2017-03-06 19:04:17 +0000396 if (SrcTy == DstTy)
397 return buildCopy(Dst, Src);
398
399 unsigned Opcode;
400 if (SrcTy.isPointer() && DstTy.isScalar())
401 Opcode = TargetOpcode::G_PTRTOINT;
402 else if (DstTy.isPointer() && SrcTy.isScalar())
403 Opcode = TargetOpcode::G_INTTOPTR;
404 else {
405 assert(!SrcTy.isPointer() && !DstTy.isPointer() && "n G_ADDRCAST yet");
406 Opcode = TargetOpcode::G_BITCAST;
407 }
408
409 return buildInstr(Opcode).addDef(Dst).addUse(Src);
410}
411
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000412MachineInstrBuilder
413MachineIRBuilderBase::buildExtract(unsigned Res, unsigned Src, uint64_t Index) {
Tim Northover1f8b1db2016-09-09 11:46:58 +0000414#ifndef NDEBUG
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000415 assert(getMRI()->getType(Src).isValid() && "invalid operand type");
416 assert(getMRI()->getType(Res).isValid() && "invalid operand type");
417 assert(Index + getMRI()->getType(Res).getSizeInBits() <=
418 getMRI()->getType(Src).getSizeInBits() &&
Tim Northoverc2c545b2017-03-06 23:50:28 +0000419 "extracting off end of register");
Tim Northover1f8b1db2016-09-09 11:46:58 +0000420#endif
421
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000422 if (getMRI()->getType(Res).getSizeInBits() ==
423 getMRI()->getType(Src).getSizeInBits()) {
Tim Northoverc2c545b2017-03-06 23:50:28 +0000424 assert(Index == 0 && "insertion past the end of a register");
425 return buildCast(Res, Src);
426 }
Tim Northover33b07d62016-07-22 20:03:43 +0000427
Tim Northoverc2c545b2017-03-06 23:50:28 +0000428 return buildInstr(TargetOpcode::G_EXTRACT)
429 .addDef(Res)
430 .addUse(Src)
431 .addImm(Index);
Tim Northover33b07d62016-07-22 20:03:43 +0000432}
433
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000434void MachineIRBuilderBase::buildSequence(unsigned Res, ArrayRef<unsigned> Ops,
435 ArrayRef<uint64_t> Indices) {
Tim Northover1f8b1db2016-09-09 11:46:58 +0000436#ifndef NDEBUG
Tim Northover0f140c72016-09-09 11:46:34 +0000437 assert(Ops.size() == Indices.size() && "incompatible args");
Tim Northover26b76f22016-08-19 18:32:14 +0000438 assert(!Ops.empty() && "invalid trivial sequence");
Tim Northover991b12b2016-08-30 20:51:25 +0000439 assert(std::is_sorted(Indices.begin(), Indices.end()) &&
440 "sequence offsets must be in ascending order");
Tim Northover91c81732016-08-19 17:17:06 +0000441
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000442 assert(getMRI()->getType(Res).isValid() && "invalid operand type");
Tim Northover1f8b1db2016-09-09 11:46:58 +0000443 for (auto Op : Ops)
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000444 assert(getMRI()->getType(Op).isValid() && "invalid operand type");
Tim Northover1f8b1db2016-09-09 11:46:58 +0000445#endif
446
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000447 LLT ResTy = getMRI()->getType(Res);
448 LLT OpTy = getMRI()->getType(Ops[0]);
Tim Northoverb57bf2a2017-06-23 16:15:37 +0000449 unsigned OpSize = OpTy.getSizeInBits();
450 bool MaybeMerge = true;
Tim Northover91c81732016-08-19 17:17:06 +0000451 for (unsigned i = 0; i < Ops.size(); ++i) {
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000452 if (getMRI()->getType(Ops[i]) != OpTy || Indices[i] != i * OpSize) {
Tim Northoverb57bf2a2017-06-23 16:15:37 +0000453 MaybeMerge = false;
454 break;
455 }
Tim Northover91c81732016-08-19 17:17:06 +0000456 }
Tim Northoverb57bf2a2017-06-23 16:15:37 +0000457
458 if (MaybeMerge && Ops.size() * OpSize == ResTy.getSizeInBits()) {
459 buildMerge(Res, Ops);
460 return;
461 }
462
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000463 unsigned ResIn = getMRI()->createGenericVirtualRegister(ResTy);
Tim Northoverb57bf2a2017-06-23 16:15:37 +0000464 buildUndef(ResIn);
465
466 for (unsigned i = 0; i < Ops.size(); ++i) {
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000467 unsigned ResOut = i + 1 == Ops.size()
468 ? Res
469 : getMRI()->createGenericVirtualRegister(ResTy);
Tim Northoverb57bf2a2017-06-23 16:15:37 +0000470 buildInsert(ResOut, ResIn, Ops[i], Indices[i]);
471 ResIn = ResOut;
472 }
Tim Northover33b07d62016-07-22 20:03:43 +0000473}
Tim Northover5fb414d2016-07-29 22:32:36 +0000474
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000475MachineInstrBuilder MachineIRBuilderBase::buildUndef(unsigned Res) {
Tim Northoverff5e7e12017-06-30 20:27:36 +0000476 return buildInstr(TargetOpcode::G_IMPLICIT_DEF).addDef(Res);
Tim Northover81dafc12017-03-06 18:36:40 +0000477}
478
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000479MachineInstrBuilder MachineIRBuilderBase::buildMerge(unsigned Res,
480 ArrayRef<unsigned> Ops) {
Tim Northoverbf017292017-03-03 22:46:09 +0000481
482#ifndef NDEBUG
483 assert(!Ops.empty() && "invalid trivial sequence");
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000484 LLT Ty = getMRI()->getType(Ops[0]);
Tim Northoverbf017292017-03-03 22:46:09 +0000485 for (auto Reg : Ops)
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000486 assert(getMRI()->getType(Reg) == Ty && "type mismatch in input list");
487 assert(Ops.size() * getMRI()->getType(Ops[0]).getSizeInBits() ==
488 getMRI()->getType(Res).getSizeInBits() &&
Tim Northoverbf017292017-03-03 22:46:09 +0000489 "input operands do not cover output register");
490#endif
491
Tim Northoverc2d5e6d2017-06-26 20:34:13 +0000492 if (Ops.size() == 1)
Tim Northover849fcca2017-06-27 21:41:40 +0000493 return buildCast(Res, Ops[0]);
Tim Northoverc2d5e6d2017-06-26 20:34:13 +0000494
Tim Northoverbf017292017-03-03 22:46:09 +0000495 MachineInstrBuilder MIB = buildInstr(TargetOpcode::G_MERGE_VALUES);
496 MIB.addDef(Res);
497 for (unsigned i = 0; i < Ops.size(); ++i)
498 MIB.addUse(Ops[i]);
499 return MIB;
500}
501
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000502MachineInstrBuilder MachineIRBuilderBase::buildUnmerge(ArrayRef<unsigned> Res,
503 unsigned Op) {
Tim Northoverbf017292017-03-03 22:46:09 +0000504
505#ifndef NDEBUG
506 assert(!Res.empty() && "invalid trivial sequence");
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000507 LLT Ty = getMRI()->getType(Res[0]);
Tim Northoverbf017292017-03-03 22:46:09 +0000508 for (auto Reg : Res)
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000509 assert(getMRI()->getType(Reg) == Ty && "type mismatch in input list");
510 assert(Res.size() * getMRI()->getType(Res[0]).getSizeInBits() ==
511 getMRI()->getType(Op).getSizeInBits() &&
Tim Northoverbf017292017-03-03 22:46:09 +0000512 "input operands do not cover output register");
513#endif
514
515 MachineInstrBuilder MIB = buildInstr(TargetOpcode::G_UNMERGE_VALUES);
516 for (unsigned i = 0; i < Res.size(); ++i)
517 MIB.addDef(Res[i]);
518 MIB.addUse(Op);
519 return MIB;
520}
521
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000522MachineInstrBuilder MachineIRBuilderBase::buildInsert(unsigned Res,
523 unsigned Src, unsigned Op,
524 unsigned Index) {
525 assert(Index + getMRI()->getType(Op).getSizeInBits() <=
526 getMRI()->getType(Res).getSizeInBits() &&
Tim Northoverc9902362017-06-27 22:45:35 +0000527 "insertion past the end of a register");
528
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000529 if (getMRI()->getType(Res).getSizeInBits() ==
530 getMRI()->getType(Op).getSizeInBits()) {
Tim Northover95b6d5f2017-03-06 19:04:17 +0000531 return buildCast(Res, Op);
532 }
533
Tim Northover3e6a7af2017-03-03 23:05:47 +0000534 return buildInstr(TargetOpcode::G_INSERT)
535 .addDef(Res)
536 .addUse(Src)
537 .addUse(Op)
538 .addImm(Index);
539}
540
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000541MachineInstrBuilder MachineIRBuilderBase::buildIntrinsic(Intrinsic::ID ID,
542 unsigned Res,
543 bool HasSideEffects) {
Tim Northover5fb414d2016-07-29 22:32:36 +0000544 auto MIB =
545 buildInstr(HasSideEffects ? TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS
Tim Northover0f140c72016-09-09 11:46:34 +0000546 : TargetOpcode::G_INTRINSIC);
Tim Northover5fb414d2016-07-29 22:32:36 +0000547 if (Res)
548 MIB.addDef(Res);
549 MIB.addIntrinsicID(ID);
550 return MIB;
551}
Tim Northover32335812016-08-04 18:35:11 +0000552
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000553MachineInstrBuilder MachineIRBuilderBase::buildTrunc(unsigned Res,
554 unsigned Op) {
Tim Northover0f140c72016-09-09 11:46:34 +0000555 validateTruncExt(Res, Op, false);
556 return buildInstr(TargetOpcode::G_TRUNC).addDef(Res).addUse(Op);
Tim Northover32335812016-08-04 18:35:11 +0000557}
Tim Northoverde3aea0412016-08-17 20:25:25 +0000558
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000559MachineInstrBuilder MachineIRBuilderBase::buildFPTrunc(unsigned Res,
560 unsigned Op) {
Tim Northover0f140c72016-09-09 11:46:34 +0000561 validateTruncExt(Res, Op, false);
562 return buildInstr(TargetOpcode::G_FPTRUNC).addDef(Res).addUse(Op);
Tim Northovera11be042016-08-19 22:40:08 +0000563}
564
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000565MachineInstrBuilder MachineIRBuilderBase::buildICmp(CmpInst::Predicate Pred,
566 unsigned Res, unsigned Op0,
567 unsigned Op1) {
Tim Northover1f8b1db2016-09-09 11:46:58 +0000568#ifndef NDEBUG
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000569 assert(getMRI()->getType(Op0) == getMRI()->getType(Op0) && "type mismatch");
Tim Northover1f8b1db2016-09-09 11:46:58 +0000570 assert(CmpInst::isIntPredicate(Pred) && "invalid predicate");
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000571 if (getMRI()->getType(Op0).isScalar() || getMRI()->getType(Op0).isPointer())
572 assert(getMRI()->getType(Res).isScalar() && "type mismatch");
Tim Northover1f8b1db2016-09-09 11:46:58 +0000573 else
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000574 assert(getMRI()->getType(Res).isVector() &&
575 getMRI()->getType(Res).getNumElements() ==
576 getMRI()->getType(Op0).getNumElements() &&
Tim Northover1f8b1db2016-09-09 11:46:58 +0000577 "type mismatch");
578#endif
579
Tim Northover0f140c72016-09-09 11:46:34 +0000580 return buildInstr(TargetOpcode::G_ICMP)
Tim Northoverde3aea0412016-08-17 20:25:25 +0000581 .addDef(Res)
582 .addPredicate(Pred)
583 .addUse(Op0)
584 .addUse(Op1);
585}
Tim Northover5a28c362016-08-19 20:09:07 +0000586
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000587MachineInstrBuilder MachineIRBuilderBase::buildFCmp(CmpInst::Predicate Pred,
588 unsigned Res, unsigned Op0,
589 unsigned Op1) {
Tim Northover1f8b1db2016-09-09 11:46:58 +0000590#ifndef NDEBUG
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000591 assert((getMRI()->getType(Op0).isScalar() ||
592 getMRI()->getType(Op0).isVector()) &&
Tim Northover1f8b1db2016-09-09 11:46:58 +0000593 "invalid operand type");
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000594 assert(getMRI()->getType(Op0) == getMRI()->getType(Op1) && "type mismatch");
Tim Northover1f8b1db2016-09-09 11:46:58 +0000595 assert(CmpInst::isFPPredicate(Pred) && "invalid predicate");
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000596 if (getMRI()->getType(Op0).isScalar())
597 assert(getMRI()->getType(Res).isScalar() && "type mismatch");
Tim Northover1f8b1db2016-09-09 11:46:58 +0000598 else
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000599 assert(getMRI()->getType(Res).isVector() &&
600 getMRI()->getType(Res).getNumElements() ==
601 getMRI()->getType(Op0).getNumElements() &&
Tim Northover1f8b1db2016-09-09 11:46:58 +0000602 "type mismatch");
603#endif
604
Tim Northover0f140c72016-09-09 11:46:34 +0000605 return buildInstr(TargetOpcode::G_FCMP)
Tim Northoverd5c23bc2016-08-19 20:48:16 +0000606 .addDef(Res)
607 .addPredicate(Pred)
608 .addUse(Op0)
609 .addUse(Op1);
610}
611
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000612MachineInstrBuilder MachineIRBuilderBase::buildSelect(unsigned Res,
613 unsigned Tst,
614 unsigned Op0,
615 unsigned Op1) {
Tim Northover1f8b1db2016-09-09 11:46:58 +0000616#ifndef NDEBUG
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000617 LLT ResTy = getMRI()->getType(Res);
Tim Northoverf50f2f32016-12-06 18:38:34 +0000618 assert((ResTy.isScalar() || ResTy.isVector() || ResTy.isPointer()) &&
Tim Northover1f8b1db2016-09-09 11:46:58 +0000619 "invalid operand type");
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000620 assert(ResTy == getMRI()->getType(Op0) && ResTy == getMRI()->getType(Op1) &&
Tim Northoverf50f2f32016-12-06 18:38:34 +0000621 "type mismatch");
622 if (ResTy.isScalar() || ResTy.isPointer())
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000623 assert(getMRI()->getType(Tst).isScalar() && "type mismatch");
Tim Northover1f8b1db2016-09-09 11:46:58 +0000624 else
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000625 assert((getMRI()->getType(Tst).isScalar() ||
626 (getMRI()->getType(Tst).isVector() &&
627 getMRI()->getType(Tst).getNumElements() ==
628 getMRI()->getType(Op0).getNumElements())) &&
Tim Northover1f8b1db2016-09-09 11:46:58 +0000629 "type mismatch");
630#endif
631
Tim Northover0f140c72016-09-09 11:46:34 +0000632 return buildInstr(TargetOpcode::G_SELECT)
Tim Northover5a28c362016-08-19 20:09:07 +0000633 .addDef(Res)
634 .addUse(Tst)
635 .addUse(Op0)
636 .addUse(Op1);
637}
Tim Northoverbdf67c92016-08-23 21:01:33 +0000638
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000639MachineInstrBuilder
640MachineIRBuilderBase::buildInsertVectorElement(unsigned Res, unsigned Val,
641 unsigned Elt, unsigned Idx) {
Volkan Keles04cb08c2017-03-10 19:08:28 +0000642#ifndef NDEBUG
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000643 LLT ResTy = getMRI()->getType(Res);
644 LLT ValTy = getMRI()->getType(Val);
645 LLT EltTy = getMRI()->getType(Elt);
646 LLT IdxTy = getMRI()->getType(Idx);
Volkan Keles04cb08c2017-03-10 19:08:28 +0000647 assert(ResTy.isVector() && ValTy.isVector() && "invalid operand type");
Kristof Beyls0f36e682017-04-19 07:23:57 +0000648 assert(IdxTy.isScalar() && "invalid operand type");
Volkan Keles04cb08c2017-03-10 19:08:28 +0000649 assert(ResTy.getNumElements() == ValTy.getNumElements() && "type mismatch");
650 assert(ResTy.getElementType() == EltTy && "type mismatch");
651#endif
652
653 return buildInstr(TargetOpcode::G_INSERT_VECTOR_ELT)
654 .addDef(Res)
655 .addUse(Val)
656 .addUse(Elt)
657 .addUse(Idx);
658}
659
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000660MachineInstrBuilder
661MachineIRBuilderBase::buildExtractVectorElement(unsigned Res, unsigned Val,
662 unsigned Idx) {
Volkan Keles04cb08c2017-03-10 19:08:28 +0000663#ifndef NDEBUG
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000664 LLT ResTy = getMRI()->getType(Res);
665 LLT ValTy = getMRI()->getType(Val);
666 LLT IdxTy = getMRI()->getType(Idx);
Volkan Keles04cb08c2017-03-10 19:08:28 +0000667 assert(ValTy.isVector() && "invalid operand type");
Kristof Beyls0f36e682017-04-19 07:23:57 +0000668 assert((ResTy.isScalar() || ResTy.isPointer()) && "invalid operand type");
669 assert(IdxTy.isScalar() && "invalid operand type");
Volkan Keles04cb08c2017-03-10 19:08:28 +0000670 assert(ValTy.getElementType() == ResTy && "type mismatch");
671#endif
672
673 return buildInstr(TargetOpcode::G_EXTRACT_VECTOR_ELT)
674 .addDef(Res)
675 .addUse(Val)
676 .addUse(Idx);
677}
678
Daniel Sanders94813992018-07-09 19:33:40 +0000679MachineInstrBuilder MachineIRBuilderBase::buildAtomicCmpXchgWithSuccess(
680 unsigned OldValRes, unsigned SuccessRes, unsigned Addr, unsigned CmpVal,
681 unsigned NewVal, MachineMemOperand &MMO) {
682#ifndef NDEBUG
683 LLT OldValResTy = getMRI()->getType(OldValRes);
684 LLT SuccessResTy = getMRI()->getType(SuccessRes);
685 LLT AddrTy = getMRI()->getType(Addr);
686 LLT CmpValTy = getMRI()->getType(CmpVal);
687 LLT NewValTy = getMRI()->getType(NewVal);
688 assert(OldValResTy.isScalar() && "invalid operand type");
689 assert(SuccessResTy.isScalar() && "invalid operand type");
690 assert(AddrTy.isPointer() && "invalid operand type");
691 assert(CmpValTy.isValid() && "invalid operand type");
692 assert(NewValTy.isValid() && "invalid operand type");
693 assert(OldValResTy == CmpValTy && "type mismatch");
694 assert(OldValResTy == NewValTy && "type mismatch");
695#endif
696
697 return buildInstr(TargetOpcode::G_ATOMIC_CMPXCHG_WITH_SUCCESS)
698 .addDef(OldValRes)
699 .addDef(SuccessRes)
700 .addUse(Addr)
701 .addUse(CmpVal)
702 .addUse(NewVal)
703 .addMemOperand(&MMO);
704}
705
Daniel Sandersaef1dfc2017-11-30 20:11:42 +0000706MachineInstrBuilder
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000707MachineIRBuilderBase::buildAtomicCmpXchg(unsigned OldValRes, unsigned Addr,
708 unsigned CmpVal, unsigned NewVal,
709 MachineMemOperand &MMO) {
Daniel Sandersaef1dfc2017-11-30 20:11:42 +0000710#ifndef NDEBUG
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000711 LLT OldValResTy = getMRI()->getType(OldValRes);
712 LLT AddrTy = getMRI()->getType(Addr);
713 LLT CmpValTy = getMRI()->getType(CmpVal);
714 LLT NewValTy = getMRI()->getType(NewVal);
Daniel Sandersaef1dfc2017-11-30 20:11:42 +0000715 assert(OldValResTy.isScalar() && "invalid operand type");
716 assert(AddrTy.isPointer() && "invalid operand type");
717 assert(CmpValTy.isValid() && "invalid operand type");
718 assert(NewValTy.isValid() && "invalid operand type");
719 assert(OldValResTy == CmpValTy && "type mismatch");
720 assert(OldValResTy == NewValTy && "type mismatch");
721#endif
722
723 return buildInstr(TargetOpcode::G_ATOMIC_CMPXCHG)
724 .addDef(OldValRes)
725 .addUse(Addr)
726 .addUse(CmpVal)
727 .addUse(NewVal)
728 .addMemOperand(&MMO);
729}
730
Daniel Sanders94813992018-07-09 19:33:40 +0000731MachineInstrBuilder
732MachineIRBuilderBase::buildAtomicRMW(unsigned Opcode, unsigned OldValRes,
733 unsigned Addr, unsigned Val,
734 MachineMemOperand &MMO) {
735#ifndef NDEBUG
736 LLT OldValResTy = getMRI()->getType(OldValRes);
737 LLT AddrTy = getMRI()->getType(Addr);
738 LLT ValTy = getMRI()->getType(Val);
739 assert(OldValResTy.isScalar() && "invalid operand type");
740 assert(AddrTy.isPointer() && "invalid operand type");
741 assert(ValTy.isValid() && "invalid operand type");
742 assert(OldValResTy == ValTy && "type mismatch");
743#endif
744
745 return buildInstr(Opcode)
746 .addDef(OldValRes)
747 .addUse(Addr)
748 .addUse(Val)
749 .addMemOperand(&MMO);
750}
751
752MachineInstrBuilder
753MachineIRBuilderBase::buildAtomicRMWXchg(unsigned OldValRes, unsigned Addr,
754 unsigned Val, MachineMemOperand &MMO) {
755 return buildAtomicRMW(TargetOpcode::G_ATOMICRMW_XCHG, OldValRes, Addr, Val,
756 MMO);
757}
758MachineInstrBuilder
759MachineIRBuilderBase::buildAtomicRMWAdd(unsigned OldValRes, unsigned Addr,
760 unsigned Val, MachineMemOperand &MMO) {
761 return buildAtomicRMW(TargetOpcode::G_ATOMICRMW_ADD, OldValRes, Addr, Val,
762 MMO);
763}
764MachineInstrBuilder
765MachineIRBuilderBase::buildAtomicRMWSub(unsigned OldValRes, unsigned Addr,
766 unsigned Val, MachineMemOperand &MMO) {
767 return buildAtomicRMW(TargetOpcode::G_ATOMICRMW_SUB, OldValRes, Addr, Val,
768 MMO);
769}
770MachineInstrBuilder
771MachineIRBuilderBase::buildAtomicRMWAnd(unsigned OldValRes, unsigned Addr,
772 unsigned Val, MachineMemOperand &MMO) {
773 return buildAtomicRMW(TargetOpcode::G_ATOMICRMW_AND, OldValRes, Addr, Val,
774 MMO);
775}
776MachineInstrBuilder
777MachineIRBuilderBase::buildAtomicRMWNand(unsigned OldValRes, unsigned Addr,
778 unsigned Val, MachineMemOperand &MMO) {
779 return buildAtomicRMW(TargetOpcode::G_ATOMICRMW_NAND, OldValRes, Addr, Val,
780 MMO);
781}
782MachineInstrBuilder
783MachineIRBuilderBase::buildAtomicRMWOr(unsigned OldValRes, unsigned Addr,
784 unsigned Val, MachineMemOperand &MMO) {
785 return buildAtomicRMW(TargetOpcode::G_ATOMICRMW_OR, OldValRes, Addr, Val,
786 MMO);
787}
788MachineInstrBuilder
789MachineIRBuilderBase::buildAtomicRMWXor(unsigned OldValRes, unsigned Addr,
790 unsigned Val, MachineMemOperand &MMO) {
791 return buildAtomicRMW(TargetOpcode::G_ATOMICRMW_XOR, OldValRes, Addr, Val,
792 MMO);
793}
794MachineInstrBuilder
795MachineIRBuilderBase::buildAtomicRMWMax(unsigned OldValRes, unsigned Addr,
796 unsigned Val, MachineMemOperand &MMO) {
797 return buildAtomicRMW(TargetOpcode::G_ATOMICRMW_MAX, OldValRes, Addr, Val,
798 MMO);
799}
800MachineInstrBuilder
801MachineIRBuilderBase::buildAtomicRMWMin(unsigned OldValRes, unsigned Addr,
802 unsigned Val, MachineMemOperand &MMO) {
803 return buildAtomicRMW(TargetOpcode::G_ATOMICRMW_MIN, OldValRes, Addr, Val,
804 MMO);
805}
806MachineInstrBuilder
807MachineIRBuilderBase::buildAtomicRMWUmax(unsigned OldValRes, unsigned Addr,
808 unsigned Val, MachineMemOperand &MMO) {
809 return buildAtomicRMW(TargetOpcode::G_ATOMICRMW_UMAX, OldValRes, Addr, Val,
810 MMO);
811}
812MachineInstrBuilder
813MachineIRBuilderBase::buildAtomicRMWUmin(unsigned OldValRes, unsigned Addr,
814 unsigned Val, MachineMemOperand &MMO) {
815 return buildAtomicRMW(TargetOpcode::G_ATOMICRMW_UMIN, OldValRes, Addr, Val,
816 MMO);
817}
818
Amara Emerson6aff5a72018-07-31 00:08:50 +0000819MachineInstrBuilder
820MachineIRBuilderBase::buildBlockAddress(unsigned Res, const BlockAddress *BA) {
821#ifndef NDEBUG
822 assert(getMRI()->getType(Res).isPointer() && "invalid res type");
823#endif
824
825 return buildInstr(TargetOpcode::G_BLOCK_ADDR).addDef(Res).addBlockAddress(BA);
826}
827
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000828void MachineIRBuilderBase::validateTruncExt(unsigned Dst, unsigned Src,
829 bool IsExtend) {
Richard Smith418237b2016-08-23 22:14:15 +0000830#ifndef NDEBUG
Aditya Nandakumarb1c467d2018-04-09 17:30:56 +0000831 LLT SrcTy = getMRI()->getType(Src);
832 LLT DstTy = getMRI()->getType(Dst);
Tim Northoverbdf67c92016-08-23 21:01:33 +0000833
834 if (DstTy.isVector()) {
Daniel Sanders94813992018-07-09 19:33:40 +0000835 assert(SrcTy.isVector() && "mismatched cast between vector and non-vector");
Tim Northoverbdf67c92016-08-23 21:01:33 +0000836 assert(SrcTy.getNumElements() == DstTy.getNumElements() &&
837 "different number of elements in a trunc/ext");
838 } else
839 assert(DstTy.isScalar() && SrcTy.isScalar() && "invalid extend/trunc");
840
841 if (IsExtend)
842 assert(DstTy.getSizeInBits() > SrcTy.getSizeInBits() &&
843 "invalid narrowing extend");
844 else
845 assert(DstTy.getSizeInBits() < SrcTy.getSizeInBits() &&
846 "invalid widening trunc");
Richard Smith418237b2016-08-23 22:14:15 +0000847#endif
Tim Northoverbdf67c92016-08-23 21:01:33 +0000848}