12ad1f851SQuentin Colombet //===-- llvm/CodeGen/GlobalISel/MachineIRBuilder.cpp - MIBuilder--*- C++ -*-==//
22ad1f851SQuentin Colombet //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
62ad1f851SQuentin Colombet //
72ad1f851SQuentin Colombet //===----------------------------------------------------------------------===//
82ad1f851SQuentin Colombet /// \file
92ad1f851SQuentin Colombet /// This file implements the MachineIRBuidler class.
102ad1f851SQuentin Colombet //===----------------------------------------------------------------------===//
112ad1f851SQuentin Colombet #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
122ad1f851SQuentin Colombet #include "llvm/CodeGen/MachineFunction.h"
132ad1f851SQuentin Colombet #include "llvm/CodeGen/MachineInstr.h"
142ad1f851SQuentin Colombet #include "llvm/CodeGen/MachineInstrBuilder.h"
150f140c76STim Northover #include "llvm/CodeGen/MachineRegisterInfo.h"
163f833edcSDavid Blaikie #include "llvm/CodeGen/TargetInstrInfo.h"
176d8e1b45SMatt Arsenault #include "llvm/CodeGen/TargetLowering.h"
18b3bde2eaSDavid Blaikie #include "llvm/CodeGen/TargetOpcodes.h"
19b3bde2eaSDavid Blaikie #include "llvm/CodeGen/TargetSubtargetInfo.h"
20ed98c1b3Sserge-sans-paille #include "llvm/IR/DebugInfoMetadata.h"
212ad1f851SQuentin Colombet 
222ad1f851SQuentin Colombet using namespace llvm;
232ad1f851SQuentin Colombet 
setMF(MachineFunction & MF)24cef44a23SAditya Nandakumar void MachineIRBuilder::setMF(MachineFunction &MF) {
25b1c467dbSAditya Nandakumar   State.MF = &MF;
26b1c467dbSAditya Nandakumar   State.MBB = nullptr;
27b1c467dbSAditya Nandakumar   State.MRI = &MF.getRegInfo();
28b1c467dbSAditya Nandakumar   State.TII = MF.getSubtarget().getInstrInfo();
29b1c467dbSAditya Nandakumar   State.DL = DebugLoc();
30b1c467dbSAditya Nandakumar   State.II = MachineBasicBlock::iterator();
31f75d4f32SAditya Nandakumar   State.Observer = nullptr;
322ad1f851SQuentin Colombet }
332ad1f851SQuentin Colombet 
34f9b4934dSQuentin Colombet //------------------------------------------------------------------------------
35f9b4934dSQuentin Colombet // Build instruction variants.
36f9b4934dSQuentin Colombet //------------------------------------------------------------------------------
37cc5f7622STim Northover 
buildInstrNoInsert(unsigned Opcode)38cef44a23SAditya Nandakumar MachineInstrBuilder MachineIRBuilder::buildInstrNoInsert(unsigned Opcode) {
39b1c467dbSAditya Nandakumar   MachineInstrBuilder MIB = BuildMI(getMF(), getDL(), getTII().get(Opcode));
40a5e38fa0STim Northover   return MIB;
41a5e38fa0STim Northover }
42a5e38fa0STim Northover 
insertInstr(MachineInstrBuilder MIB)43cef44a23SAditya Nandakumar MachineInstrBuilder MachineIRBuilder::insertInstr(MachineInstrBuilder MIB) {
44a51575ffSTim Northover   getMBB().insert(getInsertPt(), MIB);
45d5fa9fdeSRoman Tereshin   recordInsertion(MIB);
46a51575ffSTim Northover   return MIB;
4774d7d2f0SQuentin Colombet }
4874d7d2f0SQuentin Colombet 
49aac78ce4SAdrian Prantl MachineInstrBuilder
buildDirectDbgValue(Register Reg,const MDNode * Variable,const MDNode * Expr)505e66db6bSMatt Arsenault MachineIRBuilder::buildDirectDbgValue(Register Reg, const MDNode *Variable,
51aac78ce4SAdrian Prantl                                       const MDNode *Expr) {
5209aac4adSTim Northover   assert(isa<DILocalVariable>(Variable) && "not a variable");
5309aac4adSTim Northover   assert(cast<DIExpression>(Expr)->isValid() && "not an expression");
54b1c467dbSAditya Nandakumar   assert(
55b1c467dbSAditya Nandakumar       cast<DILocalVariable>(Variable)->isValidLocationForIntrinsic(getDL()) &&
5609aac4adSTim Northover       "Expected inlined-at fields to agree");
57b1c467dbSAditya Nandakumar   return insertInstr(BuildMI(getMF(), getDL(),
58b1c467dbSAditya Nandakumar                              getTII().get(TargetOpcode::DBG_VALUE),
59aac78ce4SAdrian Prantl                              /*IsIndirect*/ false, Reg, Variable, Expr));
6009aac4adSTim Northover }
6109aac4adSTim Northover 
62cef44a23SAditya Nandakumar MachineInstrBuilder
buildIndirectDbgValue(Register Reg,const MDNode * Variable,const MDNode * Expr)635e66db6bSMatt Arsenault MachineIRBuilder::buildIndirectDbgValue(Register Reg, const MDNode *Variable,
64cef44a23SAditya Nandakumar                                         const MDNode *Expr) {
6509aac4adSTim Northover   assert(isa<DILocalVariable>(Variable) && "not a variable");
6609aac4adSTim Northover   assert(cast<DIExpression>(Expr)->isValid() && "not an expression");
67b1c467dbSAditya Nandakumar   assert(
68b1c467dbSAditya Nandakumar       cast<DILocalVariable>(Variable)->isValidLocationForIntrinsic(getDL()) &&
6909aac4adSTim Northover       "Expected inlined-at fields to agree");
70b1c467dbSAditya Nandakumar   return insertInstr(BuildMI(getMF(), getDL(),
71b1c467dbSAditya Nandakumar                              getTII().get(TargetOpcode::DBG_VALUE),
726531a78aSJeremy Morse                              /*IsIndirect*/ true, Reg, Variable, Expr));
7309aac4adSTim Northover }
7409aac4adSTim Northover 
buildFIDbgValue(int FI,const MDNode * Variable,const MDNode * Expr)75cef44a23SAditya Nandakumar MachineInstrBuilder MachineIRBuilder::buildFIDbgValue(int FI,
76cef44a23SAditya Nandakumar                                                       const MDNode *Variable,
7709aac4adSTim Northover                                                       const MDNode *Expr) {
7809aac4adSTim Northover   assert(isa<DILocalVariable>(Variable) && "not a variable");
7909aac4adSTim Northover   assert(cast<DIExpression>(Expr)->isValid() && "not an expression");
80b1c467dbSAditya Nandakumar   assert(
81b1c467dbSAditya Nandakumar       cast<DILocalVariable>(Variable)->isValidLocationForIntrinsic(getDL()) &&
8209aac4adSTim Northover       "Expected inlined-at fields to agree");
8309aac4adSTim Northover   return buildInstr(TargetOpcode::DBG_VALUE)
8409aac4adSTim Northover       .addFrameIndex(FI)
856531a78aSJeremy Morse       .addImm(0)
8609aac4adSTim Northover       .addMetadata(Variable)
876531a78aSJeremy Morse       .addMetadata(Expr);
8809aac4adSTim Northover }
8909aac4adSTim Northover 
buildConstDbgValue(const Constant & C,const MDNode * Variable,const MDNode * Expr)90cef44a23SAditya Nandakumar MachineInstrBuilder MachineIRBuilder::buildConstDbgValue(const Constant &C,
91cef44a23SAditya Nandakumar                                                          const MDNode *Variable,
92cef44a23SAditya Nandakumar                                                          const MDNode *Expr) {
9309aac4adSTim Northover   assert(isa<DILocalVariable>(Variable) && "not a variable");
9409aac4adSTim Northover   assert(cast<DIExpression>(Expr)->isValid() && "not an expression");
95b1c467dbSAditya Nandakumar   assert(
96b1c467dbSAditya Nandakumar       cast<DILocalVariable>(Variable)->isValidLocationForIntrinsic(getDL()) &&
9709aac4adSTim Northover       "Expected inlined-at fields to agree");
98f24e2e9eSDominik Montada   auto MIB = buildInstrNoInsert(TargetOpcode::DBG_VALUE);
9909aac4adSTim Northover   if (auto *CI = dyn_cast<ConstantInt>(&C)) {
10009aac4adSTim Northover     if (CI->getBitWidth() > 64)
10109aac4adSTim Northover       MIB.addCImm(CI);
10209aac4adSTim Northover     else
10309aac4adSTim Northover       MIB.addImm(CI->getZExtValue());
1044826bae8SAhmed Bougacha   } else if (auto *CFP = dyn_cast<ConstantFP>(&C)) {
105adce3ee2SAhmed Bougacha     MIB.addFPImm(CFP);
1064826bae8SAhmed Bougacha   } else {
107bf6bc62dSMatt Arsenault     // Insert $noreg if we didn't find a usable constant and had to drop it.
108bf6bc62dSMatt Arsenault     MIB.addReg(Register());
1094826bae8SAhmed Bougacha   }
11009aac4adSTim Northover 
111f24e2e9eSDominik Montada   MIB.addImm(0).addMetadata(Variable).addMetadata(Expr);
112f24e2e9eSDominik Montada   return insertInstr(MIB);
11309aac4adSTim Northover }
11409aac4adSTim Northover 
buildDbgLabel(const MDNode * Label)115cef44a23SAditya Nandakumar MachineInstrBuilder MachineIRBuilder::buildDbgLabel(const MDNode *Label) {
1162532ac88SHsiangkai Wang   assert(isa<DILabel>(Label) && "not a label");
1172532ac88SHsiangkai Wang   assert(cast<DILabel>(Label)->isValidLocationForIntrinsic(State.DL) &&
1182532ac88SHsiangkai Wang          "Expected inlined-at fields to agree");
1192532ac88SHsiangkai Wang   auto MIB = buildInstr(TargetOpcode::DBG_LABEL);
1202532ac88SHsiangkai Wang 
1212532ac88SHsiangkai Wang   return MIB.addMetadata(Label);
1222532ac88SHsiangkai Wang }
1232532ac88SHsiangkai Wang 
buildDynStackAlloc(const DstOp & Res,const SrcOp & Size,Align Alignment)124e20b91c2SAmara Emerson MachineInstrBuilder MachineIRBuilder::buildDynStackAlloc(const DstOp &Res,
125e20b91c2SAmara Emerson                                                          const SrcOp &Size,
126ca11c480SGuillaume Chatelet                                                          Align Alignment) {
127e20b91c2SAmara Emerson   assert(Res.getLLTTy(*getMRI()).isPointer() && "expected ptr dst type");
128e20b91c2SAmara Emerson   auto MIB = buildInstr(TargetOpcode::G_DYN_STACKALLOC);
129e20b91c2SAmara Emerson   Res.addDefToMIB(*getMRI(), MIB);
130e20b91c2SAmara Emerson   Size.addSrcToMIB(MIB);
131ca11c480SGuillaume Chatelet   MIB.addImm(Alignment.value());
132e20b91c2SAmara Emerson   return MIB;
133e20b91c2SAmara Emerson }
134e20b91c2SAmara Emerson 
buildFrameIndex(const DstOp & Res,int Idx)135079f77b5SMatt Arsenault MachineInstrBuilder MachineIRBuilder::buildFrameIndex(const DstOp &Res,
136079f77b5SMatt Arsenault                                                       int Idx) {
137079f77b5SMatt Arsenault   assert(Res.getLLTTy(*getMRI()).isPointer() && "invalid operand type");
138079f77b5SMatt Arsenault   auto MIB = buildInstr(TargetOpcode::G_FRAME_INDEX);
139079f77b5SMatt Arsenault   Res.addDefToMIB(*getMRI(), MIB);
140079f77b5SMatt Arsenault   MIB.addFrameIndex(Idx);
141079f77b5SMatt Arsenault   return MIB;
142bd505460STim Northover }
14333b07d67STim Northover 
buildGlobalValue(const DstOp & Res,const GlobalValue * GV)144079f77b5SMatt Arsenault MachineInstrBuilder MachineIRBuilder::buildGlobalValue(const DstOp &Res,
145cef44a23SAditya Nandakumar                                                        const GlobalValue *GV) {
146079f77b5SMatt Arsenault   assert(Res.getLLTTy(*getMRI()).isPointer() && "invalid operand type");
147079f77b5SMatt Arsenault   assert(Res.getLLTTy(*getMRI()).getAddressSpace() ==
148032548fcSTim Northover              GV->getType()->getAddressSpace() &&
149032548fcSTim Northover          "address space mismatch");
150032548fcSTim Northover 
151079f77b5SMatt Arsenault   auto MIB = buildInstr(TargetOpcode::G_GLOBAL_VALUE);
152079f77b5SMatt Arsenault   Res.addDefToMIB(*getMRI(), MIB);
153079f77b5SMatt Arsenault   MIB.addGlobalAddress(GV);
154079f77b5SMatt Arsenault   return MIB;
155032548fcSTim Northover }
156032548fcSTim Northover 
buildJumpTable(const LLT PtrTy,unsigned JTI)157d133c159SAmara Emerson MachineInstrBuilder MachineIRBuilder::buildJumpTable(const LLT PtrTy,
158d133c159SAmara Emerson                                                      unsigned JTI) {
159d133c159SAmara Emerson   return buildInstr(TargetOpcode::G_JUMP_TABLE, {PtrTy}, {})
160d133c159SAmara Emerson       .addJumpTableIndex(JTI);
161d133c159SAmara Emerson }
162d133c159SAmara Emerson 
validateUnaryOp(const LLT Res,const LLT Op0)163fa2b836eSJay Foad void MachineIRBuilder::validateUnaryOp(const LLT Res, const LLT Op0) {
164fa2b836eSJay Foad   assert((Res.isScalar() || Res.isVector()) && "invalid operand type");
165fa2b836eSJay Foad   assert((Res == Op0) && "type mismatch");
166fa2b836eSJay Foad }
167fa2b836eSJay Foad 
validateBinaryOp(const LLT Res,const LLT Op0,const LLT Op1)168de256478SMatt Arsenault void MachineIRBuilder::validateBinaryOp(const LLT Res, const LLT Op0,
169de256478SMatt Arsenault                                         const LLT Op1) {
170502865bdSCraig Topper   assert((Res.isScalar() || Res.isVector()) && "invalid operand type");
171cef44a23SAditya Nandakumar   assert((Res == Op0 && Res == Op1) && "type mismatch");
17233b07d67STim Northover }
17333b07d67STim Northover 
validateShiftOp(const LLT Res,const LLT Op0,const LLT Op1)174de256478SMatt Arsenault void MachineIRBuilder::validateShiftOp(const LLT Res, const LLT Op0,
175de256478SMatt Arsenault                                        const LLT Op1) {
176fbec8fe9SMatt Arsenault   assert((Res.isScalar() || Res.isVector()) && "invalid operand type");
177fbec8fe9SMatt Arsenault   assert((Res == Op0) && "type mismatch");
178fbec8fe9SMatt Arsenault }
179fbec8fe9SMatt Arsenault 
buildPtrAdd(const DstOp & Res,const SrcOp & Op0,const SrcOp & Op1)180e74c5b96SDaniel Sanders MachineInstrBuilder MachineIRBuilder::buildPtrAdd(const DstOp &Res,
181079f77b5SMatt Arsenault                                                   const SrcOp &Op0,
182079f77b5SMatt Arsenault                                                   const SrcOp &Op1) {
18306d9230fSMatt Arsenault   assert(Res.getLLTTy(*getMRI()).getScalarType().isPointer() &&
184079f77b5SMatt Arsenault          Res.getLLTTy(*getMRI()) == Op0.getLLTTy(*getMRI()) && "type mismatch");
18506d9230fSMatt Arsenault   assert(Op1.getLLTTy(*getMRI()).getScalarType().isScalar() && "invalid offset type");
186a7653b39STim Northover 
187e74c5b96SDaniel Sanders   return buildInstr(TargetOpcode::G_PTR_ADD, {Res}, {Op0, Op1});
188a7653b39STim Northover }
189a7653b39STim Northover 
1904e52366cSDaniel Sanders Optional<MachineInstrBuilder>
materializePtrAdd(Register & Res,Register Op0,const LLT ValueTy,uint64_t Value)191e74c5b96SDaniel Sanders MachineIRBuilder::materializePtrAdd(Register &Res, Register Op0,
192de256478SMatt Arsenault                                     const LLT ValueTy, uint64_t Value) {
1934e52366cSDaniel Sanders   assert(Res == 0 && "Res is a result argument");
1944e52366cSDaniel Sanders   assert(ValueTy.isScalar()  && "invalid offset type");
1954e52366cSDaniel Sanders 
1964e52366cSDaniel Sanders   if (Value == 0) {
1974e52366cSDaniel Sanders     Res = Op0;
1984e52366cSDaniel Sanders     return None;
1994e52366cSDaniel Sanders   }
2004e52366cSDaniel Sanders 
201b1c467dbSAditya Nandakumar   Res = getMRI()->createGenericVirtualRegister(getMRI()->getType(Op0));
202946b1246SAmara Emerson   auto Cst = buildConstant(ValueTy, Value);
203e74c5b96SDaniel Sanders   return buildPtrAdd(Res, Op0, Cst.getReg(0));
2044e52366cSDaniel Sanders }
2054e52366cSDaniel Sanders 
buildMaskLowPtrBits(const DstOp & Res,const SrcOp & Op0,uint32_t NumBits)2068bc03d21SMatt Arsenault MachineInstrBuilder MachineIRBuilder::buildMaskLowPtrBits(const DstOp &Res,
207079f77b5SMatt Arsenault                                                           const SrcOp &Op0,
208c2f89563STim Northover                                                           uint32_t NumBits) {
2098bc03d21SMatt Arsenault   LLT PtrTy = Res.getLLTTy(*getMRI());
2108bc03d21SMatt Arsenault   LLT MaskTy = LLT::scalar(PtrTy.getSizeInBits());
2118bc03d21SMatt Arsenault   Register MaskReg = getMRI()->createGenericVirtualRegister(MaskTy);
21295f65a7cSMatt Arsenault   buildConstant(MaskReg, maskTrailingZeros<uint64_t>(NumBits));
2138bc03d21SMatt Arsenault   return buildPtrMask(Res, Op0, MaskReg);
214c2f89563STim Northover }
215c2f89563STim Northover 
21629f88b93SPetar Avramovic MachineInstrBuilder
buildPadVectorWithUndefElements(const DstOp & Res,const SrcOp & Op0)21729f88b93SPetar Avramovic MachineIRBuilder::buildPadVectorWithUndefElements(const DstOp &Res,
21829f88b93SPetar Avramovic                                                   const SrcOp &Op0) {
21929f88b93SPetar Avramovic   LLT ResTy = Res.getLLTTy(*getMRI());
22029f88b93SPetar Avramovic   LLT Op0Ty = Op0.getLLTTy(*getMRI());
22129f88b93SPetar Avramovic 
22229f88b93SPetar Avramovic   assert((ResTy.isVector() && Op0Ty.isVector()) && "Non vector type");
22329f88b93SPetar Avramovic   assert((ResTy.getElementType() == Op0Ty.getElementType()) &&
22429f88b93SPetar Avramovic          "Different vector element types");
22529f88b93SPetar Avramovic   assert((ResTy.getNumElements() > Op0Ty.getNumElements()) &&
22629f88b93SPetar Avramovic          "Op0 has more elements");
22729f88b93SPetar Avramovic 
22829f88b93SPetar Avramovic   auto Unmerge = buildUnmerge(Op0Ty.getElementType(), Op0);
22929f88b93SPetar Avramovic   SmallVector<Register, 8> Regs;
23029f88b93SPetar Avramovic   for (auto Op : Unmerge.getInstr()->defs())
23129f88b93SPetar Avramovic     Regs.push_back(Op.getReg());
23229f88b93SPetar Avramovic   Register Undef = buildUndef(Op0Ty.getElementType()).getReg(0);
23329f88b93SPetar Avramovic   unsigned NumberOfPadElts = ResTy.getNumElements() - Regs.size();
23429f88b93SPetar Avramovic   for (unsigned i = 0; i < NumberOfPadElts; ++i)
23529f88b93SPetar Avramovic     Regs.push_back(Undef);
23629f88b93SPetar Avramovic   return buildMerge(Res, Regs);
23729f88b93SPetar Avramovic }
23829f88b93SPetar Avramovic 
23929f88b93SPetar Avramovic MachineInstrBuilder
buildDeleteTrailingVectorElements(const DstOp & Res,const SrcOp & Op0)24029f88b93SPetar Avramovic MachineIRBuilder::buildDeleteTrailingVectorElements(const DstOp &Res,
24129f88b93SPetar Avramovic                                                     const SrcOp &Op0) {
24229f88b93SPetar Avramovic   LLT ResTy = Res.getLLTTy(*getMRI());
24329f88b93SPetar Avramovic   LLT Op0Ty = Op0.getLLTTy(*getMRI());
24429f88b93SPetar Avramovic 
24529f88b93SPetar Avramovic   assert((ResTy.isVector() && Op0Ty.isVector()) && "Non vector type");
24629f88b93SPetar Avramovic   assert((ResTy.getElementType() == Op0Ty.getElementType()) &&
24729f88b93SPetar Avramovic          "Different vector element types");
24829f88b93SPetar Avramovic   assert((ResTy.getNumElements() < Op0Ty.getNumElements()) &&
24929f88b93SPetar Avramovic          "Op0 has fewer elements");
25029f88b93SPetar Avramovic 
25129f88b93SPetar Avramovic   SmallVector<Register, 8> Regs;
25229f88b93SPetar Avramovic   auto Unmerge = buildUnmerge(Op0Ty.getElementType(), Op0);
25329f88b93SPetar Avramovic   for (unsigned i = 0; i < ResTy.getNumElements(); ++i)
25429f88b93SPetar Avramovic     Regs.push_back(Unmerge.getReg(i));
25529f88b93SPetar Avramovic   return buildMerge(Res, Regs);
25629f88b93SPetar Avramovic }
25729f88b93SPetar Avramovic 
buildBr(MachineBasicBlock & Dest)258cef44a23SAditya Nandakumar MachineInstrBuilder MachineIRBuilder::buildBr(MachineBasicBlock &Dest) {
2590f140c76STim Northover   return buildInstr(TargetOpcode::G_BR).addMBB(&Dest);
260cc5f7622STim Northover }
261cc5f7622STim Northover 
buildBrIndirect(Register Tgt)2625e66db6bSMatt Arsenault MachineInstrBuilder MachineIRBuilder::buildBrIndirect(Register Tgt) {
263b1c467dbSAditya Nandakumar   assert(getMRI()->getType(Tgt).isPointer() && "invalid branch destination");
26465a12c01SKristof Beyls   return buildInstr(TargetOpcode::G_BRINDIRECT).addUse(Tgt);
26565a12c01SKristof Beyls }
26665a12c01SKristof Beyls 
buildBrJT(Register TablePtr,unsigned JTI,Register IndexReg)2675e66db6bSMatt Arsenault MachineInstrBuilder MachineIRBuilder::buildBrJT(Register TablePtr,
268f79d3bc7SAmara Emerson                                                 unsigned JTI,
2695e66db6bSMatt Arsenault                                                 Register IndexReg) {
270f79d3bc7SAmara Emerson   assert(getMRI()->getType(TablePtr).isPointer() &&
271f79d3bc7SAmara Emerson          "Table reg must be a pointer");
272f79d3bc7SAmara Emerson   return buildInstr(TargetOpcode::G_BRJT)
273f79d3bc7SAmara Emerson       .addUse(TablePtr)
274f79d3bc7SAmara Emerson       .addJumpTableIndex(JTI)
275f79d3bc7SAmara Emerson       .addUse(IndexReg);
276f79d3bc7SAmara Emerson }
277f79d3bc7SAmara Emerson 
buildCopy(const DstOp & Res,const SrcOp & Op)278cef44a23SAditya Nandakumar MachineInstrBuilder MachineIRBuilder::buildCopy(const DstOp &Res,
2798627178dSAmara Emerson                                                 const SrcOp &Op) {
2808627178dSAmara Emerson   return buildInstr(TargetOpcode::COPY, Res, Op);
281756eca35STim Northover }
282756eca35STim Northover 
buildConstant(const DstOp & Res,const ConstantInt & Val)283cef44a23SAditya Nandakumar MachineInstrBuilder MachineIRBuilder::buildConstant(const DstOp &Res,
284cef44a23SAditya Nandakumar                                                     const ConstantInt &Val) {
285cef44a23SAditya Nandakumar   LLT Ty = Res.getLLTTy(*getMRI());
28652133812SMatt Arsenault   LLT EltTy = Ty.getScalarType();
2878121ec26SMatt Arsenault   assert(EltTy.getScalarSizeInBits() == Val.getBitWidth() &&
2888121ec26SMatt Arsenault          "creating constant with the wrong size");
28952133812SMatt Arsenault 
29052133812SMatt Arsenault   if (Ty.isVector()) {
2918121ec26SMatt Arsenault     auto Const = buildInstr(TargetOpcode::G_CONSTANT)
2928121ec26SMatt Arsenault     .addDef(getMRI()->createGenericVirtualRegister(EltTy))
2938121ec26SMatt Arsenault     .addCImm(&Val);
2948121ec26SMatt Arsenault     return buildSplatVector(Res, Const);
29552133812SMatt Arsenault   }
2969267ac5dSTim Northover 
2978121ec26SMatt Arsenault   auto Const = buildInstr(TargetOpcode::G_CONSTANT);
298c8433a5bSDavide Italiano   Const->setDebugLoc(DebugLoc());
2998121ec26SMatt Arsenault   Res.addDefToMIB(*getMRI(), Const);
3008121ec26SMatt Arsenault   Const.addCImm(&Val);
3018121ec26SMatt Arsenault   return Const;
3029267ac5dSTim Northover }
3039267ac5dSTim Northover 
buildConstant(const DstOp & Res,int64_t Val)304cef44a23SAditya Nandakumar MachineInstrBuilder MachineIRBuilder::buildConstant(const DstOp &Res,
3059267ac5dSTim Northover                                                     int64_t Val) {
306b1c467dbSAditya Nandakumar   auto IntN = IntegerType::get(getMF().getFunction().getContext(),
3078121ec26SMatt Arsenault                                Res.getLLTTy(*getMRI()).getScalarSizeInBits());
3089267ac5dSTim Northover   ConstantInt *CI = ConstantInt::get(IntN, Val, true);
3099267ac5dSTim Northover   return buildConstant(Res, *CI);
3109656f147STim Northover }
3119656f147STim Northover 
buildFConstant(const DstOp & Res,const ConstantFP & Val)312cef44a23SAditya Nandakumar MachineInstrBuilder MachineIRBuilder::buildFConstant(const DstOp &Res,
313cef44a23SAditya Nandakumar                                                      const ConstantFP &Val) {
31452133812SMatt Arsenault   LLT Ty = Res.getLLTTy(*getMRI());
3158121ec26SMatt Arsenault   LLT EltTy = Ty.getScalarType();
3168121ec26SMatt Arsenault 
3178121ec26SMatt Arsenault   assert(APFloat::getSizeInBits(Val.getValueAPF().getSemantics())
3188121ec26SMatt Arsenault          == EltTy.getSizeInBits() &&
3198121ec26SMatt Arsenault          "creating fconstant with the wrong size");
32052133812SMatt Arsenault 
32152133812SMatt Arsenault   assert(!Ty.isPointer() && "invalid operand type");
32252133812SMatt Arsenault 
32352133812SMatt Arsenault   if (Ty.isVector()) {
3248121ec26SMatt Arsenault     auto Const = buildInstr(TargetOpcode::G_FCONSTANT)
3258121ec26SMatt Arsenault     .addDef(getMRI()->createGenericVirtualRegister(EltTy))
32652133812SMatt Arsenault     .addFPImm(&Val);
32752133812SMatt Arsenault 
3288121ec26SMatt Arsenault     return buildSplatVector(Res, Const);
32952133812SMatt Arsenault   }
3301f8b1db9STim Northover 
3318121ec26SMatt Arsenault   auto Const = buildInstr(TargetOpcode::G_FCONSTANT);
332288c9e81SDavide Italiano   Const->setDebugLoc(DebugLoc());
3338121ec26SMatt Arsenault   Res.addDefToMIB(*getMRI(), Const);
3348121ec26SMatt Arsenault   Const.addFPImm(&Val);
3358121ec26SMatt Arsenault   return Const;
3368121ec26SMatt Arsenault }
3378121ec26SMatt Arsenault 
buildConstant(const DstOp & Res,const APInt & Val)3388121ec26SMatt Arsenault MachineInstrBuilder MachineIRBuilder::buildConstant(const DstOp &Res,
3398121ec26SMatt Arsenault                                                     const APInt &Val) {
3408121ec26SMatt Arsenault   ConstantInt *CI = ConstantInt::get(getMF().getFunction().getContext(), Val);
3418121ec26SMatt Arsenault   return buildConstant(Res, *CI);
342b16734fbSTim Northover }
343b16734fbSTim Northover 
buildFConstant(const DstOp & Res,double Val)344cef44a23SAditya Nandakumar MachineInstrBuilder MachineIRBuilder::buildFConstant(const DstOp &Res,
345b1c467dbSAditya Nandakumar                                                      double Val) {
346cef44a23SAditya Nandakumar   LLT DstTy = Res.getLLTTy(*getMRI());
347b1c467dbSAditya Nandakumar   auto &Ctx = getMF().getFunction().getContext();
34891fc4e09SAditya Nandakumar   auto *CFP =
3498121ec26SMatt Arsenault       ConstantFP::get(Ctx, getAPFloatFromSize(Val, DstTy.getScalarSizeInBits()));
35091fc4e09SAditya Nandakumar   return buildFConstant(Res, *CFP);
35191fc4e09SAditya Nandakumar }
35291fc4e09SAditya Nandakumar 
buildFConstant(const DstOp & Res,const APFloat & Val)35311be78bcSMatt Arsenault MachineInstrBuilder MachineIRBuilder::buildFConstant(const DstOp &Res,
35411be78bcSMatt Arsenault                                                      const APFloat &Val) {
35511be78bcSMatt Arsenault   auto &Ctx = getMF().getFunction().getContext();
35611be78bcSMatt Arsenault   auto *CFP = ConstantFP::get(Ctx, Val);
35711be78bcSMatt Arsenault   return buildFConstant(Res, *CFP);
35811be78bcSMatt Arsenault }
35911be78bcSMatt Arsenault 
buildBrCond(const SrcOp & Tst,MachineBasicBlock & Dest)3602ff14957SAmara Emerson MachineInstrBuilder MachineIRBuilder::buildBrCond(const SrcOp &Tst,
36169c2ba54STim Northover                                                   MachineBasicBlock &Dest) {
3622ff14957SAmara Emerson   assert(Tst.getLLTTy(*getMRI()).isScalar() && "invalid operand type");
3631f8b1db9STim Northover 
3642ff14957SAmara Emerson   auto MIB = buildInstr(TargetOpcode::G_BRCOND);
3652ff14957SAmara Emerson   Tst.addSrcToMIB(MIB);
3662ff14957SAmara Emerson   MIB.addMBB(&Dest);
3672ff14957SAmara Emerson   return MIB;
36869c2ba54STim Northover }
36969c2ba54STim Northover 
3700b7de796SMatt Arsenault MachineInstrBuilder
buildLoad(const DstOp & Dst,const SrcOp & Addr,MachinePointerInfo PtrInfo,Align Alignment,MachineMemOperand::Flags MMOFlags,const AAMDNodes & AAInfo)3710b7de796SMatt Arsenault MachineIRBuilder::buildLoad(const DstOp &Dst, const SrcOp &Addr,
3720b7de796SMatt Arsenault                             MachinePointerInfo PtrInfo, Align Alignment,
3730b7de796SMatt Arsenault                             MachineMemOperand::Flags MMOFlags,
3740b7de796SMatt Arsenault                             const AAMDNodes &AAInfo) {
3750b7de796SMatt Arsenault   MMOFlags |= MachineMemOperand::MOLoad;
3760b7de796SMatt Arsenault   assert((MMOFlags & MachineMemOperand::MOStore) == 0);
3770b7de796SMatt Arsenault 
378990278d0SMatt Arsenault   LLT Ty = Dst.getLLTTy(*getMRI());
3790b7de796SMatt Arsenault   MachineMemOperand *MMO =
380990278d0SMatt Arsenault       getMF().getMachineMemOperand(PtrInfo, MMOFlags, Ty, Alignment, AAInfo);
3810b7de796SMatt Arsenault   return buildLoad(Dst, Addr, *MMO);
3825eb9f581SDaniel Sanders }
3835eb9f581SDaniel Sanders 
buildLoadInstr(unsigned Opcode,const DstOp & Res,const SrcOp & Addr,MachineMemOperand & MMO)384cef44a23SAditya Nandakumar MachineInstrBuilder MachineIRBuilder::buildLoadInstr(unsigned Opcode,
385079f77b5SMatt Arsenault                                                      const DstOp &Res,
386079f77b5SMatt Arsenault                                                      const SrcOp &Addr,
387cef44a23SAditya Nandakumar                                                      MachineMemOperand &MMO) {
388079f77b5SMatt Arsenault   assert(Res.getLLTTy(*getMRI()).isValid() && "invalid operand type");
389079f77b5SMatt Arsenault   assert(Addr.getLLTTy(*getMRI()).isPointer() && "invalid operand type");
3901f8b1db9STim Northover 
391079f77b5SMatt Arsenault   auto MIB = buildInstr(Opcode);
392079f77b5SMatt Arsenault   Res.addDefToMIB(*getMRI(), MIB);
393079f77b5SMatt Arsenault   Addr.addSrcToMIB(MIB);
394079f77b5SMatt Arsenault   MIB.addMemOperand(&MMO);
395079f77b5SMatt Arsenault   return MIB;
396ad2b717fSTim Northover }
397ad2b717fSTim Northover 
buildLoadFromOffset(const DstOp & Dst,const SrcOp & BasePtr,MachineMemOperand & BaseMMO,int64_t Offset)398eaa8af93SMatt Arsenault MachineInstrBuilder MachineIRBuilder::buildLoadFromOffset(
399eaa8af93SMatt Arsenault   const DstOp &Dst, const SrcOp &BasePtr,
400eaa8af93SMatt Arsenault   MachineMemOperand &BaseMMO, int64_t Offset) {
401eaa8af93SMatt Arsenault   LLT LoadTy = Dst.getLLTTy(*getMRI());
402eaa8af93SMatt Arsenault   MachineMemOperand *OffsetMMO =
403990278d0SMatt Arsenault       getMF().getMachineMemOperand(&BaseMMO, Offset, LoadTy);
404eaa8af93SMatt Arsenault 
405eaa8af93SMatt Arsenault   if (Offset == 0) // This may be a size or type changing load.
406eaa8af93SMatt Arsenault     return buildLoad(Dst, BasePtr, *OffsetMMO);
407eaa8af93SMatt Arsenault 
408eaa8af93SMatt Arsenault   LLT PtrTy = BasePtr.getLLTTy(*getMRI());
409eaa8af93SMatt Arsenault   LLT OffsetTy = LLT::scalar(PtrTy.getSizeInBits());
410eaa8af93SMatt Arsenault   auto ConstOffset = buildConstant(OffsetTy, Offset);
411eaa8af93SMatt Arsenault   auto Ptr = buildPtrAdd(PtrTy, BasePtr, ConstOffset);
412eaa8af93SMatt Arsenault   return buildLoad(Dst, Ptr, *OffsetMMO);
413eaa8af93SMatt Arsenault }
414eaa8af93SMatt Arsenault 
buildStore(const SrcOp & Val,const SrcOp & Addr,MachineMemOperand & MMO)415079f77b5SMatt Arsenault MachineInstrBuilder MachineIRBuilder::buildStore(const SrcOp &Val,
416079f77b5SMatt Arsenault                                                  const SrcOp &Addr,
417ad2b717fSTim Northover                                                  MachineMemOperand &MMO) {
418079f77b5SMatt Arsenault   assert(Val.getLLTTy(*getMRI()).isValid() && "invalid operand type");
419079f77b5SMatt Arsenault   assert(Addr.getLLTTy(*getMRI()).isPointer() && "invalid operand type");
4201f8b1db9STim Northover 
421079f77b5SMatt Arsenault   auto MIB = buildInstr(TargetOpcode::G_STORE);
422079f77b5SMatt Arsenault   Val.addSrcToMIB(MIB);
423079f77b5SMatt Arsenault   Addr.addSrcToMIB(MIB);
424079f77b5SMatt Arsenault   MIB.addMemOperand(&MMO);
425079f77b5SMatt Arsenault   return MIB;
426ad2b717fSTim Northover }
427ad2b717fSTim Northover 
4280b7de796SMatt Arsenault MachineInstrBuilder
buildStore(const SrcOp & Val,const SrcOp & Addr,MachinePointerInfo PtrInfo,Align Alignment,MachineMemOperand::Flags MMOFlags,const AAMDNodes & AAInfo)4290b7de796SMatt Arsenault MachineIRBuilder::buildStore(const SrcOp &Val, const SrcOp &Addr,
4300b7de796SMatt Arsenault                              MachinePointerInfo PtrInfo, Align Alignment,
4310b7de796SMatt Arsenault                              MachineMemOperand::Flags MMOFlags,
4320b7de796SMatt Arsenault                              const AAMDNodes &AAInfo) {
4330b7de796SMatt Arsenault   MMOFlags |= MachineMemOperand::MOStore;
4340b7de796SMatt Arsenault   assert((MMOFlags & MachineMemOperand::MOLoad) == 0);
4350b7de796SMatt Arsenault 
436990278d0SMatt Arsenault   LLT Ty = Val.getLLTTy(*getMRI());
4370b7de796SMatt Arsenault   MachineMemOperand *MMO =
438990278d0SMatt Arsenault       getMF().getMachineMemOperand(PtrInfo, MMOFlags, Ty, Alignment, AAInfo);
4390b7de796SMatt Arsenault   return buildStore(Val, Addr, *MMO);
4400b7de796SMatt Arsenault }
4410b7de796SMatt Arsenault 
buildAnyExt(const DstOp & Res,const SrcOp & Op)442cef44a23SAditya Nandakumar MachineInstrBuilder MachineIRBuilder::buildAnyExt(const DstOp &Res,
443cef44a23SAditya Nandakumar                                                   const SrcOp &Op) {
444cef44a23SAditya Nandakumar   return buildInstr(TargetOpcode::G_ANYEXT, Res, Op);
44532335818STim Northover }
44632335818STim Northover 
buildSExt(const DstOp & Res,const SrcOp & Op)447cef44a23SAditya Nandakumar MachineInstrBuilder MachineIRBuilder::buildSExt(const DstOp &Res,
448cef44a23SAditya Nandakumar                                                 const SrcOp &Op) {
449cef44a23SAditya Nandakumar   return buildInstr(TargetOpcode::G_SEXT, Res, Op);
4506cd4b23aSTim Northover }
4516cd4b23aSTim Northover 
buildZExt(const DstOp & Res,const SrcOp & Op)452cef44a23SAditya Nandakumar MachineInstrBuilder MachineIRBuilder::buildZExt(const DstOp &Res,
453cef44a23SAditya Nandakumar                                                 const SrcOp &Op) {
454cef44a23SAditya Nandakumar   return buildInstr(TargetOpcode::G_ZEXT, Res, Op);
4556cd4b23aSTim Northover }
4566cd4b23aSTim Northover 
getBoolExtOp(bool IsVec,bool IsFP) const4576d8e1b45SMatt Arsenault unsigned MachineIRBuilder::getBoolExtOp(bool IsVec, bool IsFP) const {
4586d8e1b45SMatt Arsenault   const auto *TLI = getMF().getSubtarget().getTargetLowering();
4596d8e1b45SMatt Arsenault   switch (TLI->getBooleanContents(IsVec, IsFP)) {
4606d8e1b45SMatt Arsenault   case TargetLoweringBase::ZeroOrNegativeOneBooleanContent:
4616d8e1b45SMatt Arsenault     return TargetOpcode::G_SEXT;
4626d8e1b45SMatt Arsenault   case TargetLoweringBase::ZeroOrOneBooleanContent:
4636d8e1b45SMatt Arsenault     return TargetOpcode::G_ZEXT;
4646d8e1b45SMatt Arsenault   default:
4656d8e1b45SMatt Arsenault     return TargetOpcode::G_ANYEXT;
4666d8e1b45SMatt Arsenault   }
4676d8e1b45SMatt Arsenault }
4686d8e1b45SMatt Arsenault 
buildBoolExt(const DstOp & Res,const SrcOp & Op,bool IsFP)4696d8e1b45SMatt Arsenault MachineInstrBuilder MachineIRBuilder::buildBoolExt(const DstOp &Res,
4706d8e1b45SMatt Arsenault                                                    const SrcOp &Op,
4716d8e1b45SMatt Arsenault                                                    bool IsFP) {
4726d8e1b45SMatt Arsenault   unsigned ExtOp = getBoolExtOp(getMRI()->getType(Op.getReg()).isVector(), IsFP);
4736d8e1b45SMatt Arsenault   return buildInstr(ExtOp, Res, Op);
4746d8e1b45SMatt Arsenault }
4756d8e1b45SMatt Arsenault 
buildBoolExtInReg(const DstOp & Res,const SrcOp & Op,bool IsVector,bool IsFP)47613ac4c3dSMatt Arsenault MachineInstrBuilder MachineIRBuilder::buildBoolExtInReg(const DstOp &Res,
47713ac4c3dSMatt Arsenault                                                         const SrcOp &Op,
47813ac4c3dSMatt Arsenault                                                         bool IsVector,
47913ac4c3dSMatt Arsenault                                                         bool IsFP) {
48013ac4c3dSMatt Arsenault   const auto *TLI = getMF().getSubtarget().getTargetLowering();
48113ac4c3dSMatt Arsenault   switch (TLI->getBooleanContents(IsVector, IsFP)) {
48213ac4c3dSMatt Arsenault   case TargetLoweringBase::ZeroOrNegativeOneBooleanContent:
48313ac4c3dSMatt Arsenault     return buildSExtInReg(Res, Op, 1);
48413ac4c3dSMatt Arsenault   case TargetLoweringBase::ZeroOrOneBooleanContent:
48513ac4c3dSMatt Arsenault     return buildZExtInReg(Res, Op, 1);
48613ac4c3dSMatt Arsenault   case TargetLoweringBase::UndefinedBooleanContent:
48713ac4c3dSMatt Arsenault     return buildCopy(Res, Op);
48813ac4c3dSMatt Arsenault   }
48913ac4c3dSMatt Arsenault 
49013ac4c3dSMatt Arsenault   llvm_unreachable("unexpected BooleanContent");
49113ac4c3dSMatt Arsenault }
49213ac4c3dSMatt Arsenault 
buildExtOrTrunc(unsigned ExtOpc,const DstOp & Res,const SrcOp & Op)493cef44a23SAditya Nandakumar MachineInstrBuilder MachineIRBuilder::buildExtOrTrunc(unsigned ExtOpc,
494cef44a23SAditya Nandakumar                                                       const DstOp &Res,
495cef44a23SAditya Nandakumar                                                       const SrcOp &Op) {
496892979efSAditya Nandakumar   assert((TargetOpcode::G_ANYEXT == ExtOpc || TargetOpcode::G_ZEXT == ExtOpc ||
497892979efSAditya Nandakumar           TargetOpcode::G_SEXT == ExtOpc) &&
498892979efSAditya Nandakumar          "Expecting Extending Opc");
499cef44a23SAditya Nandakumar   assert(Res.getLLTTy(*getMRI()).isScalar() ||
500cef44a23SAditya Nandakumar          Res.getLLTTy(*getMRI()).isVector());
501cef44a23SAditya Nandakumar   assert(Res.getLLTTy(*getMRI()).isScalar() ==
502cef44a23SAditya Nandakumar          Op.getLLTTy(*getMRI()).isScalar());
503c990236fSTim Northover 
504a7653b39STim Northover   unsigned Opcode = TargetOpcode::COPY;
505cef44a23SAditya Nandakumar   if (Res.getLLTTy(*getMRI()).getSizeInBits() >
506cef44a23SAditya Nandakumar       Op.getLLTTy(*getMRI()).getSizeInBits())
507892979efSAditya Nandakumar     Opcode = ExtOpc;
508cef44a23SAditya Nandakumar   else if (Res.getLLTTy(*getMRI()).getSizeInBits() <
509cef44a23SAditya Nandakumar            Op.getLLTTy(*getMRI()).getSizeInBits())
510a7653b39STim Northover     Opcode = TargetOpcode::G_TRUNC;
511c990236fSTim Northover   else
512cef44a23SAditya Nandakumar     assert(Res.getLLTTy(*getMRI()) == Op.getLLTTy(*getMRI()));
513a7653b39STim Northover 
514cef44a23SAditya Nandakumar   return buildInstr(Opcode, Res, Op);
515a7653b39STim Northover }
516a7653b39STim Northover 
buildSExtOrTrunc(const DstOp & Res,const SrcOp & Op)517cef44a23SAditya Nandakumar MachineInstrBuilder MachineIRBuilder::buildSExtOrTrunc(const DstOp &Res,
518cef44a23SAditya Nandakumar                                                        const SrcOp &Op) {
519892979efSAditya Nandakumar   return buildExtOrTrunc(TargetOpcode::G_SEXT, Res, Op);
520892979efSAditya Nandakumar }
521892979efSAditya Nandakumar 
buildZExtOrTrunc(const DstOp & Res,const SrcOp & Op)522cef44a23SAditya Nandakumar MachineInstrBuilder MachineIRBuilder::buildZExtOrTrunc(const DstOp &Res,
523cef44a23SAditya Nandakumar                                                        const SrcOp &Op) {
524892979efSAditya Nandakumar   return buildExtOrTrunc(TargetOpcode::G_ZEXT, Res, Op);
525892979efSAditya Nandakumar }
526c990236fSTim Northover 
buildAnyExtOrTrunc(const DstOp & Res,const SrcOp & Op)527cef44a23SAditya Nandakumar MachineInstrBuilder MachineIRBuilder::buildAnyExtOrTrunc(const DstOp &Res,
528cef44a23SAditya Nandakumar                                                          const SrcOp &Op) {
529892979efSAditya Nandakumar   return buildExtOrTrunc(TargetOpcode::G_ANYEXT, Res, Op);
530c3e3f59dSTim Northover }
531c3e3f59dSTim Northover 
buildZExtInReg(const DstOp & Res,const SrcOp & Op,int64_t ImmOp)532d0e5422eSPushpinder Singh MachineInstrBuilder MachineIRBuilder::buildZExtInReg(const DstOp &Res,
533d0e5422eSPushpinder Singh                                                      const SrcOp &Op,
534d0e5422eSPushpinder Singh                                                      int64_t ImmOp) {
535d0e5422eSPushpinder Singh   LLT ResTy = Res.getLLTTy(*getMRI());
536d0e5422eSPushpinder Singh   auto Mask = buildConstant(
537d0e5422eSPushpinder Singh       ResTy, APInt::getLowBitsSet(ResTy.getScalarSizeInBits(), ImmOp));
538a3d273c9SVang Thao   return buildAnd(Res, Op, Mask);
539d0e5422eSPushpinder Singh }
540d0e5422eSPushpinder Singh 
buildCast(const DstOp & Dst,const SrcOp & Src)541cef44a23SAditya Nandakumar MachineInstrBuilder MachineIRBuilder::buildCast(const DstOp &Dst,
542cef44a23SAditya Nandakumar                                                 const SrcOp &Src) {
543cef44a23SAditya Nandakumar   LLT SrcTy = Src.getLLTTy(*getMRI());
544cef44a23SAditya Nandakumar   LLT DstTy = Dst.getLLTTy(*getMRI());
54595b6d5f2STim Northover   if (SrcTy == DstTy)
54695b6d5f2STim Northover     return buildCopy(Dst, Src);
54795b6d5f2STim Northover 
54895b6d5f2STim Northover   unsigned Opcode;
54995b6d5f2STim Northover   if (SrcTy.isPointer() && DstTy.isScalar())
55095b6d5f2STim Northover     Opcode = TargetOpcode::G_PTRTOINT;
55195b6d5f2STim Northover   else if (DstTy.isPointer() && SrcTy.isScalar())
55295b6d5f2STim Northover     Opcode = TargetOpcode::G_INTTOPTR;
55395b6d5f2STim Northover   else {
55495b6d5f2STim Northover     assert(!SrcTy.isPointer() && !DstTy.isPointer() && "n G_ADDRCAST yet");
55595b6d5f2STim Northover     Opcode = TargetOpcode::G_BITCAST;
55695b6d5f2STim Northover   }
55795b6d5f2STim Northover 
558cef44a23SAditya Nandakumar   return buildInstr(Opcode, Dst, Src);
55995b6d5f2STim Northover }
56095b6d5f2STim Northover 
buildExtract(const DstOp & Dst,const SrcOp & Src,uint64_t Index)561e84bdce6SMatt Arsenault MachineInstrBuilder MachineIRBuilder::buildExtract(const DstOp &Dst,
562e84bdce6SMatt Arsenault                                                    const SrcOp &Src,
563cef44a23SAditya Nandakumar                                                    uint64_t Index) {
564e84bdce6SMatt Arsenault   LLT SrcTy = Src.getLLTTy(*getMRI());
565e84bdce6SMatt Arsenault   LLT DstTy = Dst.getLLTTy(*getMRI());
566e84bdce6SMatt Arsenault 
5671f8b1db9STim Northover #ifndef NDEBUG
568e84bdce6SMatt Arsenault   assert(SrcTy.isValid() && "invalid operand type");
569e84bdce6SMatt Arsenault   assert(DstTy.isValid() && "invalid operand type");
570e84bdce6SMatt Arsenault   assert(Index + DstTy.getSizeInBits() <= SrcTy.getSizeInBits() &&
571c2c545b8STim Northover          "extracting off end of register");
5721f8b1db9STim Northover #endif
5731f8b1db9STim Northover 
574e84bdce6SMatt Arsenault   if (DstTy.getSizeInBits() == SrcTy.getSizeInBits()) {
575c2c545b8STim Northover     assert(Index == 0 && "insertion past the end of a register");
576e84bdce6SMatt Arsenault     return buildCast(Dst, Src);
577c2c545b8STim Northover   }
57833b07d67STim Northover 
579e84bdce6SMatt Arsenault   auto Extract = buildInstr(TargetOpcode::G_EXTRACT);
580e84bdce6SMatt Arsenault   Dst.addDefToMIB(*getMRI(), Extract);
581e84bdce6SMatt Arsenault   Src.addSrcToMIB(Extract);
582e84bdce6SMatt Arsenault   Extract.addImm(Index);
583e84bdce6SMatt Arsenault   return Extract;
58433b07d67STim Northover }
58533b07d67STim Northover 
buildUndef(const DstOp & Res)586cef44a23SAditya Nandakumar MachineInstrBuilder MachineIRBuilder::buildUndef(const DstOp &Res) {
587cef44a23SAditya Nandakumar   return buildInstr(TargetOpcode::G_IMPLICIT_DEF, {Res}, {});
58881dafc1cSTim Northover }
58981dafc1cSTim Northover 
buildMerge(const DstOp & Res,ArrayRef<Register> Ops)590cef44a23SAditya Nandakumar MachineInstrBuilder MachineIRBuilder::buildMerge(const DstOp &Res,
591e3a676e9SMatt Arsenault                                                  ArrayRef<Register> Ops) {
592cef44a23SAditya Nandakumar   // Unfortunately to convert from ArrayRef<LLT> to ArrayRef<SrcOp>,
593cef44a23SAditya Nandakumar   // we need some temporary storage for the DstOp objects. Here we use a
594cef44a23SAditya Nandakumar   // sufficiently large SmallVector to not go through the heap.
595cef44a23SAditya Nandakumar   SmallVector<SrcOp, 8> TmpVec(Ops.begin(), Ops.end());
5960966dd0dSMatt Arsenault   assert(TmpVec.size() > 1);
597cef44a23SAditya Nandakumar   return buildInstr(TargetOpcode::G_MERGE_VALUES, Res, TmpVec);
598bf017293STim Northover }
599bf017293STim Northover 
6007df5fc9eSPetar Avramovic MachineInstrBuilder
buildMerge(const DstOp & Res,std::initializer_list<SrcOp> Ops)6017df5fc9eSPetar Avramovic MachineIRBuilder::buildMerge(const DstOp &Res,
6027df5fc9eSPetar Avramovic                              std::initializer_list<SrcOp> Ops) {
6037df5fc9eSPetar Avramovic   assert(Ops.size() > 1);
6047df5fc9eSPetar Avramovic   return buildInstr(TargetOpcode::G_MERGE_VALUES, Res, Ops);
6057df5fc9eSPetar Avramovic }
6067df5fc9eSPetar Avramovic 
buildUnmerge(ArrayRef<LLT> Res,const SrcOp & Op)607cef44a23SAditya Nandakumar MachineInstrBuilder MachineIRBuilder::buildUnmerge(ArrayRef<LLT> Res,
608cef44a23SAditya Nandakumar                                                    const SrcOp &Op) {
609cef44a23SAditya Nandakumar   // Unfortunately to convert from ArrayRef<LLT> to ArrayRef<DstOp>,
610cef44a23SAditya Nandakumar   // we need some temporary storage for the DstOp objects. Here we use a
611cef44a23SAditya Nandakumar   // sufficiently large SmallVector to not go through the heap.
612cef44a23SAditya Nandakumar   SmallVector<DstOp, 8> TmpVec(Res.begin(), Res.end());
6130966dd0dSMatt Arsenault   assert(TmpVec.size() > 1);
614cef44a23SAditya Nandakumar   return buildInstr(TargetOpcode::G_UNMERGE_VALUES, TmpVec, Op);
615bf017293STim Northover }
616bf017293STim Northover 
buildUnmerge(LLT Res,const SrcOp & Op)617106429b4SMatt Arsenault MachineInstrBuilder MachineIRBuilder::buildUnmerge(LLT Res,
618106429b4SMatt Arsenault                                                    const SrcOp &Op) {
619106429b4SMatt Arsenault   unsigned NumReg = Op.getLLTTy(*getMRI()).getSizeInBits() / Res.getSizeInBits();
62029f88b93SPetar Avramovic   SmallVector<DstOp, 8> TmpVec(NumReg, Res);
62129f88b93SPetar Avramovic   return buildInstr(TargetOpcode::G_UNMERGE_VALUES, TmpVec, Op);
622106429b4SMatt Arsenault }
623106429b4SMatt Arsenault 
buildUnmerge(ArrayRef<Register> Res,const SrcOp & Op)624e3a676e9SMatt Arsenault MachineInstrBuilder MachineIRBuilder::buildUnmerge(ArrayRef<Register> Res,
625cef44a23SAditya Nandakumar                                                    const SrcOp &Op) {
6265e66db6bSMatt Arsenault   // Unfortunately to convert from ArrayRef<Register> to ArrayRef<DstOp>,
627cef44a23SAditya Nandakumar   // we need some temporary storage for the DstOp objects. Here we use a
628cef44a23SAditya Nandakumar   // sufficiently large SmallVector to not go through the heap.
629cef44a23SAditya Nandakumar   SmallVector<DstOp, 8> TmpVec(Res.begin(), Res.end());
6300966dd0dSMatt Arsenault   assert(TmpVec.size() > 1);
631cef44a23SAditya Nandakumar   return buildInstr(TargetOpcode::G_UNMERGE_VALUES, TmpVec, Op);
632a0b15d8fSAmara Emerson }
633a0b15d8fSAmara Emerson 
buildBuildVector(const DstOp & Res,ArrayRef<Register> Ops)634cef44a23SAditya Nandakumar MachineInstrBuilder MachineIRBuilder::buildBuildVector(const DstOp &Res,
635e3a676e9SMatt Arsenault                                                        ArrayRef<Register> Ops) {
6365e66db6bSMatt Arsenault   // Unfortunately to convert from ArrayRef<Register> to ArrayRef<SrcOp>,
637cef44a23SAditya Nandakumar   // we need some temporary storage for the DstOp objects. Here we use a
638cef44a23SAditya Nandakumar   // sufficiently large SmallVector to not go through the heap.
639cef44a23SAditya Nandakumar   SmallVector<SrcOp, 8> TmpVec(Ops.begin(), Ops.end());
640cef44a23SAditya Nandakumar   return buildInstr(TargetOpcode::G_BUILD_VECTOR, Res, TmpVec);
641a0b15d8fSAmara Emerson }
642a0b15d8fSAmara Emerson 
64326e1ebd3SJay Foad MachineInstrBuilder
buildBuildVectorConstant(const DstOp & Res,ArrayRef<APInt> Ops)64426e1ebd3SJay Foad MachineIRBuilder::buildBuildVectorConstant(const DstOp &Res,
64526e1ebd3SJay Foad                                            ArrayRef<APInt> Ops) {
64626e1ebd3SJay Foad   SmallVector<SrcOp> TmpVec;
64726e1ebd3SJay Foad   TmpVec.reserve(Ops.size());
64826e1ebd3SJay Foad   LLT EltTy = Res.getLLTTy(*getMRI()).getElementType();
649*9e6d1f4bSKazu Hirata   for (const auto &Op : Ops)
65026e1ebd3SJay Foad     TmpVec.push_back(buildConstant(EltTy, Op));
65126e1ebd3SJay Foad   return buildInstr(TargetOpcode::G_BUILD_VECTOR, Res, TmpVec);
65226e1ebd3SJay Foad }
65326e1ebd3SJay Foad 
buildSplatVector(const DstOp & Res,const SrcOp & Src)6548121ec26SMatt Arsenault MachineInstrBuilder MachineIRBuilder::buildSplatVector(const DstOp &Res,
6558121ec26SMatt Arsenault                                                        const SrcOp &Src) {
6568121ec26SMatt Arsenault   SmallVector<SrcOp, 8> TmpVec(Res.getLLTTy(*getMRI()).getNumElements(), Src);
6578121ec26SMatt Arsenault   return buildInstr(TargetOpcode::G_BUILD_VECTOR, Res, TmpVec);
6588121ec26SMatt Arsenault }
6598121ec26SMatt Arsenault 
660a0b15d8fSAmara Emerson MachineInstrBuilder
buildBuildVectorTrunc(const DstOp & Res,ArrayRef<Register> Ops)661cef44a23SAditya Nandakumar MachineIRBuilder::buildBuildVectorTrunc(const DstOp &Res,
662e3a676e9SMatt Arsenault                                         ArrayRef<Register> Ops) {
6635e66db6bSMatt Arsenault   // Unfortunately to convert from ArrayRef<Register> to ArrayRef<SrcOp>,
664cef44a23SAditya Nandakumar   // we need some temporary storage for the DstOp objects. Here we use a
665cef44a23SAditya Nandakumar   // sufficiently large SmallVector to not go through the heap.
666cef44a23SAditya Nandakumar   SmallVector<SrcOp, 8> TmpVec(Ops.begin(), Ops.end());
667cef44a23SAditya Nandakumar   return buildInstr(TargetOpcode::G_BUILD_VECTOR_TRUNC, Res, TmpVec);
668a0b15d8fSAmara Emerson }
669a0b15d8fSAmara Emerson 
buildShuffleSplat(const DstOp & Res,const SrcOp & Src)67087ff1564SAmara Emerson MachineInstrBuilder MachineIRBuilder::buildShuffleSplat(const DstOp &Res,
67187ff1564SAmara Emerson                                                         const SrcOp &Src) {
67287ff1564SAmara Emerson   LLT DstTy = Res.getLLTTy(*getMRI());
67336fe1a9dSFangrui Song   assert(Src.getLLTTy(*getMRI()) == DstTy.getElementType() &&
67436fe1a9dSFangrui Song          "Expected Src to match Dst elt ty");
67587ff1564SAmara Emerson   auto UndefVec = buildUndef(DstTy);
67687ff1564SAmara Emerson   auto Zero = buildConstant(LLT::scalar(64), 0);
67787ff1564SAmara Emerson   auto InsElt = buildInsertVectorElement(DstTy, UndefVec, Src, Zero);
67887ff1564SAmara Emerson   SmallVector<int, 16> ZeroMask(DstTy.getNumElements());
67987ff1564SAmara Emerson   return buildShuffleVector(DstTy, InsElt, UndefVec, ZeroMask);
68087ff1564SAmara Emerson }
68187ff1564SAmara Emerson 
buildShuffleVector(const DstOp & Res,const SrcOp & Src1,const SrcOp & Src2,ArrayRef<int> Mask)68287ff1564SAmara Emerson MachineInstrBuilder MachineIRBuilder::buildShuffleVector(const DstOp &Res,
68387ff1564SAmara Emerson                                                          const SrcOp &Src1,
68487ff1564SAmara Emerson                                                          const SrcOp &Src2,
68587ff1564SAmara Emerson                                                          ArrayRef<int> Mask) {
68687ff1564SAmara Emerson   LLT DstTy = Res.getLLTTy(*getMRI());
68787ff1564SAmara Emerson   LLT Src1Ty = Src1.getLLTTy(*getMRI());
68887ff1564SAmara Emerson   LLT Src2Ty = Src2.getLLTTy(*getMRI());
6897c25a328SSimon Pilgrim   assert((size_t)(Src1Ty.getNumElements() + Src2Ty.getNumElements()) >=
6907c25a328SSimon Pilgrim          Mask.size());
69187ff1564SAmara Emerson   assert(DstTy.getElementType() == Src1Ty.getElementType() &&
69287ff1564SAmara Emerson          DstTy.getElementType() == Src2Ty.getElementType());
6936359842bSBenjamin Kramer   (void)DstTy;
694d928dfc6SFangrui Song   (void)Src1Ty;
695d928dfc6SFangrui Song   (void)Src2Ty;
69687ff1564SAmara Emerson   ArrayRef<int> MaskAlloc = getMF().allocateShuffleMask(Mask);
697ff30436dSAmara Emerson   return buildInstr(TargetOpcode::G_SHUFFLE_VECTOR, {Res}, {Src1, Src2})
69887ff1564SAmara Emerson       .addShuffleMask(MaskAlloc);
69987ff1564SAmara Emerson }
70087ff1564SAmara Emerson 
701cef44a23SAditya Nandakumar MachineInstrBuilder
buildConcatVectors(const DstOp & Res,ArrayRef<Register> Ops)702e3a676e9SMatt Arsenault MachineIRBuilder::buildConcatVectors(const DstOp &Res, ArrayRef<Register> Ops) {
7035e66db6bSMatt Arsenault   // Unfortunately to convert from ArrayRef<Register> to ArrayRef<SrcOp>,
704cef44a23SAditya Nandakumar   // we need some temporary storage for the DstOp objects. Here we use a
705cef44a23SAditya Nandakumar   // sufficiently large SmallVector to not go through the heap.
706cef44a23SAditya Nandakumar   SmallVector<SrcOp, 8> TmpVec(Ops.begin(), Ops.end());
707cef44a23SAditya Nandakumar   return buildInstr(TargetOpcode::G_CONCAT_VECTORS, Res, TmpVec);
708cef44a23SAditya Nandakumar }
709cef44a23SAditya Nandakumar 
buildInsert(const DstOp & Res,const SrcOp & Src,const SrcOp & Op,unsigned Index)7102a1b5af2SJay Foad MachineInstrBuilder MachineIRBuilder::buildInsert(const DstOp &Res,
7112a1b5af2SJay Foad                                                   const SrcOp &Src,
7122a1b5af2SJay Foad                                                   const SrcOp &Op,
7132a1b5af2SJay Foad                                                   unsigned Index) {
7142a1b5af2SJay Foad   assert(Index + Op.getLLTTy(*getMRI()).getSizeInBits() <=
7152a1b5af2SJay Foad              Res.getLLTTy(*getMRI()).getSizeInBits() &&
716c990236fSTim Northover          "insertion past the end of a register");
717c990236fSTim Northover 
7182a1b5af2SJay Foad   if (Res.getLLTTy(*getMRI()).getSizeInBits() ==
7192a1b5af2SJay Foad       Op.getLLTTy(*getMRI()).getSizeInBits()) {
72095b6d5f2STim Northover     return buildCast(Res, Op);
72195b6d5f2STim Northover   }
72295b6d5f2STim Northover 
7232a1b5af2SJay Foad   return buildInstr(TargetOpcode::G_INSERT, Res, {Src, Op, uint64_t(Index)});
7243e6a7afdSTim Northover }
7253e6a7afdSTim Northover 
buildIntrinsic(Intrinsic::ID ID,ArrayRef<Register> ResultRegs,bool HasSideEffects)726cef44a23SAditya Nandakumar MachineInstrBuilder MachineIRBuilder::buildIntrinsic(Intrinsic::ID ID,
727e3a676e9SMatt Arsenault                                                      ArrayRef<Register> ResultRegs,
7285fb414d8STim Northover                                                      bool HasSideEffects) {
7295fb414d8STim Northover   auto MIB =
7305fb414d8STim Northover       buildInstr(HasSideEffects ? TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS
7310f140c76STim Northover                                 : TargetOpcode::G_INTRINSIC);
73213371692SMatt Arsenault   for (unsigned ResultReg : ResultRegs)
73313371692SMatt Arsenault     MIB.addDef(ResultReg);
7345fb414d8STim Northover   MIB.addIntrinsicID(ID);
7355fb414d8STim Northover   return MIB;
7365fb414d8STim Northover }
73732335818STim Northover 
buildIntrinsic(Intrinsic::ID ID,ArrayRef<DstOp> Results,bool HasSideEffects)73827ac8408SMatt Arsenault MachineInstrBuilder MachineIRBuilder::buildIntrinsic(Intrinsic::ID ID,
73927ac8408SMatt Arsenault                                                      ArrayRef<DstOp> Results,
74027ac8408SMatt Arsenault                                                      bool HasSideEffects) {
74127ac8408SMatt Arsenault   auto MIB =
74227ac8408SMatt Arsenault       buildInstr(HasSideEffects ? TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS
74327ac8408SMatt Arsenault                                 : TargetOpcode::G_INTRINSIC);
74427ac8408SMatt Arsenault   for (DstOp Result : Results)
74527ac8408SMatt Arsenault     Result.addDefToMIB(*getMRI(), MIB);
74627ac8408SMatt Arsenault   MIB.addIntrinsicID(ID);
74727ac8408SMatt Arsenault   return MIB;
74827ac8408SMatt Arsenault }
74927ac8408SMatt Arsenault 
buildTrunc(const DstOp & Res,const SrcOp & Op)750cef44a23SAditya Nandakumar MachineInstrBuilder MachineIRBuilder::buildTrunc(const DstOp &Res,
751cef44a23SAditya Nandakumar                                                  const SrcOp &Op) {
752cef44a23SAditya Nandakumar   return buildInstr(TargetOpcode::G_TRUNC, Res, Op);
75332335818STim Northover }
754de3aea04STim Northover 
buildFPTrunc(const DstOp & Res,const SrcOp & Op,Optional<unsigned> Flags)755cef44a23SAditya Nandakumar MachineInstrBuilder MachineIRBuilder::buildFPTrunc(const DstOp &Res,
756c35b358bSAustin Kerbow                                                    const SrcOp &Op,
757c35b358bSAustin Kerbow                                                    Optional<unsigned> Flags) {
758c35b358bSAustin Kerbow   return buildInstr(TargetOpcode::G_FPTRUNC, Res, Op, Flags);
759a11be047STim Northover }
760a11be047STim Northover 
buildICmp(CmpInst::Predicate Pred,const DstOp & Res,const SrcOp & Op0,const SrcOp & Op1)761cef44a23SAditya Nandakumar MachineInstrBuilder MachineIRBuilder::buildICmp(CmpInst::Predicate Pred,
762cef44a23SAditya Nandakumar                                                 const DstOp &Res,
763cef44a23SAditya Nandakumar                                                 const SrcOp &Op0,
764cef44a23SAditya Nandakumar                                                 const SrcOp &Op1) {
765cef44a23SAditya Nandakumar   return buildInstr(TargetOpcode::G_ICMP, Res, {Pred, Op0, Op1});
766de3aea04STim Northover }
7675a28c364STim Northover 
buildFCmp(CmpInst::Predicate Pred,const DstOp & Res,const SrcOp & Op0,const SrcOp & Op1,Optional<unsigned> Flags)768cef44a23SAditya Nandakumar MachineInstrBuilder MachineIRBuilder::buildFCmp(CmpInst::Predicate Pred,
769cef44a23SAditya Nandakumar                                                 const DstOp &Res,
770cef44a23SAditya Nandakumar                                                 const SrcOp &Op0,
771c99f62e3SAustin Kerbow                                                 const SrcOp &Op1,
772c99f62e3SAustin Kerbow                                                 Optional<unsigned> Flags) {
7731f8b1db9STim Northover 
774c99f62e3SAustin Kerbow   return buildInstr(TargetOpcode::G_FCMP, Res, {Pred, Op0, Op1}, Flags);
775d5c23bcfSTim Northover }
776d5c23bcfSTim Northover 
buildSelect(const DstOp & Res,const SrcOp & Tst,const SrcOp & Op0,const SrcOp & Op1,Optional<unsigned> Flags)777cef44a23SAditya Nandakumar MachineInstrBuilder MachineIRBuilder::buildSelect(const DstOp &Res,
778cef44a23SAditya Nandakumar                                                   const SrcOp &Tst,
779cef44a23SAditya Nandakumar                                                   const SrcOp &Op0,
780c99f62e3SAustin Kerbow                                                   const SrcOp &Op1,
781c99f62e3SAustin Kerbow                                                   Optional<unsigned> Flags) {
7821f8b1db9STim Northover 
783c99f62e3SAustin Kerbow   return buildInstr(TargetOpcode::G_SELECT, {Res}, {Tst, Op0, Op1}, Flags);
7845a28c364STim Northover }
785bdf67c9aSTim Northover 
786b1c467dbSAditya Nandakumar MachineInstrBuilder
buildInsertVectorElement(const DstOp & Res,const SrcOp & Val,const SrcOp & Elt,const SrcOp & Idx)787cef44a23SAditya Nandakumar MachineIRBuilder::buildInsertVectorElement(const DstOp &Res, const SrcOp &Val,
788cef44a23SAditya Nandakumar                                            const SrcOp &Elt, const SrcOp &Idx) {
789cef44a23SAditya Nandakumar   return buildInstr(TargetOpcode::G_INSERT_VECTOR_ELT, Res, {Val, Elt, Idx});
79004cb08ccSVolkan Keles }
79104cb08ccSVolkan Keles 
792b1c467dbSAditya Nandakumar MachineInstrBuilder
buildExtractVectorElement(const DstOp & Res,const SrcOp & Val,const SrcOp & Idx)793cef44a23SAditya Nandakumar MachineIRBuilder::buildExtractVectorElement(const DstOp &Res, const SrcOp &Val,
794cef44a23SAditya Nandakumar                                             const SrcOp &Idx) {
795cef44a23SAditya Nandakumar   return buildInstr(TargetOpcode::G_EXTRACT_VECTOR_ELT, Res, {Val, Idx});
79604cb08ccSVolkan Keles }
79704cb08ccSVolkan Keles 
buildAtomicCmpXchgWithSuccess(Register OldValRes,Register SuccessRes,Register Addr,Register CmpVal,Register NewVal,MachineMemOperand & MMO)798cef44a23SAditya Nandakumar MachineInstrBuilder MachineIRBuilder::buildAtomicCmpXchgWithSuccess(
7995e66db6bSMatt Arsenault     Register OldValRes, Register SuccessRes, Register Addr, Register CmpVal,
8005e66db6bSMatt Arsenault     Register NewVal, MachineMemOperand &MMO) {
8019481399cSDaniel Sanders #ifndef NDEBUG
8029481399cSDaniel Sanders   LLT OldValResTy = getMRI()->getType(OldValRes);
8039481399cSDaniel Sanders   LLT SuccessResTy = getMRI()->getType(SuccessRes);
8049481399cSDaniel Sanders   LLT AddrTy = getMRI()->getType(Addr);
8059481399cSDaniel Sanders   LLT CmpValTy = getMRI()->getType(CmpVal);
8069481399cSDaniel Sanders   LLT NewValTy = getMRI()->getType(NewVal);
8079481399cSDaniel Sanders   assert(OldValResTy.isScalar() && "invalid operand type");
8089481399cSDaniel Sanders   assert(SuccessResTy.isScalar() && "invalid operand type");
8099481399cSDaniel Sanders   assert(AddrTy.isPointer() && "invalid operand type");
8109481399cSDaniel Sanders   assert(CmpValTy.isValid() && "invalid operand type");
8119481399cSDaniel Sanders   assert(NewValTy.isValid() && "invalid operand type");
8129481399cSDaniel Sanders   assert(OldValResTy == CmpValTy && "type mismatch");
8139481399cSDaniel Sanders   assert(OldValResTy == NewValTy && "type mismatch");
8149481399cSDaniel Sanders #endif
8159481399cSDaniel Sanders 
8169481399cSDaniel Sanders   return buildInstr(TargetOpcode::G_ATOMIC_CMPXCHG_WITH_SUCCESS)
8179481399cSDaniel Sanders       .addDef(OldValRes)
8189481399cSDaniel Sanders       .addDef(SuccessRes)
8199481399cSDaniel Sanders       .addUse(Addr)
8209481399cSDaniel Sanders       .addUse(CmpVal)
8219481399cSDaniel Sanders       .addUse(NewVal)
8229481399cSDaniel Sanders       .addMemOperand(&MMO);
8239481399cSDaniel Sanders }
8249481399cSDaniel Sanders 
825aef1dfc6SDaniel Sanders MachineInstrBuilder
buildAtomicCmpXchg(Register OldValRes,Register Addr,Register CmpVal,Register NewVal,MachineMemOperand & MMO)8265e66db6bSMatt Arsenault MachineIRBuilder::buildAtomicCmpXchg(Register OldValRes, Register Addr,
8275e66db6bSMatt Arsenault                                      Register CmpVal, Register NewVal,
828aef1dfc6SDaniel Sanders                                      MachineMemOperand &MMO) {
829aef1dfc6SDaniel Sanders #ifndef NDEBUG
830b1c467dbSAditya Nandakumar   LLT OldValResTy = getMRI()->getType(OldValRes);
831b1c467dbSAditya Nandakumar   LLT AddrTy = getMRI()->getType(Addr);
832b1c467dbSAditya Nandakumar   LLT CmpValTy = getMRI()->getType(CmpVal);
833b1c467dbSAditya Nandakumar   LLT NewValTy = getMRI()->getType(NewVal);
834aef1dfc6SDaniel Sanders   assert(OldValResTy.isScalar() && "invalid operand type");
835aef1dfc6SDaniel Sanders   assert(AddrTy.isPointer() && "invalid operand type");
836aef1dfc6SDaniel Sanders   assert(CmpValTy.isValid() && "invalid operand type");
837aef1dfc6SDaniel Sanders   assert(NewValTy.isValid() && "invalid operand type");
838aef1dfc6SDaniel Sanders   assert(OldValResTy == CmpValTy && "type mismatch");
839aef1dfc6SDaniel Sanders   assert(OldValResTy == NewValTy && "type mismatch");
840aef1dfc6SDaniel Sanders #endif
841aef1dfc6SDaniel Sanders 
842aef1dfc6SDaniel Sanders   return buildInstr(TargetOpcode::G_ATOMIC_CMPXCHG)
843aef1dfc6SDaniel Sanders       .addDef(OldValRes)
844aef1dfc6SDaniel Sanders       .addUse(Addr)
845aef1dfc6SDaniel Sanders       .addUse(CmpVal)
846aef1dfc6SDaniel Sanders       .addUse(NewVal)
847aef1dfc6SDaniel Sanders       .addMemOperand(&MMO);
848aef1dfc6SDaniel Sanders }
849aef1dfc6SDaniel Sanders 
buildAtomicRMW(unsigned Opcode,const DstOp & OldValRes,const SrcOp & Addr,const SrcOp & Val,MachineMemOperand & MMO)8509cf980d4SMatt Arsenault MachineInstrBuilder MachineIRBuilder::buildAtomicRMW(
8519cf980d4SMatt Arsenault   unsigned Opcode, const DstOp &OldValRes,
8529cf980d4SMatt Arsenault   const SrcOp &Addr, const SrcOp &Val,
8539481399cSDaniel Sanders   MachineMemOperand &MMO) {
8549cf980d4SMatt Arsenault 
8559481399cSDaniel Sanders #ifndef NDEBUG
8569cf980d4SMatt Arsenault   LLT OldValResTy = OldValRes.getLLTTy(*getMRI());
8579cf980d4SMatt Arsenault   LLT AddrTy = Addr.getLLTTy(*getMRI());
8589cf980d4SMatt Arsenault   LLT ValTy = Val.getLLTTy(*getMRI());
8599481399cSDaniel Sanders   assert(OldValResTy.isScalar() && "invalid operand type");
8609481399cSDaniel Sanders   assert(AddrTy.isPointer() && "invalid operand type");
8619481399cSDaniel Sanders   assert(ValTy.isValid() && "invalid operand type");
8629481399cSDaniel Sanders   assert(OldValResTy == ValTy && "type mismatch");
8639cf980d4SMatt Arsenault   assert(MMO.isAtomic() && "not atomic mem operand");
8649481399cSDaniel Sanders #endif
8659481399cSDaniel Sanders 
8669cf980d4SMatt Arsenault   auto MIB = buildInstr(Opcode);
8679cf980d4SMatt Arsenault   OldValRes.addDefToMIB(*getMRI(), MIB);
8689cf980d4SMatt Arsenault   Addr.addSrcToMIB(MIB);
8699cf980d4SMatt Arsenault   Val.addSrcToMIB(MIB);
8709cf980d4SMatt Arsenault   MIB.addMemOperand(&MMO);
8719cf980d4SMatt Arsenault   return MIB;
8729481399cSDaniel Sanders }
8739481399cSDaniel Sanders 
8749481399cSDaniel Sanders MachineInstrBuilder
buildAtomicRMWXchg(Register OldValRes,Register Addr,Register Val,MachineMemOperand & MMO)8755e66db6bSMatt Arsenault MachineIRBuilder::buildAtomicRMWXchg(Register OldValRes, Register Addr,
8765e66db6bSMatt Arsenault                                      Register Val, MachineMemOperand &MMO) {
8779481399cSDaniel Sanders   return buildAtomicRMW(TargetOpcode::G_ATOMICRMW_XCHG, OldValRes, Addr, Val,
8789481399cSDaniel Sanders                         MMO);
8799481399cSDaniel Sanders }
8809481399cSDaniel Sanders MachineInstrBuilder
buildAtomicRMWAdd(Register OldValRes,Register Addr,Register Val,MachineMemOperand & MMO)8815e66db6bSMatt Arsenault MachineIRBuilder::buildAtomicRMWAdd(Register OldValRes, Register Addr,
8825e66db6bSMatt Arsenault                                     Register Val, MachineMemOperand &MMO) {
8839481399cSDaniel Sanders   return buildAtomicRMW(TargetOpcode::G_ATOMICRMW_ADD, OldValRes, Addr, Val,
8849481399cSDaniel Sanders                         MMO);
8859481399cSDaniel Sanders }
8869481399cSDaniel Sanders MachineInstrBuilder
buildAtomicRMWSub(Register OldValRes,Register Addr,Register Val,MachineMemOperand & MMO)8875e66db6bSMatt Arsenault MachineIRBuilder::buildAtomicRMWSub(Register OldValRes, Register Addr,
8885e66db6bSMatt Arsenault                                     Register Val, MachineMemOperand &MMO) {
8899481399cSDaniel Sanders   return buildAtomicRMW(TargetOpcode::G_ATOMICRMW_SUB, OldValRes, Addr, Val,
8909481399cSDaniel Sanders                         MMO);
8919481399cSDaniel Sanders }
8929481399cSDaniel Sanders MachineInstrBuilder
buildAtomicRMWAnd(Register OldValRes,Register Addr,Register Val,MachineMemOperand & MMO)8935e66db6bSMatt Arsenault MachineIRBuilder::buildAtomicRMWAnd(Register OldValRes, Register Addr,
8945e66db6bSMatt Arsenault                                     Register Val, MachineMemOperand &MMO) {
8959481399cSDaniel Sanders   return buildAtomicRMW(TargetOpcode::G_ATOMICRMW_AND, OldValRes, Addr, Val,
8969481399cSDaniel Sanders                         MMO);
8979481399cSDaniel Sanders }
8989481399cSDaniel Sanders MachineInstrBuilder
buildAtomicRMWNand(Register OldValRes,Register Addr,Register Val,MachineMemOperand & MMO)8995e66db6bSMatt Arsenault MachineIRBuilder::buildAtomicRMWNand(Register OldValRes, Register Addr,
9005e66db6bSMatt Arsenault                                      Register Val, MachineMemOperand &MMO) {
9019481399cSDaniel Sanders   return buildAtomicRMW(TargetOpcode::G_ATOMICRMW_NAND, OldValRes, Addr, Val,
9029481399cSDaniel Sanders                         MMO);
9039481399cSDaniel Sanders }
buildAtomicRMWOr(Register OldValRes,Register Addr,Register Val,MachineMemOperand & MMO)9045e66db6bSMatt Arsenault MachineInstrBuilder MachineIRBuilder::buildAtomicRMWOr(Register OldValRes,
9055e66db6bSMatt Arsenault                                                        Register Addr,
9065e66db6bSMatt Arsenault                                                        Register Val,
907cef44a23SAditya Nandakumar                                                        MachineMemOperand &MMO) {
9089481399cSDaniel Sanders   return buildAtomicRMW(TargetOpcode::G_ATOMICRMW_OR, OldValRes, Addr, Val,
9099481399cSDaniel Sanders                         MMO);
9109481399cSDaniel Sanders }
9119481399cSDaniel Sanders MachineInstrBuilder
buildAtomicRMWXor(Register OldValRes,Register Addr,Register Val,MachineMemOperand & MMO)9125e66db6bSMatt Arsenault MachineIRBuilder::buildAtomicRMWXor(Register OldValRes, Register Addr,
9135e66db6bSMatt Arsenault                                     Register Val, MachineMemOperand &MMO) {
9149481399cSDaniel Sanders   return buildAtomicRMW(TargetOpcode::G_ATOMICRMW_XOR, OldValRes, Addr, Val,
9159481399cSDaniel Sanders                         MMO);
9169481399cSDaniel Sanders }
9179481399cSDaniel Sanders MachineInstrBuilder
buildAtomicRMWMax(Register OldValRes,Register Addr,Register Val,MachineMemOperand & MMO)9185e66db6bSMatt Arsenault MachineIRBuilder::buildAtomicRMWMax(Register OldValRes, Register Addr,
9195e66db6bSMatt Arsenault                                     Register Val, MachineMemOperand &MMO) {
9209481399cSDaniel Sanders   return buildAtomicRMW(TargetOpcode::G_ATOMICRMW_MAX, OldValRes, Addr, Val,
9219481399cSDaniel Sanders                         MMO);
9229481399cSDaniel Sanders }
9239481399cSDaniel Sanders MachineInstrBuilder
buildAtomicRMWMin(Register OldValRes,Register Addr,Register Val,MachineMemOperand & MMO)9245e66db6bSMatt Arsenault MachineIRBuilder::buildAtomicRMWMin(Register OldValRes, Register Addr,
9255e66db6bSMatt Arsenault                                     Register Val, MachineMemOperand &MMO) {
9269481399cSDaniel Sanders   return buildAtomicRMW(TargetOpcode::G_ATOMICRMW_MIN, OldValRes, Addr, Val,
9279481399cSDaniel Sanders                         MMO);
9289481399cSDaniel Sanders }
9299481399cSDaniel Sanders MachineInstrBuilder
buildAtomicRMWUmax(Register OldValRes,Register Addr,Register Val,MachineMemOperand & MMO)9305e66db6bSMatt Arsenault MachineIRBuilder::buildAtomicRMWUmax(Register OldValRes, Register Addr,
9315e66db6bSMatt Arsenault                                      Register Val, MachineMemOperand &MMO) {
9329481399cSDaniel Sanders   return buildAtomicRMW(TargetOpcode::G_ATOMICRMW_UMAX, OldValRes, Addr, Val,
9339481399cSDaniel Sanders                         MMO);
9349481399cSDaniel Sanders }
9359481399cSDaniel Sanders MachineInstrBuilder
buildAtomicRMWUmin(Register OldValRes,Register Addr,Register Val,MachineMemOperand & MMO)9365e66db6bSMatt Arsenault MachineIRBuilder::buildAtomicRMWUmin(Register OldValRes, Register Addr,
9375e66db6bSMatt Arsenault                                      Register Val, MachineMemOperand &MMO) {
9389481399cSDaniel Sanders   return buildAtomicRMW(TargetOpcode::G_ATOMICRMW_UMIN, OldValRes, Addr, Val,
9399481399cSDaniel Sanders                         MMO);
9409481399cSDaniel Sanders }
9419481399cSDaniel Sanders 
9426aff5a78SAmara Emerson MachineInstrBuilder
buildAtomicRMWFAdd(const DstOp & OldValRes,const SrcOp & Addr,const SrcOp & Val,MachineMemOperand & MMO)9439cf980d4SMatt Arsenault MachineIRBuilder::buildAtomicRMWFAdd(
9449cf980d4SMatt Arsenault   const DstOp &OldValRes, const SrcOp &Addr, const SrcOp &Val,
9459cf980d4SMatt Arsenault   MachineMemOperand &MMO) {
9469cf980d4SMatt Arsenault   return buildAtomicRMW(TargetOpcode::G_ATOMICRMW_FADD, OldValRes, Addr, Val,
9479cf980d4SMatt Arsenault                         MMO);
9489cf980d4SMatt Arsenault }
9499cf980d4SMatt Arsenault 
9509cf980d4SMatt Arsenault MachineInstrBuilder
buildAtomicRMWFSub(const DstOp & OldValRes,const SrcOp & Addr,const SrcOp & Val,MachineMemOperand & MMO)9519cf980d4SMatt Arsenault MachineIRBuilder::buildAtomicRMWFSub(const DstOp &OldValRes, const SrcOp &Addr, const SrcOp &Val,
9529cf980d4SMatt Arsenault                                      MachineMemOperand &MMO) {
9539cf980d4SMatt Arsenault   return buildAtomicRMW(TargetOpcode::G_ATOMICRMW_FSUB, OldValRes, Addr, Val,
9549cf980d4SMatt Arsenault                         MMO);
9559cf980d4SMatt Arsenault }
9569cf980d4SMatt Arsenault 
9579cf980d4SMatt Arsenault MachineInstrBuilder
buildAtomicRMWFMax(const DstOp & OldValRes,const SrcOp & Addr,const SrcOp & Val,MachineMemOperand & MMO)9581023ddafSShilei Tian MachineIRBuilder::buildAtomicRMWFMax(const DstOp &OldValRes, const SrcOp &Addr,
9591023ddafSShilei Tian                                      const SrcOp &Val, MachineMemOperand &MMO) {
9601023ddafSShilei Tian   return buildAtomicRMW(TargetOpcode::G_ATOMICRMW_FMAX, OldValRes, Addr, Val,
9611023ddafSShilei Tian                         MMO);
9621023ddafSShilei Tian }
9631023ddafSShilei Tian 
9641023ddafSShilei Tian MachineInstrBuilder
buildAtomicRMWFMin(const DstOp & OldValRes,const SrcOp & Addr,const SrcOp & Val,MachineMemOperand & MMO)9651023ddafSShilei Tian MachineIRBuilder::buildAtomicRMWFMin(const DstOp &OldValRes, const SrcOp &Addr,
9661023ddafSShilei Tian                                      const SrcOp &Val, MachineMemOperand &MMO) {
9671023ddafSShilei Tian   return buildAtomicRMW(TargetOpcode::G_ATOMICRMW_FMIN, OldValRes, Addr, Val,
9681023ddafSShilei Tian                         MMO);
9691023ddafSShilei Tian }
9701023ddafSShilei Tian 
9711023ddafSShilei Tian MachineInstrBuilder
buildFence(unsigned Ordering,unsigned Scope)972ce690544SMatt Arsenault MachineIRBuilder::buildFence(unsigned Ordering, unsigned Scope) {
973ce690544SMatt Arsenault   return buildInstr(TargetOpcode::G_FENCE)
974ce690544SMatt Arsenault     .addImm(Ordering)
975ce690544SMatt Arsenault     .addImm(Scope);
976ce690544SMatt Arsenault }
977ce690544SMatt Arsenault 
978ce690544SMatt Arsenault MachineInstrBuilder
buildBlockAddress(Register Res,const BlockAddress * BA)9795e66db6bSMatt Arsenault MachineIRBuilder::buildBlockAddress(Register Res, const BlockAddress *BA) {
9806aff5a78SAmara Emerson #ifndef NDEBUG
9816aff5a78SAmara Emerson   assert(getMRI()->getType(Res).isPointer() && "invalid res type");
9826aff5a78SAmara Emerson #endif
9836aff5a78SAmara Emerson 
9846aff5a78SAmara Emerson   return buildInstr(TargetOpcode::G_BLOCK_ADDR).addDef(Res).addBlockAddress(BA);
9856aff5a78SAmara Emerson }
9866aff5a78SAmara Emerson 
validateTruncExt(const LLT DstTy,const LLT SrcTy,bool IsExtend)987de256478SMatt Arsenault void MachineIRBuilder::validateTruncExt(const LLT DstTy, const LLT SrcTy,
9880f140c76STim Northover                                         bool IsExtend) {
989418237beSRichard Smith #ifndef NDEBUG
990bdf67c9aSTim Northover   if (DstTy.isVector()) {
9919481399cSDaniel Sanders     assert(SrcTy.isVector() && "mismatched cast between vector and non-vector");
992bdf67c9aSTim Northover     assert(SrcTy.getNumElements() == DstTy.getNumElements() &&
993bdf67c9aSTim Northover            "different number of elements in a trunc/ext");
994bdf67c9aSTim Northover   } else
995bdf67c9aSTim Northover     assert(DstTy.isScalar() && SrcTy.isScalar() && "invalid extend/trunc");
996bdf67c9aSTim Northover 
997bdf67c9aSTim Northover   if (IsExtend)
998bdf67c9aSTim Northover     assert(DstTy.getSizeInBits() > SrcTy.getSizeInBits() &&
999bdf67c9aSTim Northover            "invalid narrowing extend");
1000bdf67c9aSTim Northover   else
1001bdf67c9aSTim Northover     assert(DstTy.getSizeInBits() < SrcTy.getSizeInBits() &&
1002bdf67c9aSTim Northover            "invalid widening trunc");
1003418237beSRichard Smith #endif
1004bdf67c9aSTim Northover }
1005cef44a23SAditya Nandakumar 
validateSelectOp(const LLT ResTy,const LLT TstTy,const LLT Op0Ty,const LLT Op1Ty)1006de256478SMatt Arsenault void MachineIRBuilder::validateSelectOp(const LLT ResTy, const LLT TstTy,
1007de256478SMatt Arsenault                                         const LLT Op0Ty, const LLT Op1Ty) {
1008cef44a23SAditya Nandakumar #ifndef NDEBUG
1009cef44a23SAditya Nandakumar   assert((ResTy.isScalar() || ResTy.isVector() || ResTy.isPointer()) &&
1010cef44a23SAditya Nandakumar          "invalid operand type");
1011cef44a23SAditya Nandakumar   assert((ResTy == Op0Ty && ResTy == Op1Ty) && "type mismatch");
1012cef44a23SAditya Nandakumar   if (ResTy.isScalar() || ResTy.isPointer())
1013cef44a23SAditya Nandakumar     assert(TstTy.isScalar() && "type mismatch");
1014cef44a23SAditya Nandakumar   else
1015cef44a23SAditya Nandakumar     assert((TstTy.isScalar() ||
1016cef44a23SAditya Nandakumar             (TstTy.isVector() &&
1017cef44a23SAditya Nandakumar              TstTy.getNumElements() == Op0Ty.getNumElements())) &&
1018cef44a23SAditya Nandakumar            "type mismatch");
1019cef44a23SAditya Nandakumar #endif
1020cef44a23SAditya Nandakumar }
1021cef44a23SAditya Nandakumar 
buildInstr(unsigned Opc,ArrayRef<DstOp> DstOps,ArrayRef<SrcOp> SrcOps,Optional<unsigned> Flags)1022cef44a23SAditya Nandakumar MachineInstrBuilder MachineIRBuilder::buildInstr(unsigned Opc,
1023cef44a23SAditya Nandakumar                                                  ArrayRef<DstOp> DstOps,
1024853a6678SAditya Nandakumar                                                  ArrayRef<SrcOp> SrcOps,
1025853a6678SAditya Nandakumar                                                  Optional<unsigned> Flags) {
1026cef44a23SAditya Nandakumar   switch (Opc) {
1027cef44a23SAditya Nandakumar   default:
1028cef44a23SAditya Nandakumar     break;
1029cef44a23SAditya Nandakumar   case TargetOpcode::G_SELECT: {
1030cef44a23SAditya Nandakumar     assert(DstOps.size() == 1 && "Invalid select");
1031cef44a23SAditya Nandakumar     assert(SrcOps.size() == 3 && "Invalid select");
1032cef44a23SAditya Nandakumar     validateSelectOp(
1033cef44a23SAditya Nandakumar         DstOps[0].getLLTTy(*getMRI()), SrcOps[0].getLLTTy(*getMRI()),
1034cef44a23SAditya Nandakumar         SrcOps[1].getLLTTy(*getMRI()), SrcOps[2].getLLTTy(*getMRI()));
1035cef44a23SAditya Nandakumar     break;
1036cef44a23SAditya Nandakumar   }
1037fa2b836eSJay Foad   case TargetOpcode::G_FNEG:
1038fa2b836eSJay Foad   case TargetOpcode::G_ABS:
1039fa2b836eSJay Foad     // All these are unary ops.
1040fa2b836eSJay Foad     assert(DstOps.size() == 1 && "Invalid Dst");
1041fa2b836eSJay Foad     assert(SrcOps.size() == 1 && "Invalid Srcs");
1042fa2b836eSJay Foad     validateUnaryOp(DstOps[0].getLLTTy(*getMRI()),
1043fa2b836eSJay Foad                     SrcOps[0].getLLTTy(*getMRI()));
1044fa2b836eSJay Foad     break;
1045cef44a23SAditya Nandakumar   case TargetOpcode::G_ADD:
1046cef44a23SAditya Nandakumar   case TargetOpcode::G_AND:
1047cef44a23SAditya Nandakumar   case TargetOpcode::G_MUL:
1048cef44a23SAditya Nandakumar   case TargetOpcode::G_OR:
1049cef44a23SAditya Nandakumar   case TargetOpcode::G_SUB:
1050cef44a23SAditya Nandakumar   case TargetOpcode::G_XOR:
1051cef44a23SAditya Nandakumar   case TargetOpcode::G_UDIV:
1052cef44a23SAditya Nandakumar   case TargetOpcode::G_SDIV:
1053cef44a23SAditya Nandakumar   case TargetOpcode::G_UREM:
1054f3cedf48SMatt Arsenault   case TargetOpcode::G_SREM:
1055f3cedf48SMatt Arsenault   case TargetOpcode::G_SMIN:
1056f3cedf48SMatt Arsenault   case TargetOpcode::G_SMAX:
1057f3cedf48SMatt Arsenault   case TargetOpcode::G_UMIN:
10580444d16aSJay Foad   case TargetOpcode::G_UMAX:
10590444d16aSJay Foad   case TargetOpcode::G_UADDSAT:
10600444d16aSJay Foad   case TargetOpcode::G_SADDSAT:
10610444d16aSJay Foad   case TargetOpcode::G_USUBSAT:
10620444d16aSJay Foad   case TargetOpcode::G_SSUBSAT: {
1063cef44a23SAditya Nandakumar     // All these are binary ops.
1064cef44a23SAditya Nandakumar     assert(DstOps.size() == 1 && "Invalid Dst");
1065cef44a23SAditya Nandakumar     assert(SrcOps.size() == 2 && "Invalid Srcs");
1066cef44a23SAditya Nandakumar     validateBinaryOp(DstOps[0].getLLTTy(*getMRI()),
1067cef44a23SAditya Nandakumar                      SrcOps[0].getLLTTy(*getMRI()),
1068cef44a23SAditya Nandakumar                      SrcOps[1].getLLTTy(*getMRI()));
1069cef44a23SAditya Nandakumar     break;
1070fbec8fe9SMatt Arsenault   }
1071fbec8fe9SMatt Arsenault   case TargetOpcode::G_SHL:
1072fbec8fe9SMatt Arsenault   case TargetOpcode::G_ASHR:
10735de6c56fSBevin Hansson   case TargetOpcode::G_LSHR:
10745de6c56fSBevin Hansson   case TargetOpcode::G_USHLSAT:
10755de6c56fSBevin Hansson   case TargetOpcode::G_SSHLSAT: {
1076fbec8fe9SMatt Arsenault     assert(DstOps.size() == 1 && "Invalid Dst");
1077fbec8fe9SMatt Arsenault     assert(SrcOps.size() == 2 && "Invalid Srcs");
1078fbec8fe9SMatt Arsenault     validateShiftOp(DstOps[0].getLLTTy(*getMRI()),
1079fbec8fe9SMatt Arsenault                     SrcOps[0].getLLTTy(*getMRI()),
1080fbec8fe9SMatt Arsenault                     SrcOps[1].getLLTTy(*getMRI()));
1081fbec8fe9SMatt Arsenault     break;
1082fbec8fe9SMatt Arsenault   }
1083cef44a23SAditya Nandakumar   case TargetOpcode::G_SEXT:
1084cef44a23SAditya Nandakumar   case TargetOpcode::G_ZEXT:
1085cef44a23SAditya Nandakumar   case TargetOpcode::G_ANYEXT:
1086cef44a23SAditya Nandakumar     assert(DstOps.size() == 1 && "Invalid Dst");
1087cef44a23SAditya Nandakumar     assert(SrcOps.size() == 1 && "Invalid Srcs");
1088cef44a23SAditya Nandakumar     validateTruncExt(DstOps[0].getLLTTy(*getMRI()),
1089cef44a23SAditya Nandakumar                      SrcOps[0].getLLTTy(*getMRI()), true);
1090cef44a23SAditya Nandakumar     break;
1091cef44a23SAditya Nandakumar   case TargetOpcode::G_TRUNC:
1092fbec8fe9SMatt Arsenault   case TargetOpcode::G_FPTRUNC: {
1093cef44a23SAditya Nandakumar     assert(DstOps.size() == 1 && "Invalid Dst");
1094cef44a23SAditya Nandakumar     assert(SrcOps.size() == 1 && "Invalid Srcs");
1095cef44a23SAditya Nandakumar     validateTruncExt(DstOps[0].getLLTTy(*getMRI()),
1096cef44a23SAditya Nandakumar                      SrcOps[0].getLLTTy(*getMRI()), false);
1097cef44a23SAditya Nandakumar     break;
1098cef44a23SAditya Nandakumar   }
1099f717483aSMatt Arsenault   case TargetOpcode::G_BITCAST: {
1100f717483aSMatt Arsenault     assert(DstOps.size() == 1 && "Invalid Dst");
1101f717483aSMatt Arsenault     assert(SrcOps.size() == 1 && "Invalid Srcs");
1102f717483aSMatt Arsenault     assert(DstOps[0].getLLTTy(*getMRI()).getSizeInBits() ==
1103f717483aSMatt Arsenault            SrcOps[0].getLLTTy(*getMRI()).getSizeInBits() && "invalid bitcast");
1104f717483aSMatt Arsenault     break;
1105f717483aSMatt Arsenault   }
1106cef44a23SAditya Nandakumar   case TargetOpcode::COPY:
1107cef44a23SAditya Nandakumar     assert(DstOps.size() == 1 && "Invalid Dst");
1108a140276aSAmara Emerson     // If the caller wants to add a subreg source it has to be done separately
1109a140276aSAmara Emerson     // so we may not have any SrcOps at this point yet.
1110cef44a23SAditya Nandakumar     break;
1111cef44a23SAditya Nandakumar   case TargetOpcode::G_FCMP:
1112cef44a23SAditya Nandakumar   case TargetOpcode::G_ICMP: {
1113cef44a23SAditya Nandakumar     assert(DstOps.size() == 1 && "Invalid Dst Operands");
1114cef44a23SAditya Nandakumar     assert(SrcOps.size() == 3 && "Invalid Src Operands");
1115cef44a23SAditya Nandakumar     // For F/ICMP, the first src operand is the predicate, followed by
1116cef44a23SAditya Nandakumar     // the two comparands.
1117cef44a23SAditya Nandakumar     assert(SrcOps[0].getSrcOpKind() == SrcOp::SrcType::Ty_Predicate &&
1118cef44a23SAditya Nandakumar            "Expecting predicate");
1119cef44a23SAditya Nandakumar     assert([&]() -> bool {
1120cef44a23SAditya Nandakumar       CmpInst::Predicate Pred = SrcOps[0].getPredicate();
1121cef44a23SAditya Nandakumar       return Opc == TargetOpcode::G_ICMP ? CmpInst::isIntPredicate(Pred)
1122cef44a23SAditya Nandakumar                                          : CmpInst::isFPPredicate(Pred);
1123cef44a23SAditya Nandakumar     }() && "Invalid predicate");
1124cef44a23SAditya Nandakumar     assert(SrcOps[1].getLLTTy(*getMRI()) == SrcOps[2].getLLTTy(*getMRI()) &&
1125cef44a23SAditya Nandakumar            "Type mismatch");
1126cef44a23SAditya Nandakumar     assert([&]() -> bool {
1127cef44a23SAditya Nandakumar       LLT Op0Ty = SrcOps[1].getLLTTy(*getMRI());
1128cef44a23SAditya Nandakumar       LLT DstTy = DstOps[0].getLLTTy(*getMRI());
1129cef44a23SAditya Nandakumar       if (Op0Ty.isScalar() || Op0Ty.isPointer())
1130cef44a23SAditya Nandakumar         return DstTy.isScalar();
1131cef44a23SAditya Nandakumar       else
1132cef44a23SAditya Nandakumar         return DstTy.isVector() &&
1133cef44a23SAditya Nandakumar                DstTy.getNumElements() == Op0Ty.getNumElements();
1134cef44a23SAditya Nandakumar     }() && "Type Mismatch");
1135cef44a23SAditya Nandakumar     break;
1136cef44a23SAditya Nandakumar   }
1137cef44a23SAditya Nandakumar   case TargetOpcode::G_UNMERGE_VALUES: {
1138cef44a23SAditya Nandakumar     assert(!DstOps.empty() && "Invalid trivial sequence");
1139cef44a23SAditya Nandakumar     assert(SrcOps.size() == 1 && "Invalid src for Unmerge");
1140cfeecdf7SKazu Hirata     assert(llvm::all_of(DstOps,
1141cef44a23SAditya Nandakumar                         [&, this](const DstOp &Op) {
1142cef44a23SAditya Nandakumar                           return Op.getLLTTy(*getMRI()) ==
1143cef44a23SAditya Nandakumar                                  DstOps[0].getLLTTy(*getMRI());
1144cef44a23SAditya Nandakumar                         }) &&
1145cef44a23SAditya Nandakumar            "type mismatch in output list");
11460e09d18cSSander de Smalen     assert((TypeSize::ScalarTy)DstOps.size() *
11470e09d18cSSander de Smalen                    DstOps[0].getLLTTy(*getMRI()).getSizeInBits() ==
1148cef44a23SAditya Nandakumar                SrcOps[0].getLLTTy(*getMRI()).getSizeInBits() &&
1149cef44a23SAditya Nandakumar            "input operands do not cover output register");
1150cef44a23SAditya Nandakumar     break;
1151cef44a23SAditya Nandakumar   }
1152cef44a23SAditya Nandakumar   case TargetOpcode::G_MERGE_VALUES: {
1153cef44a23SAditya Nandakumar     assert(!SrcOps.empty() && "invalid trivial sequence");
1154cef44a23SAditya Nandakumar     assert(DstOps.size() == 1 && "Invalid Dst");
1155cfeecdf7SKazu Hirata     assert(llvm::all_of(SrcOps,
1156cef44a23SAditya Nandakumar                         [&, this](const SrcOp &Op) {
1157cef44a23SAditya Nandakumar                           return Op.getLLTTy(*getMRI()) ==
1158cef44a23SAditya Nandakumar                                  SrcOps[0].getLLTTy(*getMRI());
1159cef44a23SAditya Nandakumar                         }) &&
1160cef44a23SAditya Nandakumar            "type mismatch in input list");
11610e09d18cSSander de Smalen     assert((TypeSize::ScalarTy)SrcOps.size() *
11620e09d18cSSander de Smalen                    SrcOps[0].getLLTTy(*getMRI()).getSizeInBits() ==
1163cef44a23SAditya Nandakumar                DstOps[0].getLLTTy(*getMRI()).getSizeInBits() &&
1164cef44a23SAditya Nandakumar            "input operands do not cover output register");
1165cef44a23SAditya Nandakumar     if (SrcOps.size() == 1)
1166cef44a23SAditya Nandakumar       return buildCast(DstOps[0], SrcOps[0]);
11677720f114SQuentin Colombet     if (DstOps[0].getLLTTy(*getMRI()).isVector()) {
11687720f114SQuentin Colombet       if (SrcOps[0].getLLTTy(*getMRI()).isVector())
1169cef44a23SAditya Nandakumar         return buildInstr(TargetOpcode::G_CONCAT_VECTORS, DstOps, SrcOps);
11707720f114SQuentin Colombet       return buildInstr(TargetOpcode::G_BUILD_VECTOR, DstOps, SrcOps);
11717720f114SQuentin Colombet     }
1172cef44a23SAditya Nandakumar     break;
1173cef44a23SAditya Nandakumar   }
1174cef44a23SAditya Nandakumar   case TargetOpcode::G_EXTRACT_VECTOR_ELT: {
1175cef44a23SAditya Nandakumar     assert(DstOps.size() == 1 && "Invalid Dst size");
1176cef44a23SAditya Nandakumar     assert(SrcOps.size() == 2 && "Invalid Src size");
1177cef44a23SAditya Nandakumar     assert(SrcOps[0].getLLTTy(*getMRI()).isVector() && "Invalid operand type");
1178cef44a23SAditya Nandakumar     assert((DstOps[0].getLLTTy(*getMRI()).isScalar() ||
1179cef44a23SAditya Nandakumar             DstOps[0].getLLTTy(*getMRI()).isPointer()) &&
1180cef44a23SAditya Nandakumar            "Invalid operand type");
1181cef44a23SAditya Nandakumar     assert(SrcOps[1].getLLTTy(*getMRI()).isScalar() && "Invalid operand type");
1182cef44a23SAditya Nandakumar     assert(SrcOps[0].getLLTTy(*getMRI()).getElementType() ==
1183cef44a23SAditya Nandakumar                DstOps[0].getLLTTy(*getMRI()) &&
1184cef44a23SAditya Nandakumar            "Type mismatch");
1185cef44a23SAditya Nandakumar     break;
1186cef44a23SAditya Nandakumar   }
1187cef44a23SAditya Nandakumar   case TargetOpcode::G_INSERT_VECTOR_ELT: {
1188cef44a23SAditya Nandakumar     assert(DstOps.size() == 1 && "Invalid dst size");
1189cef44a23SAditya Nandakumar     assert(SrcOps.size() == 3 && "Invalid src size");
1190cef44a23SAditya Nandakumar     assert(DstOps[0].getLLTTy(*getMRI()).isVector() &&
1191cef44a23SAditya Nandakumar            SrcOps[0].getLLTTy(*getMRI()).isVector() && "Invalid operand type");
1192cef44a23SAditya Nandakumar     assert(DstOps[0].getLLTTy(*getMRI()).getElementType() ==
1193cef44a23SAditya Nandakumar                SrcOps[1].getLLTTy(*getMRI()) &&
1194cef44a23SAditya Nandakumar            "Type mismatch");
1195cef44a23SAditya Nandakumar     assert(SrcOps[2].getLLTTy(*getMRI()).isScalar() && "Invalid index");
1196cef44a23SAditya Nandakumar     assert(DstOps[0].getLLTTy(*getMRI()).getNumElements() ==
1197cef44a23SAditya Nandakumar                SrcOps[0].getLLTTy(*getMRI()).getNumElements() &&
1198cef44a23SAditya Nandakumar            "Type mismatch");
1199cef44a23SAditya Nandakumar     break;
1200cef44a23SAditya Nandakumar   }
1201cef44a23SAditya Nandakumar   case TargetOpcode::G_BUILD_VECTOR: {
1202cef44a23SAditya Nandakumar     assert((!SrcOps.empty() || SrcOps.size() < 2) &&
1203cef44a23SAditya Nandakumar            "Must have at least 2 operands");
1204cef44a23SAditya Nandakumar     assert(DstOps.size() == 1 && "Invalid DstOps");
1205cef44a23SAditya Nandakumar     assert(DstOps[0].getLLTTy(*getMRI()).isVector() &&
1206cef44a23SAditya Nandakumar            "Res type must be a vector");
1207cfeecdf7SKazu Hirata     assert(llvm::all_of(SrcOps,
1208cef44a23SAditya Nandakumar                         [&, this](const SrcOp &Op) {
1209cef44a23SAditya Nandakumar                           return Op.getLLTTy(*getMRI()) ==
1210cef44a23SAditya Nandakumar                                  SrcOps[0].getLLTTy(*getMRI());
1211cef44a23SAditya Nandakumar                         }) &&
1212cef44a23SAditya Nandakumar            "type mismatch in input list");
12130e09d18cSSander de Smalen     assert((TypeSize::ScalarTy)SrcOps.size() *
12140e09d18cSSander de Smalen                    SrcOps[0].getLLTTy(*getMRI()).getSizeInBits() ==
1215cef44a23SAditya Nandakumar                DstOps[0].getLLTTy(*getMRI()).getSizeInBits() &&
1216590c6750SMatt Arsenault            "input scalars do not exactly cover the output vector register");
1217cef44a23SAditya Nandakumar     break;
1218cef44a23SAditya Nandakumar   }
1219cef44a23SAditya Nandakumar   case TargetOpcode::G_BUILD_VECTOR_TRUNC: {
1220cef44a23SAditya Nandakumar     assert((!SrcOps.empty() || SrcOps.size() < 2) &&
1221cef44a23SAditya Nandakumar            "Must have at least 2 operands");
1222cef44a23SAditya Nandakumar     assert(DstOps.size() == 1 && "Invalid DstOps");
1223cef44a23SAditya Nandakumar     assert(DstOps[0].getLLTTy(*getMRI()).isVector() &&
1224cef44a23SAditya Nandakumar            "Res type must be a vector");
1225cfeecdf7SKazu Hirata     assert(llvm::all_of(SrcOps,
1226cef44a23SAditya Nandakumar                         [&, this](const SrcOp &Op) {
1227cef44a23SAditya Nandakumar                           return Op.getLLTTy(*getMRI()) ==
1228cef44a23SAditya Nandakumar                                  SrcOps[0].getLLTTy(*getMRI());
1229cef44a23SAditya Nandakumar                         }) &&
1230cef44a23SAditya Nandakumar            "type mismatch in input list");
1231cef44a23SAditya Nandakumar     if (SrcOps[0].getLLTTy(*getMRI()).getSizeInBits() ==
1232cef44a23SAditya Nandakumar         DstOps[0].getLLTTy(*getMRI()).getElementType().getSizeInBits())
1233cef44a23SAditya Nandakumar       return buildInstr(TargetOpcode::G_BUILD_VECTOR, DstOps, SrcOps);
1234cef44a23SAditya Nandakumar     break;
1235cef44a23SAditya Nandakumar   }
1236cef44a23SAditya Nandakumar   case TargetOpcode::G_CONCAT_VECTORS: {
1237cef44a23SAditya Nandakumar     assert(DstOps.size() == 1 && "Invalid DstOps");
1238cef44a23SAditya Nandakumar     assert((!SrcOps.empty() || SrcOps.size() < 2) &&
1239cef44a23SAditya Nandakumar            "Must have at least 2 operands");
1240cfeecdf7SKazu Hirata     assert(llvm::all_of(SrcOps,
1241cef44a23SAditya Nandakumar                         [&, this](const SrcOp &Op) {
1242cef44a23SAditya Nandakumar                           return (Op.getLLTTy(*getMRI()).isVector() &&
1243cef44a23SAditya Nandakumar                                   Op.getLLTTy(*getMRI()) ==
1244cef44a23SAditya Nandakumar                                       SrcOps[0].getLLTTy(*getMRI()));
1245cef44a23SAditya Nandakumar                         }) &&
1246cef44a23SAditya Nandakumar            "type mismatch in input list");
12470e09d18cSSander de Smalen     assert((TypeSize::ScalarTy)SrcOps.size() *
12480e09d18cSSander de Smalen                    SrcOps[0].getLLTTy(*getMRI()).getSizeInBits() ==
1249cef44a23SAditya Nandakumar                DstOps[0].getLLTTy(*getMRI()).getSizeInBits() &&
1250590c6750SMatt Arsenault            "input vectors do not exactly cover the output vector register");
1251cef44a23SAditya Nandakumar     break;
1252cef44a23SAditya Nandakumar   }
1253cef44a23SAditya Nandakumar   case TargetOpcode::G_UADDE: {
1254cef44a23SAditya Nandakumar     assert(DstOps.size() == 2 && "Invalid no of dst operands");
1255cef44a23SAditya Nandakumar     assert(SrcOps.size() == 3 && "Invalid no of src operands");
1256cef44a23SAditya Nandakumar     assert(DstOps[0].getLLTTy(*getMRI()).isScalar() && "Invalid operand");
1257cef44a23SAditya Nandakumar     assert((DstOps[0].getLLTTy(*getMRI()) == SrcOps[0].getLLTTy(*getMRI())) &&
1258cef44a23SAditya Nandakumar            (DstOps[0].getLLTTy(*getMRI()) == SrcOps[1].getLLTTy(*getMRI())) &&
1259cef44a23SAditya Nandakumar            "Invalid operand");
1260cef44a23SAditya Nandakumar     assert(DstOps[1].getLLTTy(*getMRI()).isScalar() && "Invalid operand");
1261cef44a23SAditya Nandakumar     assert(DstOps[1].getLLTTy(*getMRI()) == SrcOps[2].getLLTTy(*getMRI()) &&
1262cef44a23SAditya Nandakumar            "type mismatch");
1263cef44a23SAditya Nandakumar     break;
1264cef44a23SAditya Nandakumar   }
1265cef44a23SAditya Nandakumar   }
1266cef44a23SAditya Nandakumar 
1267cef44a23SAditya Nandakumar   auto MIB = buildInstr(Opc);
1268cef44a23SAditya Nandakumar   for (const DstOp &Op : DstOps)
1269cef44a23SAditya Nandakumar     Op.addDefToMIB(*getMRI(), MIB);
1270cef44a23SAditya Nandakumar   for (const SrcOp &Op : SrcOps)
1271cef44a23SAditya Nandakumar     Op.addSrcToMIB(MIB);
1272853a6678SAditya Nandakumar   if (Flags)
1273853a6678SAditya Nandakumar     MIB->setFlags(*Flags);
1274cef44a23SAditya Nandakumar   return MIB;
1275cef44a23SAditya Nandakumar }
1276