blob: 2e9c7d8250ba2eaff1f6ef3ffdc5e9ce3ab31af2 [file] [log] [blame]
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001//== llvm/CodeGen/GlobalISel/LegalizerHelper.h ---------------- -*- C++ -*-==//
2//
Andrew Walbran16937d02019-10-22 13:54:20 +01003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01006//
7//===----------------------------------------------------------------------===//
8//
9/// \file A pass to convert the target-illegal operations created by IR -> MIR
10/// translation into ones the target expects to be able to select. This may
11/// occur in multiple phases, for example G_ADD <2 x i8> -> G_ADD <2 x i16> ->
12/// G_ADD <4 x i16>.
13///
14/// The LegalizerHelper class is where most of the work happens, and is
15/// designed to be callable from other passes that find themselves with an
16/// illegal instruction.
17//
18//===----------------------------------------------------------------------===//
19
20#ifndef LLVM_CODEGEN_GLOBALISEL_MACHINELEGALIZEHELPER_H
21#define LLVM_CODEGEN_GLOBALISEL_MACHINELEGALIZEHELPER_H
22
23#include "llvm/CodeGen/GlobalISel/CallLowering.h"
24#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
25#include "llvm/CodeGen/LowLevelType.h"
26#include "llvm/CodeGen/MachineFunctionPass.h"
27#include "llvm/CodeGen/RuntimeLibcalls.h"
28
29namespace llvm {
30// Forward declarations.
31class LegalizerInfo;
32class Legalizer;
33class MachineRegisterInfo;
Andrew Walbran16937d02019-10-22 13:54:20 +010034class GISelChangeObserver;
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020035class TargetLowering;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010036
37class LegalizerHelper {
38public:
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020039 /// Expose MIRBuilder so clients can set their own RecordInsertInstruction
40 /// functions
41 MachineIRBuilder &MIRBuilder;
42
43 /// To keep track of changes made by the LegalizerHelper.
44 GISelChangeObserver &Observer;
45
46private:
47 MachineRegisterInfo &MRI;
48 const LegalizerInfo &LI;
49 const TargetLowering &TLI;
50
51public:
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010052 enum LegalizeResult {
53 /// Instruction was already legal and no change was made to the
54 /// MachineFunction.
55 AlreadyLegal,
56
57 /// Instruction has been legalized and the MachineFunction changed.
58 Legalized,
59
60 /// Some kind of error has occurred and we could not legalize this
61 /// instruction.
62 UnableToLegalize,
63 };
64
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020065 /// Expose LegalizerInfo so the clients can re-use.
66 const LegalizerInfo &getLegalizerInfo() const { return LI; }
67 const TargetLowering &getTargetLowering() const { return TLI; }
68
Andrew Walbran16937d02019-10-22 13:54:20 +010069 LegalizerHelper(MachineFunction &MF, GISelChangeObserver &Observer,
70 MachineIRBuilder &B);
71 LegalizerHelper(MachineFunction &MF, const LegalizerInfo &LI,
72 GISelChangeObserver &Observer, MachineIRBuilder &B);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010073
74 /// Replace \p MI by a sequence of legal instructions that can implement the
75 /// same operation. Note that this means \p MI may be deleted, so any iterator
76 /// steps should be performed before calling this function. \p Helper should
77 /// be initialized to the MachineFunction containing \p MI.
78 ///
79 /// Considered as an opaque blob, the legal code will use and define the same
80 /// registers as \p MI.
81 LegalizeResult legalizeInstrStep(MachineInstr &MI);
82
83 /// Legalize an instruction by emiting a runtime library call instead.
84 LegalizeResult libcall(MachineInstr &MI);
85
86 /// Legalize an instruction by reducing the width of the underlying scalar
87 /// type.
88 LegalizeResult narrowScalar(MachineInstr &MI, unsigned TypeIdx, LLT NarrowTy);
89
90 /// Legalize an instruction by performing the operation on a wider scalar type
91 /// (for example a 16-bit addition can be safely performed at 32-bits
92 /// precision, ignoring the unused bits).
93 LegalizeResult widenScalar(MachineInstr &MI, unsigned TypeIdx, LLT WideTy);
94
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020095 /// Legalize an instruction by replacing the value type
96 LegalizeResult bitcast(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
97
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010098 /// Legalize an instruction by splitting it into simpler parts, hopefully
99 /// understood by the target.
100 LegalizeResult lower(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
101
102 /// Legalize a vector instruction by splitting into multiple components, each
103 /// acting on the same scalar type as the original but with fewer elements.
104 LegalizeResult fewerElementsVector(MachineInstr &MI, unsigned TypeIdx,
105 LLT NarrowTy);
106
107 /// Legalize a vector instruction by increasing the number of vector elements
108 /// involved and ignoring the added elements later.
109 LegalizeResult moreElementsVector(MachineInstr &MI, unsigned TypeIdx,
Andrew Walbran16937d02019-10-22 13:54:20 +0100110 LLT MoreTy);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100111
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200112 /// Cast the given value to an LLT::scalar with an equivalent size. Returns
113 /// the register to use if an instruction was inserted. Returns the original
114 /// register if no coercion was necessary.
115 //
116 // This may also fail and return Register() if there is no legal way to cast.
117 Register coerceToScalar(Register Val);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100118
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100119 /// Legalize a single operand \p OpIdx of the machine instruction \p MI as a
120 /// Use by extending the operand's type to \p WideTy using the specified \p
121 /// ExtOpcode for the extension instruction, and replacing the vreg of the
122 /// operand in place.
123 void widenScalarSrc(MachineInstr &MI, LLT WideTy, unsigned OpIdx,
124 unsigned ExtOpcode);
125
126 /// Legalize a single operand \p OpIdx of the machine instruction \p MI as a
Andrew Walbran16937d02019-10-22 13:54:20 +0100127 /// Use by truncating the operand's type to \p NarrowTy using G_TRUNC, and
128 /// replacing the vreg of the operand in place.
129 void narrowScalarSrc(MachineInstr &MI, LLT NarrowTy, unsigned OpIdx);
130
131 /// Legalize a single operand \p OpIdx of the machine instruction \p MI as a
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100132 /// Def by extending the operand's type to \p WideTy and truncating it back
133 /// with the \p TruncOpcode, and replacing the vreg of the operand in place.
134 void widenScalarDst(MachineInstr &MI, LLT WideTy, unsigned OpIdx = 0,
135 unsigned TruncOpcode = TargetOpcode::G_TRUNC);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100136
Andrew Walbran16937d02019-10-22 13:54:20 +0100137 // Legalize a single operand \p OpIdx of the machine instruction \p MI as a
138 // Def by truncating the operand's type to \p NarrowTy, replacing in place and
139 // extending back with \p ExtOpcode.
140 void narrowScalarDst(MachineInstr &MI, LLT NarrowTy, unsigned OpIdx,
141 unsigned ExtOpcode);
142 /// Legalize a single operand \p OpIdx of the machine instruction \p MI as a
143 /// Def by performing it with additional vector elements and extracting the
144 /// result elements, and replacing the vreg of the operand in place.
145 void moreElementsVectorDst(MachineInstr &MI, LLT MoreTy, unsigned OpIdx);
146
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100147 /// Legalize a single operand \p OpIdx of the machine instruction \p MI as a
148 /// Use by producing a vector with undefined high elements, extracting the
149 /// original vector type, and replacing the vreg of the operand in place.
150 void moreElementsVectorSrc(MachineInstr &MI, LLT MoreTy, unsigned OpIdx);
151
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200152 /// Legalize a single operand \p OpIdx of the machine instruction \p MI as a
153 /// use by inserting a G_BITCAST to \p CastTy
154 void bitcastSrc(MachineInstr &MI, LLT CastTy, unsigned OpIdx);
155
156 /// Legalize a single operand \p OpIdx of the machine instruction \p MI as a
157 /// def by inserting a G_BITCAST from \p CastTy
158 void bitcastDst(MachineInstr &MI, LLT CastTy, unsigned OpIdx);
159
160 /// Widen \p OrigReg to \p WideTy by merging to a wider type, padding with
161 /// G_IMPLICIT_DEF, and producing dead results.
162 Register widenWithUnmerge(LLT WideTy, Register OrigReg);
163
164private:
Andrew Walbran16937d02019-10-22 13:54:20 +0100165 LegalizeResult
166 widenScalarMergeValues(MachineInstr &MI, unsigned TypeIdx, LLT WideTy);
167 LegalizeResult
168 widenScalarUnmergeValues(MachineInstr &MI, unsigned TypeIdx, LLT WideTy);
169 LegalizeResult
170 widenScalarExtract(MachineInstr &MI, unsigned TypeIdx, LLT WideTy);
171 LegalizeResult
172 widenScalarInsert(MachineInstr &MI, unsigned TypeIdx, LLT WideTy);
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200173 LegalizeResult
174 widenScalarAddSubShlSat(MachineInstr &MI, unsigned TypeIdx, LLT WideTy);
Andrew Walbran16937d02019-10-22 13:54:20 +0100175
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100176 /// Helper function to split a wide generic register into bitwise blocks with
177 /// the given Type (which implies the number of blocks needed). The generic
178 /// registers created are appended to Ops, starting at bit 0 of Reg.
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100179 void extractParts(Register Reg, LLT Ty, int NumParts,
180 SmallVectorImpl<Register> &VRegs);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100181
Andrew Walbran16937d02019-10-22 13:54:20 +0100182 /// Version which handles irregular splits.
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100183 bool extractParts(Register Reg, LLT RegTy, LLT MainTy,
Andrew Walbran16937d02019-10-22 13:54:20 +0100184 LLT &LeftoverTy,
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100185 SmallVectorImpl<Register> &VRegs,
186 SmallVectorImpl<Register> &LeftoverVRegs);
Andrew Walbran16937d02019-10-22 13:54:20 +0100187
188 /// Helper function to build a wide generic register \p DstReg of type \p
189 /// RegTy from smaller parts. This will produce a G_MERGE_VALUES,
190 /// G_BUILD_VECTOR, G_CONCAT_VECTORS, or sequence of G_INSERT as appropriate
191 /// for the types.
192 ///
193 /// \p PartRegs must be registers of type \p PartTy.
194 ///
195 /// If \p ResultTy does not evenly break into \p PartTy sized pieces, the
196 /// remainder must be specified with \p LeftoverRegs of type \p LeftoverTy.
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100197 void insertParts(Register DstReg, LLT ResultTy,
198 LLT PartTy, ArrayRef<Register> PartRegs,
199 LLT LeftoverTy = LLT(), ArrayRef<Register> LeftoverRegs = {});
200
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200201 /// Unmerge \p SrcReg into smaller sized values, and append them to \p
202 /// Parts. The elements of \p Parts will be the greatest common divisor type
203 /// of \p DstTy, \p NarrowTy and the type of \p SrcReg. This will compute and
204 /// return the GCD type.
205 LLT extractGCDType(SmallVectorImpl<Register> &Parts, LLT DstTy,
206 LLT NarrowTy, Register SrcReg);
207
208 /// Unmerge \p SrcReg into \p GCDTy typed registers. This will append all of
209 /// the unpacked registers to \p Parts. This version is if the common unmerge
210 /// type is already known.
211 void extractGCDType(SmallVectorImpl<Register> &Parts, LLT GCDTy,
212 Register SrcReg);
213
214 /// Produce a merge of values in \p VRegs to define \p DstReg. Perform a merge
215 /// from the least common multiple type, and convert as appropriate to \p
216 /// DstReg.
217 ///
218 /// \p VRegs should each have type \p GCDTy. This type should be greatest
219 /// common divisor type of \p DstReg, \p NarrowTy, and an undetermined source
220 /// type.
221 ///
222 /// \p NarrowTy is the desired result merge source type. If the source value
223 /// needs to be widened to evenly cover \p DstReg, inserts high bits
224 /// corresponding to the extension opcode \p PadStrategy.
225 ///
226 /// \p VRegs will be cleared, and the the result \p NarrowTy register pieces
227 /// will replace it. Returns The complete LCMTy that \p VRegs will cover when
228 /// merged.
229 LLT buildLCMMergePieces(LLT DstTy, LLT NarrowTy, LLT GCDTy,
230 SmallVectorImpl<Register> &VRegs,
231 unsigned PadStrategy = TargetOpcode::G_ANYEXT);
232
233 /// Merge the values in \p RemergeRegs to an \p LCMTy typed value. Extract the
234 /// low bits into \p DstReg. This is intended to use the outputs from
235 /// buildLCMMergePieces after processing.
236 void buildWidenedRemergeToDst(Register DstReg, LLT LCMTy,
237 ArrayRef<Register> RemergeRegs);
238
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100239 /// Perform generic multiplication of values held in multiple registers.
240 /// Generated instructions use only types NarrowTy and i1.
241 /// Destination can be same or two times size of the source.
242 void multiplyRegisters(SmallVectorImpl<Register> &DstRegs,
243 ArrayRef<Register> Src1Regs,
244 ArrayRef<Register> Src2Regs, LLT NarrowTy);
Andrew Walbran16937d02019-10-22 13:54:20 +0100245
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200246 void changeOpcode(MachineInstr &MI, unsigned NewOpcode);
247
248public:
249 /// Return the alignment to use for a stack temporary object with the given
250 /// type.
251 Align getStackTemporaryAlignment(LLT Type, Align MinAlign = Align()) const;
252
253 /// Create a stack temporary based on the size in bytes and the alignment
254 MachineInstrBuilder createStackTemporary(TypeSize Bytes, Align Alignment,
255 MachinePointerInfo &PtrInfo);
256
257 /// Get a pointer to vector element \p Index located in memory for a vector of
258 /// type \p VecTy starting at a base address of \p VecPtr. If \p Index is out
259 /// of bounds the returned pointer is unspecified, but will be within the
260 /// vector bounds.
261 Register getVectorElementPointer(Register VecPtr, LLT VecTy, Register Index);
262
Andrew Walbran16937d02019-10-22 13:54:20 +0100263 LegalizeResult fewerElementsVectorImplicitDef(MachineInstr &MI,
264 unsigned TypeIdx, LLT NarrowTy);
265
Andrew Walbran16937d02019-10-22 13:54:20 +0100266 /// Legalize a instruction with a vector type where each operand may have a
267 /// different element type. All type indexes must have the same number of
268 /// elements.
269 LegalizeResult fewerElementsVectorMultiEltType(MachineInstr &MI,
270 unsigned TypeIdx, LLT NarrowTy);
271
272 LegalizeResult fewerElementsVectorCasts(MachineInstr &MI, unsigned TypeIdx,
273 LLT NarrowTy);
274
275 LegalizeResult
276 fewerElementsVectorCmp(MachineInstr &MI, unsigned TypeIdx, LLT NarrowTy);
277
278 LegalizeResult
279 fewerElementsVectorSelect(MachineInstr &MI, unsigned TypeIdx, LLT NarrowTy);
280
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100281 LegalizeResult fewerElementsVectorPhi(MachineInstr &MI,
282 unsigned TypeIdx, LLT NarrowTy);
283
284 LegalizeResult moreElementsVectorPhi(MachineInstr &MI, unsigned TypeIdx,
285 LLT MoreTy);
286
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200287 LegalizeResult fewerElementsVectorUnmergeValues(MachineInstr &MI,
288 unsigned TypeIdx,
289 LLT NarrowTy);
290 LegalizeResult fewerElementsVectorMerge(MachineInstr &MI, unsigned TypeIdx,
291 LLT NarrowTy);
292 LegalizeResult fewerElementsVectorExtractInsertVectorElt(MachineInstr &MI,
293 unsigned TypeIdx,
294 LLT NarrowTy);
295
Andrew Walbran16937d02019-10-22 13:54:20 +0100296 LegalizeResult
297 reduceLoadStoreWidth(MachineInstr &MI, unsigned TypeIdx, LLT NarrowTy);
298
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200299 /// Legalize an instruction by reducing the operation width, either by
300 /// narrowing the type of the operation or by reducing the number of elements
301 /// of a vector.
302 /// The used strategy (narrow vs. fewerElements) is decided by \p NarrowTy.
303 /// Narrow is used if the scalar type of \p NarrowTy and \p DstTy differ,
304 /// fewerElements is used when the scalar type is the same but the number of
305 /// elements between \p NarrowTy and \p DstTy differ.
306 LegalizeResult reduceOperationWidth(MachineInstr &MI, unsigned TypeIdx,
307 LLT NarrowTy);
308
309 LegalizeResult fewerElementsVectorSextInReg(MachineInstr &MI, unsigned TypeIdx,
310 LLT NarrowTy);
311
Andrew Walbran16937d02019-10-22 13:54:20 +0100312 LegalizeResult narrowScalarShiftByConstant(MachineInstr &MI, const APInt &Amt,
313 LLT HalfTy, LLT ShiftAmtTy);
314
315 LegalizeResult narrowScalarShift(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100316 LegalizeResult narrowScalarMul(MachineInstr &MI, LLT Ty);
Andrew Walbran16937d02019-10-22 13:54:20 +0100317 LegalizeResult narrowScalarExtract(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
318 LegalizeResult narrowScalarInsert(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
319
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100320 LegalizeResult narrowScalarBasic(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200321 LegalizeResult narrowScalarExt(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
Andrew Walbran16937d02019-10-22 13:54:20 +0100322 LegalizeResult narrowScalarSelect(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200323 LegalizeResult narrowScalarCTLZ(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
324 LegalizeResult narrowScalarCTTZ(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
325 LegalizeResult narrowScalarCTPOP(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
Andrew Walbran16937d02019-10-22 13:54:20 +0100326
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200327 /// Perform Bitcast legalize action on G_EXTRACT_VECTOR_ELT.
328 LegalizeResult bitcastExtractVectorElt(MachineInstr &MI, unsigned TypeIdx,
329 LLT CastTy);
330
331 /// Perform Bitcast legalize action on G_INSERT_VECTOR_ELT.
332 LegalizeResult bitcastInsertVectorElt(MachineInstr &MI, unsigned TypeIdx,
333 LLT CastTy);
334
335 LegalizeResult lowerBitcast(MachineInstr &MI);
336 LegalizeResult lowerLoad(MachineInstr &MI);
337 LegalizeResult lowerStore(MachineInstr &MI);
338 LegalizeResult lowerBitCount(MachineInstr &MI);
Andrew Scull0372a572018-11-16 15:47:06 +0000339
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100340 LegalizeResult lowerU64ToF32BitOps(MachineInstr &MI);
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200341 LegalizeResult lowerUITOFP(MachineInstr &MI);
342 LegalizeResult lowerSITOFP(MachineInstr &MI);
343 LegalizeResult lowerFPTOUI(MachineInstr &MI);
344 LegalizeResult lowerFPTOSI(MachineInstr &MI);
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100345
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200346 LegalizeResult lowerFPTRUNC_F64_TO_F16(MachineInstr &MI);
347 LegalizeResult lowerFPTRUNC(MachineInstr &MI);
348 LegalizeResult lowerFPOWI(MachineInstr &MI);
349
350 LegalizeResult lowerMinMax(MachineInstr &MI);
351 LegalizeResult lowerFCopySign(MachineInstr &MI);
352 LegalizeResult lowerFMinNumMaxNum(MachineInstr &MI);
353 LegalizeResult lowerFMad(MachineInstr &MI);
354 LegalizeResult lowerIntrinsicRound(MachineInstr &MI);
355 LegalizeResult lowerFFloor(MachineInstr &MI);
356 LegalizeResult lowerMergeValues(MachineInstr &MI);
357 LegalizeResult lowerUnmergeValues(MachineInstr &MI);
358 LegalizeResult lowerExtractInsertVectorElt(MachineInstr &MI);
359 LegalizeResult lowerShuffleVector(MachineInstr &MI);
360 LegalizeResult lowerDynStackAlloc(MachineInstr &MI);
361 LegalizeResult lowerExtract(MachineInstr &MI);
362 LegalizeResult lowerInsert(MachineInstr &MI);
363 LegalizeResult lowerSADDO_SSUBO(MachineInstr &MI);
364 LegalizeResult lowerAddSubSatToMinMax(MachineInstr &MI);
365 LegalizeResult lowerAddSubSatToAddoSubo(MachineInstr &MI);
366 LegalizeResult lowerShlSat(MachineInstr &MI);
367 LegalizeResult lowerBswap(MachineInstr &MI);
368 LegalizeResult lowerBitreverse(MachineInstr &MI);
369 LegalizeResult lowerReadWriteRegister(MachineInstr &MI);
370 LegalizeResult lowerSMULH_UMULH(MachineInstr &MI);
371 LegalizeResult lowerSelect(MachineInstr &MI);
372
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100373};
374
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200375/// Helper function that creates a libcall to the given \p Name using the given
376/// calling convention \p CC.
377LegalizerHelper::LegalizeResult
378createLibcall(MachineIRBuilder &MIRBuilder, const char *Name,
379 const CallLowering::ArgInfo &Result,
380 ArrayRef<CallLowering::ArgInfo> Args, CallingConv::ID CC);
381
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100382/// Helper function that creates the given libcall.
383LegalizerHelper::LegalizeResult
384createLibcall(MachineIRBuilder &MIRBuilder, RTLIB::Libcall Libcall,
385 const CallLowering::ArgInfo &Result,
386 ArrayRef<CallLowering::ArgInfo> Args);
387
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200388/// Create a libcall to memcpy et al.
389LegalizerHelper::LegalizeResult createMemLibcall(MachineIRBuilder &MIRBuilder,
390 MachineRegisterInfo &MRI,
391 MachineInstr &MI);
392
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100393} // End namespace llvm.
394
395#endif