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