1 //== llvm/CodeGen/GlobalISel/LegalizerHelper.h ---------------- -*- C++ -*-==// 2 // 3 // 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 6 // 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_LEGALIZERHELPER_H 21 #define LLVM_CODEGEN_GLOBALISEL_LEGALIZERHELPER_H 22 23 #include "llvm/CodeGen/GlobalISel/CallLowering.h" 24 #include "llvm/CodeGen/GlobalISel/GISelKnownBits.h" 25 #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" 26 #include "llvm/CodeGen/RuntimeLibcallUtil.h" 27 #include "llvm/CodeGen/TargetOpcodes.h" 28 29 namespace llvm { 30 // Forward declarations. 31 class APInt; 32 class GAnyLoad; 33 class GLoadStore; 34 class GStore; 35 class GenericMachineInstr; 36 class MachineFunction; 37 class MachineIRBuilder; 38 class MachineInstr; 39 class MachineInstrBuilder; 40 struct MachinePointerInfo; 41 template <typename T> class SmallVectorImpl; 42 class LegalizerInfo; 43 class MachineRegisterInfo; 44 class GISelChangeObserver; 45 class LostDebugLocObserver; 46 class TargetLowering; 47 48 class LegalizerHelper { 49 public: 50 /// Expose MIRBuilder so clients can set their own RecordInsertInstruction 51 /// functions 52 MachineIRBuilder &MIRBuilder; 53 54 /// To keep track of changes made by the LegalizerHelper. 55 GISelChangeObserver &Observer; 56 57 private: 58 MachineRegisterInfo &MRI; 59 const LegalizerInfo &LI; 60 const TargetLowering &TLI; 61 GISelKnownBits *KB; 62 63 public: 64 enum LegalizeResult { 65 /// Instruction was already legal and no change was made to the 66 /// MachineFunction. 67 AlreadyLegal, 68 69 /// Instruction has been legalized and the MachineFunction changed. 70 Legalized, 71 72 /// Some kind of error has occurred and we could not legalize this 73 /// instruction. 74 UnableToLegalize, 75 }; 76 77 /// Expose LegalizerInfo so the clients can re-use. 78 const LegalizerInfo &getLegalizerInfo() const { return LI; } 79 const TargetLowering &getTargetLowering() const { return TLI; } 80 GISelKnownBits *getKnownBits() const { return KB; } 81 82 LegalizerHelper(MachineFunction &MF, GISelChangeObserver &Observer, 83 MachineIRBuilder &B); 84 LegalizerHelper(MachineFunction &MF, const LegalizerInfo &LI, 85 GISelChangeObserver &Observer, MachineIRBuilder &B, 86 GISelKnownBits *KB = nullptr); 87 88 /// Replace \p MI by a sequence of legal instructions that can implement the 89 /// same operation. Note that this means \p MI may be deleted, so any iterator 90 /// steps should be performed before calling this function. \p Helper should 91 /// be initialized to the MachineFunction containing \p MI. 92 /// 93 /// Considered as an opaque blob, the legal code will use and define the same 94 /// registers as \p MI. 95 LegalizeResult legalizeInstrStep(MachineInstr &MI, 96 LostDebugLocObserver &LocObserver); 97 98 /// Legalize an instruction by emiting a runtime library call instead. 99 LegalizeResult libcall(MachineInstr &MI, LostDebugLocObserver &LocObserver); 100 101 /// Legalize an instruction by reducing the width of the underlying scalar 102 /// type. 103 LegalizeResult narrowScalar(MachineInstr &MI, unsigned TypeIdx, LLT NarrowTy); 104 105 /// Legalize an instruction by performing the operation on a wider scalar type 106 /// (for example a 16-bit addition can be safely performed at 32-bits 107 /// precision, ignoring the unused bits). 108 LegalizeResult widenScalar(MachineInstr &MI, unsigned TypeIdx, LLT WideTy); 109 110 /// Legalize an instruction by replacing the value type 111 LegalizeResult bitcast(MachineInstr &MI, unsigned TypeIdx, LLT Ty); 112 113 /// Legalize an instruction by splitting it into simpler parts, hopefully 114 /// understood by the target. 115 LegalizeResult lower(MachineInstr &MI, unsigned TypeIdx, LLT Ty); 116 117 /// Legalize a vector instruction by splitting into multiple components, each 118 /// acting on the same scalar type as the original but with fewer elements. 119 LegalizeResult fewerElementsVector(MachineInstr &MI, unsigned TypeIdx, 120 LLT NarrowTy); 121 122 /// Legalize a vector instruction by increasing the number of vector elements 123 /// involved and ignoring the added elements later. 124 LegalizeResult moreElementsVector(MachineInstr &MI, unsigned TypeIdx, 125 LLT MoreTy); 126 127 /// Cast the given value to an LLT::scalar with an equivalent size. Returns 128 /// the register to use if an instruction was inserted. Returns the original 129 /// register if no coercion was necessary. 130 // 131 // This may also fail and return Register() if there is no legal way to cast. 132 Register coerceToScalar(Register Val); 133 134 /// Legalize a single operand \p OpIdx of the machine instruction \p MI as a 135 /// Use by extending the operand's type to \p WideTy using the specified \p 136 /// ExtOpcode for the extension instruction, and replacing the vreg of the 137 /// operand in place. 138 void widenScalarSrc(MachineInstr &MI, LLT WideTy, unsigned OpIdx, 139 unsigned ExtOpcode); 140 141 /// Legalize a single operand \p OpIdx of the machine instruction \p MI as a 142 /// Use by truncating the operand's type to \p NarrowTy using G_TRUNC, and 143 /// replacing the vreg of the operand in place. 144 void narrowScalarSrc(MachineInstr &MI, LLT NarrowTy, unsigned OpIdx); 145 146 /// Legalize a single operand \p OpIdx of the machine instruction \p MI as a 147 /// Def by extending the operand's type to \p WideTy and truncating it back 148 /// with the \p TruncOpcode, and replacing the vreg of the operand in place. 149 void widenScalarDst(MachineInstr &MI, LLT WideTy, unsigned OpIdx = 0, 150 unsigned TruncOpcode = TargetOpcode::G_TRUNC); 151 152 // Legalize a single operand \p OpIdx of the machine instruction \p MI as a 153 // Def by truncating the operand's type to \p NarrowTy, replacing in place and 154 // extending back with \p ExtOpcode. 155 void narrowScalarDst(MachineInstr &MI, LLT NarrowTy, unsigned OpIdx, 156 unsigned ExtOpcode); 157 /// Legalize a single operand \p OpIdx of the machine instruction \p MI as a 158 /// Def by performing it with additional vector elements and extracting the 159 /// result elements, and replacing the vreg of the operand in place. 160 void moreElementsVectorDst(MachineInstr &MI, LLT MoreTy, unsigned OpIdx); 161 162 /// Legalize a single operand \p OpIdx of the machine instruction \p MI as a 163 /// Use by producing a vector with undefined high elements, extracting the 164 /// original vector type, and replacing the vreg of the operand in place. 165 void moreElementsVectorSrc(MachineInstr &MI, LLT MoreTy, unsigned OpIdx); 166 167 /// Legalize a single operand \p OpIdx of the machine instruction \p MI as a 168 /// use by inserting a G_BITCAST to \p CastTy 169 void bitcastSrc(MachineInstr &MI, LLT CastTy, unsigned OpIdx); 170 171 /// Legalize a single operand \p OpIdx of the machine instruction \p MI as a 172 /// def by inserting a G_BITCAST from \p CastTy 173 void bitcastDst(MachineInstr &MI, LLT CastTy, unsigned OpIdx); 174 175 private: 176 LegalizeResult 177 widenScalarMergeValues(MachineInstr &MI, unsigned TypeIdx, LLT WideTy); 178 LegalizeResult 179 widenScalarUnmergeValues(MachineInstr &MI, unsigned TypeIdx, LLT WideTy); 180 LegalizeResult 181 widenScalarExtract(MachineInstr &MI, unsigned TypeIdx, LLT WideTy); 182 LegalizeResult 183 widenScalarInsert(MachineInstr &MI, unsigned TypeIdx, LLT WideTy); 184 LegalizeResult widenScalarAddSubOverflow(MachineInstr &MI, unsigned TypeIdx, 185 LLT WideTy); 186 LegalizeResult widenScalarAddSubShlSat(MachineInstr &MI, unsigned TypeIdx, 187 LLT WideTy); 188 LegalizeResult widenScalarMulo(MachineInstr &MI, unsigned TypeIdx, 189 LLT WideTy); 190 191 /// Helper function to build a wide generic register \p DstReg of type \p 192 /// RegTy from smaller parts. This will produce a G_MERGE_VALUES, 193 /// G_BUILD_VECTOR, G_CONCAT_VECTORS, or sequence of G_INSERT as appropriate 194 /// for the types. 195 /// 196 /// \p PartRegs must be registers of type \p PartTy. 197 /// 198 /// If \p ResultTy does not evenly break into \p PartTy sized pieces, the 199 /// remainder must be specified with \p LeftoverRegs of type \p LeftoverTy. 200 void insertParts(Register DstReg, LLT ResultTy, 201 LLT PartTy, ArrayRef<Register> PartRegs, 202 LLT LeftoverTy = LLT(), ArrayRef<Register> LeftoverRegs = {}); 203 204 /// Merge \p PartRegs with different types into \p DstReg. 205 void mergeMixedSubvectors(Register DstReg, ArrayRef<Register> PartRegs); 206 207 void appendVectorElts(SmallVectorImpl<Register> &Elts, Register Reg); 208 209 /// Unmerge \p SrcReg into smaller sized values, and append them to \p 210 /// Parts. The elements of \p Parts will be the greatest common divisor type 211 /// of \p DstTy, \p NarrowTy and the type of \p SrcReg. This will compute and 212 /// return the GCD type. 213 LLT extractGCDType(SmallVectorImpl<Register> &Parts, LLT DstTy, 214 LLT NarrowTy, Register SrcReg); 215 216 /// Unmerge \p SrcReg into \p GCDTy typed registers. This will append all of 217 /// the unpacked registers to \p Parts. This version is if the common unmerge 218 /// type is already known. 219 void extractGCDType(SmallVectorImpl<Register> &Parts, LLT GCDTy, 220 Register SrcReg); 221 222 /// Produce a merge of values in \p VRegs to define \p DstReg. Perform a merge 223 /// from the least common multiple type, and convert as appropriate to \p 224 /// DstReg. 225 /// 226 /// \p VRegs should each have type \p GCDTy. This type should be greatest 227 /// common divisor type of \p DstReg, \p NarrowTy, and an undetermined source 228 /// type. 229 /// 230 /// \p NarrowTy is the desired result merge source type. If the source value 231 /// needs to be widened to evenly cover \p DstReg, inserts high bits 232 /// corresponding to the extension opcode \p PadStrategy. 233 /// 234 /// \p VRegs will be cleared, and the result \p NarrowTy register pieces 235 /// will replace it. Returns The complete LCMTy that \p VRegs will cover when 236 /// merged. 237 LLT buildLCMMergePieces(LLT DstTy, LLT NarrowTy, LLT GCDTy, 238 SmallVectorImpl<Register> &VRegs, 239 unsigned PadStrategy = TargetOpcode::G_ANYEXT); 240 241 /// Merge the values in \p RemergeRegs to an \p LCMTy typed value. Extract the 242 /// low bits into \p DstReg. This is intended to use the outputs from 243 /// buildLCMMergePieces after processing. 244 void buildWidenedRemergeToDst(Register DstReg, LLT LCMTy, 245 ArrayRef<Register> RemergeRegs); 246 247 /// Perform generic multiplication of values held in multiple registers. 248 /// Generated instructions use only types NarrowTy and i1. 249 /// Destination can be same or two times size of the source. 250 void multiplyRegisters(SmallVectorImpl<Register> &DstRegs, 251 ArrayRef<Register> Src1Regs, 252 ArrayRef<Register> Src2Regs, LLT NarrowTy); 253 254 void changeOpcode(MachineInstr &MI, unsigned NewOpcode); 255 256 LegalizeResult tryNarrowPow2Reduction(MachineInstr &MI, Register SrcReg, 257 LLT SrcTy, LLT NarrowTy, 258 unsigned ScalarOpc); 259 260 // Memcpy family legalization helpers. 261 LegalizeResult lowerMemset(MachineInstr &MI, Register Dst, Register Val, 262 uint64_t KnownLen, Align Alignment, 263 bool IsVolatile); 264 LegalizeResult lowerMemcpyInline(MachineInstr &MI, Register Dst, Register Src, 265 uint64_t KnownLen, Align DstAlign, 266 Align SrcAlign, bool IsVolatile); 267 LegalizeResult lowerMemcpy(MachineInstr &MI, Register Dst, Register Src, 268 uint64_t KnownLen, uint64_t Limit, Align DstAlign, 269 Align SrcAlign, bool IsVolatile); 270 LegalizeResult lowerMemmove(MachineInstr &MI, Register Dst, Register Src, 271 uint64_t KnownLen, Align DstAlign, Align SrcAlign, 272 bool IsVolatile); 273 274 // Implements floating-point environment read/write via library function call. 275 LegalizeResult createGetStateLibcall(MachineIRBuilder &MIRBuilder, 276 MachineInstr &MI, 277 LostDebugLocObserver &LocObserver); 278 LegalizeResult createSetStateLibcall(MachineIRBuilder &MIRBuilder, 279 MachineInstr &MI, 280 LostDebugLocObserver &LocObserver); 281 LegalizeResult createResetStateLibcall(MachineIRBuilder &MIRBuilder, 282 MachineInstr &MI, 283 LostDebugLocObserver &LocObserver); 284 LegalizeResult createFCMPLibcall(MachineIRBuilder &MIRBuilder, 285 MachineInstr &MI, 286 LostDebugLocObserver &LocObserver); 287 288 MachineInstrBuilder 289 getNeutralElementForVecReduce(unsigned Opcode, MachineIRBuilder &MIRBuilder, 290 LLT Ty); 291 292 public: 293 /// Return the alignment to use for a stack temporary object with the given 294 /// type. 295 Align getStackTemporaryAlignment(LLT Type, Align MinAlign = Align()) const; 296 297 /// Create a stack temporary based on the size in bytes and the alignment 298 MachineInstrBuilder createStackTemporary(TypeSize Bytes, Align Alignment, 299 MachinePointerInfo &PtrInfo); 300 301 /// Create a store of \p Val to a stack temporary and return a load as the 302 /// same type as \p Res. 303 MachineInstrBuilder createStackStoreLoad(const DstOp &Res, const SrcOp &Val); 304 305 /// Given a store of a boolean vector, scalarize it. 306 LegalizeResult scalarizeVectorBooleanStore(GStore &MI); 307 308 /// Get a pointer to vector element \p Index located in memory for a vector of 309 /// type \p VecTy starting at a base address of \p VecPtr. If \p Index is out 310 /// of bounds the returned pointer is unspecified, but will be within the 311 /// vector bounds. 312 Register getVectorElementPointer(Register VecPtr, LLT VecTy, Register Index); 313 314 /// Handles most opcodes. Split \p MI into same instruction on sub-vectors or 315 /// scalars with \p NumElts elements (1 for scalar). Supports uneven splits: 316 /// there can be leftover sub-vector with fewer then \p NumElts or a leftover 317 /// scalar. To avoid this use moreElements first and set MI number of elements 318 /// to multiple of \p NumElts. Non-vector operands that should be used on all 319 /// sub-instructions without split are listed in \p NonVecOpIndices. 320 LegalizeResult fewerElementsVectorMultiEltType( 321 GenericMachineInstr &MI, unsigned NumElts, 322 std::initializer_list<unsigned> NonVecOpIndices = {}); 323 324 LegalizeResult fewerElementsVectorPhi(GenericMachineInstr &MI, 325 unsigned NumElts); 326 327 LegalizeResult moreElementsVectorPhi(MachineInstr &MI, unsigned TypeIdx, 328 LLT MoreTy); 329 LegalizeResult moreElementsVectorShuffle(MachineInstr &MI, unsigned TypeIdx, 330 LLT MoreTy); 331 332 LegalizeResult fewerElementsVectorUnmergeValues(MachineInstr &MI, 333 unsigned TypeIdx, 334 LLT NarrowTy); 335 LegalizeResult fewerElementsVectorMerge(MachineInstr &MI, unsigned TypeIdx, 336 LLT NarrowTy); 337 LegalizeResult fewerElementsVectorExtractInsertVectorElt(MachineInstr &MI, 338 unsigned TypeIdx, 339 LLT NarrowTy); 340 341 /// Equalize source and destination vector sizes of G_SHUFFLE_VECTOR. 342 LegalizeResult equalizeVectorShuffleLengths(MachineInstr &MI); 343 344 LegalizeResult reduceLoadStoreWidth(GLoadStore &MI, unsigned TypeIdx, 345 LLT NarrowTy); 346 347 LegalizeResult narrowScalarShiftByConstant(MachineInstr &MI, const APInt &Amt, 348 LLT HalfTy, LLT ShiftAmtTy); 349 350 LegalizeResult fewerElementsVectorReductions(MachineInstr &MI, 351 unsigned TypeIdx, LLT NarrowTy); 352 LegalizeResult fewerElementsVectorSeqReductions(MachineInstr &MI, 353 unsigned TypeIdx, 354 LLT NarrowTy); 355 356 // Fewer Elements for bitcast, ensuring that the size of the Src and Dst 357 // registers will be the same 358 LegalizeResult fewerElementsBitcast(MachineInstr &MI, unsigned TypeIdx, 359 LLT NarrowTy); 360 361 LegalizeResult fewerElementsVectorShuffle(MachineInstr &MI, unsigned TypeIdx, 362 LLT NarrowTy); 363 364 LegalizeResult narrowScalarShift(MachineInstr &MI, unsigned TypeIdx, LLT Ty); 365 LegalizeResult narrowScalarAddSub(MachineInstr &MI, unsigned TypeIdx, 366 LLT NarrowTy); 367 LegalizeResult narrowScalarMul(MachineInstr &MI, LLT Ty); 368 LegalizeResult narrowScalarFPTOI(MachineInstr &MI, unsigned TypeIdx, LLT Ty); 369 LegalizeResult narrowScalarExtract(MachineInstr &MI, unsigned TypeIdx, LLT Ty); 370 LegalizeResult narrowScalarInsert(MachineInstr &MI, unsigned TypeIdx, LLT Ty); 371 372 LegalizeResult narrowScalarBasic(MachineInstr &MI, unsigned TypeIdx, LLT Ty); 373 LegalizeResult narrowScalarExt(MachineInstr &MI, unsigned TypeIdx, LLT Ty); 374 LegalizeResult narrowScalarSelect(MachineInstr &MI, unsigned TypeIdx, LLT Ty); 375 LegalizeResult narrowScalarCTLZ(MachineInstr &MI, unsigned TypeIdx, LLT Ty); 376 LegalizeResult narrowScalarCTTZ(MachineInstr &MI, unsigned TypeIdx, LLT Ty); 377 LegalizeResult narrowScalarCTPOP(MachineInstr &MI, unsigned TypeIdx, LLT Ty); 378 LegalizeResult narrowScalarFLDEXP(MachineInstr &MI, unsigned TypeIdx, LLT Ty); 379 380 /// Perform Bitcast legalize action on G_EXTRACT_VECTOR_ELT. 381 LegalizeResult bitcastExtractVectorElt(MachineInstr &MI, unsigned TypeIdx, 382 LLT CastTy); 383 384 /// Perform Bitcast legalize action on G_INSERT_VECTOR_ELT. 385 LegalizeResult bitcastInsertVectorElt(MachineInstr &MI, unsigned TypeIdx, 386 LLT CastTy); 387 LegalizeResult bitcastConcatVector(MachineInstr &MI, unsigned TypeIdx, 388 LLT CastTy); 389 LegalizeResult bitcastShuffleVector(MachineInstr &MI, unsigned TypeIdx, 390 LLT CastTy); 391 LegalizeResult bitcastExtractSubvector(MachineInstr &MI, unsigned TypeIdx, 392 LLT CastTy); 393 LegalizeResult bitcastInsertSubvector(MachineInstr &MI, unsigned TypeIdx, 394 LLT CastTy); 395 396 LegalizeResult lowerConstant(MachineInstr &MI); 397 LegalizeResult lowerFConstant(MachineInstr &MI); 398 LegalizeResult lowerBitcast(MachineInstr &MI); 399 LegalizeResult lowerLoad(GAnyLoad &MI); 400 LegalizeResult lowerStore(GStore &MI); 401 LegalizeResult lowerBitCount(MachineInstr &MI); 402 LegalizeResult lowerFunnelShiftWithInverse(MachineInstr &MI); 403 LegalizeResult lowerFunnelShiftAsShifts(MachineInstr &MI); 404 LegalizeResult lowerFunnelShift(MachineInstr &MI); 405 LegalizeResult lowerEXT(MachineInstr &MI); 406 LegalizeResult lowerTRUNC(MachineInstr &MI); 407 LegalizeResult lowerRotateWithReverseRotate(MachineInstr &MI); 408 LegalizeResult lowerRotate(MachineInstr &MI); 409 410 LegalizeResult lowerU64ToF32BitOps(MachineInstr &MI); 411 LegalizeResult lowerU64ToF32WithSITOFP(MachineInstr &MI); 412 LegalizeResult lowerU64ToF64BitFloatOps(MachineInstr &MI); 413 LegalizeResult lowerUITOFP(MachineInstr &MI); 414 LegalizeResult lowerSITOFP(MachineInstr &MI); 415 LegalizeResult lowerFPTOUI(MachineInstr &MI); 416 LegalizeResult lowerFPTOSI(MachineInstr &MI); 417 LegalizeResult lowerFPTOINT_SAT(MachineInstr &MI); 418 419 LegalizeResult lowerFPTRUNC_F64_TO_F16(MachineInstr &MI); 420 LegalizeResult lowerFPTRUNC(MachineInstr &MI); 421 LegalizeResult lowerFPOWI(MachineInstr &MI); 422 423 LegalizeResult lowerISFPCLASS(MachineInstr &MI); 424 425 LegalizeResult lowerThreewayCompare(MachineInstr &MI); 426 LegalizeResult lowerMinMax(MachineInstr &MI); 427 LegalizeResult lowerFCopySign(MachineInstr &MI); 428 LegalizeResult lowerFMinNumMaxNum(MachineInstr &MI); 429 LegalizeResult lowerFMad(MachineInstr &MI); 430 LegalizeResult lowerIntrinsicRound(MachineInstr &MI); 431 LegalizeResult lowerFFloor(MachineInstr &MI); 432 LegalizeResult lowerMergeValues(MachineInstr &MI); 433 LegalizeResult lowerUnmergeValues(MachineInstr &MI); 434 LegalizeResult lowerExtractInsertVectorElt(MachineInstr &MI); 435 LegalizeResult lowerShuffleVector(MachineInstr &MI); 436 LegalizeResult lowerVECTOR_COMPRESS(MachineInstr &MI); 437 Register getDynStackAllocTargetPtr(Register SPReg, Register AllocSize, 438 Align Alignment, LLT PtrTy); 439 LegalizeResult lowerDynStackAlloc(MachineInstr &MI); 440 LegalizeResult lowerStackSave(MachineInstr &MI); 441 LegalizeResult lowerStackRestore(MachineInstr &MI); 442 LegalizeResult lowerExtract(MachineInstr &MI); 443 LegalizeResult lowerInsert(MachineInstr &MI); 444 LegalizeResult lowerSADDO_SSUBO(MachineInstr &MI); 445 LegalizeResult lowerAddSubSatToMinMax(MachineInstr &MI); 446 LegalizeResult lowerAddSubSatToAddoSubo(MachineInstr &MI); 447 LegalizeResult lowerShlSat(MachineInstr &MI); 448 LegalizeResult lowerBswap(MachineInstr &MI); 449 LegalizeResult lowerBitreverse(MachineInstr &MI); 450 LegalizeResult lowerReadWriteRegister(MachineInstr &MI); 451 LegalizeResult lowerSMULH_UMULH(MachineInstr &MI); 452 LegalizeResult lowerSelect(MachineInstr &MI); 453 LegalizeResult lowerDIVREM(MachineInstr &MI); 454 LegalizeResult lowerAbsToAddXor(MachineInstr &MI); 455 LegalizeResult lowerAbsToMaxNeg(MachineInstr &MI); 456 LegalizeResult lowerAbsToCNeg(MachineInstr &MI); 457 LegalizeResult lowerFAbs(MachineInstr &MI); 458 LegalizeResult lowerVectorReduction(MachineInstr &MI); 459 LegalizeResult lowerMemcpyInline(MachineInstr &MI); 460 LegalizeResult lowerMemCpyFamily(MachineInstr &MI, unsigned MaxLen = 0); 461 LegalizeResult lowerVAArg(MachineInstr &MI); 462 }; 463 464 /// Helper function that creates a libcall to the given \p Name using the given 465 /// calling convention \p CC. 466 LegalizerHelper::LegalizeResult 467 createLibcall(MachineIRBuilder &MIRBuilder, const char *Name, 468 const CallLowering::ArgInfo &Result, 469 ArrayRef<CallLowering::ArgInfo> Args, CallingConv::ID CC, 470 LostDebugLocObserver &LocObserver, MachineInstr *MI = nullptr); 471 472 /// Helper function that creates the given libcall. 473 LegalizerHelper::LegalizeResult 474 createLibcall(MachineIRBuilder &MIRBuilder, RTLIB::Libcall Libcall, 475 const CallLowering::ArgInfo &Result, 476 ArrayRef<CallLowering::ArgInfo> Args, 477 LostDebugLocObserver &LocObserver, MachineInstr *MI = nullptr); 478 479 /// Create a libcall to memcpy et al. 480 LegalizerHelper::LegalizeResult 481 createMemLibcall(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI, 482 MachineInstr &MI, LostDebugLocObserver &LocObserver); 483 484 485 } // End namespace llvm. 486 487 #endif 488