1 //===-- llvm/CodeGen/GlobalISel/LegalizerHelper.cpp -----------------------===//
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 This file implements the LegalizerHelper class to legalize
10 /// individual instructions and the LegalizeMachineIR wrapper pass for the
11 /// primary legalization.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #include "llvm/CodeGen/GlobalISel/LegalizerHelper.h"
16 #include "llvm/CodeGen/GlobalISel/CallLowering.h"
17 #include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h"
18 #include "llvm/CodeGen/GlobalISel/GISelKnownBits.h"
19 #include "llvm/CodeGen/GlobalISel/GenericMachineInstrs.h"
20 #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
21 #include "llvm/CodeGen/GlobalISel/LostDebugLocObserver.h"
22 #include "llvm/CodeGen/GlobalISel/MIPatternMatch.h"
23 #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
24 #include "llvm/CodeGen/GlobalISel/Utils.h"
25 #include "llvm/CodeGen/MachineConstantPool.h"
26 #include "llvm/CodeGen/MachineFrameInfo.h"
27 #include "llvm/CodeGen/MachineRegisterInfo.h"
28 #include "llvm/CodeGen/RuntimeLibcalls.h"
29 #include "llvm/CodeGen/TargetFrameLowering.h"
30 #include "llvm/CodeGen/TargetInstrInfo.h"
31 #include "llvm/CodeGen/TargetLowering.h"
32 #include "llvm/CodeGen/TargetOpcodes.h"
33 #include "llvm/CodeGen/TargetSubtargetInfo.h"
34 #include "llvm/IR/Instructions.h"
35 #include "llvm/Support/Debug.h"
36 #include "llvm/Support/MathExtras.h"
37 #include "llvm/Support/raw_ostream.h"
38 #include "llvm/Target/TargetMachine.h"
39 #include <numeric>
40 #include <optional>
41 
42 #define DEBUG_TYPE "legalizer"
43 
44 using namespace llvm;
45 using namespace LegalizeActions;
46 using namespace MIPatternMatch;
47 
48 /// Try to break down \p OrigTy into \p NarrowTy sized pieces.
49 ///
50 /// Returns the number of \p NarrowTy elements needed to reconstruct \p OrigTy,
51 /// with any leftover piece as type \p LeftoverTy
52 ///
53 /// Returns -1 in the first element of the pair if the breakdown is not
54 /// satisfiable.
55 static std::pair<int, int>
56 getNarrowTypeBreakDown(LLT OrigTy, LLT NarrowTy, LLT &LeftoverTy) {
57   assert(!LeftoverTy.isValid() && "this is an out argument");
58 
59   unsigned Size = OrigTy.getSizeInBits();
60   unsigned NarrowSize = NarrowTy.getSizeInBits();
61   unsigned NumParts = Size / NarrowSize;
62   unsigned LeftoverSize = Size - NumParts * NarrowSize;
63   assert(Size > NarrowSize);
64 
65   if (LeftoverSize == 0)
66     return {NumParts, 0};
67 
68   if (NarrowTy.isVector()) {
69     unsigned EltSize = OrigTy.getScalarSizeInBits();
70     if (LeftoverSize % EltSize != 0)
71       return {-1, -1};
72     LeftoverTy = LLT::scalarOrVector(
73         ElementCount::getFixed(LeftoverSize / EltSize), EltSize);
74   } else {
75     LeftoverTy = LLT::scalar(LeftoverSize);
76   }
77 
78   int NumLeftover = LeftoverSize / LeftoverTy.getSizeInBits();
79   return std::make_pair(NumParts, NumLeftover);
80 }
81 
82 static Type *getFloatTypeForLLT(LLVMContext &Ctx, LLT Ty) {
83 
84   if (!Ty.isScalar())
85     return nullptr;
86 
87   switch (Ty.getSizeInBits()) {
88   case 16:
89     return Type::getHalfTy(Ctx);
90   case 32:
91     return Type::getFloatTy(Ctx);
92   case 64:
93     return Type::getDoubleTy(Ctx);
94   case 80:
95     return Type::getX86_FP80Ty(Ctx);
96   case 128:
97     return Type::getFP128Ty(Ctx);
98   default:
99     return nullptr;
100   }
101 }
102 
103 LegalizerHelper::LegalizerHelper(MachineFunction &MF,
104                                  GISelChangeObserver &Observer,
105                                  MachineIRBuilder &Builder)
106     : MIRBuilder(Builder), Observer(Observer), MRI(MF.getRegInfo()),
107       LI(*MF.getSubtarget().getLegalizerInfo()),
108       TLI(*MF.getSubtarget().getTargetLowering()), KB(nullptr) {}
109 
110 LegalizerHelper::LegalizerHelper(MachineFunction &MF, const LegalizerInfo &LI,
111                                  GISelChangeObserver &Observer,
112                                  MachineIRBuilder &B, GISelKnownBits *KB)
113     : MIRBuilder(B), Observer(Observer), MRI(MF.getRegInfo()), LI(LI),
114       TLI(*MF.getSubtarget().getTargetLowering()), KB(KB) {}
115 
116 LegalizerHelper::LegalizeResult
117 LegalizerHelper::legalizeInstrStep(MachineInstr &MI,
118                                    LostDebugLocObserver &LocObserver) {
119   LLVM_DEBUG(dbgs() << "Legalizing: " << MI);
120 
121   MIRBuilder.setInstrAndDebugLoc(MI);
122 
123   if (isa<GIntrinsic>(MI))
124     return LI.legalizeIntrinsic(*this, MI) ? Legalized : UnableToLegalize;
125   auto Step = LI.getAction(MI, MRI);
126   switch (Step.Action) {
127   case Legal:
128     LLVM_DEBUG(dbgs() << ".. Already legal\n");
129     return AlreadyLegal;
130   case Libcall:
131     LLVM_DEBUG(dbgs() << ".. Convert to libcall\n");
132     return libcall(MI, LocObserver);
133   case NarrowScalar:
134     LLVM_DEBUG(dbgs() << ".. Narrow scalar\n");
135     return narrowScalar(MI, Step.TypeIdx, Step.NewType);
136   case WidenScalar:
137     LLVM_DEBUG(dbgs() << ".. Widen scalar\n");
138     return widenScalar(MI, Step.TypeIdx, Step.NewType);
139   case Bitcast:
140     LLVM_DEBUG(dbgs() << ".. Bitcast type\n");
141     return bitcast(MI, Step.TypeIdx, Step.NewType);
142   case Lower:
143     LLVM_DEBUG(dbgs() << ".. Lower\n");
144     return lower(MI, Step.TypeIdx, Step.NewType);
145   case FewerElements:
146     LLVM_DEBUG(dbgs() << ".. Reduce number of elements\n");
147     return fewerElementsVector(MI, Step.TypeIdx, Step.NewType);
148   case MoreElements:
149     LLVM_DEBUG(dbgs() << ".. Increase number of elements\n");
150     return moreElementsVector(MI, Step.TypeIdx, Step.NewType);
151   case Custom:
152     LLVM_DEBUG(dbgs() << ".. Custom legalization\n");
153     return LI.legalizeCustom(*this, MI, LocObserver) ? Legalized
154                                                      : UnableToLegalize;
155   default:
156     LLVM_DEBUG(dbgs() << ".. Unable to legalize\n");
157     return UnableToLegalize;
158   }
159 }
160 
161 void LegalizerHelper::extractParts(Register Reg, LLT Ty, int NumParts,
162                                    SmallVectorImpl<Register> &VRegs) {
163   for (int i = 0; i < NumParts; ++i)
164     VRegs.push_back(MRI.createGenericVirtualRegister(Ty));
165   MIRBuilder.buildUnmerge(VRegs, Reg);
166 }
167 
168 bool LegalizerHelper::extractParts(Register Reg, LLT RegTy,
169                                    LLT MainTy, LLT &LeftoverTy,
170                                    SmallVectorImpl<Register> &VRegs,
171                                    SmallVectorImpl<Register> &LeftoverRegs) {
172   assert(!LeftoverTy.isValid() && "this is an out argument");
173 
174   unsigned RegSize = RegTy.getSizeInBits();
175   unsigned MainSize = MainTy.getSizeInBits();
176   unsigned NumParts = RegSize / MainSize;
177   unsigned LeftoverSize = RegSize - NumParts * MainSize;
178 
179   // Use an unmerge when possible.
180   if (LeftoverSize == 0) {
181     for (unsigned I = 0; I < NumParts; ++I)
182       VRegs.push_back(MRI.createGenericVirtualRegister(MainTy));
183     MIRBuilder.buildUnmerge(VRegs, Reg);
184     return true;
185   }
186 
187   // Perform irregular split. Leftover is last element of RegPieces.
188   if (MainTy.isVector()) {
189     SmallVector<Register, 8> RegPieces;
190     extractVectorParts(Reg, MainTy.getNumElements(), RegPieces);
191     for (unsigned i = 0; i < RegPieces.size() - 1; ++i)
192       VRegs.push_back(RegPieces[i]);
193     LeftoverRegs.push_back(RegPieces[RegPieces.size() - 1]);
194     LeftoverTy = MRI.getType(LeftoverRegs[0]);
195     return true;
196   }
197 
198   LeftoverTy = LLT::scalar(LeftoverSize);
199   // For irregular sizes, extract the individual parts.
200   for (unsigned I = 0; I != NumParts; ++I) {
201     Register NewReg = MRI.createGenericVirtualRegister(MainTy);
202     VRegs.push_back(NewReg);
203     MIRBuilder.buildExtract(NewReg, Reg, MainSize * I);
204   }
205 
206   for (unsigned Offset = MainSize * NumParts; Offset < RegSize;
207        Offset += LeftoverSize) {
208     Register NewReg = MRI.createGenericVirtualRegister(LeftoverTy);
209     LeftoverRegs.push_back(NewReg);
210     MIRBuilder.buildExtract(NewReg, Reg, Offset);
211   }
212 
213   return true;
214 }
215 
216 void LegalizerHelper::extractVectorParts(Register Reg, unsigned NumElts,
217                                          SmallVectorImpl<Register> &VRegs) {
218   LLT RegTy = MRI.getType(Reg);
219   assert(RegTy.isVector() && "Expected a vector type");
220 
221   LLT EltTy = RegTy.getElementType();
222   LLT NarrowTy = (NumElts == 1) ? EltTy : LLT::fixed_vector(NumElts, EltTy);
223   unsigned RegNumElts = RegTy.getNumElements();
224   unsigned LeftoverNumElts = RegNumElts % NumElts;
225   unsigned NumNarrowTyPieces = RegNumElts / NumElts;
226 
227   // Perfect split without leftover
228   if (LeftoverNumElts == 0)
229     return extractParts(Reg, NarrowTy, NumNarrowTyPieces, VRegs);
230 
231   // Irregular split. Provide direct access to all elements for artifact
232   // combiner using unmerge to elements. Then build vectors with NumElts
233   // elements. Remaining element(s) will be (used to build vector) Leftover.
234   SmallVector<Register, 8> Elts;
235   extractParts(Reg, EltTy, RegNumElts, Elts);
236 
237   unsigned Offset = 0;
238   // Requested sub-vectors of NarrowTy.
239   for (unsigned i = 0; i < NumNarrowTyPieces; ++i, Offset += NumElts) {
240     ArrayRef<Register> Pieces(&Elts[Offset], NumElts);
241     VRegs.push_back(MIRBuilder.buildMergeLikeInstr(NarrowTy, Pieces).getReg(0));
242   }
243 
244   // Leftover element(s).
245   if (LeftoverNumElts == 1) {
246     VRegs.push_back(Elts[Offset]);
247   } else {
248     LLT LeftoverTy = LLT::fixed_vector(LeftoverNumElts, EltTy);
249     ArrayRef<Register> Pieces(&Elts[Offset], LeftoverNumElts);
250     VRegs.push_back(
251         MIRBuilder.buildMergeLikeInstr(LeftoverTy, Pieces).getReg(0));
252   }
253 }
254 
255 void LegalizerHelper::insertParts(Register DstReg,
256                                   LLT ResultTy, LLT PartTy,
257                                   ArrayRef<Register> PartRegs,
258                                   LLT LeftoverTy,
259                                   ArrayRef<Register> LeftoverRegs) {
260   if (!LeftoverTy.isValid()) {
261     assert(LeftoverRegs.empty());
262 
263     if (!ResultTy.isVector()) {
264       MIRBuilder.buildMergeLikeInstr(DstReg, PartRegs);
265       return;
266     }
267 
268     if (PartTy.isVector())
269       MIRBuilder.buildConcatVectors(DstReg, PartRegs);
270     else
271       MIRBuilder.buildBuildVector(DstReg, PartRegs);
272     return;
273   }
274 
275   // Merge sub-vectors with different number of elements and insert into DstReg.
276   if (ResultTy.isVector()) {
277     assert(LeftoverRegs.size() == 1 && "Expected one leftover register");
278     SmallVector<Register, 8> AllRegs;
279     for (auto Reg : concat<const Register>(PartRegs, LeftoverRegs))
280       AllRegs.push_back(Reg);
281     return mergeMixedSubvectors(DstReg, AllRegs);
282   }
283 
284   SmallVector<Register> GCDRegs;
285   LLT GCDTy = getGCDType(getGCDType(ResultTy, LeftoverTy), PartTy);
286   for (auto PartReg : concat<const Register>(PartRegs, LeftoverRegs))
287     extractGCDType(GCDRegs, GCDTy, PartReg);
288   LLT ResultLCMTy = buildLCMMergePieces(ResultTy, LeftoverTy, GCDTy, GCDRegs);
289   buildWidenedRemergeToDst(DstReg, ResultLCMTy, GCDRegs);
290 }
291 
292 void LegalizerHelper::appendVectorElts(SmallVectorImpl<Register> &Elts,
293                                        Register Reg) {
294   LLT Ty = MRI.getType(Reg);
295   SmallVector<Register, 8> RegElts;
296   extractParts(Reg, Ty.getScalarType(), Ty.getNumElements(), RegElts);
297   Elts.append(RegElts);
298 }
299 
300 /// Merge \p PartRegs with different types into \p DstReg.
301 void LegalizerHelper::mergeMixedSubvectors(Register DstReg,
302                                            ArrayRef<Register> PartRegs) {
303   SmallVector<Register, 8> AllElts;
304   for (unsigned i = 0; i < PartRegs.size() - 1; ++i)
305     appendVectorElts(AllElts, PartRegs[i]);
306 
307   Register Leftover = PartRegs[PartRegs.size() - 1];
308   if (MRI.getType(Leftover).isScalar())
309     AllElts.push_back(Leftover);
310   else
311     appendVectorElts(AllElts, Leftover);
312 
313   MIRBuilder.buildMergeLikeInstr(DstReg, AllElts);
314 }
315 
316 /// Append the result registers of G_UNMERGE_VALUES \p MI to \p Regs.
317 static void getUnmergeResults(SmallVectorImpl<Register> &Regs,
318                               const MachineInstr &MI) {
319   assert(MI.getOpcode() == TargetOpcode::G_UNMERGE_VALUES);
320 
321   const int StartIdx = Regs.size();
322   const int NumResults = MI.getNumOperands() - 1;
323   Regs.resize(Regs.size() + NumResults);
324   for (int I = 0; I != NumResults; ++I)
325     Regs[StartIdx + I] = MI.getOperand(I).getReg();
326 }
327 
328 void LegalizerHelper::extractGCDType(SmallVectorImpl<Register> &Parts,
329                                      LLT GCDTy, Register SrcReg) {
330   LLT SrcTy = MRI.getType(SrcReg);
331   if (SrcTy == GCDTy) {
332     // If the source already evenly divides the result type, we don't need to do
333     // anything.
334     Parts.push_back(SrcReg);
335   } else {
336     // Need to split into common type sized pieces.
337     auto Unmerge = MIRBuilder.buildUnmerge(GCDTy, SrcReg);
338     getUnmergeResults(Parts, *Unmerge);
339   }
340 }
341 
342 LLT LegalizerHelper::extractGCDType(SmallVectorImpl<Register> &Parts, LLT DstTy,
343                                     LLT NarrowTy, Register SrcReg) {
344   LLT SrcTy = MRI.getType(SrcReg);
345   LLT GCDTy = getGCDType(getGCDType(SrcTy, NarrowTy), DstTy);
346   extractGCDType(Parts, GCDTy, SrcReg);
347   return GCDTy;
348 }
349 
350 LLT LegalizerHelper::buildLCMMergePieces(LLT DstTy, LLT NarrowTy, LLT GCDTy,
351                                          SmallVectorImpl<Register> &VRegs,
352                                          unsigned PadStrategy) {
353   LLT LCMTy = getLCMType(DstTy, NarrowTy);
354 
355   int NumParts = LCMTy.getSizeInBits() / NarrowTy.getSizeInBits();
356   int NumSubParts = NarrowTy.getSizeInBits() / GCDTy.getSizeInBits();
357   int NumOrigSrc = VRegs.size();
358 
359   Register PadReg;
360 
361   // Get a value we can use to pad the source value if the sources won't evenly
362   // cover the result type.
363   if (NumOrigSrc < NumParts * NumSubParts) {
364     if (PadStrategy == TargetOpcode::G_ZEXT)
365       PadReg = MIRBuilder.buildConstant(GCDTy, 0).getReg(0);
366     else if (PadStrategy == TargetOpcode::G_ANYEXT)
367       PadReg = MIRBuilder.buildUndef(GCDTy).getReg(0);
368     else {
369       assert(PadStrategy == TargetOpcode::G_SEXT);
370 
371       // Shift the sign bit of the low register through the high register.
372       auto ShiftAmt =
373         MIRBuilder.buildConstant(LLT::scalar(64), GCDTy.getSizeInBits() - 1);
374       PadReg = MIRBuilder.buildAShr(GCDTy, VRegs.back(), ShiftAmt).getReg(0);
375     }
376   }
377 
378   // Registers for the final merge to be produced.
379   SmallVector<Register, 4> Remerge(NumParts);
380 
381   // Registers needed for intermediate merges, which will be merged into a
382   // source for Remerge.
383   SmallVector<Register, 4> SubMerge(NumSubParts);
384 
385   // Once we've fully read off the end of the original source bits, we can reuse
386   // the same high bits for remaining padding elements.
387   Register AllPadReg;
388 
389   // Build merges to the LCM type to cover the original result type.
390   for (int I = 0; I != NumParts; ++I) {
391     bool AllMergePartsArePadding = true;
392 
393     // Build the requested merges to the requested type.
394     for (int J = 0; J != NumSubParts; ++J) {
395       int Idx = I * NumSubParts + J;
396       if (Idx >= NumOrigSrc) {
397         SubMerge[J] = PadReg;
398         continue;
399       }
400 
401       SubMerge[J] = VRegs[Idx];
402 
403       // There are meaningful bits here we can't reuse later.
404       AllMergePartsArePadding = false;
405     }
406 
407     // If we've filled up a complete piece with padding bits, we can directly
408     // emit the natural sized constant if applicable, rather than a merge of
409     // smaller constants.
410     if (AllMergePartsArePadding && !AllPadReg) {
411       if (PadStrategy == TargetOpcode::G_ANYEXT)
412         AllPadReg = MIRBuilder.buildUndef(NarrowTy).getReg(0);
413       else if (PadStrategy == TargetOpcode::G_ZEXT)
414         AllPadReg = MIRBuilder.buildConstant(NarrowTy, 0).getReg(0);
415 
416       // If this is a sign extension, we can't materialize a trivial constant
417       // with the right type and have to produce a merge.
418     }
419 
420     if (AllPadReg) {
421       // Avoid creating additional instructions if we're just adding additional
422       // copies of padding bits.
423       Remerge[I] = AllPadReg;
424       continue;
425     }
426 
427     if (NumSubParts == 1)
428       Remerge[I] = SubMerge[0];
429     else
430       Remerge[I] = MIRBuilder.buildMergeLikeInstr(NarrowTy, SubMerge).getReg(0);
431 
432     // In the sign extend padding case, re-use the first all-signbit merge.
433     if (AllMergePartsArePadding && !AllPadReg)
434       AllPadReg = Remerge[I];
435   }
436 
437   VRegs = std::move(Remerge);
438   return LCMTy;
439 }
440 
441 void LegalizerHelper::buildWidenedRemergeToDst(Register DstReg, LLT LCMTy,
442                                                ArrayRef<Register> RemergeRegs) {
443   LLT DstTy = MRI.getType(DstReg);
444 
445   // Create the merge to the widened source, and extract the relevant bits into
446   // the result.
447 
448   if (DstTy == LCMTy) {
449     MIRBuilder.buildMergeLikeInstr(DstReg, RemergeRegs);
450     return;
451   }
452 
453   auto Remerge = MIRBuilder.buildMergeLikeInstr(LCMTy, RemergeRegs);
454   if (DstTy.isScalar() && LCMTy.isScalar()) {
455     MIRBuilder.buildTrunc(DstReg, Remerge);
456     return;
457   }
458 
459   if (LCMTy.isVector()) {
460     unsigned NumDefs = LCMTy.getSizeInBits() / DstTy.getSizeInBits();
461     SmallVector<Register, 8> UnmergeDefs(NumDefs);
462     UnmergeDefs[0] = DstReg;
463     for (unsigned I = 1; I != NumDefs; ++I)
464       UnmergeDefs[I] = MRI.createGenericVirtualRegister(DstTy);
465 
466     MIRBuilder.buildUnmerge(UnmergeDefs,
467                             MIRBuilder.buildMergeLikeInstr(LCMTy, RemergeRegs));
468     return;
469   }
470 
471   llvm_unreachable("unhandled case");
472 }
473 
474 static RTLIB::Libcall getRTLibDesc(unsigned Opcode, unsigned Size) {
475 #define RTLIBCASE_INT(LibcallPrefix)                                           \
476   do {                                                                         \
477     switch (Size) {                                                            \
478     case 32:                                                                   \
479       return RTLIB::LibcallPrefix##32;                                         \
480     case 64:                                                                   \
481       return RTLIB::LibcallPrefix##64;                                         \
482     case 128:                                                                  \
483       return RTLIB::LibcallPrefix##128;                                        \
484     default:                                                                   \
485       llvm_unreachable("unexpected size");                                     \
486     }                                                                          \
487   } while (0)
488 
489 #define RTLIBCASE(LibcallPrefix)                                               \
490   do {                                                                         \
491     switch (Size) {                                                            \
492     case 32:                                                                   \
493       return RTLIB::LibcallPrefix##32;                                         \
494     case 64:                                                                   \
495       return RTLIB::LibcallPrefix##64;                                         \
496     case 80:                                                                   \
497       return RTLIB::LibcallPrefix##80;                                         \
498     case 128:                                                                  \
499       return RTLIB::LibcallPrefix##128;                                        \
500     default:                                                                   \
501       llvm_unreachable("unexpected size");                                     \
502     }                                                                          \
503   } while (0)
504 
505   switch (Opcode) {
506   case TargetOpcode::G_MUL:
507     RTLIBCASE_INT(MUL_I);
508   case TargetOpcode::G_SDIV:
509     RTLIBCASE_INT(SDIV_I);
510   case TargetOpcode::G_UDIV:
511     RTLIBCASE_INT(UDIV_I);
512   case TargetOpcode::G_SREM:
513     RTLIBCASE_INT(SREM_I);
514   case TargetOpcode::G_UREM:
515     RTLIBCASE_INT(UREM_I);
516   case TargetOpcode::G_CTLZ_ZERO_UNDEF:
517     RTLIBCASE_INT(CTLZ_I);
518   case TargetOpcode::G_FADD:
519     RTLIBCASE(ADD_F);
520   case TargetOpcode::G_FSUB:
521     RTLIBCASE(SUB_F);
522   case TargetOpcode::G_FMUL:
523     RTLIBCASE(MUL_F);
524   case TargetOpcode::G_FDIV:
525     RTLIBCASE(DIV_F);
526   case TargetOpcode::G_FEXP:
527     RTLIBCASE(EXP_F);
528   case TargetOpcode::G_FEXP2:
529     RTLIBCASE(EXP2_F);
530   case TargetOpcode::G_FEXP10:
531     RTLIBCASE(EXP10_F);
532   case TargetOpcode::G_FREM:
533     RTLIBCASE(REM_F);
534   case TargetOpcode::G_FPOW:
535     RTLIBCASE(POW_F);
536   case TargetOpcode::G_FPOWI:
537     RTLIBCASE(POWI_F);
538   case TargetOpcode::G_FMA:
539     RTLIBCASE(FMA_F);
540   case TargetOpcode::G_FSIN:
541     RTLIBCASE(SIN_F);
542   case TargetOpcode::G_FCOS:
543     RTLIBCASE(COS_F);
544   case TargetOpcode::G_FLOG10:
545     RTLIBCASE(LOG10_F);
546   case TargetOpcode::G_FLOG:
547     RTLIBCASE(LOG_F);
548   case TargetOpcode::G_FLOG2:
549     RTLIBCASE(LOG2_F);
550   case TargetOpcode::G_FLDEXP:
551     RTLIBCASE(LDEXP_F);
552   case TargetOpcode::G_FCEIL:
553     RTLIBCASE(CEIL_F);
554   case TargetOpcode::G_FFLOOR:
555     RTLIBCASE(FLOOR_F);
556   case TargetOpcode::G_FMINNUM:
557     RTLIBCASE(FMIN_F);
558   case TargetOpcode::G_FMAXNUM:
559     RTLIBCASE(FMAX_F);
560   case TargetOpcode::G_FSQRT:
561     RTLIBCASE(SQRT_F);
562   case TargetOpcode::G_FRINT:
563     RTLIBCASE(RINT_F);
564   case TargetOpcode::G_FNEARBYINT:
565     RTLIBCASE(NEARBYINT_F);
566   case TargetOpcode::G_INTRINSIC_ROUNDEVEN:
567     RTLIBCASE(ROUNDEVEN_F);
568   }
569   llvm_unreachable("Unknown libcall function");
570 }
571 
572 /// True if an instruction is in tail position in its caller. Intended for
573 /// legalizing libcalls as tail calls when possible.
574 static bool isLibCallInTailPosition(const CallLowering::ArgInfo &Result,
575                                     MachineInstr &MI,
576                                     const TargetInstrInfo &TII,
577                                     MachineRegisterInfo &MRI) {
578   MachineBasicBlock &MBB = *MI.getParent();
579   const Function &F = MBB.getParent()->getFunction();
580 
581   // Conservatively require the attributes of the call to match those of
582   // the return. Ignore NoAlias and NonNull because they don't affect the
583   // call sequence.
584   AttributeList CallerAttrs = F.getAttributes();
585   if (AttrBuilder(F.getContext(), CallerAttrs.getRetAttrs())
586           .removeAttribute(Attribute::NoAlias)
587           .removeAttribute(Attribute::NonNull)
588           .hasAttributes())
589     return false;
590 
591   // It's not safe to eliminate the sign / zero extension of the return value.
592   if (CallerAttrs.hasRetAttr(Attribute::ZExt) ||
593       CallerAttrs.hasRetAttr(Attribute::SExt))
594     return false;
595 
596   // Only tail call if the following instruction is a standard return or if we
597   // have a `thisreturn` callee, and a sequence like:
598   //
599   //   G_MEMCPY %0, %1, %2
600   //   $x0 = COPY %0
601   //   RET_ReallyLR implicit $x0
602   auto Next = next_nodbg(MI.getIterator(), MBB.instr_end());
603   if (Next != MBB.instr_end() && Next->isCopy()) {
604     if (MI.getOpcode() == TargetOpcode::G_BZERO)
605       return false;
606 
607     // For MEMCPY/MOMMOVE/MEMSET these will be the first use (the dst), as the
608     // mempy/etc routines return the same parameter. For other it will be the
609     // returned value.
610     Register VReg = MI.getOperand(0).getReg();
611     if (!VReg.isVirtual() || VReg != Next->getOperand(1).getReg())
612       return false;
613 
614     Register PReg = Next->getOperand(0).getReg();
615     if (!PReg.isPhysical())
616       return false;
617 
618     auto Ret = next_nodbg(Next, MBB.instr_end());
619     if (Ret == MBB.instr_end() || !Ret->isReturn())
620       return false;
621 
622     if (Ret->getNumImplicitOperands() != 1)
623       return false;
624 
625     if (!Ret->getOperand(0).isReg() || PReg != Ret->getOperand(0).getReg())
626       return false;
627 
628     // Skip over the COPY that we just validated.
629     Next = Ret;
630   }
631 
632   if (Next == MBB.instr_end() || TII.isTailCall(*Next) || !Next->isReturn())
633     return false;
634 
635   return true;
636 }
637 
638 LegalizerHelper::LegalizeResult
639 llvm::createLibcall(MachineIRBuilder &MIRBuilder, const char *Name,
640                     const CallLowering::ArgInfo &Result,
641                     ArrayRef<CallLowering::ArgInfo> Args,
642                     const CallingConv::ID CC, LostDebugLocObserver &LocObserver,
643                     MachineInstr *MI) {
644   auto &CLI = *MIRBuilder.getMF().getSubtarget().getCallLowering();
645 
646   CallLowering::CallLoweringInfo Info;
647   Info.CallConv = CC;
648   Info.Callee = MachineOperand::CreateES(Name);
649   Info.OrigRet = Result;
650   if (MI)
651     Info.IsTailCall =
652         (Result.Ty->isVoidTy() ||
653          Result.Ty == MIRBuilder.getMF().getFunction().getReturnType()) &&
654         isLibCallInTailPosition(Result, *MI, MIRBuilder.getTII(),
655                                 *MIRBuilder.getMRI());
656 
657   std::copy(Args.begin(), Args.end(), std::back_inserter(Info.OrigArgs));
658   if (!CLI.lowerCall(MIRBuilder, Info))
659     return LegalizerHelper::UnableToLegalize;
660 
661   if (MI && Info.LoweredTailCall) {
662     assert(Info.IsTailCall && "Lowered tail call when it wasn't a tail call?");
663 
664     // Check debug locations before removing the return.
665     LocObserver.checkpoint(true);
666 
667     // We must have a return following the call (or debug insts) to get past
668     // isLibCallInTailPosition.
669     do {
670       MachineInstr *Next = MI->getNextNode();
671       assert(Next &&
672              (Next->isCopy() || Next->isReturn() || Next->isDebugInstr()) &&
673              "Expected instr following MI to be return or debug inst?");
674       // We lowered a tail call, so the call is now the return from the block.
675       // Delete the old return.
676       Next->eraseFromParent();
677     } while (MI->getNextNode());
678 
679     // We expect to lose the debug location from the return.
680     LocObserver.checkpoint(false);
681   }
682   return LegalizerHelper::Legalized;
683 }
684 
685 LegalizerHelper::LegalizeResult
686 llvm::createLibcall(MachineIRBuilder &MIRBuilder, RTLIB::Libcall Libcall,
687                     const CallLowering::ArgInfo &Result,
688                     ArrayRef<CallLowering::ArgInfo> Args,
689                     LostDebugLocObserver &LocObserver, MachineInstr *MI) {
690   auto &TLI = *MIRBuilder.getMF().getSubtarget().getTargetLowering();
691   const char *Name = TLI.getLibcallName(Libcall);
692   const CallingConv::ID CC = TLI.getLibcallCallingConv(Libcall);
693   return createLibcall(MIRBuilder, Name, Result, Args, CC, LocObserver, MI);
694 }
695 
696 // Useful for libcalls where all operands have the same type.
697 static LegalizerHelper::LegalizeResult
698 simpleLibcall(MachineInstr &MI, MachineIRBuilder &MIRBuilder, unsigned Size,
699               Type *OpType, LostDebugLocObserver &LocObserver) {
700   auto Libcall = getRTLibDesc(MI.getOpcode(), Size);
701 
702   // FIXME: What does the original arg index mean here?
703   SmallVector<CallLowering::ArgInfo, 3> Args;
704   for (const MachineOperand &MO : llvm::drop_begin(MI.operands()))
705     Args.push_back({MO.getReg(), OpType, 0});
706   return createLibcall(MIRBuilder, Libcall,
707                        {MI.getOperand(0).getReg(), OpType, 0}, Args,
708                        LocObserver, &MI);
709 }
710 
711 LegalizerHelper::LegalizeResult
712 llvm::createMemLibcall(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
713                        MachineInstr &MI, LostDebugLocObserver &LocObserver) {
714   auto &Ctx = MIRBuilder.getMF().getFunction().getContext();
715 
716   SmallVector<CallLowering::ArgInfo, 3> Args;
717   // Add all the args, except for the last which is an imm denoting 'tail'.
718   for (unsigned i = 0; i < MI.getNumOperands() - 1; ++i) {
719     Register Reg = MI.getOperand(i).getReg();
720 
721     // Need derive an IR type for call lowering.
722     LLT OpLLT = MRI.getType(Reg);
723     Type *OpTy = nullptr;
724     if (OpLLT.isPointer())
725       OpTy = PointerType::get(Ctx, OpLLT.getAddressSpace());
726     else
727       OpTy = IntegerType::get(Ctx, OpLLT.getSizeInBits());
728     Args.push_back({Reg, OpTy, 0});
729   }
730 
731   auto &CLI = *MIRBuilder.getMF().getSubtarget().getCallLowering();
732   auto &TLI = *MIRBuilder.getMF().getSubtarget().getTargetLowering();
733   RTLIB::Libcall RTLibcall;
734   unsigned Opc = MI.getOpcode();
735   switch (Opc) {
736   case TargetOpcode::G_BZERO:
737     RTLibcall = RTLIB::BZERO;
738     break;
739   case TargetOpcode::G_MEMCPY:
740     RTLibcall = RTLIB::MEMCPY;
741     Args[0].Flags[0].setReturned();
742     break;
743   case TargetOpcode::G_MEMMOVE:
744     RTLibcall = RTLIB::MEMMOVE;
745     Args[0].Flags[0].setReturned();
746     break;
747   case TargetOpcode::G_MEMSET:
748     RTLibcall = RTLIB::MEMSET;
749     Args[0].Flags[0].setReturned();
750     break;
751   default:
752     llvm_unreachable("unsupported opcode");
753   }
754   const char *Name = TLI.getLibcallName(RTLibcall);
755 
756   // Unsupported libcall on the target.
757   if (!Name) {
758     LLVM_DEBUG(dbgs() << ".. .. Could not find libcall name for "
759                       << MIRBuilder.getTII().getName(Opc) << "\n");
760     return LegalizerHelper::UnableToLegalize;
761   }
762 
763   CallLowering::CallLoweringInfo Info;
764   Info.CallConv = TLI.getLibcallCallingConv(RTLibcall);
765   Info.Callee = MachineOperand::CreateES(Name);
766   Info.OrigRet = CallLowering::ArgInfo({0}, Type::getVoidTy(Ctx), 0);
767   Info.IsTailCall =
768       MI.getOperand(MI.getNumOperands() - 1).getImm() &&
769       isLibCallInTailPosition(Info.OrigRet, MI, MIRBuilder.getTII(), MRI);
770 
771   std::copy(Args.begin(), Args.end(), std::back_inserter(Info.OrigArgs));
772   if (!CLI.lowerCall(MIRBuilder, Info))
773     return LegalizerHelper::UnableToLegalize;
774 
775   if (Info.LoweredTailCall) {
776     assert(Info.IsTailCall && "Lowered tail call when it wasn't a tail call?");
777 
778     // Check debug locations before removing the return.
779     LocObserver.checkpoint(true);
780 
781     // We must have a return following the call (or debug insts) to get past
782     // isLibCallInTailPosition.
783     do {
784       MachineInstr *Next = MI.getNextNode();
785       assert(Next &&
786              (Next->isCopy() || Next->isReturn() || Next->isDebugInstr()) &&
787              "Expected instr following MI to be return or debug inst?");
788       // We lowered a tail call, so the call is now the return from the block.
789       // Delete the old return.
790       Next->eraseFromParent();
791     } while (MI.getNextNode());
792 
793     // We expect to lose the debug location from the return.
794     LocObserver.checkpoint(false);
795   }
796 
797   return LegalizerHelper::Legalized;
798 }
799 
800 static RTLIB::Libcall getOutlineAtomicLibcall(MachineInstr &MI) {
801   unsigned Opc = MI.getOpcode();
802   auto &AtomicMI = cast<GMemOperation>(MI);
803   auto &MMO = AtomicMI.getMMO();
804   auto Ordering = MMO.getMergedOrdering();
805   LLT MemType = MMO.getMemoryType();
806   uint64_t MemSize = MemType.getSizeInBytes();
807   if (MemType.isVector())
808     return RTLIB::UNKNOWN_LIBCALL;
809 
810 #define LCALLS(A, B)                                                           \
811   { A##B##_RELAX, A##B##_ACQ, A##B##_REL, A##B##_ACQ_REL }
812 #define LCALL5(A)                                                              \
813   LCALLS(A, 1), LCALLS(A, 2), LCALLS(A, 4), LCALLS(A, 8), LCALLS(A, 16)
814   switch (Opc) {
815   case TargetOpcode::G_ATOMIC_CMPXCHG:
816   case TargetOpcode::G_ATOMIC_CMPXCHG_WITH_SUCCESS: {
817     const RTLIB::Libcall LC[5][4] = {LCALL5(RTLIB::OUTLINE_ATOMIC_CAS)};
818     return getOutlineAtomicHelper(LC, Ordering, MemSize);
819   }
820   case TargetOpcode::G_ATOMICRMW_XCHG: {
821     const RTLIB::Libcall LC[5][4] = {LCALL5(RTLIB::OUTLINE_ATOMIC_SWP)};
822     return getOutlineAtomicHelper(LC, Ordering, MemSize);
823   }
824   case TargetOpcode::G_ATOMICRMW_ADD:
825   case TargetOpcode::G_ATOMICRMW_SUB: {
826     const RTLIB::Libcall LC[5][4] = {LCALL5(RTLIB::OUTLINE_ATOMIC_LDADD)};
827     return getOutlineAtomicHelper(LC, Ordering, MemSize);
828   }
829   case TargetOpcode::G_ATOMICRMW_AND: {
830     const RTLIB::Libcall LC[5][4] = {LCALL5(RTLIB::OUTLINE_ATOMIC_LDCLR)};
831     return getOutlineAtomicHelper(LC, Ordering, MemSize);
832   }
833   case TargetOpcode::G_ATOMICRMW_OR: {
834     const RTLIB::Libcall LC[5][4] = {LCALL5(RTLIB::OUTLINE_ATOMIC_LDSET)};
835     return getOutlineAtomicHelper(LC, Ordering, MemSize);
836   }
837   case TargetOpcode::G_ATOMICRMW_XOR: {
838     const RTLIB::Libcall LC[5][4] = {LCALL5(RTLIB::OUTLINE_ATOMIC_LDEOR)};
839     return getOutlineAtomicHelper(LC, Ordering, MemSize);
840   }
841   default:
842     return RTLIB::UNKNOWN_LIBCALL;
843   }
844 #undef LCALLS
845 #undef LCALL5
846 }
847 
848 static LegalizerHelper::LegalizeResult
849 createAtomicLibcall(MachineIRBuilder &MIRBuilder, MachineInstr &MI) {
850   auto &Ctx = MIRBuilder.getMF().getFunction().getContext();
851 
852   Type *RetTy;
853   SmallVector<Register> RetRegs;
854   SmallVector<CallLowering::ArgInfo, 3> Args;
855   unsigned Opc = MI.getOpcode();
856   switch (Opc) {
857   case TargetOpcode::G_ATOMIC_CMPXCHG:
858   case TargetOpcode::G_ATOMIC_CMPXCHG_WITH_SUCCESS: {
859     Register Success;
860     LLT SuccessLLT;
861     auto [Ret, RetLLT, Mem, MemLLT, Cmp, CmpLLT, New, NewLLT] =
862         MI.getFirst4RegLLTs();
863     RetRegs.push_back(Ret);
864     RetTy = IntegerType::get(Ctx, RetLLT.getSizeInBits());
865     if (Opc == TargetOpcode::G_ATOMIC_CMPXCHG_WITH_SUCCESS) {
866       std::tie(Ret, RetLLT, Success, SuccessLLT, Mem, MemLLT, Cmp, CmpLLT, New,
867                NewLLT) = MI.getFirst5RegLLTs();
868       RetRegs.push_back(Success);
869       RetTy = StructType::get(
870           Ctx, {RetTy, IntegerType::get(Ctx, SuccessLLT.getSizeInBits())});
871     }
872     Args.push_back({Cmp, IntegerType::get(Ctx, CmpLLT.getSizeInBits()), 0});
873     Args.push_back({New, IntegerType::get(Ctx, NewLLT.getSizeInBits()), 0});
874     Args.push_back({Mem, PointerType::get(Ctx, MemLLT.getAddressSpace()), 0});
875     break;
876   }
877   case TargetOpcode::G_ATOMICRMW_XCHG:
878   case TargetOpcode::G_ATOMICRMW_ADD:
879   case TargetOpcode::G_ATOMICRMW_SUB:
880   case TargetOpcode::G_ATOMICRMW_AND:
881   case TargetOpcode::G_ATOMICRMW_OR:
882   case TargetOpcode::G_ATOMICRMW_XOR: {
883     auto [Ret, RetLLT, Mem, MemLLT, Val, ValLLT] = MI.getFirst3RegLLTs();
884     RetRegs.push_back(Ret);
885     RetTy = IntegerType::get(Ctx, RetLLT.getSizeInBits());
886     if (Opc == TargetOpcode::G_ATOMICRMW_AND)
887       Val =
888           MIRBuilder.buildXor(ValLLT, MIRBuilder.buildConstant(ValLLT, -1), Val)
889               .getReg(0);
890     else if (Opc == TargetOpcode::G_ATOMICRMW_SUB)
891       Val =
892           MIRBuilder.buildSub(ValLLT, MIRBuilder.buildConstant(ValLLT, 0), Val)
893               .getReg(0);
894     Args.push_back({Val, IntegerType::get(Ctx, ValLLT.getSizeInBits()), 0});
895     Args.push_back({Mem, PointerType::get(Ctx, MemLLT.getAddressSpace()), 0});
896     break;
897   }
898   default:
899     llvm_unreachable("unsupported opcode");
900   }
901 
902   auto &CLI = *MIRBuilder.getMF().getSubtarget().getCallLowering();
903   auto &TLI = *MIRBuilder.getMF().getSubtarget().getTargetLowering();
904   RTLIB::Libcall RTLibcall = getOutlineAtomicLibcall(MI);
905   const char *Name = TLI.getLibcallName(RTLibcall);
906 
907   // Unsupported libcall on the target.
908   if (!Name) {
909     LLVM_DEBUG(dbgs() << ".. .. Could not find libcall name for "
910                       << MIRBuilder.getTII().getName(Opc) << "\n");
911     return LegalizerHelper::UnableToLegalize;
912   }
913 
914   CallLowering::CallLoweringInfo Info;
915   Info.CallConv = TLI.getLibcallCallingConv(RTLibcall);
916   Info.Callee = MachineOperand::CreateES(Name);
917   Info.OrigRet = CallLowering::ArgInfo(RetRegs, RetTy, 0);
918 
919   std::copy(Args.begin(), Args.end(), std::back_inserter(Info.OrigArgs));
920   if (!CLI.lowerCall(MIRBuilder, Info))
921     return LegalizerHelper::UnableToLegalize;
922 
923   return LegalizerHelper::Legalized;
924 }
925 
926 static RTLIB::Libcall getConvRTLibDesc(unsigned Opcode, Type *ToType,
927                                        Type *FromType) {
928   auto ToMVT = MVT::getVT(ToType);
929   auto FromMVT = MVT::getVT(FromType);
930 
931   switch (Opcode) {
932   case TargetOpcode::G_FPEXT:
933     return RTLIB::getFPEXT(FromMVT, ToMVT);
934   case TargetOpcode::G_FPTRUNC:
935     return RTLIB::getFPROUND(FromMVT, ToMVT);
936   case TargetOpcode::G_FPTOSI:
937     return RTLIB::getFPTOSINT(FromMVT, ToMVT);
938   case TargetOpcode::G_FPTOUI:
939     return RTLIB::getFPTOUINT(FromMVT, ToMVT);
940   case TargetOpcode::G_SITOFP:
941     return RTLIB::getSINTTOFP(FromMVT, ToMVT);
942   case TargetOpcode::G_UITOFP:
943     return RTLIB::getUINTTOFP(FromMVT, ToMVT);
944   }
945   llvm_unreachable("Unsupported libcall function");
946 }
947 
948 static LegalizerHelper::LegalizeResult
949 conversionLibcall(MachineInstr &MI, MachineIRBuilder &MIRBuilder, Type *ToType,
950                   Type *FromType, LostDebugLocObserver &LocObserver) {
951   RTLIB::Libcall Libcall = getConvRTLibDesc(MI.getOpcode(), ToType, FromType);
952   return createLibcall(
953       MIRBuilder, Libcall, {MI.getOperand(0).getReg(), ToType, 0},
954       {{MI.getOperand(1).getReg(), FromType, 0}}, LocObserver, &MI);
955 }
956 
957 static RTLIB::Libcall
958 getStateLibraryFunctionFor(MachineInstr &MI, const TargetLowering &TLI) {
959   RTLIB::Libcall RTLibcall;
960   switch (MI.getOpcode()) {
961   case TargetOpcode::G_GET_FPENV:
962     RTLibcall = RTLIB::FEGETENV;
963     break;
964   case TargetOpcode::G_SET_FPENV:
965   case TargetOpcode::G_RESET_FPENV:
966     RTLibcall = RTLIB::FESETENV;
967     break;
968   case TargetOpcode::G_GET_FPMODE:
969     RTLibcall = RTLIB::FEGETMODE;
970     break;
971   case TargetOpcode::G_SET_FPMODE:
972   case TargetOpcode::G_RESET_FPMODE:
973     RTLibcall = RTLIB::FESETMODE;
974     break;
975   default:
976     llvm_unreachable("Unexpected opcode");
977   }
978   return RTLibcall;
979 }
980 
981 // Some library functions that read FP state (fegetmode, fegetenv) write the
982 // state into a region in memory. IR intrinsics that do the same operations
983 // (get_fpmode, get_fpenv) return the state as integer value. To implement these
984 // intrinsics via the library functions, we need to use temporary variable,
985 // for example:
986 //
987 //     %0:_(s32) = G_GET_FPMODE
988 //
989 // is transformed to:
990 //
991 //     %1:_(p0) = G_FRAME_INDEX %stack.0
992 //     BL &fegetmode
993 //     %0:_(s32) = G_LOAD % 1
994 //
995 LegalizerHelper::LegalizeResult
996 LegalizerHelper::createGetStateLibcall(MachineIRBuilder &MIRBuilder,
997                                        MachineInstr &MI,
998                                        LostDebugLocObserver &LocObserver) {
999   const DataLayout &DL = MIRBuilder.getDataLayout();
1000   auto &MF = MIRBuilder.getMF();
1001   auto &MRI = *MIRBuilder.getMRI();
1002   auto &Ctx = MF.getFunction().getContext();
1003 
1004   // Create temporary, where library function will put the read state.
1005   Register Dst = MI.getOperand(0).getReg();
1006   LLT StateTy = MRI.getType(Dst);
1007   TypeSize StateSize = StateTy.getSizeInBytes();
1008   Align TempAlign = getStackTemporaryAlignment(StateTy);
1009   MachinePointerInfo TempPtrInfo;
1010   auto Temp = createStackTemporary(StateSize, TempAlign, TempPtrInfo);
1011 
1012   // Create a call to library function, with the temporary as an argument.
1013   unsigned TempAddrSpace = DL.getAllocaAddrSpace();
1014   Type *StatePtrTy = PointerType::get(Ctx, TempAddrSpace);
1015   RTLIB::Libcall RTLibcall = getStateLibraryFunctionFor(MI, TLI);
1016   auto Res =
1017       createLibcall(MIRBuilder, RTLibcall,
1018                     CallLowering::ArgInfo({0}, Type::getVoidTy(Ctx), 0),
1019                     CallLowering::ArgInfo({Temp.getReg(0), StatePtrTy, 0}),
1020                     LocObserver, nullptr);
1021   if (Res != LegalizerHelper::Legalized)
1022     return Res;
1023 
1024   // Create a load from the temporary.
1025   MachineMemOperand *MMO = MF.getMachineMemOperand(
1026       TempPtrInfo, MachineMemOperand::MOLoad, StateTy, TempAlign);
1027   MIRBuilder.buildLoadInstr(TargetOpcode::G_LOAD, Dst, Temp, *MMO);
1028 
1029   return LegalizerHelper::Legalized;
1030 }
1031 
1032 // Similar to `createGetStateLibcall` the function calls a library function
1033 // using transient space in stack. In this case the library function reads
1034 // content of memory region.
1035 LegalizerHelper::LegalizeResult
1036 LegalizerHelper::createSetStateLibcall(MachineIRBuilder &MIRBuilder,
1037                                        MachineInstr &MI,
1038                                        LostDebugLocObserver &LocObserver) {
1039   const DataLayout &DL = MIRBuilder.getDataLayout();
1040   auto &MF = MIRBuilder.getMF();
1041   auto &MRI = *MIRBuilder.getMRI();
1042   auto &Ctx = MF.getFunction().getContext();
1043 
1044   // Create temporary, where library function will get the new state.
1045   Register Src = MI.getOperand(0).getReg();
1046   LLT StateTy = MRI.getType(Src);
1047   TypeSize StateSize = StateTy.getSizeInBytes();
1048   Align TempAlign = getStackTemporaryAlignment(StateTy);
1049   MachinePointerInfo TempPtrInfo;
1050   auto Temp = createStackTemporary(StateSize, TempAlign, TempPtrInfo);
1051 
1052   // Put the new state into the temporary.
1053   MachineMemOperand *MMO = MF.getMachineMemOperand(
1054       TempPtrInfo, MachineMemOperand::MOStore, StateTy, TempAlign);
1055   MIRBuilder.buildStore(Src, Temp, *MMO);
1056 
1057   // Create a call to library function, with the temporary as an argument.
1058   unsigned TempAddrSpace = DL.getAllocaAddrSpace();
1059   Type *StatePtrTy = PointerType::get(Ctx, TempAddrSpace);
1060   RTLIB::Libcall RTLibcall = getStateLibraryFunctionFor(MI, TLI);
1061   return createLibcall(MIRBuilder, RTLibcall,
1062                        CallLowering::ArgInfo({0}, Type::getVoidTy(Ctx), 0),
1063                        CallLowering::ArgInfo({Temp.getReg(0), StatePtrTy, 0}),
1064                        LocObserver, nullptr);
1065 }
1066 
1067 // The function is used to legalize operations that set default environment
1068 // state. In C library a call like `fesetmode(FE_DFL_MODE)` is used for that.
1069 // On most targets supported in glibc FE_DFL_MODE is defined as
1070 // `((const femode_t *) -1)`. Such assumption is used here. If for some target
1071 // it is not true, the target must provide custom lowering.
1072 LegalizerHelper::LegalizeResult
1073 LegalizerHelper::createResetStateLibcall(MachineIRBuilder &MIRBuilder,
1074                                          MachineInstr &MI,
1075                                          LostDebugLocObserver &LocObserver) {
1076   const DataLayout &DL = MIRBuilder.getDataLayout();
1077   auto &MF = MIRBuilder.getMF();
1078   auto &Ctx = MF.getFunction().getContext();
1079 
1080   // Create an argument for the library function.
1081   unsigned AddrSpace = DL.getDefaultGlobalsAddressSpace();
1082   Type *StatePtrTy = PointerType::get(Ctx, AddrSpace);
1083   unsigned PtrSize = DL.getPointerSizeInBits(AddrSpace);
1084   LLT MemTy = LLT::pointer(AddrSpace, PtrSize);
1085   auto DefValue = MIRBuilder.buildConstant(LLT::scalar(PtrSize), -1LL);
1086   DstOp Dest(MRI.createGenericVirtualRegister(MemTy));
1087   MIRBuilder.buildIntToPtr(Dest, DefValue);
1088 
1089   RTLIB::Libcall RTLibcall = getStateLibraryFunctionFor(MI, TLI);
1090   return createLibcall(MIRBuilder, RTLibcall,
1091                        CallLowering::ArgInfo({0}, Type::getVoidTy(Ctx), 0),
1092                        CallLowering::ArgInfo({Dest.getReg(), StatePtrTy, 0}),
1093                        LocObserver, &MI);
1094 }
1095 
1096 LegalizerHelper::LegalizeResult
1097 LegalizerHelper::libcall(MachineInstr &MI, LostDebugLocObserver &LocObserver) {
1098   auto &Ctx = MIRBuilder.getMF().getFunction().getContext();
1099 
1100   switch (MI.getOpcode()) {
1101   default:
1102     return UnableToLegalize;
1103   case TargetOpcode::G_MUL:
1104   case TargetOpcode::G_SDIV:
1105   case TargetOpcode::G_UDIV:
1106   case TargetOpcode::G_SREM:
1107   case TargetOpcode::G_UREM:
1108   case TargetOpcode::G_CTLZ_ZERO_UNDEF: {
1109     LLT LLTy = MRI.getType(MI.getOperand(0).getReg());
1110     unsigned Size = LLTy.getSizeInBits();
1111     Type *HLTy = IntegerType::get(Ctx, Size);
1112     auto Status = simpleLibcall(MI, MIRBuilder, Size, HLTy, LocObserver);
1113     if (Status != Legalized)
1114       return Status;
1115     break;
1116   }
1117   case TargetOpcode::G_FADD:
1118   case TargetOpcode::G_FSUB:
1119   case TargetOpcode::G_FMUL:
1120   case TargetOpcode::G_FDIV:
1121   case TargetOpcode::G_FMA:
1122   case TargetOpcode::G_FPOW:
1123   case TargetOpcode::G_FREM:
1124   case TargetOpcode::G_FCOS:
1125   case TargetOpcode::G_FSIN:
1126   case TargetOpcode::G_FLOG10:
1127   case TargetOpcode::G_FLOG:
1128   case TargetOpcode::G_FLOG2:
1129   case TargetOpcode::G_FLDEXP:
1130   case TargetOpcode::G_FEXP:
1131   case TargetOpcode::G_FEXP2:
1132   case TargetOpcode::G_FEXP10:
1133   case TargetOpcode::G_FCEIL:
1134   case TargetOpcode::G_FFLOOR:
1135   case TargetOpcode::G_FMINNUM:
1136   case TargetOpcode::G_FMAXNUM:
1137   case TargetOpcode::G_FSQRT:
1138   case TargetOpcode::G_FRINT:
1139   case TargetOpcode::G_FNEARBYINT:
1140   case TargetOpcode::G_INTRINSIC_ROUNDEVEN: {
1141     LLT LLTy = MRI.getType(MI.getOperand(0).getReg());
1142     unsigned Size = LLTy.getSizeInBits();
1143     Type *HLTy = getFloatTypeForLLT(Ctx, LLTy);
1144     if (!HLTy || (Size != 32 && Size != 64 && Size != 80 && Size != 128)) {
1145       LLVM_DEBUG(dbgs() << "No libcall available for type " << LLTy << ".\n");
1146       return UnableToLegalize;
1147     }
1148     auto Status = simpleLibcall(MI, MIRBuilder, Size, HLTy, LocObserver);
1149     if (Status != Legalized)
1150       return Status;
1151     break;
1152   }
1153   case TargetOpcode::G_FPOWI: {
1154     LLT LLTy = MRI.getType(MI.getOperand(0).getReg());
1155     unsigned Size = LLTy.getSizeInBits();
1156     Type *HLTy = getFloatTypeForLLT(Ctx, LLTy);
1157     Type *ITy = IntegerType::get(
1158         Ctx, MRI.getType(MI.getOperand(2).getReg()).getSizeInBits());
1159     if (!HLTy || (Size != 32 && Size != 64 && Size != 80 && Size != 128)) {
1160       LLVM_DEBUG(dbgs() << "No libcall available for type " << LLTy << ".\n");
1161       return UnableToLegalize;
1162     }
1163     auto Libcall = getRTLibDesc(MI.getOpcode(), Size);
1164     std::initializer_list<CallLowering::ArgInfo> Args = {
1165         {MI.getOperand(1).getReg(), HLTy, 0},
1166         {MI.getOperand(2).getReg(), ITy, 1}};
1167     LegalizeResult Status =
1168         createLibcall(MIRBuilder, Libcall, {MI.getOperand(0).getReg(), HLTy, 0},
1169                       Args, LocObserver, &MI);
1170     if (Status != Legalized)
1171       return Status;
1172     break;
1173   }
1174   case TargetOpcode::G_FPEXT:
1175   case TargetOpcode::G_FPTRUNC: {
1176     Type *FromTy = getFloatTypeForLLT(Ctx,  MRI.getType(MI.getOperand(1).getReg()));
1177     Type *ToTy = getFloatTypeForLLT(Ctx, MRI.getType(MI.getOperand(0).getReg()));
1178     if (!FromTy || !ToTy)
1179       return UnableToLegalize;
1180     LegalizeResult Status =
1181         conversionLibcall(MI, MIRBuilder, ToTy, FromTy, LocObserver);
1182     if (Status != Legalized)
1183       return Status;
1184     break;
1185   }
1186   case TargetOpcode::G_FPTOSI:
1187   case TargetOpcode::G_FPTOUI: {
1188     // FIXME: Support other types
1189     unsigned FromSize = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits();
1190     unsigned ToSize = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
1191     if ((ToSize != 32 && ToSize != 64) || (FromSize != 32 && FromSize != 64))
1192       return UnableToLegalize;
1193     LegalizeResult Status = conversionLibcall(
1194         MI, MIRBuilder,
1195         ToSize == 32 ? Type::getInt32Ty(Ctx) : Type::getInt64Ty(Ctx),
1196         FromSize == 64 ? Type::getDoubleTy(Ctx) : Type::getFloatTy(Ctx),
1197         LocObserver);
1198     if (Status != Legalized)
1199       return Status;
1200     break;
1201   }
1202   case TargetOpcode::G_SITOFP:
1203   case TargetOpcode::G_UITOFP: {
1204     // FIXME: Support other types
1205     unsigned FromSize = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits();
1206     unsigned ToSize = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
1207     if ((FromSize != 32 && FromSize != 64) || (ToSize != 32 && ToSize != 64))
1208       return UnableToLegalize;
1209     LegalizeResult Status = conversionLibcall(
1210         MI, MIRBuilder,
1211         ToSize == 64 ? Type::getDoubleTy(Ctx) : Type::getFloatTy(Ctx),
1212         FromSize == 32 ? Type::getInt32Ty(Ctx) : Type::getInt64Ty(Ctx),
1213         LocObserver);
1214     if (Status != Legalized)
1215       return Status;
1216     break;
1217   }
1218   case TargetOpcode::G_ATOMICRMW_XCHG:
1219   case TargetOpcode::G_ATOMICRMW_ADD:
1220   case TargetOpcode::G_ATOMICRMW_SUB:
1221   case TargetOpcode::G_ATOMICRMW_AND:
1222   case TargetOpcode::G_ATOMICRMW_OR:
1223   case TargetOpcode::G_ATOMICRMW_XOR:
1224   case TargetOpcode::G_ATOMIC_CMPXCHG:
1225   case TargetOpcode::G_ATOMIC_CMPXCHG_WITH_SUCCESS: {
1226     auto Status = createAtomicLibcall(MIRBuilder, MI);
1227     if (Status != Legalized)
1228       return Status;
1229     break;
1230   }
1231   case TargetOpcode::G_BZERO:
1232   case TargetOpcode::G_MEMCPY:
1233   case TargetOpcode::G_MEMMOVE:
1234   case TargetOpcode::G_MEMSET: {
1235     LegalizeResult Result =
1236         createMemLibcall(MIRBuilder, *MIRBuilder.getMRI(), MI, LocObserver);
1237     if (Result != Legalized)
1238       return Result;
1239     MI.eraseFromParent();
1240     return Result;
1241   }
1242   case TargetOpcode::G_GET_FPENV:
1243   case TargetOpcode::G_GET_FPMODE: {
1244     LegalizeResult Result = createGetStateLibcall(MIRBuilder, MI, LocObserver);
1245     if (Result != Legalized)
1246       return Result;
1247     break;
1248   }
1249   case TargetOpcode::G_SET_FPENV:
1250   case TargetOpcode::G_SET_FPMODE: {
1251     LegalizeResult Result = createSetStateLibcall(MIRBuilder, MI, LocObserver);
1252     if (Result != Legalized)
1253       return Result;
1254     break;
1255   }
1256   case TargetOpcode::G_RESET_FPENV:
1257   case TargetOpcode::G_RESET_FPMODE: {
1258     LegalizeResult Result =
1259         createResetStateLibcall(MIRBuilder, MI, LocObserver);
1260     if (Result != Legalized)
1261       return Result;
1262     break;
1263   }
1264   }
1265 
1266   MI.eraseFromParent();
1267   return Legalized;
1268 }
1269 
1270 LegalizerHelper::LegalizeResult LegalizerHelper::narrowScalar(MachineInstr &MI,
1271                                                               unsigned TypeIdx,
1272                                                               LLT NarrowTy) {
1273   uint64_t SizeOp0 = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
1274   uint64_t NarrowSize = NarrowTy.getSizeInBits();
1275 
1276   switch (MI.getOpcode()) {
1277   default:
1278     return UnableToLegalize;
1279   case TargetOpcode::G_IMPLICIT_DEF: {
1280     Register DstReg = MI.getOperand(0).getReg();
1281     LLT DstTy = MRI.getType(DstReg);
1282 
1283     // If SizeOp0 is not an exact multiple of NarrowSize, emit
1284     // G_ANYEXT(G_IMPLICIT_DEF). Cast result to vector if needed.
1285     // FIXME: Although this would also be legal for the general case, it causes
1286     //  a lot of regressions in the emitted code (superfluous COPYs, artifact
1287     //  combines not being hit). This seems to be a problem related to the
1288     //  artifact combiner.
1289     if (SizeOp0 % NarrowSize != 0) {
1290       LLT ImplicitTy = NarrowTy;
1291       if (DstTy.isVector())
1292         ImplicitTy = LLT::vector(DstTy.getElementCount(), ImplicitTy);
1293 
1294       Register ImplicitReg = MIRBuilder.buildUndef(ImplicitTy).getReg(0);
1295       MIRBuilder.buildAnyExt(DstReg, ImplicitReg);
1296 
1297       MI.eraseFromParent();
1298       return Legalized;
1299     }
1300 
1301     int NumParts = SizeOp0 / NarrowSize;
1302 
1303     SmallVector<Register, 2> DstRegs;
1304     for (int i = 0; i < NumParts; ++i)
1305       DstRegs.push_back(MIRBuilder.buildUndef(NarrowTy).getReg(0));
1306 
1307     if (DstTy.isVector())
1308       MIRBuilder.buildBuildVector(DstReg, DstRegs);
1309     else
1310       MIRBuilder.buildMergeLikeInstr(DstReg, DstRegs);
1311     MI.eraseFromParent();
1312     return Legalized;
1313   }
1314   case TargetOpcode::G_CONSTANT: {
1315     LLT Ty = MRI.getType(MI.getOperand(0).getReg());
1316     const APInt &Val = MI.getOperand(1).getCImm()->getValue();
1317     unsigned TotalSize = Ty.getSizeInBits();
1318     unsigned NarrowSize = NarrowTy.getSizeInBits();
1319     int NumParts = TotalSize / NarrowSize;
1320 
1321     SmallVector<Register, 4> PartRegs;
1322     for (int I = 0; I != NumParts; ++I) {
1323       unsigned Offset = I * NarrowSize;
1324       auto K = MIRBuilder.buildConstant(NarrowTy,
1325                                         Val.lshr(Offset).trunc(NarrowSize));
1326       PartRegs.push_back(K.getReg(0));
1327     }
1328 
1329     LLT LeftoverTy;
1330     unsigned LeftoverBits = TotalSize - NumParts * NarrowSize;
1331     SmallVector<Register, 1> LeftoverRegs;
1332     if (LeftoverBits != 0) {
1333       LeftoverTy = LLT::scalar(LeftoverBits);
1334       auto K = MIRBuilder.buildConstant(
1335         LeftoverTy,
1336         Val.lshr(NumParts * NarrowSize).trunc(LeftoverBits));
1337       LeftoverRegs.push_back(K.getReg(0));
1338     }
1339 
1340     insertParts(MI.getOperand(0).getReg(),
1341                 Ty, NarrowTy, PartRegs, LeftoverTy, LeftoverRegs);
1342 
1343     MI.eraseFromParent();
1344     return Legalized;
1345   }
1346   case TargetOpcode::G_SEXT:
1347   case TargetOpcode::G_ZEXT:
1348   case TargetOpcode::G_ANYEXT:
1349     return narrowScalarExt(MI, TypeIdx, NarrowTy);
1350   case TargetOpcode::G_TRUNC: {
1351     if (TypeIdx != 1)
1352       return UnableToLegalize;
1353 
1354     uint64_t SizeOp1 = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits();
1355     if (NarrowTy.getSizeInBits() * 2 != SizeOp1) {
1356       LLVM_DEBUG(dbgs() << "Can't narrow trunc to type " << NarrowTy << "\n");
1357       return UnableToLegalize;
1358     }
1359 
1360     auto Unmerge = MIRBuilder.buildUnmerge(NarrowTy, MI.getOperand(1));
1361     MIRBuilder.buildCopy(MI.getOperand(0), Unmerge.getReg(0));
1362     MI.eraseFromParent();
1363     return Legalized;
1364   }
1365 
1366   case TargetOpcode::G_FREEZE: {
1367     if (TypeIdx != 0)
1368       return UnableToLegalize;
1369 
1370     LLT Ty = MRI.getType(MI.getOperand(0).getReg());
1371     // Should widen scalar first
1372     if (Ty.getSizeInBits() % NarrowTy.getSizeInBits() != 0)
1373       return UnableToLegalize;
1374 
1375     auto Unmerge = MIRBuilder.buildUnmerge(NarrowTy, MI.getOperand(1).getReg());
1376     SmallVector<Register, 8> Parts;
1377     for (unsigned i = 0; i < Unmerge->getNumDefs(); ++i) {
1378       Parts.push_back(
1379           MIRBuilder.buildFreeze(NarrowTy, Unmerge.getReg(i)).getReg(0));
1380     }
1381 
1382     MIRBuilder.buildMergeLikeInstr(MI.getOperand(0).getReg(), Parts);
1383     MI.eraseFromParent();
1384     return Legalized;
1385   }
1386   case TargetOpcode::G_ADD:
1387   case TargetOpcode::G_SUB:
1388   case TargetOpcode::G_SADDO:
1389   case TargetOpcode::G_SSUBO:
1390   case TargetOpcode::G_SADDE:
1391   case TargetOpcode::G_SSUBE:
1392   case TargetOpcode::G_UADDO:
1393   case TargetOpcode::G_USUBO:
1394   case TargetOpcode::G_UADDE:
1395   case TargetOpcode::G_USUBE:
1396     return narrowScalarAddSub(MI, TypeIdx, NarrowTy);
1397   case TargetOpcode::G_MUL:
1398   case TargetOpcode::G_UMULH:
1399     return narrowScalarMul(MI, NarrowTy);
1400   case TargetOpcode::G_EXTRACT:
1401     return narrowScalarExtract(MI, TypeIdx, NarrowTy);
1402   case TargetOpcode::G_INSERT:
1403     return narrowScalarInsert(MI, TypeIdx, NarrowTy);
1404   case TargetOpcode::G_LOAD: {
1405     auto &LoadMI = cast<GLoad>(MI);
1406     Register DstReg = LoadMI.getDstReg();
1407     LLT DstTy = MRI.getType(DstReg);
1408     if (DstTy.isVector())
1409       return UnableToLegalize;
1410 
1411     if (8 * LoadMI.getMemSize() != DstTy.getSizeInBits()) {
1412       Register TmpReg = MRI.createGenericVirtualRegister(NarrowTy);
1413       MIRBuilder.buildLoad(TmpReg, LoadMI.getPointerReg(), LoadMI.getMMO());
1414       MIRBuilder.buildAnyExt(DstReg, TmpReg);
1415       LoadMI.eraseFromParent();
1416       return Legalized;
1417     }
1418 
1419     return reduceLoadStoreWidth(LoadMI, TypeIdx, NarrowTy);
1420   }
1421   case TargetOpcode::G_ZEXTLOAD:
1422   case TargetOpcode::G_SEXTLOAD: {
1423     auto &LoadMI = cast<GExtLoad>(MI);
1424     Register DstReg = LoadMI.getDstReg();
1425     Register PtrReg = LoadMI.getPointerReg();
1426 
1427     Register TmpReg = MRI.createGenericVirtualRegister(NarrowTy);
1428     auto &MMO = LoadMI.getMMO();
1429     unsigned MemSize = MMO.getSizeInBits();
1430 
1431     if (MemSize == NarrowSize) {
1432       MIRBuilder.buildLoad(TmpReg, PtrReg, MMO);
1433     } else if (MemSize < NarrowSize) {
1434       MIRBuilder.buildLoadInstr(LoadMI.getOpcode(), TmpReg, PtrReg, MMO);
1435     } else if (MemSize > NarrowSize) {
1436       // FIXME: Need to split the load.
1437       return UnableToLegalize;
1438     }
1439 
1440     if (isa<GZExtLoad>(LoadMI))
1441       MIRBuilder.buildZExt(DstReg, TmpReg);
1442     else
1443       MIRBuilder.buildSExt(DstReg, TmpReg);
1444 
1445     LoadMI.eraseFromParent();
1446     return Legalized;
1447   }
1448   case TargetOpcode::G_STORE: {
1449     auto &StoreMI = cast<GStore>(MI);
1450 
1451     Register SrcReg = StoreMI.getValueReg();
1452     LLT SrcTy = MRI.getType(SrcReg);
1453     if (SrcTy.isVector())
1454       return UnableToLegalize;
1455 
1456     int NumParts = SizeOp0 / NarrowSize;
1457     unsigned HandledSize = NumParts * NarrowTy.getSizeInBits();
1458     unsigned LeftoverBits = SrcTy.getSizeInBits() - HandledSize;
1459     if (SrcTy.isVector() && LeftoverBits != 0)
1460       return UnableToLegalize;
1461 
1462     if (8 * StoreMI.getMemSize() != SrcTy.getSizeInBits()) {
1463       Register TmpReg = MRI.createGenericVirtualRegister(NarrowTy);
1464       MIRBuilder.buildTrunc(TmpReg, SrcReg);
1465       MIRBuilder.buildStore(TmpReg, StoreMI.getPointerReg(), StoreMI.getMMO());
1466       StoreMI.eraseFromParent();
1467       return Legalized;
1468     }
1469 
1470     return reduceLoadStoreWidth(StoreMI, 0, NarrowTy);
1471   }
1472   case TargetOpcode::G_SELECT:
1473     return narrowScalarSelect(MI, TypeIdx, NarrowTy);
1474   case TargetOpcode::G_AND:
1475   case TargetOpcode::G_OR:
1476   case TargetOpcode::G_XOR: {
1477     // Legalize bitwise operation:
1478     // A = BinOp<Ty> B, C
1479     // into:
1480     // B1, ..., BN = G_UNMERGE_VALUES B
1481     // C1, ..., CN = G_UNMERGE_VALUES C
1482     // A1 = BinOp<Ty/N> B1, C2
1483     // ...
1484     // AN = BinOp<Ty/N> BN, CN
1485     // A = G_MERGE_VALUES A1, ..., AN
1486     return narrowScalarBasic(MI, TypeIdx, NarrowTy);
1487   }
1488   case TargetOpcode::G_SHL:
1489   case TargetOpcode::G_LSHR:
1490   case TargetOpcode::G_ASHR:
1491     return narrowScalarShift(MI, TypeIdx, NarrowTy);
1492   case TargetOpcode::G_CTLZ:
1493   case TargetOpcode::G_CTLZ_ZERO_UNDEF:
1494   case TargetOpcode::G_CTTZ:
1495   case TargetOpcode::G_CTTZ_ZERO_UNDEF:
1496   case TargetOpcode::G_CTPOP:
1497     if (TypeIdx == 1)
1498       switch (MI.getOpcode()) {
1499       case TargetOpcode::G_CTLZ:
1500       case TargetOpcode::G_CTLZ_ZERO_UNDEF:
1501         return narrowScalarCTLZ(MI, TypeIdx, NarrowTy);
1502       case TargetOpcode::G_CTTZ:
1503       case TargetOpcode::G_CTTZ_ZERO_UNDEF:
1504         return narrowScalarCTTZ(MI, TypeIdx, NarrowTy);
1505       case TargetOpcode::G_CTPOP:
1506         return narrowScalarCTPOP(MI, TypeIdx, NarrowTy);
1507       default:
1508         return UnableToLegalize;
1509       }
1510 
1511     Observer.changingInstr(MI);
1512     narrowScalarDst(MI, NarrowTy, 0, TargetOpcode::G_ZEXT);
1513     Observer.changedInstr(MI);
1514     return Legalized;
1515   case TargetOpcode::G_INTTOPTR:
1516     if (TypeIdx != 1)
1517       return UnableToLegalize;
1518 
1519     Observer.changingInstr(MI);
1520     narrowScalarSrc(MI, NarrowTy, 1);
1521     Observer.changedInstr(MI);
1522     return Legalized;
1523   case TargetOpcode::G_PTRTOINT:
1524     if (TypeIdx != 0)
1525       return UnableToLegalize;
1526 
1527     Observer.changingInstr(MI);
1528     narrowScalarDst(MI, NarrowTy, 0, TargetOpcode::G_ZEXT);
1529     Observer.changedInstr(MI);
1530     return Legalized;
1531   case TargetOpcode::G_PHI: {
1532     // FIXME: add support for when SizeOp0 isn't an exact multiple of
1533     // NarrowSize.
1534     if (SizeOp0 % NarrowSize != 0)
1535       return UnableToLegalize;
1536 
1537     unsigned NumParts = SizeOp0 / NarrowSize;
1538     SmallVector<Register, 2> DstRegs(NumParts);
1539     SmallVector<SmallVector<Register, 2>, 2> SrcRegs(MI.getNumOperands() / 2);
1540     Observer.changingInstr(MI);
1541     for (unsigned i = 1; i < MI.getNumOperands(); i += 2) {
1542       MachineBasicBlock &OpMBB = *MI.getOperand(i + 1).getMBB();
1543       MIRBuilder.setInsertPt(OpMBB, OpMBB.getFirstTerminatorForward());
1544       extractParts(MI.getOperand(i).getReg(), NarrowTy, NumParts,
1545                    SrcRegs[i / 2]);
1546     }
1547     MachineBasicBlock &MBB = *MI.getParent();
1548     MIRBuilder.setInsertPt(MBB, MI);
1549     for (unsigned i = 0; i < NumParts; ++i) {
1550       DstRegs[i] = MRI.createGenericVirtualRegister(NarrowTy);
1551       MachineInstrBuilder MIB =
1552           MIRBuilder.buildInstr(TargetOpcode::G_PHI).addDef(DstRegs[i]);
1553       for (unsigned j = 1; j < MI.getNumOperands(); j += 2)
1554         MIB.addUse(SrcRegs[j / 2][i]).add(MI.getOperand(j + 1));
1555     }
1556     MIRBuilder.setInsertPt(MBB, MBB.getFirstNonPHI());
1557     MIRBuilder.buildMergeLikeInstr(MI.getOperand(0), DstRegs);
1558     Observer.changedInstr(MI);
1559     MI.eraseFromParent();
1560     return Legalized;
1561   }
1562   case TargetOpcode::G_EXTRACT_VECTOR_ELT:
1563   case TargetOpcode::G_INSERT_VECTOR_ELT: {
1564     if (TypeIdx != 2)
1565       return UnableToLegalize;
1566 
1567     int OpIdx = MI.getOpcode() == TargetOpcode::G_EXTRACT_VECTOR_ELT ? 2 : 3;
1568     Observer.changingInstr(MI);
1569     narrowScalarSrc(MI, NarrowTy, OpIdx);
1570     Observer.changedInstr(MI);
1571     return Legalized;
1572   }
1573   case TargetOpcode::G_ICMP: {
1574     Register LHS = MI.getOperand(2).getReg();
1575     LLT SrcTy = MRI.getType(LHS);
1576     uint64_t SrcSize = SrcTy.getSizeInBits();
1577     CmpInst::Predicate Pred =
1578         static_cast<CmpInst::Predicate>(MI.getOperand(1).getPredicate());
1579 
1580     // TODO: Handle the non-equality case for weird sizes.
1581     if (NarrowSize * 2 != SrcSize && !ICmpInst::isEquality(Pred))
1582       return UnableToLegalize;
1583 
1584     LLT LeftoverTy; // Example: s88 -> s64 (NarrowTy) + s24 (leftover)
1585     SmallVector<Register, 4> LHSPartRegs, LHSLeftoverRegs;
1586     if (!extractParts(LHS, SrcTy, NarrowTy, LeftoverTy, LHSPartRegs,
1587                       LHSLeftoverRegs))
1588       return UnableToLegalize;
1589 
1590     LLT Unused; // Matches LeftoverTy; G_ICMP LHS and RHS are the same type.
1591     SmallVector<Register, 4> RHSPartRegs, RHSLeftoverRegs;
1592     if (!extractParts(MI.getOperand(3).getReg(), SrcTy, NarrowTy, Unused,
1593                       RHSPartRegs, RHSLeftoverRegs))
1594       return UnableToLegalize;
1595 
1596     // We now have the LHS and RHS of the compare split into narrow-type
1597     // registers, plus potentially some leftover type.
1598     Register Dst = MI.getOperand(0).getReg();
1599     LLT ResTy = MRI.getType(Dst);
1600     if (ICmpInst::isEquality(Pred)) {
1601       // For each part on the LHS and RHS, keep track of the result of XOR-ing
1602       // them together. For each equal part, the result should be all 0s. For
1603       // each non-equal part, we'll get at least one 1.
1604       auto Zero = MIRBuilder.buildConstant(NarrowTy, 0);
1605       SmallVector<Register, 4> Xors;
1606       for (auto LHSAndRHS : zip(LHSPartRegs, RHSPartRegs)) {
1607         auto LHS = std::get<0>(LHSAndRHS);
1608         auto RHS = std::get<1>(LHSAndRHS);
1609         auto Xor = MIRBuilder.buildXor(NarrowTy, LHS, RHS).getReg(0);
1610         Xors.push_back(Xor);
1611       }
1612 
1613       // Build a G_XOR for each leftover register. Each G_XOR must be widened
1614       // to the desired narrow type so that we can OR them together later.
1615       SmallVector<Register, 4> WidenedXors;
1616       for (auto LHSAndRHS : zip(LHSLeftoverRegs, RHSLeftoverRegs)) {
1617         auto LHS = std::get<0>(LHSAndRHS);
1618         auto RHS = std::get<1>(LHSAndRHS);
1619         auto Xor = MIRBuilder.buildXor(LeftoverTy, LHS, RHS).getReg(0);
1620         LLT GCDTy = extractGCDType(WidenedXors, NarrowTy, LeftoverTy, Xor);
1621         buildLCMMergePieces(LeftoverTy, NarrowTy, GCDTy, WidenedXors,
1622                             /* PadStrategy = */ TargetOpcode::G_ZEXT);
1623         Xors.insert(Xors.end(), WidenedXors.begin(), WidenedXors.end());
1624       }
1625 
1626       // Now, for each part we broke up, we know if they are equal/not equal
1627       // based off the G_XOR. We can OR these all together and compare against
1628       // 0 to get the result.
1629       assert(Xors.size() >= 2 && "Should have gotten at least two Xors?");
1630       auto Or = MIRBuilder.buildOr(NarrowTy, Xors[0], Xors[1]);
1631       for (unsigned I = 2, E = Xors.size(); I < E; ++I)
1632         Or = MIRBuilder.buildOr(NarrowTy, Or, Xors[I]);
1633       MIRBuilder.buildICmp(Pred, Dst, Or, Zero);
1634     } else {
1635       // TODO: Handle non-power-of-two types.
1636       assert(LHSPartRegs.size() == 2 && "Expected exactly 2 LHS part regs?");
1637       assert(RHSPartRegs.size() == 2 && "Expected exactly 2 RHS part regs?");
1638       Register LHSL = LHSPartRegs[0];
1639       Register LHSH = LHSPartRegs[1];
1640       Register RHSL = RHSPartRegs[0];
1641       Register RHSH = RHSPartRegs[1];
1642       MachineInstrBuilder CmpH = MIRBuilder.buildICmp(Pred, ResTy, LHSH, RHSH);
1643       MachineInstrBuilder CmpHEQ =
1644           MIRBuilder.buildICmp(CmpInst::Predicate::ICMP_EQ, ResTy, LHSH, RHSH);
1645       MachineInstrBuilder CmpLU = MIRBuilder.buildICmp(
1646           ICmpInst::getUnsignedPredicate(Pred), ResTy, LHSL, RHSL);
1647       MIRBuilder.buildSelect(Dst, CmpHEQ, CmpLU, CmpH);
1648     }
1649     MI.eraseFromParent();
1650     return Legalized;
1651   }
1652   case TargetOpcode::G_SEXT_INREG: {
1653     if (TypeIdx != 0)
1654       return UnableToLegalize;
1655 
1656     int64_t SizeInBits = MI.getOperand(2).getImm();
1657 
1658     // So long as the new type has more bits than the bits we're extending we
1659     // don't need to break it apart.
1660     if (NarrowTy.getScalarSizeInBits() > SizeInBits) {
1661       Observer.changingInstr(MI);
1662       // We don't lose any non-extension bits by truncating the src and
1663       // sign-extending the dst.
1664       MachineOperand &MO1 = MI.getOperand(1);
1665       auto TruncMIB = MIRBuilder.buildTrunc(NarrowTy, MO1);
1666       MO1.setReg(TruncMIB.getReg(0));
1667 
1668       MachineOperand &MO2 = MI.getOperand(0);
1669       Register DstExt = MRI.createGenericVirtualRegister(NarrowTy);
1670       MIRBuilder.setInsertPt(MIRBuilder.getMBB(), ++MIRBuilder.getInsertPt());
1671       MIRBuilder.buildSExt(MO2, DstExt);
1672       MO2.setReg(DstExt);
1673       Observer.changedInstr(MI);
1674       return Legalized;
1675     }
1676 
1677     // Break it apart. Components below the extension point are unmodified. The
1678     // component containing the extension point becomes a narrower SEXT_INREG.
1679     // Components above it are ashr'd from the component containing the
1680     // extension point.
1681     if (SizeOp0 % NarrowSize != 0)
1682       return UnableToLegalize;
1683     int NumParts = SizeOp0 / NarrowSize;
1684 
1685     // List the registers where the destination will be scattered.
1686     SmallVector<Register, 2> DstRegs;
1687     // List the registers where the source will be split.
1688     SmallVector<Register, 2> SrcRegs;
1689 
1690     // Create all the temporary registers.
1691     for (int i = 0; i < NumParts; ++i) {
1692       Register SrcReg = MRI.createGenericVirtualRegister(NarrowTy);
1693 
1694       SrcRegs.push_back(SrcReg);
1695     }
1696 
1697     // Explode the big arguments into smaller chunks.
1698     MIRBuilder.buildUnmerge(SrcRegs, MI.getOperand(1));
1699 
1700     Register AshrCstReg =
1701         MIRBuilder.buildConstant(NarrowTy, NarrowTy.getScalarSizeInBits() - 1)
1702             .getReg(0);
1703     Register FullExtensionReg;
1704     Register PartialExtensionReg;
1705 
1706     // Do the operation on each small part.
1707     for (int i = 0; i < NumParts; ++i) {
1708       if ((i + 1) * NarrowTy.getScalarSizeInBits() <= SizeInBits) {
1709         DstRegs.push_back(SrcRegs[i]);
1710         PartialExtensionReg = DstRegs.back();
1711       } else if (i * NarrowTy.getScalarSizeInBits() >= SizeInBits) {
1712         assert(PartialExtensionReg &&
1713                "Expected to visit partial extension before full");
1714         if (FullExtensionReg) {
1715           DstRegs.push_back(FullExtensionReg);
1716           continue;
1717         }
1718         DstRegs.push_back(
1719             MIRBuilder.buildAShr(NarrowTy, PartialExtensionReg, AshrCstReg)
1720                 .getReg(0));
1721         FullExtensionReg = DstRegs.back();
1722       } else {
1723         DstRegs.push_back(
1724             MIRBuilder
1725                 .buildInstr(
1726                     TargetOpcode::G_SEXT_INREG, {NarrowTy},
1727                     {SrcRegs[i], SizeInBits % NarrowTy.getScalarSizeInBits()})
1728                 .getReg(0));
1729         PartialExtensionReg = DstRegs.back();
1730       }
1731     }
1732 
1733     // Gather the destination registers into the final destination.
1734     Register DstReg = MI.getOperand(0).getReg();
1735     MIRBuilder.buildMergeLikeInstr(DstReg, DstRegs);
1736     MI.eraseFromParent();
1737     return Legalized;
1738   }
1739   case TargetOpcode::G_BSWAP:
1740   case TargetOpcode::G_BITREVERSE: {
1741     if (SizeOp0 % NarrowSize != 0)
1742       return UnableToLegalize;
1743 
1744     Observer.changingInstr(MI);
1745     SmallVector<Register, 2> SrcRegs, DstRegs;
1746     unsigned NumParts = SizeOp0 / NarrowSize;
1747     extractParts(MI.getOperand(1).getReg(), NarrowTy, NumParts, SrcRegs);
1748 
1749     for (unsigned i = 0; i < NumParts; ++i) {
1750       auto DstPart = MIRBuilder.buildInstr(MI.getOpcode(), {NarrowTy},
1751                                            {SrcRegs[NumParts - 1 - i]});
1752       DstRegs.push_back(DstPart.getReg(0));
1753     }
1754 
1755     MIRBuilder.buildMergeLikeInstr(MI.getOperand(0), DstRegs);
1756 
1757     Observer.changedInstr(MI);
1758     MI.eraseFromParent();
1759     return Legalized;
1760   }
1761   case TargetOpcode::G_PTR_ADD:
1762   case TargetOpcode::G_PTRMASK: {
1763     if (TypeIdx != 1)
1764       return UnableToLegalize;
1765     Observer.changingInstr(MI);
1766     narrowScalarSrc(MI, NarrowTy, 2);
1767     Observer.changedInstr(MI);
1768     return Legalized;
1769   }
1770   case TargetOpcode::G_FPTOUI:
1771   case TargetOpcode::G_FPTOSI:
1772     return narrowScalarFPTOI(MI, TypeIdx, NarrowTy);
1773   case TargetOpcode::G_FPEXT:
1774     if (TypeIdx != 0)
1775       return UnableToLegalize;
1776     Observer.changingInstr(MI);
1777     narrowScalarDst(MI, NarrowTy, 0, TargetOpcode::G_FPEXT);
1778     Observer.changedInstr(MI);
1779     return Legalized;
1780   case TargetOpcode::G_FLDEXP:
1781   case TargetOpcode::G_STRICT_FLDEXP:
1782     return narrowScalarFLDEXP(MI, TypeIdx, NarrowTy);
1783   }
1784 }
1785 
1786 Register LegalizerHelper::coerceToScalar(Register Val) {
1787   LLT Ty = MRI.getType(Val);
1788   if (Ty.isScalar())
1789     return Val;
1790 
1791   const DataLayout &DL = MIRBuilder.getDataLayout();
1792   LLT NewTy = LLT::scalar(Ty.getSizeInBits());
1793   if (Ty.isPointer()) {
1794     if (DL.isNonIntegralAddressSpace(Ty.getAddressSpace()))
1795       return Register();
1796     return MIRBuilder.buildPtrToInt(NewTy, Val).getReg(0);
1797   }
1798 
1799   Register NewVal = Val;
1800 
1801   assert(Ty.isVector());
1802   LLT EltTy = Ty.getElementType();
1803   if (EltTy.isPointer())
1804     NewVal = MIRBuilder.buildPtrToInt(NewTy, NewVal).getReg(0);
1805   return MIRBuilder.buildBitcast(NewTy, NewVal).getReg(0);
1806 }
1807 
1808 void LegalizerHelper::widenScalarSrc(MachineInstr &MI, LLT WideTy,
1809                                      unsigned OpIdx, unsigned ExtOpcode) {
1810   MachineOperand &MO = MI.getOperand(OpIdx);
1811   auto ExtB = MIRBuilder.buildInstr(ExtOpcode, {WideTy}, {MO});
1812   MO.setReg(ExtB.getReg(0));
1813 }
1814 
1815 void LegalizerHelper::narrowScalarSrc(MachineInstr &MI, LLT NarrowTy,
1816                                       unsigned OpIdx) {
1817   MachineOperand &MO = MI.getOperand(OpIdx);
1818   auto ExtB = MIRBuilder.buildTrunc(NarrowTy, MO);
1819   MO.setReg(ExtB.getReg(0));
1820 }
1821 
1822 void LegalizerHelper::widenScalarDst(MachineInstr &MI, LLT WideTy,
1823                                      unsigned OpIdx, unsigned TruncOpcode) {
1824   MachineOperand &MO = MI.getOperand(OpIdx);
1825   Register DstExt = MRI.createGenericVirtualRegister(WideTy);
1826   MIRBuilder.setInsertPt(MIRBuilder.getMBB(), ++MIRBuilder.getInsertPt());
1827   MIRBuilder.buildInstr(TruncOpcode, {MO}, {DstExt});
1828   MO.setReg(DstExt);
1829 }
1830 
1831 void LegalizerHelper::narrowScalarDst(MachineInstr &MI, LLT NarrowTy,
1832                                       unsigned OpIdx, unsigned ExtOpcode) {
1833   MachineOperand &MO = MI.getOperand(OpIdx);
1834   Register DstTrunc = MRI.createGenericVirtualRegister(NarrowTy);
1835   MIRBuilder.setInsertPt(MIRBuilder.getMBB(), ++MIRBuilder.getInsertPt());
1836   MIRBuilder.buildInstr(ExtOpcode, {MO}, {DstTrunc});
1837   MO.setReg(DstTrunc);
1838 }
1839 
1840 void LegalizerHelper::moreElementsVectorDst(MachineInstr &MI, LLT WideTy,
1841                                             unsigned OpIdx) {
1842   MachineOperand &MO = MI.getOperand(OpIdx);
1843   MIRBuilder.setInsertPt(MIRBuilder.getMBB(), ++MIRBuilder.getInsertPt());
1844   Register Dst = MO.getReg();
1845   Register DstExt = MRI.createGenericVirtualRegister(WideTy);
1846   MO.setReg(DstExt);
1847   MIRBuilder.buildDeleteTrailingVectorElements(Dst, DstExt);
1848 }
1849 
1850 void LegalizerHelper::moreElementsVectorSrc(MachineInstr &MI, LLT MoreTy,
1851                                             unsigned OpIdx) {
1852   MachineOperand &MO = MI.getOperand(OpIdx);
1853   SmallVector<Register, 8> Regs;
1854   MO.setReg(MIRBuilder.buildPadVectorWithUndefElements(MoreTy, MO).getReg(0));
1855 }
1856 
1857 void LegalizerHelper::bitcastSrc(MachineInstr &MI, LLT CastTy, unsigned OpIdx) {
1858   MachineOperand &Op = MI.getOperand(OpIdx);
1859   Op.setReg(MIRBuilder.buildBitcast(CastTy, Op).getReg(0));
1860 }
1861 
1862 void LegalizerHelper::bitcastDst(MachineInstr &MI, LLT CastTy, unsigned OpIdx) {
1863   MachineOperand &MO = MI.getOperand(OpIdx);
1864   Register CastDst = MRI.createGenericVirtualRegister(CastTy);
1865   MIRBuilder.setInsertPt(MIRBuilder.getMBB(), ++MIRBuilder.getInsertPt());
1866   MIRBuilder.buildBitcast(MO, CastDst);
1867   MO.setReg(CastDst);
1868 }
1869 
1870 LegalizerHelper::LegalizeResult
1871 LegalizerHelper::widenScalarMergeValues(MachineInstr &MI, unsigned TypeIdx,
1872                                         LLT WideTy) {
1873   if (TypeIdx != 1)
1874     return UnableToLegalize;
1875 
1876   auto [DstReg, DstTy, Src1Reg, Src1Ty] = MI.getFirst2RegLLTs();
1877   if (DstTy.isVector())
1878     return UnableToLegalize;
1879 
1880   LLT SrcTy = MRI.getType(Src1Reg);
1881   const int DstSize = DstTy.getSizeInBits();
1882   const int SrcSize = SrcTy.getSizeInBits();
1883   const int WideSize = WideTy.getSizeInBits();
1884   const int NumMerge = (DstSize + WideSize - 1) / WideSize;
1885 
1886   unsigned NumOps = MI.getNumOperands();
1887   unsigned NumSrc = MI.getNumOperands() - 1;
1888   unsigned PartSize = DstTy.getSizeInBits() / NumSrc;
1889 
1890   if (WideSize >= DstSize) {
1891     // Directly pack the bits in the target type.
1892     Register ResultReg = MIRBuilder.buildZExt(WideTy, Src1Reg).getReg(0);
1893 
1894     for (unsigned I = 2; I != NumOps; ++I) {
1895       const unsigned Offset = (I - 1) * PartSize;
1896 
1897       Register SrcReg = MI.getOperand(I).getReg();
1898       assert(MRI.getType(SrcReg) == LLT::scalar(PartSize));
1899 
1900       auto ZextInput = MIRBuilder.buildZExt(WideTy, SrcReg);
1901 
1902       Register NextResult = I + 1 == NumOps && WideTy == DstTy ? DstReg :
1903         MRI.createGenericVirtualRegister(WideTy);
1904 
1905       auto ShiftAmt = MIRBuilder.buildConstant(WideTy, Offset);
1906       auto Shl = MIRBuilder.buildShl(WideTy, ZextInput, ShiftAmt);
1907       MIRBuilder.buildOr(NextResult, ResultReg, Shl);
1908       ResultReg = NextResult;
1909     }
1910 
1911     if (WideSize > DstSize)
1912       MIRBuilder.buildTrunc(DstReg, ResultReg);
1913     else if (DstTy.isPointer())
1914       MIRBuilder.buildIntToPtr(DstReg, ResultReg);
1915 
1916     MI.eraseFromParent();
1917     return Legalized;
1918   }
1919 
1920   // Unmerge the original values to the GCD type, and recombine to the next
1921   // multiple greater than the original type.
1922   //
1923   // %3:_(s12) = G_MERGE_VALUES %0:_(s4), %1:_(s4), %2:_(s4) -> s6
1924   // %4:_(s2), %5:_(s2) = G_UNMERGE_VALUES %0
1925   // %6:_(s2), %7:_(s2) = G_UNMERGE_VALUES %1
1926   // %8:_(s2), %9:_(s2) = G_UNMERGE_VALUES %2
1927   // %10:_(s6) = G_MERGE_VALUES %4, %5, %6
1928   // %11:_(s6) = G_MERGE_VALUES %7, %8, %9
1929   // %12:_(s12) = G_MERGE_VALUES %10, %11
1930   //
1931   // Padding with undef if necessary:
1932   //
1933   // %2:_(s8) = G_MERGE_VALUES %0:_(s4), %1:_(s4) -> s6
1934   // %3:_(s2), %4:_(s2) = G_UNMERGE_VALUES %0
1935   // %5:_(s2), %6:_(s2) = G_UNMERGE_VALUES %1
1936   // %7:_(s2) = G_IMPLICIT_DEF
1937   // %8:_(s6) = G_MERGE_VALUES %3, %4, %5
1938   // %9:_(s6) = G_MERGE_VALUES %6, %7, %7
1939   // %10:_(s12) = G_MERGE_VALUES %8, %9
1940 
1941   const int GCD = std::gcd(SrcSize, WideSize);
1942   LLT GCDTy = LLT::scalar(GCD);
1943 
1944   SmallVector<Register, 8> Parts;
1945   SmallVector<Register, 8> NewMergeRegs;
1946   SmallVector<Register, 8> Unmerges;
1947   LLT WideDstTy = LLT::scalar(NumMerge * WideSize);
1948 
1949   // Decompose the original operands if they don't evenly divide.
1950   for (const MachineOperand &MO : llvm::drop_begin(MI.operands())) {
1951     Register SrcReg = MO.getReg();
1952     if (GCD == SrcSize) {
1953       Unmerges.push_back(SrcReg);
1954     } else {
1955       auto Unmerge = MIRBuilder.buildUnmerge(GCDTy, SrcReg);
1956       for (int J = 0, JE = Unmerge->getNumOperands() - 1; J != JE; ++J)
1957         Unmerges.push_back(Unmerge.getReg(J));
1958     }
1959   }
1960 
1961   // Pad with undef to the next size that is a multiple of the requested size.
1962   if (static_cast<int>(Unmerges.size()) != NumMerge * WideSize) {
1963     Register UndefReg = MIRBuilder.buildUndef(GCDTy).getReg(0);
1964     for (int I = Unmerges.size(); I != NumMerge * WideSize; ++I)
1965       Unmerges.push_back(UndefReg);
1966   }
1967 
1968   const int PartsPerGCD = WideSize / GCD;
1969 
1970   // Build merges of each piece.
1971   ArrayRef<Register> Slicer(Unmerges);
1972   for (int I = 0; I != NumMerge; ++I, Slicer = Slicer.drop_front(PartsPerGCD)) {
1973     auto Merge =
1974         MIRBuilder.buildMergeLikeInstr(WideTy, Slicer.take_front(PartsPerGCD));
1975     NewMergeRegs.push_back(Merge.getReg(0));
1976   }
1977 
1978   // A truncate may be necessary if the requested type doesn't evenly divide the
1979   // original result type.
1980   if (DstTy.getSizeInBits() == WideDstTy.getSizeInBits()) {
1981     MIRBuilder.buildMergeLikeInstr(DstReg, NewMergeRegs);
1982   } else {
1983     auto FinalMerge = MIRBuilder.buildMergeLikeInstr(WideDstTy, NewMergeRegs);
1984     MIRBuilder.buildTrunc(DstReg, FinalMerge.getReg(0));
1985   }
1986 
1987   MI.eraseFromParent();
1988   return Legalized;
1989 }
1990 
1991 LegalizerHelper::LegalizeResult
1992 LegalizerHelper::widenScalarUnmergeValues(MachineInstr &MI, unsigned TypeIdx,
1993                                           LLT WideTy) {
1994   if (TypeIdx != 0)
1995     return UnableToLegalize;
1996 
1997   int NumDst = MI.getNumOperands() - 1;
1998   Register SrcReg = MI.getOperand(NumDst).getReg();
1999   LLT SrcTy = MRI.getType(SrcReg);
2000   if (SrcTy.isVector())
2001     return UnableToLegalize;
2002 
2003   Register Dst0Reg = MI.getOperand(0).getReg();
2004   LLT DstTy = MRI.getType(Dst0Reg);
2005   if (!DstTy.isScalar())
2006     return UnableToLegalize;
2007 
2008   if (WideTy.getSizeInBits() >= SrcTy.getSizeInBits()) {
2009     if (SrcTy.isPointer()) {
2010       const DataLayout &DL = MIRBuilder.getDataLayout();
2011       if (DL.isNonIntegralAddressSpace(SrcTy.getAddressSpace())) {
2012         LLVM_DEBUG(
2013             dbgs() << "Not casting non-integral address space integer\n");
2014         return UnableToLegalize;
2015       }
2016 
2017       SrcTy = LLT::scalar(SrcTy.getSizeInBits());
2018       SrcReg = MIRBuilder.buildPtrToInt(SrcTy, SrcReg).getReg(0);
2019     }
2020 
2021     // Widen SrcTy to WideTy. This does not affect the result, but since the
2022     // user requested this size, it is probably better handled than SrcTy and
2023     // should reduce the total number of legalization artifacts.
2024     if (WideTy.getSizeInBits() > SrcTy.getSizeInBits()) {
2025       SrcTy = WideTy;
2026       SrcReg = MIRBuilder.buildAnyExt(WideTy, SrcReg).getReg(0);
2027     }
2028 
2029     // Theres no unmerge type to target. Directly extract the bits from the
2030     // source type
2031     unsigned DstSize = DstTy.getSizeInBits();
2032 
2033     MIRBuilder.buildTrunc(Dst0Reg, SrcReg);
2034     for (int I = 1; I != NumDst; ++I) {
2035       auto ShiftAmt = MIRBuilder.buildConstant(SrcTy, DstSize * I);
2036       auto Shr = MIRBuilder.buildLShr(SrcTy, SrcReg, ShiftAmt);
2037       MIRBuilder.buildTrunc(MI.getOperand(I), Shr);
2038     }
2039 
2040     MI.eraseFromParent();
2041     return Legalized;
2042   }
2043 
2044   // Extend the source to a wider type.
2045   LLT LCMTy = getLCMType(SrcTy, WideTy);
2046 
2047   Register WideSrc = SrcReg;
2048   if (LCMTy.getSizeInBits() != SrcTy.getSizeInBits()) {
2049     // TODO: If this is an integral address space, cast to integer and anyext.
2050     if (SrcTy.isPointer()) {
2051       LLVM_DEBUG(dbgs() << "Widening pointer source types not implemented\n");
2052       return UnableToLegalize;
2053     }
2054 
2055     WideSrc = MIRBuilder.buildAnyExt(LCMTy, WideSrc).getReg(0);
2056   }
2057 
2058   auto Unmerge = MIRBuilder.buildUnmerge(WideTy, WideSrc);
2059 
2060   // Create a sequence of unmerges and merges to the original results. Since we
2061   // may have widened the source, we will need to pad the results with dead defs
2062   // to cover the source register.
2063   // e.g. widen s48 to s64:
2064   // %1:_(s48), %2:_(s48) = G_UNMERGE_VALUES %0:_(s96)
2065   //
2066   // =>
2067   //  %4:_(s192) = G_ANYEXT %0:_(s96)
2068   //  %5:_(s64), %6, %7 = G_UNMERGE_VALUES %4 ; Requested unmerge
2069   //  ; unpack to GCD type, with extra dead defs
2070   //  %8:_(s16), %9, %10, %11 = G_UNMERGE_VALUES %5:_(s64)
2071   //  %12:_(s16), %13, dead %14, dead %15 = G_UNMERGE_VALUES %6:_(s64)
2072   //  dead %16:_(s16), dead %17, dead %18, dead %18 = G_UNMERGE_VALUES %7:_(s64)
2073   //  %1:_(s48) = G_MERGE_VALUES %8:_(s16), %9, %10   ; Remerge to destination
2074   //  %2:_(s48) = G_MERGE_VALUES %11:_(s16), %12, %13 ; Remerge to destination
2075   const LLT GCDTy = getGCDType(WideTy, DstTy);
2076   const int NumUnmerge = Unmerge->getNumOperands() - 1;
2077   const int PartsPerRemerge = DstTy.getSizeInBits() / GCDTy.getSizeInBits();
2078 
2079   // Directly unmerge to the destination without going through a GCD type
2080   // if possible
2081   if (PartsPerRemerge == 1) {
2082     const int PartsPerUnmerge = WideTy.getSizeInBits() / DstTy.getSizeInBits();
2083 
2084     for (int I = 0; I != NumUnmerge; ++I) {
2085       auto MIB = MIRBuilder.buildInstr(TargetOpcode::G_UNMERGE_VALUES);
2086 
2087       for (int J = 0; J != PartsPerUnmerge; ++J) {
2088         int Idx = I * PartsPerUnmerge + J;
2089         if (Idx < NumDst)
2090           MIB.addDef(MI.getOperand(Idx).getReg());
2091         else {
2092           // Create dead def for excess components.
2093           MIB.addDef(MRI.createGenericVirtualRegister(DstTy));
2094         }
2095       }
2096 
2097       MIB.addUse(Unmerge.getReg(I));
2098     }
2099   } else {
2100     SmallVector<Register, 16> Parts;
2101     for (int J = 0; J != NumUnmerge; ++J)
2102       extractGCDType(Parts, GCDTy, Unmerge.getReg(J));
2103 
2104     SmallVector<Register, 8> RemergeParts;
2105     for (int I = 0; I != NumDst; ++I) {
2106       for (int J = 0; J < PartsPerRemerge; ++J) {
2107         const int Idx = I * PartsPerRemerge + J;
2108         RemergeParts.emplace_back(Parts[Idx]);
2109       }
2110 
2111       MIRBuilder.buildMergeLikeInstr(MI.getOperand(I).getReg(), RemergeParts);
2112       RemergeParts.clear();
2113     }
2114   }
2115 
2116   MI.eraseFromParent();
2117   return Legalized;
2118 }
2119 
2120 LegalizerHelper::LegalizeResult
2121 LegalizerHelper::widenScalarExtract(MachineInstr &MI, unsigned TypeIdx,
2122                                     LLT WideTy) {
2123   auto [DstReg, DstTy, SrcReg, SrcTy] = MI.getFirst2RegLLTs();
2124   unsigned Offset = MI.getOperand(2).getImm();
2125 
2126   if (TypeIdx == 0) {
2127     if (SrcTy.isVector() || DstTy.isVector())
2128       return UnableToLegalize;
2129 
2130     SrcOp Src(SrcReg);
2131     if (SrcTy.isPointer()) {
2132       // Extracts from pointers can be handled only if they are really just
2133       // simple integers.
2134       const DataLayout &DL = MIRBuilder.getDataLayout();
2135       if (DL.isNonIntegralAddressSpace(SrcTy.getAddressSpace()))
2136         return UnableToLegalize;
2137 
2138       LLT SrcAsIntTy = LLT::scalar(SrcTy.getSizeInBits());
2139       Src = MIRBuilder.buildPtrToInt(SrcAsIntTy, Src);
2140       SrcTy = SrcAsIntTy;
2141     }
2142 
2143     if (DstTy.isPointer())
2144       return UnableToLegalize;
2145 
2146     if (Offset == 0) {
2147       // Avoid a shift in the degenerate case.
2148       MIRBuilder.buildTrunc(DstReg,
2149                             MIRBuilder.buildAnyExtOrTrunc(WideTy, Src));
2150       MI.eraseFromParent();
2151       return Legalized;
2152     }
2153 
2154     // Do a shift in the source type.
2155     LLT ShiftTy = SrcTy;
2156     if (WideTy.getSizeInBits() > SrcTy.getSizeInBits()) {
2157       Src = MIRBuilder.buildAnyExt(WideTy, Src);
2158       ShiftTy = WideTy;
2159     }
2160 
2161     auto LShr = MIRBuilder.buildLShr(
2162       ShiftTy, Src, MIRBuilder.buildConstant(ShiftTy, Offset));
2163     MIRBuilder.buildTrunc(DstReg, LShr);
2164     MI.eraseFromParent();
2165     return Legalized;
2166   }
2167 
2168   if (SrcTy.isScalar()) {
2169     Observer.changingInstr(MI);
2170     widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_ANYEXT);
2171     Observer.changedInstr(MI);
2172     return Legalized;
2173   }
2174 
2175   if (!SrcTy.isVector())
2176     return UnableToLegalize;
2177 
2178   if (DstTy != SrcTy.getElementType())
2179     return UnableToLegalize;
2180 
2181   if (Offset % SrcTy.getScalarSizeInBits() != 0)
2182     return UnableToLegalize;
2183 
2184   Observer.changingInstr(MI);
2185   widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_ANYEXT);
2186 
2187   MI.getOperand(2).setImm((WideTy.getSizeInBits() / SrcTy.getSizeInBits()) *
2188                           Offset);
2189   widenScalarDst(MI, WideTy.getScalarType(), 0);
2190   Observer.changedInstr(MI);
2191   return Legalized;
2192 }
2193 
2194 LegalizerHelper::LegalizeResult
2195 LegalizerHelper::widenScalarInsert(MachineInstr &MI, unsigned TypeIdx,
2196                                    LLT WideTy) {
2197   if (TypeIdx != 0 || WideTy.isVector())
2198     return UnableToLegalize;
2199   Observer.changingInstr(MI);
2200   widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_ANYEXT);
2201   widenScalarDst(MI, WideTy);
2202   Observer.changedInstr(MI);
2203   return Legalized;
2204 }
2205 
2206 LegalizerHelper::LegalizeResult
2207 LegalizerHelper::widenScalarAddSubOverflow(MachineInstr &MI, unsigned TypeIdx,
2208                                            LLT WideTy) {
2209   unsigned Opcode;
2210   unsigned ExtOpcode;
2211   std::optional<Register> CarryIn;
2212   switch (MI.getOpcode()) {
2213   default:
2214     llvm_unreachable("Unexpected opcode!");
2215   case TargetOpcode::G_SADDO:
2216     Opcode = TargetOpcode::G_ADD;
2217     ExtOpcode = TargetOpcode::G_SEXT;
2218     break;
2219   case TargetOpcode::G_SSUBO:
2220     Opcode = TargetOpcode::G_SUB;
2221     ExtOpcode = TargetOpcode::G_SEXT;
2222     break;
2223   case TargetOpcode::G_UADDO:
2224     Opcode = TargetOpcode::G_ADD;
2225     ExtOpcode = TargetOpcode::G_ZEXT;
2226     break;
2227   case TargetOpcode::G_USUBO:
2228     Opcode = TargetOpcode::G_SUB;
2229     ExtOpcode = TargetOpcode::G_ZEXT;
2230     break;
2231   case TargetOpcode::G_SADDE:
2232     Opcode = TargetOpcode::G_UADDE;
2233     ExtOpcode = TargetOpcode::G_SEXT;
2234     CarryIn = MI.getOperand(4).getReg();
2235     break;
2236   case TargetOpcode::G_SSUBE:
2237     Opcode = TargetOpcode::G_USUBE;
2238     ExtOpcode = TargetOpcode::G_SEXT;
2239     CarryIn = MI.getOperand(4).getReg();
2240     break;
2241   case TargetOpcode::G_UADDE:
2242     Opcode = TargetOpcode::G_UADDE;
2243     ExtOpcode = TargetOpcode::G_ZEXT;
2244     CarryIn = MI.getOperand(4).getReg();
2245     break;
2246   case TargetOpcode::G_USUBE:
2247     Opcode = TargetOpcode::G_USUBE;
2248     ExtOpcode = TargetOpcode::G_ZEXT;
2249     CarryIn = MI.getOperand(4).getReg();
2250     break;
2251   }
2252 
2253   if (TypeIdx == 1) {
2254     unsigned BoolExtOp = MIRBuilder.getBoolExtOp(WideTy.isVector(), false);
2255 
2256     Observer.changingInstr(MI);
2257     if (CarryIn)
2258       widenScalarSrc(MI, WideTy, 4, BoolExtOp);
2259     widenScalarDst(MI, WideTy, 1);
2260 
2261     Observer.changedInstr(MI);
2262     return Legalized;
2263   }
2264 
2265   auto LHSExt = MIRBuilder.buildInstr(ExtOpcode, {WideTy}, {MI.getOperand(2)});
2266   auto RHSExt = MIRBuilder.buildInstr(ExtOpcode, {WideTy}, {MI.getOperand(3)});
2267   // Do the arithmetic in the larger type.
2268   Register NewOp;
2269   if (CarryIn) {
2270     LLT CarryOutTy = MRI.getType(MI.getOperand(1).getReg());
2271     NewOp = MIRBuilder
2272                 .buildInstr(Opcode, {WideTy, CarryOutTy},
2273                             {LHSExt, RHSExt, *CarryIn})
2274                 .getReg(0);
2275   } else {
2276     NewOp = MIRBuilder.buildInstr(Opcode, {WideTy}, {LHSExt, RHSExt}).getReg(0);
2277   }
2278   LLT OrigTy = MRI.getType(MI.getOperand(0).getReg());
2279   auto TruncOp = MIRBuilder.buildTrunc(OrigTy, NewOp);
2280   auto ExtOp = MIRBuilder.buildInstr(ExtOpcode, {WideTy}, {TruncOp});
2281   // There is no overflow if the ExtOp is the same as NewOp.
2282   MIRBuilder.buildICmp(CmpInst::ICMP_NE, MI.getOperand(1), NewOp, ExtOp);
2283   // Now trunc the NewOp to the original result.
2284   MIRBuilder.buildTrunc(MI.getOperand(0), NewOp);
2285   MI.eraseFromParent();
2286   return Legalized;
2287 }
2288 
2289 LegalizerHelper::LegalizeResult
2290 LegalizerHelper::widenScalarAddSubShlSat(MachineInstr &MI, unsigned TypeIdx,
2291                                          LLT WideTy) {
2292   bool IsSigned = MI.getOpcode() == TargetOpcode::G_SADDSAT ||
2293                   MI.getOpcode() == TargetOpcode::G_SSUBSAT ||
2294                   MI.getOpcode() == TargetOpcode::G_SSHLSAT;
2295   bool IsShift = MI.getOpcode() == TargetOpcode::G_SSHLSAT ||
2296                  MI.getOpcode() == TargetOpcode::G_USHLSAT;
2297   // We can convert this to:
2298   //   1. Any extend iN to iM
2299   //   2. SHL by M-N
2300   //   3. [US][ADD|SUB|SHL]SAT
2301   //   4. L/ASHR by M-N
2302   //
2303   // It may be more efficient to lower this to a min and a max operation in
2304   // the higher precision arithmetic if the promoted operation isn't legal,
2305   // but this decision is up to the target's lowering request.
2306   Register DstReg = MI.getOperand(0).getReg();
2307 
2308   unsigned NewBits = WideTy.getScalarSizeInBits();
2309   unsigned SHLAmount = NewBits - MRI.getType(DstReg).getScalarSizeInBits();
2310 
2311   // Shifts must zero-extend the RHS to preserve the unsigned quantity, and
2312   // must not left shift the RHS to preserve the shift amount.
2313   auto LHS = MIRBuilder.buildAnyExt(WideTy, MI.getOperand(1));
2314   auto RHS = IsShift ? MIRBuilder.buildZExt(WideTy, MI.getOperand(2))
2315                      : MIRBuilder.buildAnyExt(WideTy, MI.getOperand(2));
2316   auto ShiftK = MIRBuilder.buildConstant(WideTy, SHLAmount);
2317   auto ShiftL = MIRBuilder.buildShl(WideTy, LHS, ShiftK);
2318   auto ShiftR = IsShift ? RHS : MIRBuilder.buildShl(WideTy, RHS, ShiftK);
2319 
2320   auto WideInst = MIRBuilder.buildInstr(MI.getOpcode(), {WideTy},
2321                                         {ShiftL, ShiftR}, MI.getFlags());
2322 
2323   // Use a shift that will preserve the number of sign bits when the trunc is
2324   // folded away.
2325   auto Result = IsSigned ? MIRBuilder.buildAShr(WideTy, WideInst, ShiftK)
2326                          : MIRBuilder.buildLShr(WideTy, WideInst, ShiftK);
2327 
2328   MIRBuilder.buildTrunc(DstReg, Result);
2329   MI.eraseFromParent();
2330   return Legalized;
2331 }
2332 
2333 LegalizerHelper::LegalizeResult
2334 LegalizerHelper::widenScalarMulo(MachineInstr &MI, unsigned TypeIdx,
2335                                  LLT WideTy) {
2336   if (TypeIdx == 1) {
2337     Observer.changingInstr(MI);
2338     widenScalarDst(MI, WideTy, 1);
2339     Observer.changedInstr(MI);
2340     return Legalized;
2341   }
2342 
2343   bool IsSigned = MI.getOpcode() == TargetOpcode::G_SMULO;
2344   auto [Result, OriginalOverflow, LHS, RHS] = MI.getFirst4Regs();
2345   LLT SrcTy = MRI.getType(LHS);
2346   LLT OverflowTy = MRI.getType(OriginalOverflow);
2347   unsigned SrcBitWidth = SrcTy.getScalarSizeInBits();
2348 
2349   // To determine if the result overflowed in the larger type, we extend the
2350   // input to the larger type, do the multiply (checking if it overflows),
2351   // then also check the high bits of the result to see if overflow happened
2352   // there.
2353   unsigned ExtOp = IsSigned ? TargetOpcode::G_SEXT : TargetOpcode::G_ZEXT;
2354   auto LeftOperand = MIRBuilder.buildInstr(ExtOp, {WideTy}, {LHS});
2355   auto RightOperand = MIRBuilder.buildInstr(ExtOp, {WideTy}, {RHS});
2356 
2357   // Multiplication cannot overflow if the WideTy is >= 2 * original width,
2358   // so we don't need to check the overflow result of larger type Mulo.
2359   bool WideMulCanOverflow = WideTy.getScalarSizeInBits() < 2 * SrcBitWidth;
2360 
2361   unsigned MulOpc =
2362       WideMulCanOverflow ? MI.getOpcode() : (unsigned)TargetOpcode::G_MUL;
2363 
2364   MachineInstrBuilder Mulo;
2365   if (WideMulCanOverflow)
2366     Mulo = MIRBuilder.buildInstr(MulOpc, {WideTy, OverflowTy},
2367                                  {LeftOperand, RightOperand});
2368   else
2369     Mulo = MIRBuilder.buildInstr(MulOpc, {WideTy}, {LeftOperand, RightOperand});
2370 
2371   auto Mul = Mulo->getOperand(0);
2372   MIRBuilder.buildTrunc(Result, Mul);
2373 
2374   MachineInstrBuilder ExtResult;
2375   // Overflow occurred if it occurred in the larger type, or if the high part
2376   // of the result does not zero/sign-extend the low part.  Check this second
2377   // possibility first.
2378   if (IsSigned) {
2379     // For signed, overflow occurred when the high part does not sign-extend
2380     // the low part.
2381     ExtResult = MIRBuilder.buildSExtInReg(WideTy, Mul, SrcBitWidth);
2382   } else {
2383     // Unsigned overflow occurred when the high part does not zero-extend the
2384     // low part.
2385     ExtResult = MIRBuilder.buildZExtInReg(WideTy, Mul, SrcBitWidth);
2386   }
2387 
2388   if (WideMulCanOverflow) {
2389     auto Overflow =
2390         MIRBuilder.buildICmp(CmpInst::ICMP_NE, OverflowTy, Mul, ExtResult);
2391     // Finally check if the multiplication in the larger type itself overflowed.
2392     MIRBuilder.buildOr(OriginalOverflow, Mulo->getOperand(1), Overflow);
2393   } else {
2394     MIRBuilder.buildICmp(CmpInst::ICMP_NE, OriginalOverflow, Mul, ExtResult);
2395   }
2396   MI.eraseFromParent();
2397   return Legalized;
2398 }
2399 
2400 LegalizerHelper::LegalizeResult
2401 LegalizerHelper::widenScalar(MachineInstr &MI, unsigned TypeIdx, LLT WideTy) {
2402   switch (MI.getOpcode()) {
2403   default:
2404     return UnableToLegalize;
2405   case TargetOpcode::G_ATOMICRMW_XCHG:
2406   case TargetOpcode::G_ATOMICRMW_ADD:
2407   case TargetOpcode::G_ATOMICRMW_SUB:
2408   case TargetOpcode::G_ATOMICRMW_AND:
2409   case TargetOpcode::G_ATOMICRMW_OR:
2410   case TargetOpcode::G_ATOMICRMW_XOR:
2411   case TargetOpcode::G_ATOMICRMW_MIN:
2412   case TargetOpcode::G_ATOMICRMW_MAX:
2413   case TargetOpcode::G_ATOMICRMW_UMIN:
2414   case TargetOpcode::G_ATOMICRMW_UMAX:
2415     assert(TypeIdx == 0 && "atomicrmw with second scalar type");
2416     Observer.changingInstr(MI);
2417     widenScalarSrc(MI, WideTy, 2, TargetOpcode::G_ANYEXT);
2418     widenScalarDst(MI, WideTy, 0);
2419     Observer.changedInstr(MI);
2420     return Legalized;
2421   case TargetOpcode::G_ATOMIC_CMPXCHG:
2422     assert(TypeIdx == 0 && "G_ATOMIC_CMPXCHG with second scalar type");
2423     Observer.changingInstr(MI);
2424     widenScalarSrc(MI, WideTy, 2, TargetOpcode::G_ANYEXT);
2425     widenScalarSrc(MI, WideTy, 3, TargetOpcode::G_ANYEXT);
2426     widenScalarDst(MI, WideTy, 0);
2427     Observer.changedInstr(MI);
2428     return Legalized;
2429   case TargetOpcode::G_ATOMIC_CMPXCHG_WITH_SUCCESS:
2430     if (TypeIdx == 0) {
2431       Observer.changingInstr(MI);
2432       widenScalarSrc(MI, WideTy, 3, TargetOpcode::G_ANYEXT);
2433       widenScalarSrc(MI, WideTy, 4, TargetOpcode::G_ANYEXT);
2434       widenScalarDst(MI, WideTy, 0);
2435       Observer.changedInstr(MI);
2436       return Legalized;
2437     }
2438     assert(TypeIdx == 1 &&
2439            "G_ATOMIC_CMPXCHG_WITH_SUCCESS with third scalar type");
2440     Observer.changingInstr(MI);
2441     widenScalarDst(MI, WideTy, 1);
2442     Observer.changedInstr(MI);
2443     return Legalized;
2444   case TargetOpcode::G_EXTRACT:
2445     return widenScalarExtract(MI, TypeIdx, WideTy);
2446   case TargetOpcode::G_INSERT:
2447     return widenScalarInsert(MI, TypeIdx, WideTy);
2448   case TargetOpcode::G_MERGE_VALUES:
2449     return widenScalarMergeValues(MI, TypeIdx, WideTy);
2450   case TargetOpcode::G_UNMERGE_VALUES:
2451     return widenScalarUnmergeValues(MI, TypeIdx, WideTy);
2452   case TargetOpcode::G_SADDO:
2453   case TargetOpcode::G_SSUBO:
2454   case TargetOpcode::G_UADDO:
2455   case TargetOpcode::G_USUBO:
2456   case TargetOpcode::G_SADDE:
2457   case TargetOpcode::G_SSUBE:
2458   case TargetOpcode::G_UADDE:
2459   case TargetOpcode::G_USUBE:
2460     return widenScalarAddSubOverflow(MI, TypeIdx, WideTy);
2461   case TargetOpcode::G_UMULO:
2462   case TargetOpcode::G_SMULO:
2463     return widenScalarMulo(MI, TypeIdx, WideTy);
2464   case TargetOpcode::G_SADDSAT:
2465   case TargetOpcode::G_SSUBSAT:
2466   case TargetOpcode::G_SSHLSAT:
2467   case TargetOpcode::G_UADDSAT:
2468   case TargetOpcode::G_USUBSAT:
2469   case TargetOpcode::G_USHLSAT:
2470     return widenScalarAddSubShlSat(MI, TypeIdx, WideTy);
2471   case TargetOpcode::G_CTTZ:
2472   case TargetOpcode::G_CTTZ_ZERO_UNDEF:
2473   case TargetOpcode::G_CTLZ:
2474   case TargetOpcode::G_CTLZ_ZERO_UNDEF:
2475   case TargetOpcode::G_CTPOP: {
2476     if (TypeIdx == 0) {
2477       Observer.changingInstr(MI);
2478       widenScalarDst(MI, WideTy, 0);
2479       Observer.changedInstr(MI);
2480       return Legalized;
2481     }
2482 
2483     Register SrcReg = MI.getOperand(1).getReg();
2484 
2485     // First extend the input.
2486     unsigned ExtOpc = MI.getOpcode() == TargetOpcode::G_CTTZ ||
2487                               MI.getOpcode() == TargetOpcode::G_CTTZ_ZERO_UNDEF
2488                           ? TargetOpcode::G_ANYEXT
2489                           : TargetOpcode::G_ZEXT;
2490     auto MIBSrc = MIRBuilder.buildInstr(ExtOpc, {WideTy}, {SrcReg});
2491     LLT CurTy = MRI.getType(SrcReg);
2492     unsigned NewOpc = MI.getOpcode();
2493     if (NewOpc == TargetOpcode::G_CTTZ) {
2494       // The count is the same in the larger type except if the original
2495       // value was zero.  This can be handled by setting the bit just off
2496       // the top of the original type.
2497       auto TopBit =
2498           APInt::getOneBitSet(WideTy.getSizeInBits(), CurTy.getSizeInBits());
2499       MIBSrc = MIRBuilder.buildOr(
2500         WideTy, MIBSrc, MIRBuilder.buildConstant(WideTy, TopBit));
2501       // Now we know the operand is non-zero, use the more relaxed opcode.
2502       NewOpc = TargetOpcode::G_CTTZ_ZERO_UNDEF;
2503     }
2504 
2505     // Perform the operation at the larger size.
2506     auto MIBNewOp = MIRBuilder.buildInstr(NewOpc, {WideTy}, {MIBSrc});
2507     // This is already the correct result for CTPOP and CTTZs
2508     if (MI.getOpcode() == TargetOpcode::G_CTLZ ||
2509         MI.getOpcode() == TargetOpcode::G_CTLZ_ZERO_UNDEF) {
2510       // The correct result is NewOp - (Difference in widety and current ty).
2511       unsigned SizeDiff = WideTy.getSizeInBits() - CurTy.getSizeInBits();
2512       MIBNewOp = MIRBuilder.buildSub(
2513           WideTy, MIBNewOp, MIRBuilder.buildConstant(WideTy, SizeDiff));
2514     }
2515 
2516     MIRBuilder.buildZExtOrTrunc(MI.getOperand(0), MIBNewOp);
2517     MI.eraseFromParent();
2518     return Legalized;
2519   }
2520   case TargetOpcode::G_BSWAP: {
2521     Observer.changingInstr(MI);
2522     Register DstReg = MI.getOperand(0).getReg();
2523 
2524     Register ShrReg = MRI.createGenericVirtualRegister(WideTy);
2525     Register DstExt = MRI.createGenericVirtualRegister(WideTy);
2526     Register ShiftAmtReg = MRI.createGenericVirtualRegister(WideTy);
2527     widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_ANYEXT);
2528 
2529     MI.getOperand(0).setReg(DstExt);
2530 
2531     MIRBuilder.setInsertPt(MIRBuilder.getMBB(), ++MIRBuilder.getInsertPt());
2532 
2533     LLT Ty = MRI.getType(DstReg);
2534     unsigned DiffBits = WideTy.getScalarSizeInBits() - Ty.getScalarSizeInBits();
2535     MIRBuilder.buildConstant(ShiftAmtReg, DiffBits);
2536     MIRBuilder.buildLShr(ShrReg, DstExt, ShiftAmtReg);
2537 
2538     MIRBuilder.buildTrunc(DstReg, ShrReg);
2539     Observer.changedInstr(MI);
2540     return Legalized;
2541   }
2542   case TargetOpcode::G_BITREVERSE: {
2543     Observer.changingInstr(MI);
2544 
2545     Register DstReg = MI.getOperand(0).getReg();
2546     LLT Ty = MRI.getType(DstReg);
2547     unsigned DiffBits = WideTy.getScalarSizeInBits() - Ty.getScalarSizeInBits();
2548 
2549     Register DstExt = MRI.createGenericVirtualRegister(WideTy);
2550     widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_ANYEXT);
2551     MI.getOperand(0).setReg(DstExt);
2552     MIRBuilder.setInsertPt(MIRBuilder.getMBB(), ++MIRBuilder.getInsertPt());
2553 
2554     auto ShiftAmt = MIRBuilder.buildConstant(WideTy, DiffBits);
2555     auto Shift = MIRBuilder.buildLShr(WideTy, DstExt, ShiftAmt);
2556     MIRBuilder.buildTrunc(DstReg, Shift);
2557     Observer.changedInstr(MI);
2558     return Legalized;
2559   }
2560   case TargetOpcode::G_FREEZE:
2561     Observer.changingInstr(MI);
2562     widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_ANYEXT);
2563     widenScalarDst(MI, WideTy);
2564     Observer.changedInstr(MI);
2565     return Legalized;
2566 
2567   case TargetOpcode::G_ABS:
2568     Observer.changingInstr(MI);
2569     widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_SEXT);
2570     widenScalarDst(MI, WideTy);
2571     Observer.changedInstr(MI);
2572     return Legalized;
2573 
2574   case TargetOpcode::G_ADD:
2575   case TargetOpcode::G_AND:
2576   case TargetOpcode::G_MUL:
2577   case TargetOpcode::G_OR:
2578   case TargetOpcode::G_XOR:
2579   case TargetOpcode::G_SUB:
2580     // Perform operation at larger width (any extension is fines here, high bits
2581     // don't affect the result) and then truncate the result back to the
2582     // original type.
2583     Observer.changingInstr(MI);
2584     widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_ANYEXT);
2585     widenScalarSrc(MI, WideTy, 2, TargetOpcode::G_ANYEXT);
2586     widenScalarDst(MI, WideTy);
2587     Observer.changedInstr(MI);
2588     return Legalized;
2589 
2590   case TargetOpcode::G_SBFX:
2591   case TargetOpcode::G_UBFX:
2592     Observer.changingInstr(MI);
2593 
2594     if (TypeIdx == 0) {
2595       widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_ANYEXT);
2596       widenScalarDst(MI, WideTy);
2597     } else {
2598       widenScalarSrc(MI, WideTy, 2, TargetOpcode::G_ZEXT);
2599       widenScalarSrc(MI, WideTy, 3, TargetOpcode::G_ZEXT);
2600     }
2601 
2602     Observer.changedInstr(MI);
2603     return Legalized;
2604 
2605   case TargetOpcode::G_SHL:
2606     Observer.changingInstr(MI);
2607 
2608     if (TypeIdx == 0) {
2609       widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_ANYEXT);
2610       widenScalarDst(MI, WideTy);
2611     } else {
2612       assert(TypeIdx == 1);
2613       // The "number of bits to shift" operand must preserve its value as an
2614       // unsigned integer:
2615       widenScalarSrc(MI, WideTy, 2, TargetOpcode::G_ZEXT);
2616     }
2617 
2618     Observer.changedInstr(MI);
2619     return Legalized;
2620 
2621   case TargetOpcode::G_ROTR:
2622   case TargetOpcode::G_ROTL:
2623     if (TypeIdx != 1)
2624       return UnableToLegalize;
2625 
2626     Observer.changingInstr(MI);
2627     widenScalarSrc(MI, WideTy, 2, TargetOpcode::G_ZEXT);
2628     Observer.changedInstr(MI);
2629     return Legalized;
2630 
2631   case TargetOpcode::G_SDIV:
2632   case TargetOpcode::G_SREM:
2633   case TargetOpcode::G_SMIN:
2634   case TargetOpcode::G_SMAX:
2635     Observer.changingInstr(MI);
2636     widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_SEXT);
2637     widenScalarSrc(MI, WideTy, 2, TargetOpcode::G_SEXT);
2638     widenScalarDst(MI, WideTy);
2639     Observer.changedInstr(MI);
2640     return Legalized;
2641 
2642   case TargetOpcode::G_SDIVREM:
2643     Observer.changingInstr(MI);
2644     widenScalarSrc(MI, WideTy, 2, TargetOpcode::G_SEXT);
2645     widenScalarSrc(MI, WideTy, 3, TargetOpcode::G_SEXT);
2646     widenScalarDst(MI, WideTy);
2647     widenScalarDst(MI, WideTy, 1);
2648     Observer.changedInstr(MI);
2649     return Legalized;
2650 
2651   case TargetOpcode::G_ASHR:
2652   case TargetOpcode::G_LSHR:
2653     Observer.changingInstr(MI);
2654 
2655     if (TypeIdx == 0) {
2656       unsigned CvtOp = MI.getOpcode() == TargetOpcode::G_ASHR ?
2657         TargetOpcode::G_SEXT : TargetOpcode::G_ZEXT;
2658 
2659       widenScalarSrc(MI, WideTy, 1, CvtOp);
2660       widenScalarDst(MI, WideTy);
2661     } else {
2662       assert(TypeIdx == 1);
2663       // The "number of bits to shift" operand must preserve its value as an
2664       // unsigned integer:
2665       widenScalarSrc(MI, WideTy, 2, TargetOpcode::G_ZEXT);
2666     }
2667 
2668     Observer.changedInstr(MI);
2669     return Legalized;
2670   case TargetOpcode::G_UDIV:
2671   case TargetOpcode::G_UREM:
2672   case TargetOpcode::G_UMIN:
2673   case TargetOpcode::G_UMAX:
2674     Observer.changingInstr(MI);
2675     widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_ZEXT);
2676     widenScalarSrc(MI, WideTy, 2, TargetOpcode::G_ZEXT);
2677     widenScalarDst(MI, WideTy);
2678     Observer.changedInstr(MI);
2679     return Legalized;
2680 
2681   case TargetOpcode::G_UDIVREM:
2682     Observer.changingInstr(MI);
2683     widenScalarSrc(MI, WideTy, 2, TargetOpcode::G_ZEXT);
2684     widenScalarSrc(MI, WideTy, 3, TargetOpcode::G_ZEXT);
2685     widenScalarDst(MI, WideTy);
2686     widenScalarDst(MI, WideTy, 1);
2687     Observer.changedInstr(MI);
2688     return Legalized;
2689 
2690   case TargetOpcode::G_SELECT:
2691     Observer.changingInstr(MI);
2692     if (TypeIdx == 0) {
2693       // Perform operation at larger width (any extension is fine here, high
2694       // bits don't affect the result) and then truncate the result back to the
2695       // original type.
2696       widenScalarSrc(MI, WideTy, 2, TargetOpcode::G_ANYEXT);
2697       widenScalarSrc(MI, WideTy, 3, TargetOpcode::G_ANYEXT);
2698       widenScalarDst(MI, WideTy);
2699     } else {
2700       bool IsVec = MRI.getType(MI.getOperand(1).getReg()).isVector();
2701       // Explicit extension is required here since high bits affect the result.
2702       widenScalarSrc(MI, WideTy, 1, MIRBuilder.getBoolExtOp(IsVec, false));
2703     }
2704     Observer.changedInstr(MI);
2705     return Legalized;
2706 
2707   case TargetOpcode::G_FPTOSI:
2708   case TargetOpcode::G_FPTOUI:
2709   case TargetOpcode::G_IS_FPCLASS:
2710     Observer.changingInstr(MI);
2711 
2712     if (TypeIdx == 0)
2713       widenScalarDst(MI, WideTy);
2714     else
2715       widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_FPEXT);
2716 
2717     Observer.changedInstr(MI);
2718     return Legalized;
2719   case TargetOpcode::G_SITOFP:
2720     Observer.changingInstr(MI);
2721 
2722     if (TypeIdx == 0)
2723       widenScalarDst(MI, WideTy, 0, TargetOpcode::G_FPTRUNC);
2724     else
2725       widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_SEXT);
2726 
2727     Observer.changedInstr(MI);
2728     return Legalized;
2729   case TargetOpcode::G_UITOFP:
2730     Observer.changingInstr(MI);
2731 
2732     if (TypeIdx == 0)
2733       widenScalarDst(MI, WideTy, 0, TargetOpcode::G_FPTRUNC);
2734     else
2735       widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_ZEXT);
2736 
2737     Observer.changedInstr(MI);
2738     return Legalized;
2739   case TargetOpcode::G_LOAD:
2740   case TargetOpcode::G_SEXTLOAD:
2741   case TargetOpcode::G_ZEXTLOAD:
2742     Observer.changingInstr(MI);
2743     widenScalarDst(MI, WideTy);
2744     Observer.changedInstr(MI);
2745     return Legalized;
2746 
2747   case TargetOpcode::G_STORE: {
2748     if (TypeIdx != 0)
2749       return UnableToLegalize;
2750 
2751     LLT Ty = MRI.getType(MI.getOperand(0).getReg());
2752     if (!Ty.isScalar())
2753       return UnableToLegalize;
2754 
2755     Observer.changingInstr(MI);
2756 
2757     unsigned ExtType = Ty.getScalarSizeInBits() == 1 ?
2758       TargetOpcode::G_ZEXT : TargetOpcode::G_ANYEXT;
2759     widenScalarSrc(MI, WideTy, 0, ExtType);
2760 
2761     Observer.changedInstr(MI);
2762     return Legalized;
2763   }
2764   case TargetOpcode::G_CONSTANT: {
2765     MachineOperand &SrcMO = MI.getOperand(1);
2766     LLVMContext &Ctx = MIRBuilder.getMF().getFunction().getContext();
2767     unsigned ExtOpc = LI.getExtOpcodeForWideningConstant(
2768         MRI.getType(MI.getOperand(0).getReg()));
2769     assert((ExtOpc == TargetOpcode::G_ZEXT || ExtOpc == TargetOpcode::G_SEXT ||
2770             ExtOpc == TargetOpcode::G_ANYEXT) &&
2771            "Illegal Extend");
2772     const APInt &SrcVal = SrcMO.getCImm()->getValue();
2773     const APInt &Val = (ExtOpc == TargetOpcode::G_SEXT)
2774                            ? SrcVal.sext(WideTy.getSizeInBits())
2775                            : SrcVal.zext(WideTy.getSizeInBits());
2776     Observer.changingInstr(MI);
2777     SrcMO.setCImm(ConstantInt::get(Ctx, Val));
2778 
2779     widenScalarDst(MI, WideTy);
2780     Observer.changedInstr(MI);
2781     return Legalized;
2782   }
2783   case TargetOpcode::G_FCONSTANT: {
2784     // To avoid changing the bits of the constant due to extension to a larger
2785     // type and then using G_FPTRUNC, we simply convert to a G_CONSTANT.
2786     MachineOperand &SrcMO = MI.getOperand(1);
2787     APInt Val = SrcMO.getFPImm()->getValueAPF().bitcastToAPInt();
2788     MIRBuilder.setInstrAndDebugLoc(MI);
2789     auto IntCst = MIRBuilder.buildConstant(MI.getOperand(0).getReg(), Val);
2790     widenScalarDst(*IntCst, WideTy, 0, TargetOpcode::G_TRUNC);
2791     MI.eraseFromParent();
2792     return Legalized;
2793   }
2794   case TargetOpcode::G_IMPLICIT_DEF: {
2795     Observer.changingInstr(MI);
2796     widenScalarDst(MI, WideTy);
2797     Observer.changedInstr(MI);
2798     return Legalized;
2799   }
2800   case TargetOpcode::G_BRCOND:
2801     Observer.changingInstr(MI);
2802     widenScalarSrc(MI, WideTy, 0, MIRBuilder.getBoolExtOp(false, false));
2803     Observer.changedInstr(MI);
2804     return Legalized;
2805 
2806   case TargetOpcode::G_FCMP:
2807     Observer.changingInstr(MI);
2808     if (TypeIdx == 0)
2809       widenScalarDst(MI, WideTy);
2810     else {
2811       widenScalarSrc(MI, WideTy, 2, TargetOpcode::G_FPEXT);
2812       widenScalarSrc(MI, WideTy, 3, TargetOpcode::G_FPEXT);
2813     }
2814     Observer.changedInstr(MI);
2815     return Legalized;
2816 
2817   case TargetOpcode::G_ICMP:
2818     Observer.changingInstr(MI);
2819     if (TypeIdx == 0)
2820       widenScalarDst(MI, WideTy);
2821     else {
2822       unsigned ExtOpcode = CmpInst::isSigned(static_cast<CmpInst::Predicate>(
2823                                MI.getOperand(1).getPredicate()))
2824                                ? TargetOpcode::G_SEXT
2825                                : TargetOpcode::G_ZEXT;
2826       widenScalarSrc(MI, WideTy, 2, ExtOpcode);
2827       widenScalarSrc(MI, WideTy, 3, ExtOpcode);
2828     }
2829     Observer.changedInstr(MI);
2830     return Legalized;
2831 
2832   case TargetOpcode::G_PTR_ADD:
2833     assert(TypeIdx == 1 && "unable to legalize pointer of G_PTR_ADD");
2834     Observer.changingInstr(MI);
2835     widenScalarSrc(MI, WideTy, 2, TargetOpcode::G_SEXT);
2836     Observer.changedInstr(MI);
2837     return Legalized;
2838 
2839   case TargetOpcode::G_PHI: {
2840     assert(TypeIdx == 0 && "Expecting only Idx 0");
2841 
2842     Observer.changingInstr(MI);
2843     for (unsigned I = 1; I < MI.getNumOperands(); I += 2) {
2844       MachineBasicBlock &OpMBB = *MI.getOperand(I + 1).getMBB();
2845       MIRBuilder.setInsertPt(OpMBB, OpMBB.getFirstTerminatorForward());
2846       widenScalarSrc(MI, WideTy, I, TargetOpcode::G_ANYEXT);
2847     }
2848 
2849     MachineBasicBlock &MBB = *MI.getParent();
2850     MIRBuilder.setInsertPt(MBB, --MBB.getFirstNonPHI());
2851     widenScalarDst(MI, WideTy);
2852     Observer.changedInstr(MI);
2853     return Legalized;
2854   }
2855   case TargetOpcode::G_EXTRACT_VECTOR_ELT: {
2856     if (TypeIdx == 0) {
2857       Register VecReg = MI.getOperand(1).getReg();
2858       LLT VecTy = MRI.getType(VecReg);
2859       Observer.changingInstr(MI);
2860 
2861       widenScalarSrc(
2862           MI, LLT::vector(VecTy.getElementCount(), WideTy.getSizeInBits()), 1,
2863           TargetOpcode::G_ANYEXT);
2864 
2865       widenScalarDst(MI, WideTy, 0);
2866       Observer.changedInstr(MI);
2867       return Legalized;
2868     }
2869 
2870     if (TypeIdx != 2)
2871       return UnableToLegalize;
2872     Observer.changingInstr(MI);
2873     // TODO: Probably should be zext
2874     widenScalarSrc(MI, WideTy, 2, TargetOpcode::G_SEXT);
2875     Observer.changedInstr(MI);
2876     return Legalized;
2877   }
2878   case TargetOpcode::G_INSERT_VECTOR_ELT: {
2879     if (TypeIdx == 0) {
2880       Observer.changingInstr(MI);
2881       const LLT WideEltTy = WideTy.getElementType();
2882 
2883       widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_ANYEXT);
2884       widenScalarSrc(MI, WideEltTy, 2, TargetOpcode::G_ANYEXT);
2885       widenScalarDst(MI, WideTy, 0);
2886       Observer.changedInstr(MI);
2887       return Legalized;
2888     }
2889 
2890     if (TypeIdx == 1) {
2891       Observer.changingInstr(MI);
2892 
2893       Register VecReg = MI.getOperand(1).getReg();
2894       LLT VecTy = MRI.getType(VecReg);
2895       LLT WideVecTy = LLT::vector(VecTy.getElementCount(), WideTy);
2896 
2897       widenScalarSrc(MI, WideVecTy, 1, TargetOpcode::G_ANYEXT);
2898       widenScalarSrc(MI, WideTy, 2, TargetOpcode::G_ANYEXT);
2899       widenScalarDst(MI, WideVecTy, 0);
2900       Observer.changedInstr(MI);
2901       return Legalized;
2902     }
2903 
2904     if (TypeIdx == 2) {
2905       Observer.changingInstr(MI);
2906       // TODO: Probably should be zext
2907       widenScalarSrc(MI, WideTy, 3, TargetOpcode::G_SEXT);
2908       Observer.changedInstr(MI);
2909       return Legalized;
2910     }
2911 
2912     return UnableToLegalize;
2913   }
2914   case TargetOpcode::G_FADD:
2915   case TargetOpcode::G_FMUL:
2916   case TargetOpcode::G_FSUB:
2917   case TargetOpcode::G_FMA:
2918   case TargetOpcode::G_FMAD:
2919   case TargetOpcode::G_FNEG:
2920   case TargetOpcode::G_FABS:
2921   case TargetOpcode::G_FCANONICALIZE:
2922   case TargetOpcode::G_FMINNUM:
2923   case TargetOpcode::G_FMAXNUM:
2924   case TargetOpcode::G_FMINNUM_IEEE:
2925   case TargetOpcode::G_FMAXNUM_IEEE:
2926   case TargetOpcode::G_FMINIMUM:
2927   case TargetOpcode::G_FMAXIMUM:
2928   case TargetOpcode::G_FDIV:
2929   case TargetOpcode::G_FREM:
2930   case TargetOpcode::G_FCEIL:
2931   case TargetOpcode::G_FFLOOR:
2932   case TargetOpcode::G_FCOS:
2933   case TargetOpcode::G_FSIN:
2934   case TargetOpcode::G_FLOG10:
2935   case TargetOpcode::G_FLOG:
2936   case TargetOpcode::G_FLOG2:
2937   case TargetOpcode::G_FRINT:
2938   case TargetOpcode::G_FNEARBYINT:
2939   case TargetOpcode::G_FSQRT:
2940   case TargetOpcode::G_FEXP:
2941   case TargetOpcode::G_FEXP2:
2942   case TargetOpcode::G_FEXP10:
2943   case TargetOpcode::G_FPOW:
2944   case TargetOpcode::G_INTRINSIC_TRUNC:
2945   case TargetOpcode::G_INTRINSIC_ROUND:
2946   case TargetOpcode::G_INTRINSIC_ROUNDEVEN:
2947     assert(TypeIdx == 0);
2948     Observer.changingInstr(MI);
2949 
2950     for (unsigned I = 1, E = MI.getNumOperands(); I != E; ++I)
2951       widenScalarSrc(MI, WideTy, I, TargetOpcode::G_FPEXT);
2952 
2953     widenScalarDst(MI, WideTy, 0, TargetOpcode::G_FPTRUNC);
2954     Observer.changedInstr(MI);
2955     return Legalized;
2956   case TargetOpcode::G_FPOWI:
2957   case TargetOpcode::G_FLDEXP:
2958   case TargetOpcode::G_STRICT_FLDEXP: {
2959     if (TypeIdx == 0) {
2960       if (MI.getOpcode() == TargetOpcode::G_STRICT_FLDEXP)
2961         return UnableToLegalize;
2962 
2963       Observer.changingInstr(MI);
2964       widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_FPEXT);
2965       widenScalarDst(MI, WideTy, 0, TargetOpcode::G_FPTRUNC);
2966       Observer.changedInstr(MI);
2967       return Legalized;
2968     }
2969 
2970     if (TypeIdx == 1) {
2971       // For some reason SelectionDAG tries to promote to a libcall without
2972       // actually changing the integer type for promotion.
2973       Observer.changingInstr(MI);
2974       widenScalarSrc(MI, WideTy, 2, TargetOpcode::G_SEXT);
2975       Observer.changedInstr(MI);
2976       return Legalized;
2977     }
2978 
2979     return UnableToLegalize;
2980   }
2981   case TargetOpcode::G_FFREXP: {
2982     Observer.changingInstr(MI);
2983 
2984     if (TypeIdx == 0) {
2985       widenScalarSrc(MI, WideTy, 2, TargetOpcode::G_FPEXT);
2986       widenScalarDst(MI, WideTy, 0, TargetOpcode::G_FPTRUNC);
2987     } else {
2988       widenScalarDst(MI, WideTy, 1);
2989     }
2990 
2991     Observer.changedInstr(MI);
2992     return Legalized;
2993   }
2994   case TargetOpcode::G_INTTOPTR:
2995     if (TypeIdx != 1)
2996       return UnableToLegalize;
2997 
2998     Observer.changingInstr(MI);
2999     widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_ZEXT);
3000     Observer.changedInstr(MI);
3001     return Legalized;
3002   case TargetOpcode::G_PTRTOINT:
3003     if (TypeIdx != 0)
3004       return UnableToLegalize;
3005 
3006     Observer.changingInstr(MI);
3007     widenScalarDst(MI, WideTy, 0);
3008     Observer.changedInstr(MI);
3009     return Legalized;
3010   case TargetOpcode::G_BUILD_VECTOR: {
3011     Observer.changingInstr(MI);
3012 
3013     const LLT WideEltTy = TypeIdx == 1 ? WideTy : WideTy.getElementType();
3014     for (int I = 1, E = MI.getNumOperands(); I != E; ++I)
3015       widenScalarSrc(MI, WideEltTy, I, TargetOpcode::G_ANYEXT);
3016 
3017     // Avoid changing the result vector type if the source element type was
3018     // requested.
3019     if (TypeIdx == 1) {
3020       MI.setDesc(MIRBuilder.getTII().get(TargetOpcode::G_BUILD_VECTOR_TRUNC));
3021     } else {
3022       widenScalarDst(MI, WideTy, 0);
3023     }
3024 
3025     Observer.changedInstr(MI);
3026     return Legalized;
3027   }
3028   case TargetOpcode::G_SEXT_INREG:
3029     if (TypeIdx != 0)
3030       return UnableToLegalize;
3031 
3032     Observer.changingInstr(MI);
3033     widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_ANYEXT);
3034     widenScalarDst(MI, WideTy, 0, TargetOpcode::G_TRUNC);
3035     Observer.changedInstr(MI);
3036     return Legalized;
3037   case TargetOpcode::G_PTRMASK: {
3038     if (TypeIdx != 1)
3039       return UnableToLegalize;
3040     Observer.changingInstr(MI);
3041     widenScalarSrc(MI, WideTy, 2, TargetOpcode::G_ZEXT);
3042     Observer.changedInstr(MI);
3043     return Legalized;
3044   }
3045   case TargetOpcode::G_VECREDUCE_FADD:
3046   case TargetOpcode::G_VECREDUCE_FMUL:
3047   case TargetOpcode::G_VECREDUCE_FMIN:
3048   case TargetOpcode::G_VECREDUCE_FMAX:
3049   case TargetOpcode::G_VECREDUCE_FMINIMUM:
3050   case TargetOpcode::G_VECREDUCE_FMAXIMUM:
3051     if (TypeIdx != 0)
3052       return UnableToLegalize;
3053     Observer.changingInstr(MI);
3054     Register VecReg = MI.getOperand(1).getReg();
3055     LLT VecTy = MRI.getType(VecReg);
3056     LLT WideVecTy = VecTy.isVector()
3057                         ? LLT::vector(VecTy.getElementCount(), WideTy)
3058                         : WideTy;
3059     widenScalarSrc(MI, WideVecTy, 1, TargetOpcode::G_FPEXT);
3060     widenScalarDst(MI, WideTy, 0, TargetOpcode::G_FPTRUNC);
3061     Observer.changedInstr(MI);
3062     return Legalized;
3063   }
3064 }
3065 
3066 static void getUnmergePieces(SmallVectorImpl<Register> &Pieces,
3067                              MachineIRBuilder &B, Register Src, LLT Ty) {
3068   auto Unmerge = B.buildUnmerge(Ty, Src);
3069   for (int I = 0, E = Unmerge->getNumOperands() - 1; I != E; ++I)
3070     Pieces.push_back(Unmerge.getReg(I));
3071 }
3072 
3073 LegalizerHelper::LegalizeResult
3074 LegalizerHelper::lowerFConstant(MachineInstr &MI) {
3075   Register Dst = MI.getOperand(0).getReg();
3076 
3077   MachineFunction &MF = MIRBuilder.getMF();
3078   const DataLayout &DL = MIRBuilder.getDataLayout();
3079 
3080   unsigned AddrSpace = DL.getDefaultGlobalsAddressSpace();
3081   LLT AddrPtrTy = LLT::pointer(AddrSpace, DL.getPointerSizeInBits(AddrSpace));
3082   Align Alignment = Align(DL.getABITypeAlign(
3083       getFloatTypeForLLT(MF.getFunction().getContext(), MRI.getType(Dst))));
3084 
3085   auto Addr = MIRBuilder.buildConstantPool(
3086       AddrPtrTy, MF.getConstantPool()->getConstantPoolIndex(
3087                      MI.getOperand(1).getFPImm(), Alignment));
3088 
3089   MachineMemOperand *MMO = MF.getMachineMemOperand(
3090       MachinePointerInfo::getConstantPool(MF), MachineMemOperand::MOLoad,
3091       MRI.getType(Dst), Alignment);
3092 
3093   MIRBuilder.buildLoadInstr(TargetOpcode::G_LOAD, Dst, Addr, *MMO);
3094   MI.eraseFromParent();
3095 
3096   return Legalized;
3097 }
3098 
3099 LegalizerHelper::LegalizeResult
3100 LegalizerHelper::lowerBitcast(MachineInstr &MI) {
3101   auto [Dst, DstTy, Src, SrcTy] = MI.getFirst2RegLLTs();
3102   if (SrcTy.isVector()) {
3103     LLT SrcEltTy = SrcTy.getElementType();
3104     SmallVector<Register, 8> SrcRegs;
3105 
3106     if (DstTy.isVector()) {
3107       int NumDstElt = DstTy.getNumElements();
3108       int NumSrcElt = SrcTy.getNumElements();
3109 
3110       LLT DstEltTy = DstTy.getElementType();
3111       LLT DstCastTy = DstEltTy; // Intermediate bitcast result type
3112       LLT SrcPartTy = SrcEltTy; // Original unmerge result type.
3113 
3114       // If there's an element size mismatch, insert intermediate casts to match
3115       // the result element type.
3116       if (NumSrcElt < NumDstElt) { // Source element type is larger.
3117         // %1:_(<4 x s8>) = G_BITCAST %0:_(<2 x s16>)
3118         //
3119         // =>
3120         //
3121         // %2:_(s16), %3:_(s16) = G_UNMERGE_VALUES %0
3122         // %3:_(<2 x s8>) = G_BITCAST %2
3123         // %4:_(<2 x s8>) = G_BITCAST %3
3124         // %1:_(<4 x s16>) = G_CONCAT_VECTORS %3, %4
3125         DstCastTy = LLT::fixed_vector(NumDstElt / NumSrcElt, DstEltTy);
3126         SrcPartTy = SrcEltTy;
3127       } else if (NumSrcElt > NumDstElt) { // Source element type is smaller.
3128         //
3129         // %1:_(<2 x s16>) = G_BITCAST %0:_(<4 x s8>)
3130         //
3131         // =>
3132         //
3133         // %2:_(<2 x s8>), %3:_(<2 x s8>) = G_UNMERGE_VALUES %0
3134         // %3:_(s16) = G_BITCAST %2
3135         // %4:_(s16) = G_BITCAST %3
3136         // %1:_(<2 x s16>) = G_BUILD_VECTOR %3, %4
3137         SrcPartTy = LLT::fixed_vector(NumSrcElt / NumDstElt, SrcEltTy);
3138         DstCastTy = DstEltTy;
3139       }
3140 
3141       getUnmergePieces(SrcRegs, MIRBuilder, Src, SrcPartTy);
3142       for (Register &SrcReg : SrcRegs)
3143         SrcReg = MIRBuilder.buildBitcast(DstCastTy, SrcReg).getReg(0);
3144     } else
3145       getUnmergePieces(SrcRegs, MIRBuilder, Src, SrcEltTy);
3146 
3147     MIRBuilder.buildMergeLikeInstr(Dst, SrcRegs);
3148     MI.eraseFromParent();
3149     return Legalized;
3150   }
3151 
3152   if (DstTy.isVector()) {
3153     SmallVector<Register, 8> SrcRegs;
3154     getUnmergePieces(SrcRegs, MIRBuilder, Src, DstTy.getElementType());
3155     MIRBuilder.buildMergeLikeInstr(Dst, SrcRegs);
3156     MI.eraseFromParent();
3157     return Legalized;
3158   }
3159 
3160   return UnableToLegalize;
3161 }
3162 
3163 /// Figure out the bit offset into a register when coercing a vector index for
3164 /// the wide element type. This is only for the case when promoting vector to
3165 /// one with larger elements.
3166 //
3167 ///
3168 /// %offset_idx = G_AND %idx, ~(-1 << Log2(DstEltSize / SrcEltSize))
3169 /// %offset_bits = G_SHL %offset_idx, Log2(SrcEltSize)
3170 static Register getBitcastWiderVectorElementOffset(MachineIRBuilder &B,
3171                                                    Register Idx,
3172                                                    unsigned NewEltSize,
3173                                                    unsigned OldEltSize) {
3174   const unsigned Log2EltRatio = Log2_32(NewEltSize / OldEltSize);
3175   LLT IdxTy = B.getMRI()->getType(Idx);
3176 
3177   // Now figure out the amount we need to shift to get the target bits.
3178   auto OffsetMask = B.buildConstant(
3179       IdxTy, ~(APInt::getAllOnes(IdxTy.getSizeInBits()) << Log2EltRatio));
3180   auto OffsetIdx = B.buildAnd(IdxTy, Idx, OffsetMask);
3181   return B.buildShl(IdxTy, OffsetIdx,
3182                     B.buildConstant(IdxTy, Log2_32(OldEltSize))).getReg(0);
3183 }
3184 
3185 /// Perform a G_EXTRACT_VECTOR_ELT in a different sized vector element. If this
3186 /// is casting to a vector with a smaller element size, perform multiple element
3187 /// extracts and merge the results. If this is coercing to a vector with larger
3188 /// elements, index the bitcasted vector and extract the target element with bit
3189 /// operations. This is intended to force the indexing in the native register
3190 /// size for architectures that can dynamically index the register file.
3191 LegalizerHelper::LegalizeResult
3192 LegalizerHelper::bitcastExtractVectorElt(MachineInstr &MI, unsigned TypeIdx,
3193                                          LLT CastTy) {
3194   if (TypeIdx != 1)
3195     return UnableToLegalize;
3196 
3197   auto [Dst, DstTy, SrcVec, SrcVecTy, Idx, IdxTy] = MI.getFirst3RegLLTs();
3198 
3199   LLT SrcEltTy = SrcVecTy.getElementType();
3200   unsigned NewNumElts = CastTy.isVector() ? CastTy.getNumElements() : 1;
3201   unsigned OldNumElts = SrcVecTy.getNumElements();
3202 
3203   LLT NewEltTy = CastTy.isVector() ? CastTy.getElementType() : CastTy;
3204   Register CastVec = MIRBuilder.buildBitcast(CastTy, SrcVec).getReg(0);
3205 
3206   const unsigned NewEltSize = NewEltTy.getSizeInBits();
3207   const unsigned OldEltSize = SrcEltTy.getSizeInBits();
3208   if (NewNumElts > OldNumElts) {
3209     // Decreasing the vector element size
3210     //
3211     // e.g. i64 = extract_vector_elt x:v2i64, y:i32
3212     //  =>
3213     //  v4i32:castx = bitcast x:v2i64
3214     //
3215     // i64 = bitcast
3216     //   (v2i32 build_vector (i32 (extract_vector_elt castx, (2 * y))),
3217     //                       (i32 (extract_vector_elt castx, (2 * y + 1)))
3218     //
3219     if (NewNumElts % OldNumElts != 0)
3220       return UnableToLegalize;
3221 
3222     // Type of the intermediate result vector.
3223     const unsigned NewEltsPerOldElt = NewNumElts / OldNumElts;
3224     LLT MidTy =
3225         LLT::scalarOrVector(ElementCount::getFixed(NewEltsPerOldElt), NewEltTy);
3226 
3227     auto NewEltsPerOldEltK = MIRBuilder.buildConstant(IdxTy, NewEltsPerOldElt);
3228 
3229     SmallVector<Register, 8> NewOps(NewEltsPerOldElt);
3230     auto NewBaseIdx = MIRBuilder.buildMul(IdxTy, Idx, NewEltsPerOldEltK);
3231 
3232     for (unsigned I = 0; I < NewEltsPerOldElt; ++I) {
3233       auto IdxOffset = MIRBuilder.buildConstant(IdxTy, I);
3234       auto TmpIdx = MIRBuilder.buildAdd(IdxTy, NewBaseIdx, IdxOffset);
3235       auto Elt = MIRBuilder.buildExtractVectorElement(NewEltTy, CastVec, TmpIdx);
3236       NewOps[I] = Elt.getReg(0);
3237     }
3238 
3239     auto NewVec = MIRBuilder.buildBuildVector(MidTy, NewOps);
3240     MIRBuilder.buildBitcast(Dst, NewVec);
3241     MI.eraseFromParent();
3242     return Legalized;
3243   }
3244 
3245   if (NewNumElts < OldNumElts) {
3246     if (NewEltSize % OldEltSize != 0)
3247       return UnableToLegalize;
3248 
3249     // This only depends on powers of 2 because we use bit tricks to figure out
3250     // the bit offset we need to shift to get the target element. A general
3251     // expansion could emit division/multiply.
3252     if (!isPowerOf2_32(NewEltSize / OldEltSize))
3253       return UnableToLegalize;
3254 
3255     // Increasing the vector element size.
3256     // %elt:_(small_elt) = G_EXTRACT_VECTOR_ELT %vec:_(<N x small_elt>), %idx
3257     //
3258     //   =>
3259     //
3260     // %cast = G_BITCAST %vec
3261     // %scaled_idx = G_LSHR %idx, Log2(DstEltSize / SrcEltSize)
3262     // %wide_elt  = G_EXTRACT_VECTOR_ELT %cast, %scaled_idx
3263     // %offset_idx = G_AND %idx, ~(-1 << Log2(DstEltSize / SrcEltSize))
3264     // %offset_bits = G_SHL %offset_idx, Log2(SrcEltSize)
3265     // %elt_bits = G_LSHR %wide_elt, %offset_bits
3266     // %elt = G_TRUNC %elt_bits
3267 
3268     const unsigned Log2EltRatio = Log2_32(NewEltSize / OldEltSize);
3269     auto Log2Ratio = MIRBuilder.buildConstant(IdxTy, Log2EltRatio);
3270 
3271     // Divide to get the index in the wider element type.
3272     auto ScaledIdx = MIRBuilder.buildLShr(IdxTy, Idx, Log2Ratio);
3273 
3274     Register WideElt = CastVec;
3275     if (CastTy.isVector()) {
3276       WideElt = MIRBuilder.buildExtractVectorElement(NewEltTy, CastVec,
3277                                                      ScaledIdx).getReg(0);
3278     }
3279 
3280     // Compute the bit offset into the register of the target element.
3281     Register OffsetBits = getBitcastWiderVectorElementOffset(
3282       MIRBuilder, Idx, NewEltSize, OldEltSize);
3283 
3284     // Shift the wide element to get the target element.
3285     auto ExtractedBits = MIRBuilder.buildLShr(NewEltTy, WideElt, OffsetBits);
3286     MIRBuilder.buildTrunc(Dst, ExtractedBits);
3287     MI.eraseFromParent();
3288     return Legalized;
3289   }
3290 
3291   return UnableToLegalize;
3292 }
3293 
3294 /// Emit code to insert \p InsertReg into \p TargetRet at \p OffsetBits in \p
3295 /// TargetReg, while preserving other bits in \p TargetReg.
3296 ///
3297 /// (InsertReg << Offset) | (TargetReg & ~(-1 >> InsertReg.size()) << Offset)
3298 static Register buildBitFieldInsert(MachineIRBuilder &B,
3299                                     Register TargetReg, Register InsertReg,
3300                                     Register OffsetBits) {
3301   LLT TargetTy = B.getMRI()->getType(TargetReg);
3302   LLT InsertTy = B.getMRI()->getType(InsertReg);
3303   auto ZextVal = B.buildZExt(TargetTy, InsertReg);
3304   auto ShiftedInsertVal = B.buildShl(TargetTy, ZextVal, OffsetBits);
3305 
3306   // Produce a bitmask of the value to insert
3307   auto EltMask = B.buildConstant(
3308     TargetTy, APInt::getLowBitsSet(TargetTy.getSizeInBits(),
3309                                    InsertTy.getSizeInBits()));
3310   // Shift it into position
3311   auto ShiftedMask = B.buildShl(TargetTy, EltMask, OffsetBits);
3312   auto InvShiftedMask = B.buildNot(TargetTy, ShiftedMask);
3313 
3314   // Clear out the bits in the wide element
3315   auto MaskedOldElt = B.buildAnd(TargetTy, TargetReg, InvShiftedMask);
3316 
3317   // The value to insert has all zeros already, so stick it into the masked
3318   // wide element.
3319   return B.buildOr(TargetTy, MaskedOldElt, ShiftedInsertVal).getReg(0);
3320 }
3321 
3322 /// Perform a G_INSERT_VECTOR_ELT in a different sized vector element. If this
3323 /// is increasing the element size, perform the indexing in the target element
3324 /// type, and use bit operations to insert at the element position. This is
3325 /// intended for architectures that can dynamically index the register file and
3326 /// want to force indexing in the native register size.
3327 LegalizerHelper::LegalizeResult
3328 LegalizerHelper::bitcastInsertVectorElt(MachineInstr &MI, unsigned TypeIdx,
3329                                         LLT CastTy) {
3330   if (TypeIdx != 0)
3331     return UnableToLegalize;
3332 
3333   auto [Dst, DstTy, SrcVec, SrcVecTy, Val, ValTy, Idx, IdxTy] =
3334       MI.getFirst4RegLLTs();
3335   LLT VecTy = DstTy;
3336 
3337   LLT VecEltTy = VecTy.getElementType();
3338   LLT NewEltTy = CastTy.isVector() ? CastTy.getElementType() : CastTy;
3339   const unsigned NewEltSize = NewEltTy.getSizeInBits();
3340   const unsigned OldEltSize = VecEltTy.getSizeInBits();
3341 
3342   unsigned NewNumElts = CastTy.isVector() ? CastTy.getNumElements() : 1;
3343   unsigned OldNumElts = VecTy.getNumElements();
3344 
3345   Register CastVec = MIRBuilder.buildBitcast(CastTy, SrcVec).getReg(0);
3346   if (NewNumElts < OldNumElts) {
3347     if (NewEltSize % OldEltSize != 0)
3348       return UnableToLegalize;
3349 
3350     // This only depends on powers of 2 because we use bit tricks to figure out
3351     // the bit offset we need to shift to get the target element. A general
3352     // expansion could emit division/multiply.
3353     if (!isPowerOf2_32(NewEltSize / OldEltSize))
3354       return UnableToLegalize;
3355 
3356     const unsigned Log2EltRatio = Log2_32(NewEltSize / OldEltSize);
3357     auto Log2Ratio = MIRBuilder.buildConstant(IdxTy, Log2EltRatio);
3358 
3359     // Divide to get the index in the wider element type.
3360     auto ScaledIdx = MIRBuilder.buildLShr(IdxTy, Idx, Log2Ratio);
3361 
3362     Register ExtractedElt = CastVec;
3363     if (CastTy.isVector()) {
3364       ExtractedElt = MIRBuilder.buildExtractVectorElement(NewEltTy, CastVec,
3365                                                           ScaledIdx).getReg(0);
3366     }
3367 
3368     // Compute the bit offset into the register of the target element.
3369     Register OffsetBits = getBitcastWiderVectorElementOffset(
3370       MIRBuilder, Idx, NewEltSize, OldEltSize);
3371 
3372     Register InsertedElt = buildBitFieldInsert(MIRBuilder, ExtractedElt,
3373                                                Val, OffsetBits);
3374     if (CastTy.isVector()) {
3375       InsertedElt = MIRBuilder.buildInsertVectorElement(
3376         CastTy, CastVec, InsertedElt, ScaledIdx).getReg(0);
3377     }
3378 
3379     MIRBuilder.buildBitcast(Dst, InsertedElt);
3380     MI.eraseFromParent();
3381     return Legalized;
3382   }
3383 
3384   return UnableToLegalize;
3385 }
3386 
3387 LegalizerHelper::LegalizeResult LegalizerHelper::lowerLoad(GAnyLoad &LoadMI) {
3388   // Lower to a memory-width G_LOAD and a G_SEXT/G_ZEXT/G_ANYEXT
3389   Register DstReg = LoadMI.getDstReg();
3390   Register PtrReg = LoadMI.getPointerReg();
3391   LLT DstTy = MRI.getType(DstReg);
3392   MachineMemOperand &MMO = LoadMI.getMMO();
3393   LLT MemTy = MMO.getMemoryType();
3394   MachineFunction &MF = MIRBuilder.getMF();
3395 
3396   unsigned MemSizeInBits = MemTy.getSizeInBits();
3397   unsigned MemStoreSizeInBits = 8 * MemTy.getSizeInBytes();
3398 
3399   if (MemSizeInBits != MemStoreSizeInBits) {
3400     if (MemTy.isVector())
3401       return UnableToLegalize;
3402 
3403     // Promote to a byte-sized load if not loading an integral number of
3404     // bytes.  For example, promote EXTLOAD:i20 -> EXTLOAD:i24.
3405     LLT WideMemTy = LLT::scalar(MemStoreSizeInBits);
3406     MachineMemOperand *NewMMO =
3407         MF.getMachineMemOperand(&MMO, MMO.getPointerInfo(), WideMemTy);
3408 
3409     Register LoadReg = DstReg;
3410     LLT LoadTy = DstTy;
3411 
3412     // If this wasn't already an extending load, we need to widen the result
3413     // register to avoid creating a load with a narrower result than the source.
3414     if (MemStoreSizeInBits > DstTy.getSizeInBits()) {
3415       LoadTy = WideMemTy;
3416       LoadReg = MRI.createGenericVirtualRegister(WideMemTy);
3417     }
3418 
3419     if (isa<GSExtLoad>(LoadMI)) {
3420       auto NewLoad = MIRBuilder.buildLoad(LoadTy, PtrReg, *NewMMO);
3421       MIRBuilder.buildSExtInReg(LoadReg, NewLoad, MemSizeInBits);
3422     } else if (isa<GZExtLoad>(LoadMI) || WideMemTy == LoadTy) {
3423       auto NewLoad = MIRBuilder.buildLoad(LoadTy, PtrReg, *NewMMO);
3424       // The extra bits are guaranteed to be zero, since we stored them that
3425       // way.  A zext load from Wide thus automatically gives zext from MemVT.
3426       MIRBuilder.buildAssertZExt(LoadReg, NewLoad, MemSizeInBits);
3427     } else {
3428       MIRBuilder.buildLoad(LoadReg, PtrReg, *NewMMO);
3429     }
3430 
3431     if (DstTy != LoadTy)
3432       MIRBuilder.buildTrunc(DstReg, LoadReg);
3433 
3434     LoadMI.eraseFromParent();
3435     return Legalized;
3436   }
3437 
3438   // Big endian lowering not implemented.
3439   if (MIRBuilder.getDataLayout().isBigEndian())
3440     return UnableToLegalize;
3441 
3442   // This load needs splitting into power of 2 sized loads.
3443   //
3444   // Our strategy here is to generate anyextending loads for the smaller
3445   // types up to next power-2 result type, and then combine the two larger
3446   // result values together, before truncating back down to the non-pow-2
3447   // type.
3448   // E.g. v1 = i24 load =>
3449   // v2 = i32 zextload (2 byte)
3450   // v3 = i32 load (1 byte)
3451   // v4 = i32 shl v3, 16
3452   // v5 = i32 or v4, v2
3453   // v1 = i24 trunc v5
3454   // By doing this we generate the correct truncate which should get
3455   // combined away as an artifact with a matching extend.
3456 
3457   uint64_t LargeSplitSize, SmallSplitSize;
3458 
3459   if (!isPowerOf2_32(MemSizeInBits)) {
3460     // This load needs splitting into power of 2 sized loads.
3461     LargeSplitSize = llvm::bit_floor(MemSizeInBits);
3462     SmallSplitSize = MemSizeInBits - LargeSplitSize;
3463   } else {
3464     // This is already a power of 2, but we still need to split this in half.
3465     //
3466     // Assume we're being asked to decompose an unaligned load.
3467     // TODO: If this requires multiple splits, handle them all at once.
3468     auto &Ctx = MF.getFunction().getContext();
3469     if (TLI.allowsMemoryAccess(Ctx, MIRBuilder.getDataLayout(), MemTy, MMO))
3470       return UnableToLegalize;
3471 
3472     SmallSplitSize = LargeSplitSize = MemSizeInBits / 2;
3473   }
3474 
3475   if (MemTy.isVector()) {
3476     // TODO: Handle vector extloads
3477     if (MemTy != DstTy)
3478       return UnableToLegalize;
3479 
3480     // TODO: We can do better than scalarizing the vector and at least split it
3481     // in half.
3482     return reduceLoadStoreWidth(LoadMI, 0, DstTy.getElementType());
3483   }
3484 
3485   MachineMemOperand *LargeMMO =
3486       MF.getMachineMemOperand(&MMO, 0, LargeSplitSize / 8);
3487   MachineMemOperand *SmallMMO =
3488       MF.getMachineMemOperand(&MMO, LargeSplitSize / 8, SmallSplitSize / 8);
3489 
3490   LLT PtrTy = MRI.getType(PtrReg);
3491   unsigned AnyExtSize = PowerOf2Ceil(DstTy.getSizeInBits());
3492   LLT AnyExtTy = LLT::scalar(AnyExtSize);
3493   auto LargeLoad = MIRBuilder.buildLoadInstr(TargetOpcode::G_ZEXTLOAD, AnyExtTy,
3494                                              PtrReg, *LargeMMO);
3495 
3496   auto OffsetCst = MIRBuilder.buildConstant(LLT::scalar(PtrTy.getSizeInBits()),
3497                                             LargeSplitSize / 8);
3498   Register PtrAddReg = MRI.createGenericVirtualRegister(PtrTy);
3499   auto SmallPtr = MIRBuilder.buildPtrAdd(PtrAddReg, PtrReg, OffsetCst);
3500   auto SmallLoad = MIRBuilder.buildLoadInstr(LoadMI.getOpcode(), AnyExtTy,
3501                                              SmallPtr, *SmallMMO);
3502 
3503   auto ShiftAmt = MIRBuilder.buildConstant(AnyExtTy, LargeSplitSize);
3504   auto Shift = MIRBuilder.buildShl(AnyExtTy, SmallLoad, ShiftAmt);
3505 
3506   if (AnyExtTy == DstTy)
3507     MIRBuilder.buildOr(DstReg, Shift, LargeLoad);
3508   else if (AnyExtTy.getSizeInBits() != DstTy.getSizeInBits()) {
3509     auto Or = MIRBuilder.buildOr(AnyExtTy, Shift, LargeLoad);
3510     MIRBuilder.buildTrunc(DstReg, {Or});
3511   } else {
3512     assert(DstTy.isPointer() && "expected pointer");
3513     auto Or = MIRBuilder.buildOr(AnyExtTy, Shift, LargeLoad);
3514 
3515     // FIXME: We currently consider this to be illegal for non-integral address
3516     // spaces, but we need still need a way to reinterpret the bits.
3517     MIRBuilder.buildIntToPtr(DstReg, Or);
3518   }
3519 
3520   LoadMI.eraseFromParent();
3521   return Legalized;
3522 }
3523 
3524 LegalizerHelper::LegalizeResult LegalizerHelper::lowerStore(GStore &StoreMI) {
3525   // Lower a non-power of 2 store into multiple pow-2 stores.
3526   // E.g. split an i24 store into an i16 store + i8 store.
3527   // We do this by first extending the stored value to the next largest power
3528   // of 2 type, and then using truncating stores to store the components.
3529   // By doing this, likewise with G_LOAD, generate an extend that can be
3530   // artifact-combined away instead of leaving behind extracts.
3531   Register SrcReg = StoreMI.getValueReg();
3532   Register PtrReg = StoreMI.getPointerReg();
3533   LLT SrcTy = MRI.getType(SrcReg);
3534   MachineFunction &MF = MIRBuilder.getMF();
3535   MachineMemOperand &MMO = **StoreMI.memoperands_begin();
3536   LLT MemTy = MMO.getMemoryType();
3537 
3538   unsigned StoreWidth = MemTy.getSizeInBits();
3539   unsigned StoreSizeInBits = 8 * MemTy.getSizeInBytes();
3540 
3541   if (StoreWidth != StoreSizeInBits) {
3542     if (SrcTy.isVector())
3543       return UnableToLegalize;
3544 
3545     // Promote to a byte-sized store with upper bits zero if not
3546     // storing an integral number of bytes.  For example, promote
3547     // TRUNCSTORE:i1 X -> TRUNCSTORE:i8 (and X, 1)
3548     LLT WideTy = LLT::scalar(StoreSizeInBits);
3549 
3550     if (StoreSizeInBits > SrcTy.getSizeInBits()) {
3551       // Avoid creating a store with a narrower source than result.
3552       SrcReg = MIRBuilder.buildAnyExt(WideTy, SrcReg).getReg(0);
3553       SrcTy = WideTy;
3554     }
3555 
3556     auto ZextInReg = MIRBuilder.buildZExtInReg(SrcTy, SrcReg, StoreWidth);
3557 
3558     MachineMemOperand *NewMMO =
3559         MF.getMachineMemOperand(&MMO, MMO.getPointerInfo(), WideTy);
3560     MIRBuilder.buildStore(ZextInReg, PtrReg, *NewMMO);
3561     StoreMI.eraseFromParent();
3562     return Legalized;
3563   }
3564 
3565   if (MemTy.isVector()) {
3566     // TODO: Handle vector trunc stores
3567     if (MemTy != SrcTy)
3568       return UnableToLegalize;
3569 
3570     // TODO: We can do better than scalarizing the vector and at least split it
3571     // in half.
3572     return reduceLoadStoreWidth(StoreMI, 0, SrcTy.getElementType());
3573   }
3574 
3575   unsigned MemSizeInBits = MemTy.getSizeInBits();
3576   uint64_t LargeSplitSize, SmallSplitSize;
3577 
3578   if (!isPowerOf2_32(MemSizeInBits)) {
3579     LargeSplitSize = llvm::bit_floor<uint64_t>(MemTy.getSizeInBits());
3580     SmallSplitSize = MemTy.getSizeInBits() - LargeSplitSize;
3581   } else {
3582     auto &Ctx = MF.getFunction().getContext();
3583     if (TLI.allowsMemoryAccess(Ctx, MIRBuilder.getDataLayout(), MemTy, MMO))
3584       return UnableToLegalize; // Don't know what we're being asked to do.
3585 
3586     SmallSplitSize = LargeSplitSize = MemSizeInBits / 2;
3587   }
3588 
3589   // Extend to the next pow-2. If this store was itself the result of lowering,
3590   // e.g. an s56 store being broken into s32 + s24, we might have a stored type
3591   // that's wider than the stored size.
3592   unsigned AnyExtSize = PowerOf2Ceil(MemTy.getSizeInBits());
3593   const LLT NewSrcTy = LLT::scalar(AnyExtSize);
3594 
3595   if (SrcTy.isPointer()) {
3596     const LLT IntPtrTy = LLT::scalar(SrcTy.getSizeInBits());
3597     SrcReg = MIRBuilder.buildPtrToInt(IntPtrTy, SrcReg).getReg(0);
3598   }
3599 
3600   auto ExtVal = MIRBuilder.buildAnyExtOrTrunc(NewSrcTy, SrcReg);
3601 
3602   // Obtain the smaller value by shifting away the larger value.
3603   auto ShiftAmt = MIRBuilder.buildConstant(NewSrcTy, LargeSplitSize);
3604   auto SmallVal = MIRBuilder.buildLShr(NewSrcTy, ExtVal, ShiftAmt);
3605 
3606   // Generate the PtrAdd and truncating stores.
3607   LLT PtrTy = MRI.getType(PtrReg);
3608   auto OffsetCst = MIRBuilder.buildConstant(
3609     LLT::scalar(PtrTy.getSizeInBits()), LargeSplitSize / 8);
3610   auto SmallPtr =
3611     MIRBuilder.buildPtrAdd(PtrTy, PtrReg, OffsetCst);
3612 
3613   MachineMemOperand *LargeMMO =
3614     MF.getMachineMemOperand(&MMO, 0, LargeSplitSize / 8);
3615   MachineMemOperand *SmallMMO =
3616     MF.getMachineMemOperand(&MMO, LargeSplitSize / 8, SmallSplitSize / 8);
3617   MIRBuilder.buildStore(ExtVal, PtrReg, *LargeMMO);
3618   MIRBuilder.buildStore(SmallVal, SmallPtr, *SmallMMO);
3619   StoreMI.eraseFromParent();
3620   return Legalized;
3621 }
3622 
3623 LegalizerHelper::LegalizeResult
3624 LegalizerHelper::bitcast(MachineInstr &MI, unsigned TypeIdx, LLT CastTy) {
3625   switch (MI.getOpcode()) {
3626   case TargetOpcode::G_LOAD: {
3627     if (TypeIdx != 0)
3628       return UnableToLegalize;
3629     MachineMemOperand &MMO = **MI.memoperands_begin();
3630 
3631     // Not sure how to interpret a bitcast of an extending load.
3632     if (MMO.getMemoryType().getSizeInBits() != CastTy.getSizeInBits())
3633       return UnableToLegalize;
3634 
3635     Observer.changingInstr(MI);
3636     bitcastDst(MI, CastTy, 0);
3637     MMO.setType(CastTy);
3638     Observer.changedInstr(MI);
3639     return Legalized;
3640   }
3641   case TargetOpcode::G_STORE: {
3642     if (TypeIdx != 0)
3643       return UnableToLegalize;
3644 
3645     MachineMemOperand &MMO = **MI.memoperands_begin();
3646 
3647     // Not sure how to interpret a bitcast of a truncating store.
3648     if (MMO.getMemoryType().getSizeInBits() != CastTy.getSizeInBits())
3649       return UnableToLegalize;
3650 
3651     Observer.changingInstr(MI);
3652     bitcastSrc(MI, CastTy, 0);
3653     MMO.setType(CastTy);
3654     Observer.changedInstr(MI);
3655     return Legalized;
3656   }
3657   case TargetOpcode::G_SELECT: {
3658     if (TypeIdx != 0)
3659       return UnableToLegalize;
3660 
3661     if (MRI.getType(MI.getOperand(1).getReg()).isVector()) {
3662       LLVM_DEBUG(
3663           dbgs() << "bitcast action not implemented for vector select\n");
3664       return UnableToLegalize;
3665     }
3666 
3667     Observer.changingInstr(MI);
3668     bitcastSrc(MI, CastTy, 2);
3669     bitcastSrc(MI, CastTy, 3);
3670     bitcastDst(MI, CastTy, 0);
3671     Observer.changedInstr(MI);
3672     return Legalized;
3673   }
3674   case TargetOpcode::G_AND:
3675   case TargetOpcode::G_OR:
3676   case TargetOpcode::G_XOR: {
3677     Observer.changingInstr(MI);
3678     bitcastSrc(MI, CastTy, 1);
3679     bitcastSrc(MI, CastTy, 2);
3680     bitcastDst(MI, CastTy, 0);
3681     Observer.changedInstr(MI);
3682     return Legalized;
3683   }
3684   case TargetOpcode::G_EXTRACT_VECTOR_ELT:
3685     return bitcastExtractVectorElt(MI, TypeIdx, CastTy);
3686   case TargetOpcode::G_INSERT_VECTOR_ELT:
3687     return bitcastInsertVectorElt(MI, TypeIdx, CastTy);
3688   default:
3689     return UnableToLegalize;
3690   }
3691 }
3692 
3693 // Legalize an instruction by changing the opcode in place.
3694 void LegalizerHelper::changeOpcode(MachineInstr &MI, unsigned NewOpcode) {
3695     Observer.changingInstr(MI);
3696     MI.setDesc(MIRBuilder.getTII().get(NewOpcode));
3697     Observer.changedInstr(MI);
3698 }
3699 
3700 LegalizerHelper::LegalizeResult
3701 LegalizerHelper::lower(MachineInstr &MI, unsigned TypeIdx, LLT LowerHintTy) {
3702   using namespace TargetOpcode;
3703 
3704   switch(MI.getOpcode()) {
3705   default:
3706     return UnableToLegalize;
3707   case TargetOpcode::G_FCONSTANT:
3708     return lowerFConstant(MI);
3709   case TargetOpcode::G_BITCAST:
3710     return lowerBitcast(MI);
3711   case TargetOpcode::G_SREM:
3712   case TargetOpcode::G_UREM: {
3713     LLT Ty = MRI.getType(MI.getOperand(0).getReg());
3714     auto Quot =
3715         MIRBuilder.buildInstr(MI.getOpcode() == G_SREM ? G_SDIV : G_UDIV, {Ty},
3716                               {MI.getOperand(1), MI.getOperand(2)});
3717 
3718     auto Prod = MIRBuilder.buildMul(Ty, Quot, MI.getOperand(2));
3719     MIRBuilder.buildSub(MI.getOperand(0), MI.getOperand(1), Prod);
3720     MI.eraseFromParent();
3721     return Legalized;
3722   }
3723   case TargetOpcode::G_SADDO:
3724   case TargetOpcode::G_SSUBO:
3725     return lowerSADDO_SSUBO(MI);
3726   case TargetOpcode::G_UMULH:
3727   case TargetOpcode::G_SMULH:
3728     return lowerSMULH_UMULH(MI);
3729   case TargetOpcode::G_SMULO:
3730   case TargetOpcode::G_UMULO: {
3731     // Generate G_UMULH/G_SMULH to check for overflow and a normal G_MUL for the
3732     // result.
3733     auto [Res, Overflow, LHS, RHS] = MI.getFirst4Regs();
3734     LLT Ty = MRI.getType(Res);
3735 
3736     unsigned Opcode = MI.getOpcode() == TargetOpcode::G_SMULO
3737                           ? TargetOpcode::G_SMULH
3738                           : TargetOpcode::G_UMULH;
3739 
3740     Observer.changingInstr(MI);
3741     const auto &TII = MIRBuilder.getTII();
3742     MI.setDesc(TII.get(TargetOpcode::G_MUL));
3743     MI.removeOperand(1);
3744     Observer.changedInstr(MI);
3745 
3746     auto HiPart = MIRBuilder.buildInstr(Opcode, {Ty}, {LHS, RHS});
3747     auto Zero = MIRBuilder.buildConstant(Ty, 0);
3748 
3749     // Move insert point forward so we can use the Res register if needed.
3750     MIRBuilder.setInsertPt(MIRBuilder.getMBB(), ++MIRBuilder.getInsertPt());
3751 
3752     // For *signed* multiply, overflow is detected by checking:
3753     // (hi != (lo >> bitwidth-1))
3754     if (Opcode == TargetOpcode::G_SMULH) {
3755       auto ShiftAmt = MIRBuilder.buildConstant(Ty, Ty.getSizeInBits() - 1);
3756       auto Shifted = MIRBuilder.buildAShr(Ty, Res, ShiftAmt);
3757       MIRBuilder.buildICmp(CmpInst::ICMP_NE, Overflow, HiPart, Shifted);
3758     } else {
3759       MIRBuilder.buildICmp(CmpInst::ICMP_NE, Overflow, HiPart, Zero);
3760     }
3761     return Legalized;
3762   }
3763   case TargetOpcode::G_FNEG: {
3764     auto [Res, SubByReg] = MI.getFirst2Regs();
3765     LLT Ty = MRI.getType(Res);
3766 
3767     // TODO: Handle vector types once we are able to
3768     // represent them.
3769     if (Ty.isVector())
3770       return UnableToLegalize;
3771     auto SignMask =
3772         MIRBuilder.buildConstant(Ty, APInt::getSignMask(Ty.getSizeInBits()));
3773     MIRBuilder.buildXor(Res, SubByReg, SignMask);
3774     MI.eraseFromParent();
3775     return Legalized;
3776   }
3777   case TargetOpcode::G_FSUB:
3778   case TargetOpcode::G_STRICT_FSUB: {
3779     auto [Res, LHS, RHS] = MI.getFirst3Regs();
3780     LLT Ty = MRI.getType(Res);
3781 
3782     // Lower (G_FSUB LHS, RHS) to (G_FADD LHS, (G_FNEG RHS)).
3783     auto Neg = MIRBuilder.buildFNeg(Ty, RHS);
3784 
3785     if (MI.getOpcode() == TargetOpcode::G_STRICT_FSUB)
3786       MIRBuilder.buildStrictFAdd(Res, LHS, Neg, MI.getFlags());
3787     else
3788       MIRBuilder.buildFAdd(Res, LHS, Neg, MI.getFlags());
3789 
3790     MI.eraseFromParent();
3791     return Legalized;
3792   }
3793   case TargetOpcode::G_FMAD:
3794     return lowerFMad(MI);
3795   case TargetOpcode::G_FFLOOR:
3796     return lowerFFloor(MI);
3797   case TargetOpcode::G_INTRINSIC_ROUND:
3798     return lowerIntrinsicRound(MI);
3799   case TargetOpcode::G_FRINT: {
3800     // Since round even is the assumed rounding mode for unconstrained FP
3801     // operations, rint and roundeven are the same operation.
3802     changeOpcode(MI, TargetOpcode::G_INTRINSIC_ROUNDEVEN);
3803     return Legalized;
3804   }
3805   case TargetOpcode::G_ATOMIC_CMPXCHG_WITH_SUCCESS: {
3806     auto [OldValRes, SuccessRes, Addr, CmpVal, NewVal] = MI.getFirst5Regs();
3807     MIRBuilder.buildAtomicCmpXchg(OldValRes, Addr, CmpVal, NewVal,
3808                                   **MI.memoperands_begin());
3809     MIRBuilder.buildICmp(CmpInst::ICMP_EQ, SuccessRes, OldValRes, CmpVal);
3810     MI.eraseFromParent();
3811     return Legalized;
3812   }
3813   case TargetOpcode::G_LOAD:
3814   case TargetOpcode::G_SEXTLOAD:
3815   case TargetOpcode::G_ZEXTLOAD:
3816     return lowerLoad(cast<GAnyLoad>(MI));
3817   case TargetOpcode::G_STORE:
3818     return lowerStore(cast<GStore>(MI));
3819   case TargetOpcode::G_CTLZ_ZERO_UNDEF:
3820   case TargetOpcode::G_CTTZ_ZERO_UNDEF:
3821   case TargetOpcode::G_CTLZ:
3822   case TargetOpcode::G_CTTZ:
3823   case TargetOpcode::G_CTPOP:
3824     return lowerBitCount(MI);
3825   case G_UADDO: {
3826     auto [Res, CarryOut, LHS, RHS] = MI.getFirst4Regs();
3827 
3828     MIRBuilder.buildAdd(Res, LHS, RHS);
3829     MIRBuilder.buildICmp(CmpInst::ICMP_ULT, CarryOut, Res, RHS);
3830 
3831     MI.eraseFromParent();
3832     return Legalized;
3833   }
3834   case G_UADDE: {
3835     auto [Res, CarryOut, LHS, RHS, CarryIn] = MI.getFirst5Regs();
3836     const LLT CondTy = MRI.getType(CarryOut);
3837     const LLT Ty = MRI.getType(Res);
3838 
3839     // Initial add of the two operands.
3840     auto TmpRes = MIRBuilder.buildAdd(Ty, LHS, RHS);
3841 
3842     // Initial check for carry.
3843     auto Carry = MIRBuilder.buildICmp(CmpInst::ICMP_ULT, CondTy, TmpRes, LHS);
3844 
3845     // Add the sum and the carry.
3846     auto ZExtCarryIn = MIRBuilder.buildZExt(Ty, CarryIn);
3847     MIRBuilder.buildAdd(Res, TmpRes, ZExtCarryIn);
3848 
3849     // Second check for carry. We can only carry if the initial sum is all 1s
3850     // and the carry is set, resulting in a new sum of 0.
3851     auto Zero = MIRBuilder.buildConstant(Ty, 0);
3852     auto ResEqZero = MIRBuilder.buildICmp(CmpInst::ICMP_EQ, CondTy, Res, Zero);
3853     auto Carry2 = MIRBuilder.buildAnd(CondTy, ResEqZero, CarryIn);
3854     MIRBuilder.buildOr(CarryOut, Carry, Carry2);
3855 
3856     MI.eraseFromParent();
3857     return Legalized;
3858   }
3859   case G_USUBO: {
3860     auto [Res, BorrowOut, LHS, RHS] = MI.getFirst4Regs();
3861 
3862     MIRBuilder.buildSub(Res, LHS, RHS);
3863     MIRBuilder.buildICmp(CmpInst::ICMP_ULT, BorrowOut, LHS, RHS);
3864 
3865     MI.eraseFromParent();
3866     return Legalized;
3867   }
3868   case G_USUBE: {
3869     auto [Res, BorrowOut, LHS, RHS, BorrowIn] = MI.getFirst5Regs();
3870     const LLT CondTy = MRI.getType(BorrowOut);
3871     const LLT Ty = MRI.getType(Res);
3872 
3873     // Initial subtract of the two operands.
3874     auto TmpRes = MIRBuilder.buildSub(Ty, LHS, RHS);
3875 
3876     // Initial check for borrow.
3877     auto Borrow = MIRBuilder.buildICmp(CmpInst::ICMP_UGT, CondTy, TmpRes, LHS);
3878 
3879     // Subtract the borrow from the first subtract.
3880     auto ZExtBorrowIn = MIRBuilder.buildZExt(Ty, BorrowIn);
3881     MIRBuilder.buildSub(Res, TmpRes, ZExtBorrowIn);
3882 
3883     // Second check for borrow. We can only borrow if the initial difference is
3884     // 0 and the borrow is set, resulting in a new difference of all 1s.
3885     auto Zero = MIRBuilder.buildConstant(Ty, 0);
3886     auto TmpResEqZero =
3887         MIRBuilder.buildICmp(CmpInst::ICMP_EQ, CondTy, TmpRes, Zero);
3888     auto Borrow2 = MIRBuilder.buildAnd(CondTy, TmpResEqZero, BorrowIn);
3889     MIRBuilder.buildOr(BorrowOut, Borrow, Borrow2);
3890 
3891     MI.eraseFromParent();
3892     return Legalized;
3893   }
3894   case G_UITOFP:
3895     return lowerUITOFP(MI);
3896   case G_SITOFP:
3897     return lowerSITOFP(MI);
3898   case G_FPTOUI:
3899     return lowerFPTOUI(MI);
3900   case G_FPTOSI:
3901     return lowerFPTOSI(MI);
3902   case G_FPTRUNC:
3903     return lowerFPTRUNC(MI);
3904   case G_FPOWI:
3905     return lowerFPOWI(MI);
3906   case G_SMIN:
3907   case G_SMAX:
3908   case G_UMIN:
3909   case G_UMAX:
3910     return lowerMinMax(MI);
3911   case G_FCOPYSIGN:
3912     return lowerFCopySign(MI);
3913   case G_FMINNUM:
3914   case G_FMAXNUM:
3915     return lowerFMinNumMaxNum(MI);
3916   case G_MERGE_VALUES:
3917     return lowerMergeValues(MI);
3918   case G_UNMERGE_VALUES:
3919     return lowerUnmergeValues(MI);
3920   case TargetOpcode::G_SEXT_INREG: {
3921     assert(MI.getOperand(2).isImm() && "Expected immediate");
3922     int64_t SizeInBits = MI.getOperand(2).getImm();
3923 
3924     auto [DstReg, SrcReg] = MI.getFirst2Regs();
3925     LLT DstTy = MRI.getType(DstReg);
3926     Register TmpRes = MRI.createGenericVirtualRegister(DstTy);
3927 
3928     auto MIBSz = MIRBuilder.buildConstant(DstTy, DstTy.getScalarSizeInBits() - SizeInBits);
3929     MIRBuilder.buildShl(TmpRes, SrcReg, MIBSz->getOperand(0));
3930     MIRBuilder.buildAShr(DstReg, TmpRes, MIBSz->getOperand(0));
3931     MI.eraseFromParent();
3932     return Legalized;
3933   }
3934   case G_EXTRACT_VECTOR_ELT:
3935   case G_INSERT_VECTOR_ELT:
3936     return lowerExtractInsertVectorElt(MI);
3937   case G_SHUFFLE_VECTOR:
3938     return lowerShuffleVector(MI);
3939   case G_DYN_STACKALLOC:
3940     return lowerDynStackAlloc(MI);
3941   case G_STACKSAVE:
3942     return lowerStackSave(MI);
3943   case G_STACKRESTORE:
3944     return lowerStackRestore(MI);
3945   case G_EXTRACT:
3946     return lowerExtract(MI);
3947   case G_INSERT:
3948     return lowerInsert(MI);
3949   case G_BSWAP:
3950     return lowerBswap(MI);
3951   case G_BITREVERSE:
3952     return lowerBitreverse(MI);
3953   case G_READ_REGISTER:
3954   case G_WRITE_REGISTER:
3955     return lowerReadWriteRegister(MI);
3956   case G_UADDSAT:
3957   case G_USUBSAT: {
3958     // Try to make a reasonable guess about which lowering strategy to use. The
3959     // target can override this with custom lowering and calling the
3960     // implementation functions.
3961     LLT Ty = MRI.getType(MI.getOperand(0).getReg());
3962     if (LI.isLegalOrCustom({G_UMIN, Ty}))
3963       return lowerAddSubSatToMinMax(MI);
3964     return lowerAddSubSatToAddoSubo(MI);
3965   }
3966   case G_SADDSAT:
3967   case G_SSUBSAT: {
3968     LLT Ty = MRI.getType(MI.getOperand(0).getReg());
3969 
3970     // FIXME: It would probably make more sense to see if G_SADDO is preferred,
3971     // since it's a shorter expansion. However, we would need to figure out the
3972     // preferred boolean type for the carry out for the query.
3973     if (LI.isLegalOrCustom({G_SMIN, Ty}) && LI.isLegalOrCustom({G_SMAX, Ty}))
3974       return lowerAddSubSatToMinMax(MI);
3975     return lowerAddSubSatToAddoSubo(MI);
3976   }
3977   case G_SSHLSAT:
3978   case G_USHLSAT:
3979     return lowerShlSat(MI);
3980   case G_ABS:
3981     return lowerAbsToAddXor(MI);
3982   case G_SELECT:
3983     return lowerSelect(MI);
3984   case G_IS_FPCLASS:
3985     return lowerISFPCLASS(MI);
3986   case G_SDIVREM:
3987   case G_UDIVREM:
3988     return lowerDIVREM(MI);
3989   case G_FSHL:
3990   case G_FSHR:
3991     return lowerFunnelShift(MI);
3992   case G_ROTL:
3993   case G_ROTR:
3994     return lowerRotate(MI);
3995   case G_MEMSET:
3996   case G_MEMCPY:
3997   case G_MEMMOVE:
3998     return lowerMemCpyFamily(MI);
3999   case G_MEMCPY_INLINE:
4000     return lowerMemcpyInline(MI);
4001   case G_ZEXT:
4002   case G_SEXT:
4003   case G_ANYEXT:
4004     return lowerEXT(MI);
4005   case G_TRUNC:
4006     return lowerTRUNC(MI);
4007   GISEL_VECREDUCE_CASES_NONSEQ
4008     return lowerVectorReduction(MI);
4009   case G_VAARG:
4010     return lowerVAArg(MI);
4011   }
4012 }
4013 
4014 Align LegalizerHelper::getStackTemporaryAlignment(LLT Ty,
4015                                                   Align MinAlign) const {
4016   // FIXME: We're missing a way to go back from LLT to llvm::Type to query the
4017   // datalayout for the preferred alignment. Also there should be a target hook
4018   // for this to allow targets to reduce the alignment and ignore the
4019   // datalayout. e.g. AMDGPU should always use a 4-byte alignment, regardless of
4020   // the type.
4021   return std::max(Align(PowerOf2Ceil(Ty.getSizeInBytes())), MinAlign);
4022 }
4023 
4024 MachineInstrBuilder
4025 LegalizerHelper::createStackTemporary(TypeSize Bytes, Align Alignment,
4026                                       MachinePointerInfo &PtrInfo) {
4027   MachineFunction &MF = MIRBuilder.getMF();
4028   const DataLayout &DL = MIRBuilder.getDataLayout();
4029   int FrameIdx = MF.getFrameInfo().CreateStackObject(Bytes, Alignment, false);
4030 
4031   unsigned AddrSpace = DL.getAllocaAddrSpace();
4032   LLT FramePtrTy = LLT::pointer(AddrSpace, DL.getPointerSizeInBits(AddrSpace));
4033 
4034   PtrInfo = MachinePointerInfo::getFixedStack(MF, FrameIdx);
4035   return MIRBuilder.buildFrameIndex(FramePtrTy, FrameIdx);
4036 }
4037 
4038 static Register clampDynamicVectorIndex(MachineIRBuilder &B, Register IdxReg,
4039                                         LLT VecTy) {
4040   int64_t IdxVal;
4041   if (mi_match(IdxReg, *B.getMRI(), m_ICst(IdxVal)))
4042     return IdxReg;
4043 
4044   LLT IdxTy = B.getMRI()->getType(IdxReg);
4045   unsigned NElts = VecTy.getNumElements();
4046   if (isPowerOf2_32(NElts)) {
4047     APInt Imm = APInt::getLowBitsSet(IdxTy.getSizeInBits(), Log2_32(NElts));
4048     return B.buildAnd(IdxTy, IdxReg, B.buildConstant(IdxTy, Imm)).getReg(0);
4049   }
4050 
4051   return B.buildUMin(IdxTy, IdxReg, B.buildConstant(IdxTy, NElts - 1))
4052       .getReg(0);
4053 }
4054 
4055 Register LegalizerHelper::getVectorElementPointer(Register VecPtr, LLT VecTy,
4056                                                   Register Index) {
4057   LLT EltTy = VecTy.getElementType();
4058 
4059   // Calculate the element offset and add it to the pointer.
4060   unsigned EltSize = EltTy.getSizeInBits() / 8; // FIXME: should be ABI size.
4061   assert(EltSize * 8 == EltTy.getSizeInBits() &&
4062          "Converting bits to bytes lost precision");
4063 
4064   Index = clampDynamicVectorIndex(MIRBuilder, Index, VecTy);
4065 
4066   LLT IdxTy = MRI.getType(Index);
4067   auto Mul = MIRBuilder.buildMul(IdxTy, Index,
4068                                  MIRBuilder.buildConstant(IdxTy, EltSize));
4069 
4070   LLT PtrTy = MRI.getType(VecPtr);
4071   return MIRBuilder.buildPtrAdd(PtrTy, VecPtr, Mul).getReg(0);
4072 }
4073 
4074 #ifndef NDEBUG
4075 /// Check that all vector operands have same number of elements. Other operands
4076 /// should be listed in NonVecOp.
4077 static bool hasSameNumEltsOnAllVectorOperands(
4078     GenericMachineInstr &MI, MachineRegisterInfo &MRI,
4079     std::initializer_list<unsigned> NonVecOpIndices) {
4080   if (MI.getNumMemOperands() != 0)
4081     return false;
4082 
4083   LLT VecTy = MRI.getType(MI.getReg(0));
4084   if (!VecTy.isVector())
4085     return false;
4086   unsigned NumElts = VecTy.getNumElements();
4087 
4088   for (unsigned OpIdx = 1; OpIdx < MI.getNumOperands(); ++OpIdx) {
4089     MachineOperand &Op = MI.getOperand(OpIdx);
4090     if (!Op.isReg()) {
4091       if (!is_contained(NonVecOpIndices, OpIdx))
4092         return false;
4093       continue;
4094     }
4095 
4096     LLT Ty = MRI.getType(Op.getReg());
4097     if (!Ty.isVector()) {
4098       if (!is_contained(NonVecOpIndices, OpIdx))
4099         return false;
4100       continue;
4101     }
4102 
4103     if (Ty.getNumElements() != NumElts)
4104       return false;
4105   }
4106 
4107   return true;
4108 }
4109 #endif
4110 
4111 /// Fill \p DstOps with DstOps that have same number of elements combined as
4112 /// the Ty. These DstOps have either scalar type when \p NumElts = 1 or are
4113 /// vectors with \p NumElts elements. When Ty.getNumElements() is not multiple
4114 /// of \p NumElts last DstOp (leftover) has fewer then \p NumElts elements.
4115 static void makeDstOps(SmallVectorImpl<DstOp> &DstOps, LLT Ty,
4116                        unsigned NumElts) {
4117   LLT LeftoverTy;
4118   assert(Ty.isVector() && "Expected vector type");
4119   LLT EltTy = Ty.getElementType();
4120   LLT NarrowTy = (NumElts == 1) ? EltTy : LLT::fixed_vector(NumElts, EltTy);
4121   int NumParts, NumLeftover;
4122   std::tie(NumParts, NumLeftover) =
4123       getNarrowTypeBreakDown(Ty, NarrowTy, LeftoverTy);
4124 
4125   assert(NumParts > 0 && "Error in getNarrowTypeBreakDown");
4126   for (int i = 0; i < NumParts; ++i) {
4127     DstOps.push_back(NarrowTy);
4128   }
4129 
4130   if (LeftoverTy.isValid()) {
4131     assert(NumLeftover == 1 && "expected exactly one leftover");
4132     DstOps.push_back(LeftoverTy);
4133   }
4134 }
4135 
4136 /// Operand \p Op is used on \p N sub-instructions. Fill \p Ops with \p N SrcOps
4137 /// made from \p Op depending on operand type.
4138 static void broadcastSrcOp(SmallVectorImpl<SrcOp> &Ops, unsigned N,
4139                            MachineOperand &Op) {
4140   for (unsigned i = 0; i < N; ++i) {
4141     if (Op.isReg())
4142       Ops.push_back(Op.getReg());
4143     else if (Op.isImm())
4144       Ops.push_back(Op.getImm());
4145     else if (Op.isPredicate())
4146       Ops.push_back(static_cast<CmpInst::Predicate>(Op.getPredicate()));
4147     else
4148       llvm_unreachable("Unsupported type");
4149   }
4150 }
4151 
4152 // Handle splitting vector operations which need to have the same number of
4153 // elements in each type index, but each type index may have a different element
4154 // type.
4155 //
4156 // e.g.  <4 x s64> = G_SHL <4 x s64>, <4 x s32> ->
4157 //       <2 x s64> = G_SHL <2 x s64>, <2 x s32>
4158 //       <2 x s64> = G_SHL <2 x s64>, <2 x s32>
4159 //
4160 // Also handles some irregular breakdown cases, e.g.
4161 // e.g.  <3 x s64> = G_SHL <3 x s64>, <3 x s32> ->
4162 //       <2 x s64> = G_SHL <2 x s64>, <2 x s32>
4163 //             s64 = G_SHL s64, s32
4164 LegalizerHelper::LegalizeResult
4165 LegalizerHelper::fewerElementsVectorMultiEltType(
4166     GenericMachineInstr &MI, unsigned NumElts,
4167     std::initializer_list<unsigned> NonVecOpIndices) {
4168   assert(hasSameNumEltsOnAllVectorOperands(MI, MRI, NonVecOpIndices) &&
4169          "Non-compatible opcode or not specified non-vector operands");
4170   unsigned OrigNumElts = MRI.getType(MI.getReg(0)).getNumElements();
4171 
4172   unsigned NumInputs = MI.getNumOperands() - MI.getNumDefs();
4173   unsigned NumDefs = MI.getNumDefs();
4174 
4175   // Create DstOps (sub-vectors with NumElts elts + Leftover) for each output.
4176   // Build instructions with DstOps to use instruction found by CSE directly.
4177   // CSE copies found instruction into given vreg when building with vreg dest.
4178   SmallVector<SmallVector<DstOp, 8>, 2> OutputOpsPieces(NumDefs);
4179   // Output registers will be taken from created instructions.
4180   SmallVector<SmallVector<Register, 8>, 2> OutputRegs(NumDefs);
4181   for (unsigned i = 0; i < NumDefs; ++i) {
4182     makeDstOps(OutputOpsPieces[i], MRI.getType(MI.getReg(i)), NumElts);
4183   }
4184 
4185   // Split vector input operands into sub-vectors with NumElts elts + Leftover.
4186   // Operands listed in NonVecOpIndices will be used as is without splitting;
4187   // examples: compare predicate in icmp and fcmp (op 1), vector select with i1
4188   // scalar condition (op 1), immediate in sext_inreg (op 2).
4189   SmallVector<SmallVector<SrcOp, 8>, 3> InputOpsPieces(NumInputs);
4190   for (unsigned UseIdx = NumDefs, UseNo = 0; UseIdx < MI.getNumOperands();
4191        ++UseIdx, ++UseNo) {
4192     if (is_contained(NonVecOpIndices, UseIdx)) {
4193       broadcastSrcOp(InputOpsPieces[UseNo], OutputOpsPieces[0].size(),
4194                      MI.getOperand(UseIdx));
4195     } else {
4196       SmallVector<Register, 8> SplitPieces;
4197       extractVectorParts(MI.getReg(UseIdx), NumElts, SplitPieces);
4198       for (auto Reg : SplitPieces)
4199         InputOpsPieces[UseNo].push_back(Reg);
4200     }
4201   }
4202 
4203   unsigned NumLeftovers = OrigNumElts % NumElts ? 1 : 0;
4204 
4205   // Take i-th piece of each input operand split and build sub-vector/scalar
4206   // instruction. Set i-th DstOp(s) from OutputOpsPieces as destination(s).
4207   for (unsigned i = 0; i < OrigNumElts / NumElts + NumLeftovers; ++i) {
4208     SmallVector<DstOp, 2> Defs;
4209     for (unsigned DstNo = 0; DstNo < NumDefs; ++DstNo)
4210       Defs.push_back(OutputOpsPieces[DstNo][i]);
4211 
4212     SmallVector<SrcOp, 3> Uses;
4213     for (unsigned InputNo = 0; InputNo < NumInputs; ++InputNo)
4214       Uses.push_back(InputOpsPieces[InputNo][i]);
4215 
4216     auto I = MIRBuilder.buildInstr(MI.getOpcode(), Defs, Uses, MI.getFlags());
4217     for (unsigned DstNo = 0; DstNo < NumDefs; ++DstNo)
4218       OutputRegs[DstNo].push_back(I.getReg(DstNo));
4219   }
4220 
4221   // Merge small outputs into MI's output for each def operand.
4222   if (NumLeftovers) {
4223     for (unsigned i = 0; i < NumDefs; ++i)
4224       mergeMixedSubvectors(MI.getReg(i), OutputRegs[i]);
4225   } else {
4226     for (unsigned i = 0; i < NumDefs; ++i)
4227       MIRBuilder.buildMergeLikeInstr(MI.getReg(i), OutputRegs[i]);
4228   }
4229 
4230   MI.eraseFromParent();
4231   return Legalized;
4232 }
4233 
4234 LegalizerHelper::LegalizeResult
4235 LegalizerHelper::fewerElementsVectorPhi(GenericMachineInstr &MI,
4236                                         unsigned NumElts) {
4237   unsigned OrigNumElts = MRI.getType(MI.getReg(0)).getNumElements();
4238 
4239   unsigned NumInputs = MI.getNumOperands() - MI.getNumDefs();
4240   unsigned NumDefs = MI.getNumDefs();
4241 
4242   SmallVector<DstOp, 8> OutputOpsPieces;
4243   SmallVector<Register, 8> OutputRegs;
4244   makeDstOps(OutputOpsPieces, MRI.getType(MI.getReg(0)), NumElts);
4245 
4246   // Instructions that perform register split will be inserted in basic block
4247   // where register is defined (basic block is in the next operand).
4248   SmallVector<SmallVector<Register, 8>, 3> InputOpsPieces(NumInputs / 2);
4249   for (unsigned UseIdx = NumDefs, UseNo = 0; UseIdx < MI.getNumOperands();
4250        UseIdx += 2, ++UseNo) {
4251     MachineBasicBlock &OpMBB = *MI.getOperand(UseIdx + 1).getMBB();
4252     MIRBuilder.setInsertPt(OpMBB, OpMBB.getFirstTerminatorForward());
4253     extractVectorParts(MI.getReg(UseIdx), NumElts, InputOpsPieces[UseNo]);
4254   }
4255 
4256   // Build PHIs with fewer elements.
4257   unsigned NumLeftovers = OrigNumElts % NumElts ? 1 : 0;
4258   MIRBuilder.setInsertPt(*MI.getParent(), MI);
4259   for (unsigned i = 0; i < OrigNumElts / NumElts + NumLeftovers; ++i) {
4260     auto Phi = MIRBuilder.buildInstr(TargetOpcode::G_PHI);
4261     Phi.addDef(
4262         MRI.createGenericVirtualRegister(OutputOpsPieces[i].getLLTTy(MRI)));
4263     OutputRegs.push_back(Phi.getReg(0));
4264 
4265     for (unsigned j = 0; j < NumInputs / 2; ++j) {
4266       Phi.addUse(InputOpsPieces[j][i]);
4267       Phi.add(MI.getOperand(1 + j * 2 + 1));
4268     }
4269   }
4270 
4271   // Merge small outputs into MI's def.
4272   if (NumLeftovers) {
4273     mergeMixedSubvectors(MI.getReg(0), OutputRegs);
4274   } else {
4275     MIRBuilder.buildMergeLikeInstr(MI.getReg(0), OutputRegs);
4276   }
4277 
4278   MI.eraseFromParent();
4279   return Legalized;
4280 }
4281 
4282 LegalizerHelper::LegalizeResult
4283 LegalizerHelper::fewerElementsVectorUnmergeValues(MachineInstr &MI,
4284                                                   unsigned TypeIdx,
4285                                                   LLT NarrowTy) {
4286   const int NumDst = MI.getNumOperands() - 1;
4287   const Register SrcReg = MI.getOperand(NumDst).getReg();
4288   LLT DstTy = MRI.getType(MI.getOperand(0).getReg());
4289   LLT SrcTy = MRI.getType(SrcReg);
4290 
4291   if (TypeIdx != 1 || NarrowTy == DstTy)
4292     return UnableToLegalize;
4293 
4294   // Requires compatible types. Otherwise SrcReg should have been defined by
4295   // merge-like instruction that would get artifact combined. Most likely
4296   // instruction that defines SrcReg has to perform more/fewer elements
4297   // legalization compatible with NarrowTy.
4298   assert(SrcTy.isVector() && NarrowTy.isVector() && "Expected vector types");
4299   assert((SrcTy.getScalarType() == NarrowTy.getScalarType()) && "bad type");
4300 
4301   if ((SrcTy.getSizeInBits() % NarrowTy.getSizeInBits() != 0) ||
4302       (NarrowTy.getSizeInBits() % DstTy.getSizeInBits() != 0))
4303     return UnableToLegalize;
4304 
4305   // This is most likely DstTy (smaller then register size) packed in SrcTy
4306   // (larger then register size) and since unmerge was not combined it will be
4307   // lowered to bit sequence extracts from register. Unpack SrcTy to NarrowTy
4308   // (register size) pieces first. Then unpack each of NarrowTy pieces to DstTy.
4309 
4310   // %1:_(DstTy), %2, %3, %4 = G_UNMERGE_VALUES %0:_(SrcTy)
4311   //
4312   // %5:_(NarrowTy), %6 = G_UNMERGE_VALUES %0:_(SrcTy) - reg sequence
4313   // %1:_(DstTy), %2 = G_UNMERGE_VALUES %5:_(NarrowTy) - sequence of bits in reg
4314   // %3:_(DstTy), %4 = G_UNMERGE_VALUES %6:_(NarrowTy)
4315   auto Unmerge = MIRBuilder.buildUnmerge(NarrowTy, SrcReg);
4316   const int NumUnmerge = Unmerge->getNumOperands() - 1;
4317   const int PartsPerUnmerge = NumDst / NumUnmerge;
4318 
4319   for (int I = 0; I != NumUnmerge; ++I) {
4320     auto MIB = MIRBuilder.buildInstr(TargetOpcode::G_UNMERGE_VALUES);
4321 
4322     for (int J = 0; J != PartsPerUnmerge; ++J)
4323       MIB.addDef(MI.getOperand(I * PartsPerUnmerge + J).getReg());
4324     MIB.addUse(Unmerge.getReg(I));
4325   }
4326 
4327   MI.eraseFromParent();
4328   return Legalized;
4329 }
4330 
4331 LegalizerHelper::LegalizeResult
4332 LegalizerHelper::fewerElementsVectorMerge(MachineInstr &MI, unsigned TypeIdx,
4333                                           LLT NarrowTy) {
4334   auto [DstReg, DstTy, SrcReg, SrcTy] = MI.getFirst2RegLLTs();
4335   // Requires compatible types. Otherwise user of DstReg did not perform unmerge
4336   // that should have been artifact combined. Most likely instruction that uses
4337   // DstReg has to do more/fewer elements legalization compatible with NarrowTy.
4338   assert(DstTy.isVector() && NarrowTy.isVector() && "Expected vector types");
4339   assert((DstTy.getScalarType() == NarrowTy.getScalarType()) && "bad type");
4340   if (NarrowTy == SrcTy)
4341     return UnableToLegalize;
4342 
4343   // This attempts to lower part of LCMTy merge/unmerge sequence. Intended use
4344   // is for old mir tests. Since the changes to more/fewer elements it should no
4345   // longer be possible to generate MIR like this when starting from llvm-ir
4346   // because LCMTy approach was replaced with merge/unmerge to vector elements.
4347   if (TypeIdx == 1) {
4348     assert(SrcTy.isVector() && "Expected vector types");
4349     assert((SrcTy.getScalarType() == NarrowTy.getScalarType()) && "bad type");
4350     if ((DstTy.getSizeInBits() % NarrowTy.getSizeInBits() != 0) ||
4351         (NarrowTy.getNumElements() >= SrcTy.getNumElements()))
4352       return UnableToLegalize;
4353     // %2:_(DstTy) = G_CONCAT_VECTORS %0:_(SrcTy), %1:_(SrcTy)
4354     //
4355     // %3:_(EltTy), %4, %5 = G_UNMERGE_VALUES %0:_(SrcTy)
4356     // %6:_(EltTy), %7, %8 = G_UNMERGE_VALUES %1:_(SrcTy)
4357     // %9:_(NarrowTy) = G_BUILD_VECTOR %3:_(EltTy), %4
4358     // %10:_(NarrowTy) = G_BUILD_VECTOR %5:_(EltTy), %6
4359     // %11:_(NarrowTy) = G_BUILD_VECTOR %7:_(EltTy), %8
4360     // %2:_(DstTy) = G_CONCAT_VECTORS %9:_(NarrowTy), %10, %11
4361 
4362     SmallVector<Register, 8> Elts;
4363     LLT EltTy = MRI.getType(MI.getOperand(1).getReg()).getScalarType();
4364     for (unsigned i = 1; i < MI.getNumOperands(); ++i) {
4365       auto Unmerge = MIRBuilder.buildUnmerge(EltTy, MI.getOperand(i).getReg());
4366       for (unsigned j = 0; j < Unmerge->getNumDefs(); ++j)
4367         Elts.push_back(Unmerge.getReg(j));
4368     }
4369 
4370     SmallVector<Register, 8> NarrowTyElts;
4371     unsigned NumNarrowTyElts = NarrowTy.getNumElements();
4372     unsigned NumNarrowTyPieces = DstTy.getNumElements() / NumNarrowTyElts;
4373     for (unsigned i = 0, Offset = 0; i < NumNarrowTyPieces;
4374          ++i, Offset += NumNarrowTyElts) {
4375       ArrayRef<Register> Pieces(&Elts[Offset], NumNarrowTyElts);
4376       NarrowTyElts.push_back(
4377           MIRBuilder.buildMergeLikeInstr(NarrowTy, Pieces).getReg(0));
4378     }
4379 
4380     MIRBuilder.buildMergeLikeInstr(DstReg, NarrowTyElts);
4381     MI.eraseFromParent();
4382     return Legalized;
4383   }
4384 
4385   assert(TypeIdx == 0 && "Bad type index");
4386   if ((NarrowTy.getSizeInBits() % SrcTy.getSizeInBits() != 0) ||
4387       (DstTy.getSizeInBits() % NarrowTy.getSizeInBits() != 0))
4388     return UnableToLegalize;
4389 
4390   // This is most likely SrcTy (smaller then register size) packed in DstTy
4391   // (larger then register size) and since merge was not combined it will be
4392   // lowered to bit sequence packing into register. Merge SrcTy to NarrowTy
4393   // (register size) pieces first. Then merge each of NarrowTy pieces to DstTy.
4394 
4395   // %0:_(DstTy) = G_MERGE_VALUES %1:_(SrcTy), %2, %3, %4
4396   //
4397   // %5:_(NarrowTy) = G_MERGE_VALUES %1:_(SrcTy), %2 - sequence of bits in reg
4398   // %6:_(NarrowTy) = G_MERGE_VALUES %3:_(SrcTy), %4
4399   // %0:_(DstTy)  = G_MERGE_VALUES %5:_(NarrowTy), %6 - reg sequence
4400   SmallVector<Register, 8> NarrowTyElts;
4401   unsigned NumParts = DstTy.getNumElements() / NarrowTy.getNumElements();
4402   unsigned NumSrcElts = SrcTy.isVector() ? SrcTy.getNumElements() : 1;
4403   unsigned NumElts = NarrowTy.getNumElements() / NumSrcElts;
4404   for (unsigned i = 0; i < NumParts; ++i) {
4405     SmallVector<Register, 8> Sources;
4406     for (unsigned j = 0; j < NumElts; ++j)
4407       Sources.push_back(MI.getOperand(1 + i * NumElts + j).getReg());
4408     NarrowTyElts.push_back(
4409         MIRBuilder.buildMergeLikeInstr(NarrowTy, Sources).getReg(0));
4410   }
4411 
4412   MIRBuilder.buildMergeLikeInstr(DstReg, NarrowTyElts);
4413   MI.eraseFromParent();
4414   return Legalized;
4415 }
4416 
4417 LegalizerHelper::LegalizeResult
4418 LegalizerHelper::fewerElementsVectorExtractInsertVectorElt(MachineInstr &MI,
4419                                                            unsigned TypeIdx,
4420                                                            LLT NarrowVecTy) {
4421   auto [DstReg, SrcVec] = MI.getFirst2Regs();
4422   Register InsertVal;
4423   bool IsInsert = MI.getOpcode() == TargetOpcode::G_INSERT_VECTOR_ELT;
4424 
4425   assert((IsInsert ? TypeIdx == 0 : TypeIdx == 1) && "not a vector type index");
4426   if (IsInsert)
4427     InsertVal = MI.getOperand(2).getReg();
4428 
4429   Register Idx = MI.getOperand(MI.getNumOperands() - 1).getReg();
4430 
4431   // TODO: Handle total scalarization case.
4432   if (!NarrowVecTy.isVector())
4433     return UnableToLegalize;
4434 
4435   LLT VecTy = MRI.getType(SrcVec);
4436 
4437   // If the index is a constant, we can really break this down as you would
4438   // expect, and index into the target size pieces.
4439   int64_t IdxVal;
4440   auto MaybeCst = getIConstantVRegValWithLookThrough(Idx, MRI);
4441   if (MaybeCst) {
4442     IdxVal = MaybeCst->Value.getSExtValue();
4443     // Avoid out of bounds indexing the pieces.
4444     if (IdxVal >= VecTy.getNumElements()) {
4445       MIRBuilder.buildUndef(DstReg);
4446       MI.eraseFromParent();
4447       return Legalized;
4448     }
4449 
4450     SmallVector<Register, 8> VecParts;
4451     LLT GCDTy = extractGCDType(VecParts, VecTy, NarrowVecTy, SrcVec);
4452 
4453     // Build a sequence of NarrowTy pieces in VecParts for this operand.
4454     LLT LCMTy = buildLCMMergePieces(VecTy, NarrowVecTy, GCDTy, VecParts,
4455                                     TargetOpcode::G_ANYEXT);
4456 
4457     unsigned NewNumElts = NarrowVecTy.getNumElements();
4458 
4459     LLT IdxTy = MRI.getType(Idx);
4460     int64_t PartIdx = IdxVal / NewNumElts;
4461     auto NewIdx =
4462         MIRBuilder.buildConstant(IdxTy, IdxVal - NewNumElts * PartIdx);
4463 
4464     if (IsInsert) {
4465       LLT PartTy = MRI.getType(VecParts[PartIdx]);
4466 
4467       // Use the adjusted index to insert into one of the subvectors.
4468       auto InsertPart = MIRBuilder.buildInsertVectorElement(
4469           PartTy, VecParts[PartIdx], InsertVal, NewIdx);
4470       VecParts[PartIdx] = InsertPart.getReg(0);
4471 
4472       // Recombine the inserted subvector with the others to reform the result
4473       // vector.
4474       buildWidenedRemergeToDst(DstReg, LCMTy, VecParts);
4475     } else {
4476       MIRBuilder.buildExtractVectorElement(DstReg, VecParts[PartIdx], NewIdx);
4477     }
4478 
4479     MI.eraseFromParent();
4480     return Legalized;
4481   }
4482 
4483   // With a variable index, we can't perform the operation in a smaller type, so
4484   // we're forced to expand this.
4485   //
4486   // TODO: We could emit a chain of compare/select to figure out which piece to
4487   // index.
4488   return lowerExtractInsertVectorElt(MI);
4489 }
4490 
4491 LegalizerHelper::LegalizeResult
4492 LegalizerHelper::reduceLoadStoreWidth(GLoadStore &LdStMI, unsigned TypeIdx,
4493                                       LLT NarrowTy) {
4494   // FIXME: Don't know how to handle secondary types yet.
4495   if (TypeIdx != 0)
4496     return UnableToLegalize;
4497 
4498   // This implementation doesn't work for atomics. Give up instead of doing
4499   // something invalid.
4500   if (LdStMI.isAtomic())
4501     return UnableToLegalize;
4502 
4503   bool IsLoad = isa<GLoad>(LdStMI);
4504   Register ValReg = LdStMI.getReg(0);
4505   Register AddrReg = LdStMI.getPointerReg();
4506   LLT ValTy = MRI.getType(ValReg);
4507 
4508   // FIXME: Do we need a distinct NarrowMemory legalize action?
4509   if (ValTy.getSizeInBits() != 8 * LdStMI.getMemSize()) {
4510     LLVM_DEBUG(dbgs() << "Can't narrow extload/truncstore\n");
4511     return UnableToLegalize;
4512   }
4513 
4514   int NumParts = -1;
4515   int NumLeftover = -1;
4516   LLT LeftoverTy;
4517   SmallVector<Register, 8> NarrowRegs, NarrowLeftoverRegs;
4518   if (IsLoad) {
4519     std::tie(NumParts, NumLeftover) = getNarrowTypeBreakDown(ValTy, NarrowTy, LeftoverTy);
4520   } else {
4521     if (extractParts(ValReg, ValTy, NarrowTy, LeftoverTy, NarrowRegs,
4522                      NarrowLeftoverRegs)) {
4523       NumParts = NarrowRegs.size();
4524       NumLeftover = NarrowLeftoverRegs.size();
4525     }
4526   }
4527 
4528   if (NumParts == -1)
4529     return UnableToLegalize;
4530 
4531   LLT PtrTy = MRI.getType(AddrReg);
4532   const LLT OffsetTy = LLT::scalar(PtrTy.getSizeInBits());
4533 
4534   unsigned TotalSize = ValTy.getSizeInBits();
4535 
4536   // Split the load/store into PartTy sized pieces starting at Offset. If this
4537   // is a load, return the new registers in ValRegs. For a store, each elements
4538   // of ValRegs should be PartTy. Returns the next offset that needs to be
4539   // handled.
4540   bool isBigEndian = MIRBuilder.getDataLayout().isBigEndian();
4541   auto MMO = LdStMI.getMMO();
4542   auto splitTypePieces = [=](LLT PartTy, SmallVectorImpl<Register> &ValRegs,
4543                              unsigned NumParts, unsigned Offset) -> unsigned {
4544     MachineFunction &MF = MIRBuilder.getMF();
4545     unsigned PartSize = PartTy.getSizeInBits();
4546     for (unsigned Idx = 0, E = NumParts; Idx != E && Offset < TotalSize;
4547          ++Idx) {
4548       unsigned ByteOffset = Offset / 8;
4549       Register NewAddrReg;
4550 
4551       MIRBuilder.materializePtrAdd(NewAddrReg, AddrReg, OffsetTy, ByteOffset);
4552 
4553       MachineMemOperand *NewMMO =
4554           MF.getMachineMemOperand(&MMO, ByteOffset, PartTy);
4555 
4556       if (IsLoad) {
4557         Register Dst = MRI.createGenericVirtualRegister(PartTy);
4558         ValRegs.push_back(Dst);
4559         MIRBuilder.buildLoad(Dst, NewAddrReg, *NewMMO);
4560       } else {
4561         MIRBuilder.buildStore(ValRegs[Idx], NewAddrReg, *NewMMO);
4562       }
4563       Offset = isBigEndian ? Offset - PartSize : Offset + PartSize;
4564     }
4565 
4566     return Offset;
4567   };
4568 
4569   unsigned Offset = isBigEndian ? TotalSize - NarrowTy.getSizeInBits() : 0;
4570   unsigned HandledOffset =
4571       splitTypePieces(NarrowTy, NarrowRegs, NumParts, Offset);
4572 
4573   // Handle the rest of the register if this isn't an even type breakdown.
4574   if (LeftoverTy.isValid())
4575     splitTypePieces(LeftoverTy, NarrowLeftoverRegs, NumLeftover, HandledOffset);
4576 
4577   if (IsLoad) {
4578     insertParts(ValReg, ValTy, NarrowTy, NarrowRegs,
4579                 LeftoverTy, NarrowLeftoverRegs);
4580   }
4581 
4582   LdStMI.eraseFromParent();
4583   return Legalized;
4584 }
4585 
4586 LegalizerHelper::LegalizeResult
4587 LegalizerHelper::fewerElementsVector(MachineInstr &MI, unsigned TypeIdx,
4588                                      LLT NarrowTy) {
4589   using namespace TargetOpcode;
4590   GenericMachineInstr &GMI = cast<GenericMachineInstr>(MI);
4591   unsigned NumElts = NarrowTy.isVector() ? NarrowTy.getNumElements() : 1;
4592 
4593   switch (MI.getOpcode()) {
4594   case G_IMPLICIT_DEF:
4595   case G_TRUNC:
4596   case G_AND:
4597   case G_OR:
4598   case G_XOR:
4599   case G_ADD:
4600   case G_SUB:
4601   case G_MUL:
4602   case G_PTR_ADD:
4603   case G_SMULH:
4604   case G_UMULH:
4605   case G_FADD:
4606   case G_FMUL:
4607   case G_FSUB:
4608   case G_FNEG:
4609   case G_FABS:
4610   case G_FCANONICALIZE:
4611   case G_FDIV:
4612   case G_FREM:
4613   case G_FMA:
4614   case G_FMAD:
4615   case G_FPOW:
4616   case G_FEXP:
4617   case G_FEXP2:
4618   case G_FEXP10:
4619   case G_FLOG:
4620   case G_FLOG2:
4621   case G_FLOG10:
4622   case G_FLDEXP:
4623   case G_FNEARBYINT:
4624   case G_FCEIL:
4625   case G_FFLOOR:
4626   case G_FRINT:
4627   case G_INTRINSIC_ROUND:
4628   case G_INTRINSIC_ROUNDEVEN:
4629   case G_INTRINSIC_TRUNC:
4630   case G_FCOS:
4631   case G_FSIN:
4632   case G_FSQRT:
4633   case G_BSWAP:
4634   case G_BITREVERSE:
4635   case G_SDIV:
4636   case G_UDIV:
4637   case G_SREM:
4638   case G_UREM:
4639   case G_SDIVREM:
4640   case G_UDIVREM:
4641   case G_SMIN:
4642   case G_SMAX:
4643   case G_UMIN:
4644   case G_UMAX:
4645   case G_ABS:
4646   case G_FMINNUM:
4647   case G_FMAXNUM:
4648   case G_FMINNUM_IEEE:
4649   case G_FMAXNUM_IEEE:
4650   case G_FMINIMUM:
4651   case G_FMAXIMUM:
4652   case G_FSHL:
4653   case G_FSHR:
4654   case G_ROTL:
4655   case G_ROTR:
4656   case G_FREEZE:
4657   case G_SADDSAT:
4658   case G_SSUBSAT:
4659   case G_UADDSAT:
4660   case G_USUBSAT:
4661   case G_UMULO:
4662   case G_SMULO:
4663   case G_SHL:
4664   case G_LSHR:
4665   case G_ASHR:
4666   case G_SSHLSAT:
4667   case G_USHLSAT:
4668   case G_CTLZ:
4669   case G_CTLZ_ZERO_UNDEF:
4670   case G_CTTZ:
4671   case G_CTTZ_ZERO_UNDEF:
4672   case G_CTPOP:
4673   case G_FCOPYSIGN:
4674   case G_ZEXT:
4675   case G_SEXT:
4676   case G_ANYEXT:
4677   case G_FPEXT:
4678   case G_FPTRUNC:
4679   case G_SITOFP:
4680   case G_UITOFP:
4681   case G_FPTOSI:
4682   case G_FPTOUI:
4683   case G_INTTOPTR:
4684   case G_PTRTOINT:
4685   case G_ADDRSPACE_CAST:
4686   case G_UADDO:
4687   case G_USUBO:
4688   case G_UADDE:
4689   case G_USUBE:
4690   case G_SADDO:
4691   case G_SSUBO:
4692   case G_SADDE:
4693   case G_SSUBE:
4694   case G_STRICT_FADD:
4695   case G_STRICT_FSUB:
4696   case G_STRICT_FMUL:
4697   case G_STRICT_FMA:
4698   case G_STRICT_FLDEXP:
4699   case G_FFREXP:
4700     return fewerElementsVectorMultiEltType(GMI, NumElts);
4701   case G_ICMP:
4702   case G_FCMP:
4703     return fewerElementsVectorMultiEltType(GMI, NumElts, {1 /*cpm predicate*/});
4704   case G_IS_FPCLASS:
4705     return fewerElementsVectorMultiEltType(GMI, NumElts, {2, 3 /*mask,fpsem*/});
4706   case G_SELECT:
4707     if (MRI.getType(MI.getOperand(1).getReg()).isVector())
4708       return fewerElementsVectorMultiEltType(GMI, NumElts);
4709     return fewerElementsVectorMultiEltType(GMI, NumElts, {1 /*scalar cond*/});
4710   case G_PHI:
4711     return fewerElementsVectorPhi(GMI, NumElts);
4712   case G_UNMERGE_VALUES:
4713     return fewerElementsVectorUnmergeValues(MI, TypeIdx, NarrowTy);
4714   case G_BUILD_VECTOR:
4715     assert(TypeIdx == 0 && "not a vector type index");
4716     return fewerElementsVectorMerge(MI, TypeIdx, NarrowTy);
4717   case G_CONCAT_VECTORS:
4718     if (TypeIdx != 1) // TODO: This probably does work as expected already.
4719       return UnableToLegalize;
4720     return fewerElementsVectorMerge(MI, TypeIdx, NarrowTy);
4721   case G_EXTRACT_VECTOR_ELT:
4722   case G_INSERT_VECTOR_ELT:
4723     return fewerElementsVectorExtractInsertVectorElt(MI, TypeIdx, NarrowTy);
4724   case G_LOAD:
4725   case G_STORE:
4726     return reduceLoadStoreWidth(cast<GLoadStore>(MI), TypeIdx, NarrowTy);
4727   case G_SEXT_INREG:
4728     return fewerElementsVectorMultiEltType(GMI, NumElts, {2 /*imm*/});
4729   GISEL_VECREDUCE_CASES_NONSEQ
4730     return fewerElementsVectorReductions(MI, TypeIdx, NarrowTy);
4731   case TargetOpcode::G_VECREDUCE_SEQ_FADD:
4732   case TargetOpcode::G_VECREDUCE_SEQ_FMUL:
4733     return fewerElementsVectorSeqReductions(MI, TypeIdx, NarrowTy);
4734   case G_SHUFFLE_VECTOR:
4735     return fewerElementsVectorShuffle(MI, TypeIdx, NarrowTy);
4736   case G_FPOWI:
4737     return fewerElementsVectorMultiEltType(GMI, NumElts, {2 /*pow*/});
4738   default:
4739     return UnableToLegalize;
4740   }
4741 }
4742 
4743 LegalizerHelper::LegalizeResult LegalizerHelper::fewerElementsVectorShuffle(
4744     MachineInstr &MI, unsigned int TypeIdx, LLT NarrowTy) {
4745   assert(MI.getOpcode() == TargetOpcode::G_SHUFFLE_VECTOR);
4746   if (TypeIdx != 0)
4747     return UnableToLegalize;
4748 
4749   auto [DstReg, DstTy, Src1Reg, Src1Ty, Src2Reg, Src2Ty] =
4750       MI.getFirst3RegLLTs();
4751   ArrayRef<int> Mask = MI.getOperand(3).getShuffleMask();
4752   // The shuffle should be canonicalized by now.
4753   if (DstTy != Src1Ty)
4754     return UnableToLegalize;
4755   if (DstTy != Src2Ty)
4756     return UnableToLegalize;
4757 
4758   if (!isPowerOf2_32(DstTy.getNumElements()))
4759     return UnableToLegalize;
4760 
4761   // We only support splitting a shuffle into 2, so adjust NarrowTy accordingly.
4762   // Further legalization attempts will be needed to do split further.
4763   NarrowTy =
4764       DstTy.changeElementCount(DstTy.getElementCount().divideCoefficientBy(2));
4765   unsigned NewElts = NarrowTy.getNumElements();
4766 
4767   SmallVector<Register> SplitSrc1Regs, SplitSrc2Regs;
4768   extractParts(Src1Reg, NarrowTy, 2, SplitSrc1Regs);
4769   extractParts(Src2Reg, NarrowTy, 2, SplitSrc2Regs);
4770   Register Inputs[4] = {SplitSrc1Regs[0], SplitSrc1Regs[1], SplitSrc2Regs[0],
4771                         SplitSrc2Regs[1]};
4772 
4773   Register Hi, Lo;
4774 
4775   // If Lo or Hi uses elements from at most two of the four input vectors, then
4776   // express it as a vector shuffle of those two inputs.  Otherwise extract the
4777   // input elements by hand and construct the Lo/Hi output using a BUILD_VECTOR.
4778   SmallVector<int, 16> Ops;
4779   for (unsigned High = 0; High < 2; ++High) {
4780     Register &Output = High ? Hi : Lo;
4781 
4782     // Build a shuffle mask for the output, discovering on the fly which
4783     // input vectors to use as shuffle operands (recorded in InputUsed).
4784     // If building a suitable shuffle vector proves too hard, then bail
4785     // out with useBuildVector set.
4786     unsigned InputUsed[2] = {-1U, -1U}; // Not yet discovered.
4787     unsigned FirstMaskIdx = High * NewElts;
4788     bool UseBuildVector = false;
4789     for (unsigned MaskOffset = 0; MaskOffset < NewElts; ++MaskOffset) {
4790       // The mask element.  This indexes into the input.
4791       int Idx = Mask[FirstMaskIdx + MaskOffset];
4792 
4793       // The input vector this mask element indexes into.
4794       unsigned Input = (unsigned)Idx / NewElts;
4795 
4796       if (Input >= std::size(Inputs)) {
4797         // The mask element does not index into any input vector.
4798         Ops.push_back(-1);
4799         continue;
4800       }
4801 
4802       // Turn the index into an offset from the start of the input vector.
4803       Idx -= Input * NewElts;
4804 
4805       // Find or create a shuffle vector operand to hold this input.
4806       unsigned OpNo;
4807       for (OpNo = 0; OpNo < std::size(InputUsed); ++OpNo) {
4808         if (InputUsed[OpNo] == Input) {
4809           // This input vector is already an operand.
4810           break;
4811         } else if (InputUsed[OpNo] == -1U) {
4812           // Create a new operand for this input vector.
4813           InputUsed[OpNo] = Input;
4814           break;
4815         }
4816       }
4817 
4818       if (OpNo >= std::size(InputUsed)) {
4819         // More than two input vectors used!  Give up on trying to create a
4820         // shuffle vector.  Insert all elements into a BUILD_VECTOR instead.
4821         UseBuildVector = true;
4822         break;
4823       }
4824 
4825       // Add the mask index for the new shuffle vector.
4826       Ops.push_back(Idx + OpNo * NewElts);
4827     }
4828 
4829     if (UseBuildVector) {
4830       LLT EltTy = NarrowTy.getElementType();
4831       SmallVector<Register, 16> SVOps;
4832 
4833       // Extract the input elements by hand.
4834       for (unsigned MaskOffset = 0; MaskOffset < NewElts; ++MaskOffset) {
4835         // The mask element.  This indexes into the input.
4836         int Idx = Mask[FirstMaskIdx + MaskOffset];
4837 
4838         // The input vector this mask element indexes into.
4839         unsigned Input = (unsigned)Idx / NewElts;
4840 
4841         if (Input >= std::size(Inputs)) {
4842           // The mask element is "undef" or indexes off the end of the input.
4843           SVOps.push_back(MIRBuilder.buildUndef(EltTy).getReg(0));
4844           continue;
4845         }
4846 
4847         // Turn the index into an offset from the start of the input vector.
4848         Idx -= Input * NewElts;
4849 
4850         // Extract the vector element by hand.
4851         SVOps.push_back(MIRBuilder
4852                             .buildExtractVectorElement(
4853                                 EltTy, Inputs[Input],
4854                                 MIRBuilder.buildConstant(LLT::scalar(32), Idx))
4855                             .getReg(0));
4856       }
4857 
4858       // Construct the Lo/Hi output using a G_BUILD_VECTOR.
4859       Output = MIRBuilder.buildBuildVector(NarrowTy, SVOps).getReg(0);
4860     } else if (InputUsed[0] == -1U) {
4861       // No input vectors were used! The result is undefined.
4862       Output = MIRBuilder.buildUndef(NarrowTy).getReg(0);
4863     } else {
4864       Register Op0 = Inputs[InputUsed[0]];
4865       // If only one input was used, use an undefined vector for the other.
4866       Register Op1 = InputUsed[1] == -1U
4867                          ? MIRBuilder.buildUndef(NarrowTy).getReg(0)
4868                          : Inputs[InputUsed[1]];
4869       // At least one input vector was used. Create a new shuffle vector.
4870       Output = MIRBuilder.buildShuffleVector(NarrowTy, Op0, Op1, Ops).getReg(0);
4871     }
4872 
4873     Ops.clear();
4874   }
4875 
4876   MIRBuilder.buildConcatVectors(DstReg, {Lo, Hi});
4877   MI.eraseFromParent();
4878   return Legalized;
4879 }
4880 
4881 LegalizerHelper::LegalizeResult LegalizerHelper::fewerElementsVectorReductions(
4882     MachineInstr &MI, unsigned int TypeIdx, LLT NarrowTy) {
4883   auto &RdxMI = cast<GVecReduce>(MI);
4884 
4885   if (TypeIdx != 1)
4886     return UnableToLegalize;
4887 
4888   // The semantics of the normal non-sequential reductions allow us to freely
4889   // re-associate the operation.
4890   auto [DstReg, DstTy, SrcReg, SrcTy] = RdxMI.getFirst2RegLLTs();
4891 
4892   if (NarrowTy.isVector() &&
4893       (SrcTy.getNumElements() % NarrowTy.getNumElements() != 0))
4894     return UnableToLegalize;
4895 
4896   unsigned ScalarOpc = RdxMI.getScalarOpcForReduction();
4897   SmallVector<Register> SplitSrcs;
4898   // If NarrowTy is a scalar then we're being asked to scalarize.
4899   const unsigned NumParts =
4900       NarrowTy.isVector() ? SrcTy.getNumElements() / NarrowTy.getNumElements()
4901                           : SrcTy.getNumElements();
4902 
4903   extractParts(SrcReg, NarrowTy, NumParts, SplitSrcs);
4904   if (NarrowTy.isScalar()) {
4905     if (DstTy != NarrowTy)
4906       return UnableToLegalize; // FIXME: handle implicit extensions.
4907 
4908     if (isPowerOf2_32(NumParts)) {
4909       // Generate a tree of scalar operations to reduce the critical path.
4910       SmallVector<Register> PartialResults;
4911       unsigned NumPartsLeft = NumParts;
4912       while (NumPartsLeft > 1) {
4913         for (unsigned Idx = 0; Idx < NumPartsLeft - 1; Idx += 2) {
4914           PartialResults.emplace_back(
4915               MIRBuilder
4916                   .buildInstr(ScalarOpc, {NarrowTy},
4917                               {SplitSrcs[Idx], SplitSrcs[Idx + 1]})
4918                   .getReg(0));
4919         }
4920         SplitSrcs = PartialResults;
4921         PartialResults.clear();
4922         NumPartsLeft = SplitSrcs.size();
4923       }
4924       assert(SplitSrcs.size() == 1);
4925       MIRBuilder.buildCopy(DstReg, SplitSrcs[0]);
4926       MI.eraseFromParent();
4927       return Legalized;
4928     }
4929     // If we can't generate a tree, then just do sequential operations.
4930     Register Acc = SplitSrcs[0];
4931     for (unsigned Idx = 1; Idx < NumParts; ++Idx)
4932       Acc = MIRBuilder.buildInstr(ScalarOpc, {NarrowTy}, {Acc, SplitSrcs[Idx]})
4933                 .getReg(0);
4934     MIRBuilder.buildCopy(DstReg, Acc);
4935     MI.eraseFromParent();
4936     return Legalized;
4937   }
4938   SmallVector<Register> PartialReductions;
4939   for (unsigned Part = 0; Part < NumParts; ++Part) {
4940     PartialReductions.push_back(
4941         MIRBuilder.buildInstr(RdxMI.getOpcode(), {DstTy}, {SplitSrcs[Part]})
4942             .getReg(0));
4943   }
4944 
4945   // If the types involved are powers of 2, we can generate intermediate vector
4946   // ops, before generating a final reduction operation.
4947   if (isPowerOf2_32(SrcTy.getNumElements()) &&
4948       isPowerOf2_32(NarrowTy.getNumElements())) {
4949     return tryNarrowPow2Reduction(MI, SrcReg, SrcTy, NarrowTy, ScalarOpc);
4950   }
4951 
4952   Register Acc = PartialReductions[0];
4953   for (unsigned Part = 1; Part < NumParts; ++Part) {
4954     if (Part == NumParts - 1) {
4955       MIRBuilder.buildInstr(ScalarOpc, {DstReg},
4956                             {Acc, PartialReductions[Part]});
4957     } else {
4958       Acc = MIRBuilder
4959                 .buildInstr(ScalarOpc, {DstTy}, {Acc, PartialReductions[Part]})
4960                 .getReg(0);
4961     }
4962   }
4963   MI.eraseFromParent();
4964   return Legalized;
4965 }
4966 
4967 LegalizerHelper::LegalizeResult
4968 LegalizerHelper::fewerElementsVectorSeqReductions(MachineInstr &MI,
4969                                                   unsigned int TypeIdx,
4970                                                   LLT NarrowTy) {
4971   auto [DstReg, DstTy, ScalarReg, ScalarTy, SrcReg, SrcTy] =
4972       MI.getFirst3RegLLTs();
4973   if (!NarrowTy.isScalar() || TypeIdx != 2 || DstTy != ScalarTy ||
4974       DstTy != NarrowTy)
4975     return UnableToLegalize;
4976 
4977   assert((MI.getOpcode() == TargetOpcode::G_VECREDUCE_SEQ_FADD ||
4978           MI.getOpcode() == TargetOpcode::G_VECREDUCE_SEQ_FMUL) &&
4979          "Unexpected vecreduce opcode");
4980   unsigned ScalarOpc = MI.getOpcode() == TargetOpcode::G_VECREDUCE_SEQ_FADD
4981                            ? TargetOpcode::G_FADD
4982                            : TargetOpcode::G_FMUL;
4983 
4984   SmallVector<Register> SplitSrcs;
4985   unsigned NumParts = SrcTy.getNumElements();
4986   extractParts(SrcReg, NarrowTy, NumParts, SplitSrcs);
4987   Register Acc = ScalarReg;
4988   for (unsigned i = 0; i < NumParts; i++)
4989     Acc = MIRBuilder.buildInstr(ScalarOpc, {NarrowTy}, {Acc, SplitSrcs[i]})
4990               .getReg(0);
4991 
4992   MIRBuilder.buildCopy(DstReg, Acc);
4993   MI.eraseFromParent();
4994   return Legalized;
4995 }
4996 
4997 LegalizerHelper::LegalizeResult
4998 LegalizerHelper::tryNarrowPow2Reduction(MachineInstr &MI, Register SrcReg,
4999                                         LLT SrcTy, LLT NarrowTy,
5000                                         unsigned ScalarOpc) {
5001   SmallVector<Register> SplitSrcs;
5002   // Split the sources into NarrowTy size pieces.
5003   extractParts(SrcReg, NarrowTy,
5004                SrcTy.getNumElements() / NarrowTy.getNumElements(), SplitSrcs);
5005   // We're going to do a tree reduction using vector operations until we have
5006   // one NarrowTy size value left.
5007   while (SplitSrcs.size() > 1) {
5008     SmallVector<Register> PartialRdxs;
5009     for (unsigned Idx = 0; Idx < SplitSrcs.size()-1; Idx += 2) {
5010       Register LHS = SplitSrcs[Idx];
5011       Register RHS = SplitSrcs[Idx + 1];
5012       // Create the intermediate vector op.
5013       Register Res =
5014           MIRBuilder.buildInstr(ScalarOpc, {NarrowTy}, {LHS, RHS}).getReg(0);
5015       PartialRdxs.push_back(Res);
5016     }
5017     SplitSrcs = std::move(PartialRdxs);
5018   }
5019   // Finally generate the requested NarrowTy based reduction.
5020   Observer.changingInstr(MI);
5021   MI.getOperand(1).setReg(SplitSrcs[0]);
5022   Observer.changedInstr(MI);
5023   return Legalized;
5024 }
5025 
5026 LegalizerHelper::LegalizeResult
5027 LegalizerHelper::narrowScalarShiftByConstant(MachineInstr &MI, const APInt &Amt,
5028                                              const LLT HalfTy, const LLT AmtTy) {
5029 
5030   Register InL = MRI.createGenericVirtualRegister(HalfTy);
5031   Register InH = MRI.createGenericVirtualRegister(HalfTy);
5032   MIRBuilder.buildUnmerge({InL, InH}, MI.getOperand(1));
5033 
5034   if (Amt.isZero()) {
5035     MIRBuilder.buildMergeLikeInstr(MI.getOperand(0), {InL, InH});
5036     MI.eraseFromParent();
5037     return Legalized;
5038   }
5039 
5040   LLT NVT = HalfTy;
5041   unsigned NVTBits = HalfTy.getSizeInBits();
5042   unsigned VTBits = 2 * NVTBits;
5043 
5044   SrcOp Lo(Register(0)), Hi(Register(0));
5045   if (MI.getOpcode() == TargetOpcode::G_SHL) {
5046     if (Amt.ugt(VTBits)) {
5047       Lo = Hi = MIRBuilder.buildConstant(NVT, 0);
5048     } else if (Amt.ugt(NVTBits)) {
5049       Lo = MIRBuilder.buildConstant(NVT, 0);
5050       Hi = MIRBuilder.buildShl(NVT, InL,
5051                                MIRBuilder.buildConstant(AmtTy, Amt - NVTBits));
5052     } else if (Amt == NVTBits) {
5053       Lo = MIRBuilder.buildConstant(NVT, 0);
5054       Hi = InL;
5055     } else {
5056       Lo = MIRBuilder.buildShl(NVT, InL, MIRBuilder.buildConstant(AmtTy, Amt));
5057       auto OrLHS =
5058           MIRBuilder.buildShl(NVT, InH, MIRBuilder.buildConstant(AmtTy, Amt));
5059       auto OrRHS = MIRBuilder.buildLShr(
5060           NVT, InL, MIRBuilder.buildConstant(AmtTy, -Amt + NVTBits));
5061       Hi = MIRBuilder.buildOr(NVT, OrLHS, OrRHS);
5062     }
5063   } else if (MI.getOpcode() == TargetOpcode::G_LSHR) {
5064     if (Amt.ugt(VTBits)) {
5065       Lo = Hi = MIRBuilder.buildConstant(NVT, 0);
5066     } else if (Amt.ugt(NVTBits)) {
5067       Lo = MIRBuilder.buildLShr(NVT, InH,
5068                                 MIRBuilder.buildConstant(AmtTy, Amt - NVTBits));
5069       Hi = MIRBuilder.buildConstant(NVT, 0);
5070     } else if (Amt == NVTBits) {
5071       Lo = InH;
5072       Hi = MIRBuilder.buildConstant(NVT, 0);
5073     } else {
5074       auto ShiftAmtConst = MIRBuilder.buildConstant(AmtTy, Amt);
5075 
5076       auto OrLHS = MIRBuilder.buildLShr(NVT, InL, ShiftAmtConst);
5077       auto OrRHS = MIRBuilder.buildShl(
5078           NVT, InH, MIRBuilder.buildConstant(AmtTy, -Amt + NVTBits));
5079 
5080       Lo = MIRBuilder.buildOr(NVT, OrLHS, OrRHS);
5081       Hi = MIRBuilder.buildLShr(NVT, InH, ShiftAmtConst);
5082     }
5083   } else {
5084     if (Amt.ugt(VTBits)) {
5085       Hi = Lo = MIRBuilder.buildAShr(
5086           NVT, InH, MIRBuilder.buildConstant(AmtTy, NVTBits - 1));
5087     } else if (Amt.ugt(NVTBits)) {
5088       Lo = MIRBuilder.buildAShr(NVT, InH,
5089                                 MIRBuilder.buildConstant(AmtTy, Amt - NVTBits));
5090       Hi = MIRBuilder.buildAShr(NVT, InH,
5091                                 MIRBuilder.buildConstant(AmtTy, NVTBits - 1));
5092     } else if (Amt == NVTBits) {
5093       Lo = InH;
5094       Hi = MIRBuilder.buildAShr(NVT, InH,
5095                                 MIRBuilder.buildConstant(AmtTy, NVTBits - 1));
5096     } else {
5097       auto ShiftAmtConst = MIRBuilder.buildConstant(AmtTy, Amt);
5098 
5099       auto OrLHS = MIRBuilder.buildLShr(NVT, InL, ShiftAmtConst);
5100       auto OrRHS = MIRBuilder.buildShl(
5101           NVT, InH, MIRBuilder.buildConstant(AmtTy, -Amt + NVTBits));
5102 
5103       Lo = MIRBuilder.buildOr(NVT, OrLHS, OrRHS);
5104       Hi = MIRBuilder.buildAShr(NVT, InH, ShiftAmtConst);
5105     }
5106   }
5107 
5108   MIRBuilder.buildMergeLikeInstr(MI.getOperand(0), {Lo, Hi});
5109   MI.eraseFromParent();
5110 
5111   return Legalized;
5112 }
5113 
5114 // TODO: Optimize if constant shift amount.
5115 LegalizerHelper::LegalizeResult
5116 LegalizerHelper::narrowScalarShift(MachineInstr &MI, unsigned TypeIdx,
5117                                    LLT RequestedTy) {
5118   if (TypeIdx == 1) {
5119     Observer.changingInstr(MI);
5120     narrowScalarSrc(MI, RequestedTy, 2);
5121     Observer.changedInstr(MI);
5122     return Legalized;
5123   }
5124 
5125   Register DstReg = MI.getOperand(0).getReg();
5126   LLT DstTy = MRI.getType(DstReg);
5127   if (DstTy.isVector())
5128     return UnableToLegalize;
5129 
5130   Register Amt = MI.getOperand(2).getReg();
5131   LLT ShiftAmtTy = MRI.getType(Amt);
5132   const unsigned DstEltSize = DstTy.getScalarSizeInBits();
5133   if (DstEltSize % 2 != 0)
5134     return UnableToLegalize;
5135 
5136   // Ignore the input type. We can only go to exactly half the size of the
5137   // input. If that isn't small enough, the resulting pieces will be further
5138   // legalized.
5139   const unsigned NewBitSize = DstEltSize / 2;
5140   const LLT HalfTy = LLT::scalar(NewBitSize);
5141   const LLT CondTy = LLT::scalar(1);
5142 
5143   if (auto VRegAndVal = getIConstantVRegValWithLookThrough(Amt, MRI)) {
5144     return narrowScalarShiftByConstant(MI, VRegAndVal->Value, HalfTy,
5145                                        ShiftAmtTy);
5146   }
5147 
5148   // TODO: Expand with known bits.
5149 
5150   // Handle the fully general expansion by an unknown amount.
5151   auto NewBits = MIRBuilder.buildConstant(ShiftAmtTy, NewBitSize);
5152 
5153   Register InL = MRI.createGenericVirtualRegister(HalfTy);
5154   Register InH = MRI.createGenericVirtualRegister(HalfTy);
5155   MIRBuilder.buildUnmerge({InL, InH}, MI.getOperand(1));
5156 
5157   auto AmtExcess = MIRBuilder.buildSub(ShiftAmtTy, Amt, NewBits);
5158   auto AmtLack = MIRBuilder.buildSub(ShiftAmtTy, NewBits, Amt);
5159 
5160   auto Zero = MIRBuilder.buildConstant(ShiftAmtTy, 0);
5161   auto IsShort = MIRBuilder.buildICmp(ICmpInst::ICMP_ULT, CondTy, Amt, NewBits);
5162   auto IsZero = MIRBuilder.buildICmp(ICmpInst::ICMP_EQ, CondTy, Amt, Zero);
5163 
5164   Register ResultRegs[2];
5165   switch (MI.getOpcode()) {
5166   case TargetOpcode::G_SHL: {
5167     // Short: ShAmt < NewBitSize
5168     auto LoS = MIRBuilder.buildShl(HalfTy, InL, Amt);
5169 
5170     auto LoOr = MIRBuilder.buildLShr(HalfTy, InL, AmtLack);
5171     auto HiOr = MIRBuilder.buildShl(HalfTy, InH, Amt);
5172     auto HiS = MIRBuilder.buildOr(HalfTy, LoOr, HiOr);
5173 
5174     // Long: ShAmt >= NewBitSize
5175     auto LoL = MIRBuilder.buildConstant(HalfTy, 0);         // Lo part is zero.
5176     auto HiL = MIRBuilder.buildShl(HalfTy, InL, AmtExcess); // Hi from Lo part.
5177 
5178     auto Lo = MIRBuilder.buildSelect(HalfTy, IsShort, LoS, LoL);
5179     auto Hi = MIRBuilder.buildSelect(
5180         HalfTy, IsZero, InH, MIRBuilder.buildSelect(HalfTy, IsShort, HiS, HiL));
5181 
5182     ResultRegs[0] = Lo.getReg(0);
5183     ResultRegs[1] = Hi.getReg(0);
5184     break;
5185   }
5186   case TargetOpcode::G_LSHR:
5187   case TargetOpcode::G_ASHR: {
5188     // Short: ShAmt < NewBitSize
5189     auto HiS = MIRBuilder.buildInstr(MI.getOpcode(), {HalfTy}, {InH, Amt});
5190 
5191     auto LoOr = MIRBuilder.buildLShr(HalfTy, InL, Amt);
5192     auto HiOr = MIRBuilder.buildShl(HalfTy, InH, AmtLack);
5193     auto LoS = MIRBuilder.buildOr(HalfTy, LoOr, HiOr);
5194 
5195     // Long: ShAmt >= NewBitSize
5196     MachineInstrBuilder HiL;
5197     if (MI.getOpcode() == TargetOpcode::G_LSHR) {
5198       HiL = MIRBuilder.buildConstant(HalfTy, 0);            // Hi part is zero.
5199     } else {
5200       auto ShiftAmt = MIRBuilder.buildConstant(ShiftAmtTy, NewBitSize - 1);
5201       HiL = MIRBuilder.buildAShr(HalfTy, InH, ShiftAmt);    // Sign of Hi part.
5202     }
5203     auto LoL = MIRBuilder.buildInstr(MI.getOpcode(), {HalfTy},
5204                                      {InH, AmtExcess});     // Lo from Hi part.
5205 
5206     auto Lo = MIRBuilder.buildSelect(
5207         HalfTy, IsZero, InL, MIRBuilder.buildSelect(HalfTy, IsShort, LoS, LoL));
5208 
5209     auto Hi = MIRBuilder.buildSelect(HalfTy, IsShort, HiS, HiL);
5210 
5211     ResultRegs[0] = Lo.getReg(0);
5212     ResultRegs[1] = Hi.getReg(0);
5213     break;
5214   }
5215   default:
5216     llvm_unreachable("not a shift");
5217   }
5218 
5219   MIRBuilder.buildMergeLikeInstr(DstReg, ResultRegs);
5220   MI.eraseFromParent();
5221   return Legalized;
5222 }
5223 
5224 LegalizerHelper::LegalizeResult
5225 LegalizerHelper::moreElementsVectorPhi(MachineInstr &MI, unsigned TypeIdx,
5226                                        LLT MoreTy) {
5227   assert(TypeIdx == 0 && "Expecting only Idx 0");
5228 
5229   Observer.changingInstr(MI);
5230   for (unsigned I = 1, E = MI.getNumOperands(); I != E; I += 2) {
5231     MachineBasicBlock &OpMBB = *MI.getOperand(I + 1).getMBB();
5232     MIRBuilder.setInsertPt(OpMBB, OpMBB.getFirstTerminator());
5233     moreElementsVectorSrc(MI, MoreTy, I);
5234   }
5235 
5236   MachineBasicBlock &MBB = *MI.getParent();
5237   MIRBuilder.setInsertPt(MBB, --MBB.getFirstNonPHI());
5238   moreElementsVectorDst(MI, MoreTy, 0);
5239   Observer.changedInstr(MI);
5240   return Legalized;
5241 }
5242 
5243 LegalizerHelper::LegalizeResult
5244 LegalizerHelper::moreElementsVector(MachineInstr &MI, unsigned TypeIdx,
5245                                     LLT MoreTy) {
5246   unsigned Opc = MI.getOpcode();
5247   switch (Opc) {
5248   case TargetOpcode::G_IMPLICIT_DEF:
5249   case TargetOpcode::G_LOAD: {
5250     if (TypeIdx != 0)
5251       return UnableToLegalize;
5252     Observer.changingInstr(MI);
5253     moreElementsVectorDst(MI, MoreTy, 0);
5254     Observer.changedInstr(MI);
5255     return Legalized;
5256   }
5257   case TargetOpcode::G_STORE:
5258     if (TypeIdx != 0)
5259       return UnableToLegalize;
5260     Observer.changingInstr(MI);
5261     moreElementsVectorSrc(MI, MoreTy, 0);
5262     Observer.changedInstr(MI);
5263     return Legalized;
5264   case TargetOpcode::G_AND:
5265   case TargetOpcode::G_OR:
5266   case TargetOpcode::G_XOR:
5267   case TargetOpcode::G_ADD:
5268   case TargetOpcode::G_SUB:
5269   case TargetOpcode::G_MUL:
5270   case TargetOpcode::G_FADD:
5271   case TargetOpcode::G_FSUB:
5272   case TargetOpcode::G_FMUL:
5273   case TargetOpcode::G_FDIV:
5274   case TargetOpcode::G_UADDSAT:
5275   case TargetOpcode::G_USUBSAT:
5276   case TargetOpcode::G_SADDSAT:
5277   case TargetOpcode::G_SSUBSAT:
5278   case TargetOpcode::G_SMIN:
5279   case TargetOpcode::G_SMAX:
5280   case TargetOpcode::G_UMIN:
5281   case TargetOpcode::G_UMAX:
5282   case TargetOpcode::G_FMINNUM:
5283   case TargetOpcode::G_FMAXNUM:
5284   case TargetOpcode::G_FMINNUM_IEEE:
5285   case TargetOpcode::G_FMAXNUM_IEEE:
5286   case TargetOpcode::G_FMINIMUM:
5287   case TargetOpcode::G_FMAXIMUM:
5288   case TargetOpcode::G_STRICT_FADD:
5289   case TargetOpcode::G_STRICT_FSUB:
5290   case TargetOpcode::G_STRICT_FMUL: {
5291     Observer.changingInstr(MI);
5292     moreElementsVectorSrc(MI, MoreTy, 1);
5293     moreElementsVectorSrc(MI, MoreTy, 2);
5294     moreElementsVectorDst(MI, MoreTy, 0);
5295     Observer.changedInstr(MI);
5296     return Legalized;
5297   }
5298   case TargetOpcode::G_FMA:
5299   case TargetOpcode::G_STRICT_FMA:
5300   case TargetOpcode::G_FSHR:
5301   case TargetOpcode::G_FSHL: {
5302     Observer.changingInstr(MI);
5303     moreElementsVectorSrc(MI, MoreTy, 1);
5304     moreElementsVectorSrc(MI, MoreTy, 2);
5305     moreElementsVectorSrc(MI, MoreTy, 3);
5306     moreElementsVectorDst(MI, MoreTy, 0);
5307     Observer.changedInstr(MI);
5308     return Legalized;
5309   }
5310   case TargetOpcode::G_EXTRACT_VECTOR_ELT:
5311   case TargetOpcode::G_EXTRACT:
5312     if (TypeIdx != 1)
5313       return UnableToLegalize;
5314     Observer.changingInstr(MI);
5315     moreElementsVectorSrc(MI, MoreTy, 1);
5316     Observer.changedInstr(MI);
5317     return Legalized;
5318   case TargetOpcode::G_INSERT:
5319   case TargetOpcode::G_INSERT_VECTOR_ELT:
5320   case TargetOpcode::G_FREEZE:
5321   case TargetOpcode::G_FNEG:
5322   case TargetOpcode::G_FABS:
5323   case TargetOpcode::G_FSQRT:
5324   case TargetOpcode::G_FCEIL:
5325   case TargetOpcode::G_FFLOOR:
5326   case TargetOpcode::G_FNEARBYINT:
5327   case TargetOpcode::G_FRINT:
5328   case TargetOpcode::G_INTRINSIC_ROUND:
5329   case TargetOpcode::G_INTRINSIC_ROUNDEVEN:
5330   case TargetOpcode::G_INTRINSIC_TRUNC:
5331   case TargetOpcode::G_BSWAP:
5332   case TargetOpcode::G_FCANONICALIZE:
5333   case TargetOpcode::G_SEXT_INREG:
5334     if (TypeIdx != 0)
5335       return UnableToLegalize;
5336     Observer.changingInstr(MI);
5337     moreElementsVectorSrc(MI, MoreTy, 1);
5338     moreElementsVectorDst(MI, MoreTy, 0);
5339     Observer.changedInstr(MI);
5340     return Legalized;
5341   case TargetOpcode::G_SELECT: {
5342     auto [DstReg, DstTy, CondReg, CondTy] = MI.getFirst2RegLLTs();
5343     if (TypeIdx == 1) {
5344       if (!CondTy.isScalar() ||
5345           DstTy.getElementCount() != MoreTy.getElementCount())
5346         return UnableToLegalize;
5347 
5348       // This is turning a scalar select of vectors into a vector
5349       // select. Broadcast the select condition.
5350       auto ShufSplat = MIRBuilder.buildShuffleSplat(MoreTy, CondReg);
5351       Observer.changingInstr(MI);
5352       MI.getOperand(1).setReg(ShufSplat.getReg(0));
5353       Observer.changedInstr(MI);
5354       return Legalized;
5355     }
5356 
5357     if (CondTy.isVector())
5358       return UnableToLegalize;
5359 
5360     Observer.changingInstr(MI);
5361     moreElementsVectorSrc(MI, MoreTy, 2);
5362     moreElementsVectorSrc(MI, MoreTy, 3);
5363     moreElementsVectorDst(MI, MoreTy, 0);
5364     Observer.changedInstr(MI);
5365     return Legalized;
5366   }
5367   case TargetOpcode::G_UNMERGE_VALUES:
5368     return UnableToLegalize;
5369   case TargetOpcode::G_PHI:
5370     return moreElementsVectorPhi(MI, TypeIdx, MoreTy);
5371   case TargetOpcode::G_SHUFFLE_VECTOR:
5372     return moreElementsVectorShuffle(MI, TypeIdx, MoreTy);
5373   case TargetOpcode::G_BUILD_VECTOR: {
5374     SmallVector<SrcOp, 8> Elts;
5375     for (auto Op : MI.uses()) {
5376       Elts.push_back(Op.getReg());
5377     }
5378 
5379     for (unsigned i = Elts.size(); i < MoreTy.getNumElements(); ++i) {
5380       Elts.push_back(MIRBuilder.buildUndef(MoreTy.getScalarType()));
5381     }
5382 
5383     MIRBuilder.buildDeleteTrailingVectorElements(
5384         MI.getOperand(0).getReg(), MIRBuilder.buildInstr(Opc, {MoreTy}, Elts));
5385     MI.eraseFromParent();
5386     return Legalized;
5387   }
5388   case TargetOpcode::G_TRUNC:
5389   case TargetOpcode::G_FPTRUNC:
5390   case TargetOpcode::G_FPEXT:
5391   case TargetOpcode::G_FPTOSI:
5392   case TargetOpcode::G_FPTOUI:
5393   case TargetOpcode::G_SITOFP:
5394   case TargetOpcode::G_UITOFP: {
5395     if (TypeIdx != 0)
5396       return UnableToLegalize;
5397     Observer.changingInstr(MI);
5398     LLT SrcTy = LLT::fixed_vector(
5399         MoreTy.getNumElements(),
5400         MRI.getType(MI.getOperand(1).getReg()).getElementType());
5401     moreElementsVectorSrc(MI, SrcTy, 1);
5402     moreElementsVectorDst(MI, MoreTy, 0);
5403     Observer.changedInstr(MI);
5404     return Legalized;
5405   }
5406   default:
5407     return UnableToLegalize;
5408   }
5409 }
5410 
5411 LegalizerHelper::LegalizeResult
5412 LegalizerHelper::equalizeVectorShuffleLengths(MachineInstr &MI) {
5413   auto [DstReg, DstTy, SrcReg, SrcTy] = MI.getFirst2RegLLTs();
5414   ArrayRef<int> Mask = MI.getOperand(3).getShuffleMask();
5415   unsigned MaskNumElts = Mask.size();
5416   unsigned SrcNumElts = SrcTy.getNumElements();
5417   LLT DestEltTy = DstTy.getElementType();
5418 
5419   if (MaskNumElts == SrcNumElts)
5420     return Legalized;
5421 
5422   if (MaskNumElts < SrcNumElts) {
5423     // Extend mask to match new destination vector size with
5424     // undef values.
5425     SmallVector<int, 16> NewMask(Mask);
5426     for (unsigned I = MaskNumElts; I < SrcNumElts; ++I)
5427       NewMask.push_back(-1);
5428 
5429     moreElementsVectorDst(MI, SrcTy, 0);
5430     MIRBuilder.setInstrAndDebugLoc(MI);
5431     MIRBuilder.buildShuffleVector(MI.getOperand(0).getReg(),
5432                                   MI.getOperand(1).getReg(),
5433                                   MI.getOperand(2).getReg(), NewMask);
5434     MI.eraseFromParent();
5435 
5436     return Legalized;
5437   }
5438 
5439   unsigned PaddedMaskNumElts = alignTo(MaskNumElts, SrcNumElts);
5440   unsigned NumConcat = PaddedMaskNumElts / SrcNumElts;
5441   LLT PaddedTy = LLT::fixed_vector(PaddedMaskNumElts, DestEltTy);
5442 
5443   // Create new source vectors by concatenating the initial
5444   // source vectors with undefined vectors of the same size.
5445   auto Undef = MIRBuilder.buildUndef(SrcTy);
5446   SmallVector<Register, 8> MOps1(NumConcat, Undef.getReg(0));
5447   SmallVector<Register, 8> MOps2(NumConcat, Undef.getReg(0));
5448   MOps1[0] = MI.getOperand(1).getReg();
5449   MOps2[0] = MI.getOperand(2).getReg();
5450 
5451   auto Src1 = MIRBuilder.buildConcatVectors(PaddedTy, MOps1);
5452   auto Src2 = MIRBuilder.buildConcatVectors(PaddedTy, MOps2);
5453 
5454   // Readjust mask for new input vector length.
5455   SmallVector<int, 8> MappedOps(PaddedMaskNumElts, -1);
5456   for (unsigned I = 0; I != MaskNumElts; ++I) {
5457     int Idx = Mask[I];
5458     if (Idx >= static_cast<int>(SrcNumElts))
5459       Idx += PaddedMaskNumElts - SrcNumElts;
5460     MappedOps[I] = Idx;
5461   }
5462 
5463   // If we got more elements than required, extract subvector.
5464   if (MaskNumElts != PaddedMaskNumElts) {
5465     auto Shuffle =
5466         MIRBuilder.buildShuffleVector(PaddedTy, Src1, Src2, MappedOps);
5467 
5468     SmallVector<Register, 16> Elts(MaskNumElts);
5469     for (unsigned I = 0; I < MaskNumElts; ++I) {
5470       Elts[I] =
5471           MIRBuilder.buildExtractVectorElementConstant(DestEltTy, Shuffle, I)
5472               .getReg(0);
5473     }
5474     MIRBuilder.buildBuildVector(DstReg, Elts);
5475   } else {
5476     MIRBuilder.buildShuffleVector(DstReg, Src1, Src2, MappedOps);
5477   }
5478 
5479   MI.eraseFromParent();
5480   return LegalizerHelper::LegalizeResult::Legalized;
5481 }
5482 
5483 LegalizerHelper::LegalizeResult
5484 LegalizerHelper::moreElementsVectorShuffle(MachineInstr &MI,
5485                                            unsigned int TypeIdx, LLT MoreTy) {
5486   auto [DstTy, Src1Ty, Src2Ty] = MI.getFirst3LLTs();
5487   ArrayRef<int> Mask = MI.getOperand(3).getShuffleMask();
5488   unsigned NumElts = DstTy.getNumElements();
5489   unsigned WidenNumElts = MoreTy.getNumElements();
5490 
5491   if (DstTy.isVector() && Src1Ty.isVector() &&
5492       DstTy.getNumElements() != Src1Ty.getNumElements()) {
5493     return equalizeVectorShuffleLengths(MI);
5494   }
5495 
5496   if (TypeIdx != 0)
5497     return UnableToLegalize;
5498 
5499   // Expect a canonicalized shuffle.
5500   if (DstTy != Src1Ty || DstTy != Src2Ty)
5501     return UnableToLegalize;
5502 
5503   moreElementsVectorSrc(MI, MoreTy, 1);
5504   moreElementsVectorSrc(MI, MoreTy, 2);
5505 
5506   // Adjust mask based on new input vector length.
5507   SmallVector<int, 16> NewMask;
5508   for (unsigned I = 0; I != NumElts; ++I) {
5509     int Idx = Mask[I];
5510     if (Idx < static_cast<int>(NumElts))
5511       NewMask.push_back(Idx);
5512     else
5513       NewMask.push_back(Idx - NumElts + WidenNumElts);
5514   }
5515   for (unsigned I = NumElts; I != WidenNumElts; ++I)
5516     NewMask.push_back(-1);
5517   moreElementsVectorDst(MI, MoreTy, 0);
5518   MIRBuilder.setInstrAndDebugLoc(MI);
5519   MIRBuilder.buildShuffleVector(MI.getOperand(0).getReg(),
5520                                 MI.getOperand(1).getReg(),
5521                                 MI.getOperand(2).getReg(), NewMask);
5522   MI.eraseFromParent();
5523   return Legalized;
5524 }
5525 
5526 void LegalizerHelper::multiplyRegisters(SmallVectorImpl<Register> &DstRegs,
5527                                         ArrayRef<Register> Src1Regs,
5528                                         ArrayRef<Register> Src2Regs,
5529                                         LLT NarrowTy) {
5530   MachineIRBuilder &B = MIRBuilder;
5531   unsigned SrcParts = Src1Regs.size();
5532   unsigned DstParts = DstRegs.size();
5533 
5534   unsigned DstIdx = 0; // Low bits of the result.
5535   Register FactorSum =
5536       B.buildMul(NarrowTy, Src1Regs[DstIdx], Src2Regs[DstIdx]).getReg(0);
5537   DstRegs[DstIdx] = FactorSum;
5538 
5539   unsigned CarrySumPrevDstIdx;
5540   SmallVector<Register, 4> Factors;
5541 
5542   for (DstIdx = 1; DstIdx < DstParts; DstIdx++) {
5543     // Collect low parts of muls for DstIdx.
5544     for (unsigned i = DstIdx + 1 < SrcParts ? 0 : DstIdx - SrcParts + 1;
5545          i <= std::min(DstIdx, SrcParts - 1); ++i) {
5546       MachineInstrBuilder Mul =
5547           B.buildMul(NarrowTy, Src1Regs[DstIdx - i], Src2Regs[i]);
5548       Factors.push_back(Mul.getReg(0));
5549     }
5550     // Collect high parts of muls from previous DstIdx.
5551     for (unsigned i = DstIdx < SrcParts ? 0 : DstIdx - SrcParts;
5552          i <= std::min(DstIdx - 1, SrcParts - 1); ++i) {
5553       MachineInstrBuilder Umulh =
5554           B.buildUMulH(NarrowTy, Src1Regs[DstIdx - 1 - i], Src2Regs[i]);
5555       Factors.push_back(Umulh.getReg(0));
5556     }
5557     // Add CarrySum from additions calculated for previous DstIdx.
5558     if (DstIdx != 1) {
5559       Factors.push_back(CarrySumPrevDstIdx);
5560     }
5561 
5562     Register CarrySum;
5563     // Add all factors and accumulate all carries into CarrySum.
5564     if (DstIdx != DstParts - 1) {
5565       MachineInstrBuilder Uaddo =
5566           B.buildUAddo(NarrowTy, LLT::scalar(1), Factors[0], Factors[1]);
5567       FactorSum = Uaddo.getReg(0);
5568       CarrySum = B.buildZExt(NarrowTy, Uaddo.getReg(1)).getReg(0);
5569       for (unsigned i = 2; i < Factors.size(); ++i) {
5570         MachineInstrBuilder Uaddo =
5571             B.buildUAddo(NarrowTy, LLT::scalar(1), FactorSum, Factors[i]);
5572         FactorSum = Uaddo.getReg(0);
5573         MachineInstrBuilder Carry = B.buildZExt(NarrowTy, Uaddo.getReg(1));
5574         CarrySum = B.buildAdd(NarrowTy, CarrySum, Carry).getReg(0);
5575       }
5576     } else {
5577       // Since value for the next index is not calculated, neither is CarrySum.
5578       FactorSum = B.buildAdd(NarrowTy, Factors[0], Factors[1]).getReg(0);
5579       for (unsigned i = 2; i < Factors.size(); ++i)
5580         FactorSum = B.buildAdd(NarrowTy, FactorSum, Factors[i]).getReg(0);
5581     }
5582 
5583     CarrySumPrevDstIdx = CarrySum;
5584     DstRegs[DstIdx] = FactorSum;
5585     Factors.clear();
5586   }
5587 }
5588 
5589 LegalizerHelper::LegalizeResult
5590 LegalizerHelper::narrowScalarAddSub(MachineInstr &MI, unsigned TypeIdx,
5591                                     LLT NarrowTy) {
5592   if (TypeIdx != 0)
5593     return UnableToLegalize;
5594 
5595   Register DstReg = MI.getOperand(0).getReg();
5596   LLT DstType = MRI.getType(DstReg);
5597   // FIXME: add support for vector types
5598   if (DstType.isVector())
5599     return UnableToLegalize;
5600 
5601   unsigned Opcode = MI.getOpcode();
5602   unsigned OpO, OpE, OpF;
5603   switch (Opcode) {
5604   case TargetOpcode::G_SADDO:
5605   case TargetOpcode::G_SADDE:
5606   case TargetOpcode::G_UADDO:
5607   case TargetOpcode::G_UADDE:
5608   case TargetOpcode::G_ADD:
5609     OpO = TargetOpcode::G_UADDO;
5610     OpE = TargetOpcode::G_UADDE;
5611     OpF = TargetOpcode::G_UADDE;
5612     if (Opcode == TargetOpcode::G_SADDO || Opcode == TargetOpcode::G_SADDE)
5613       OpF = TargetOpcode::G_SADDE;
5614     break;
5615   case TargetOpcode::G_SSUBO:
5616   case TargetOpcode::G_SSUBE:
5617   case TargetOpcode::G_USUBO:
5618   case TargetOpcode::G_USUBE:
5619   case TargetOpcode::G_SUB:
5620     OpO = TargetOpcode::G_USUBO;
5621     OpE = TargetOpcode::G_USUBE;
5622     OpF = TargetOpcode::G_USUBE;
5623     if (Opcode == TargetOpcode::G_SSUBO || Opcode == TargetOpcode::G_SSUBE)
5624       OpF = TargetOpcode::G_SSUBE;
5625     break;
5626   default:
5627     llvm_unreachable("Unexpected add/sub opcode!");
5628   }
5629 
5630   // 1 for a plain add/sub, 2 if this is an operation with a carry-out.
5631   unsigned NumDefs = MI.getNumExplicitDefs();
5632   Register Src1 = MI.getOperand(NumDefs).getReg();
5633   Register Src2 = MI.getOperand(NumDefs + 1).getReg();
5634   Register CarryDst, CarryIn;
5635   if (NumDefs == 2)
5636     CarryDst = MI.getOperand(1).getReg();
5637   if (MI.getNumOperands() == NumDefs + 3)
5638     CarryIn = MI.getOperand(NumDefs + 2).getReg();
5639 
5640   LLT RegTy = MRI.getType(MI.getOperand(0).getReg());
5641   LLT LeftoverTy, DummyTy;
5642   SmallVector<Register, 2> Src1Regs, Src2Regs, Src1Left, Src2Left, DstRegs;
5643   extractParts(Src1, RegTy, NarrowTy, LeftoverTy, Src1Regs, Src1Left);
5644   extractParts(Src2, RegTy, NarrowTy, DummyTy, Src2Regs, Src2Left);
5645 
5646   int NarrowParts = Src1Regs.size();
5647   for (int I = 0, E = Src1Left.size(); I != E; ++I) {
5648     Src1Regs.push_back(Src1Left[I]);
5649     Src2Regs.push_back(Src2Left[I]);
5650   }
5651   DstRegs.reserve(Src1Regs.size());
5652 
5653   for (int i = 0, e = Src1Regs.size(); i != e; ++i) {
5654     Register DstReg =
5655         MRI.createGenericVirtualRegister(MRI.getType(Src1Regs[i]));
5656     Register CarryOut = MRI.createGenericVirtualRegister(LLT::scalar(1));
5657     // Forward the final carry-out to the destination register
5658     if (i == e - 1 && CarryDst)
5659       CarryOut = CarryDst;
5660 
5661     if (!CarryIn) {
5662       MIRBuilder.buildInstr(OpO, {DstReg, CarryOut},
5663                             {Src1Regs[i], Src2Regs[i]});
5664     } else if (i == e - 1) {
5665       MIRBuilder.buildInstr(OpF, {DstReg, CarryOut},
5666                             {Src1Regs[i], Src2Regs[i], CarryIn});
5667     } else {
5668       MIRBuilder.buildInstr(OpE, {DstReg, CarryOut},
5669                             {Src1Regs[i], Src2Regs[i], CarryIn});
5670     }
5671 
5672     DstRegs.push_back(DstReg);
5673     CarryIn = CarryOut;
5674   }
5675   insertParts(MI.getOperand(0).getReg(), RegTy, NarrowTy,
5676               ArrayRef(DstRegs).take_front(NarrowParts), LeftoverTy,
5677               ArrayRef(DstRegs).drop_front(NarrowParts));
5678 
5679   MI.eraseFromParent();
5680   return Legalized;
5681 }
5682 
5683 LegalizerHelper::LegalizeResult
5684 LegalizerHelper::narrowScalarMul(MachineInstr &MI, LLT NarrowTy) {
5685   auto [DstReg, Src1, Src2] = MI.getFirst3Regs();
5686 
5687   LLT Ty = MRI.getType(DstReg);
5688   if (Ty.isVector())
5689     return UnableToLegalize;
5690 
5691   unsigned Size = Ty.getSizeInBits();
5692   unsigned NarrowSize = NarrowTy.getSizeInBits();
5693   if (Size % NarrowSize != 0)
5694     return UnableToLegalize;
5695 
5696   unsigned NumParts = Size / NarrowSize;
5697   bool IsMulHigh = MI.getOpcode() == TargetOpcode::G_UMULH;
5698   unsigned DstTmpParts = NumParts * (IsMulHigh ? 2 : 1);
5699 
5700   SmallVector<Register, 2> Src1Parts, Src2Parts;
5701   SmallVector<Register, 2> DstTmpRegs(DstTmpParts);
5702   extractParts(Src1, NarrowTy, NumParts, Src1Parts);
5703   extractParts(Src2, NarrowTy, NumParts, Src2Parts);
5704   multiplyRegisters(DstTmpRegs, Src1Parts, Src2Parts, NarrowTy);
5705 
5706   // Take only high half of registers if this is high mul.
5707   ArrayRef<Register> DstRegs(&DstTmpRegs[DstTmpParts - NumParts], NumParts);
5708   MIRBuilder.buildMergeLikeInstr(DstReg, DstRegs);
5709   MI.eraseFromParent();
5710   return Legalized;
5711 }
5712 
5713 LegalizerHelper::LegalizeResult
5714 LegalizerHelper::narrowScalarFPTOI(MachineInstr &MI, unsigned TypeIdx,
5715                                    LLT NarrowTy) {
5716   if (TypeIdx != 0)
5717     return UnableToLegalize;
5718 
5719   bool IsSigned = MI.getOpcode() == TargetOpcode::G_FPTOSI;
5720 
5721   Register Src = MI.getOperand(1).getReg();
5722   LLT SrcTy = MRI.getType(Src);
5723 
5724   // If all finite floats fit into the narrowed integer type, we can just swap
5725   // out the result type. This is practically only useful for conversions from
5726   // half to at least 16-bits, so just handle the one case.
5727   if (SrcTy.getScalarType() != LLT::scalar(16) ||
5728       NarrowTy.getScalarSizeInBits() < (IsSigned ? 17u : 16u))
5729     return UnableToLegalize;
5730 
5731   Observer.changingInstr(MI);
5732   narrowScalarDst(MI, NarrowTy, 0,
5733                   IsSigned ? TargetOpcode::G_SEXT : TargetOpcode::G_ZEXT);
5734   Observer.changedInstr(MI);
5735   return Legalized;
5736 }
5737 
5738 LegalizerHelper::LegalizeResult
5739 LegalizerHelper::narrowScalarExtract(MachineInstr &MI, unsigned TypeIdx,
5740                                      LLT NarrowTy) {
5741   if (TypeIdx != 1)
5742     return UnableToLegalize;
5743 
5744   uint64_t NarrowSize = NarrowTy.getSizeInBits();
5745 
5746   int64_t SizeOp1 = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits();
5747   // FIXME: add support for when SizeOp1 isn't an exact multiple of
5748   // NarrowSize.
5749   if (SizeOp1 % NarrowSize != 0)
5750     return UnableToLegalize;
5751   int NumParts = SizeOp1 / NarrowSize;
5752 
5753   SmallVector<Register, 2> SrcRegs, DstRegs;
5754   SmallVector<uint64_t, 2> Indexes;
5755   extractParts(MI.getOperand(1).getReg(), NarrowTy, NumParts, SrcRegs);
5756 
5757   Register OpReg = MI.getOperand(0).getReg();
5758   uint64_t OpStart = MI.getOperand(2).getImm();
5759   uint64_t OpSize = MRI.getType(OpReg).getSizeInBits();
5760   for (int i = 0; i < NumParts; ++i) {
5761     unsigned SrcStart = i * NarrowSize;
5762 
5763     if (SrcStart + NarrowSize <= OpStart || SrcStart >= OpStart + OpSize) {
5764       // No part of the extract uses this subregister, ignore it.
5765       continue;
5766     } else if (SrcStart == OpStart && NarrowTy == MRI.getType(OpReg)) {
5767       // The entire subregister is extracted, forward the value.
5768       DstRegs.push_back(SrcRegs[i]);
5769       continue;
5770     }
5771 
5772     // OpSegStart is where this destination segment would start in OpReg if it
5773     // extended infinitely in both directions.
5774     int64_t ExtractOffset;
5775     uint64_t SegSize;
5776     if (OpStart < SrcStart) {
5777       ExtractOffset = 0;
5778       SegSize = std::min(NarrowSize, OpStart + OpSize - SrcStart);
5779     } else {
5780       ExtractOffset = OpStart - SrcStart;
5781       SegSize = std::min(SrcStart + NarrowSize - OpStart, OpSize);
5782     }
5783 
5784     Register SegReg = SrcRegs[i];
5785     if (ExtractOffset != 0 || SegSize != NarrowSize) {
5786       // A genuine extract is needed.
5787       SegReg = MRI.createGenericVirtualRegister(LLT::scalar(SegSize));
5788       MIRBuilder.buildExtract(SegReg, SrcRegs[i], ExtractOffset);
5789     }
5790 
5791     DstRegs.push_back(SegReg);
5792   }
5793 
5794   Register DstReg = MI.getOperand(0).getReg();
5795   if (MRI.getType(DstReg).isVector())
5796     MIRBuilder.buildBuildVector(DstReg, DstRegs);
5797   else if (DstRegs.size() > 1)
5798     MIRBuilder.buildMergeLikeInstr(DstReg, DstRegs);
5799   else
5800     MIRBuilder.buildCopy(DstReg, DstRegs[0]);
5801   MI.eraseFromParent();
5802   return Legalized;
5803 }
5804 
5805 LegalizerHelper::LegalizeResult
5806 LegalizerHelper::narrowScalarInsert(MachineInstr &MI, unsigned TypeIdx,
5807                                     LLT NarrowTy) {
5808   // FIXME: Don't know how to handle secondary types yet.
5809   if (TypeIdx != 0)
5810     return UnableToLegalize;
5811 
5812   SmallVector<Register, 2> SrcRegs, LeftoverRegs, DstRegs;
5813   SmallVector<uint64_t, 2> Indexes;
5814   LLT RegTy = MRI.getType(MI.getOperand(0).getReg());
5815   LLT LeftoverTy;
5816   extractParts(MI.getOperand(1).getReg(), RegTy, NarrowTy, LeftoverTy, SrcRegs,
5817                LeftoverRegs);
5818 
5819   for (Register Reg : LeftoverRegs)
5820     SrcRegs.push_back(Reg);
5821 
5822   uint64_t NarrowSize = NarrowTy.getSizeInBits();
5823   Register OpReg = MI.getOperand(2).getReg();
5824   uint64_t OpStart = MI.getOperand(3).getImm();
5825   uint64_t OpSize = MRI.getType(OpReg).getSizeInBits();
5826   for (int I = 0, E = SrcRegs.size(); I != E; ++I) {
5827     unsigned DstStart = I * NarrowSize;
5828 
5829     if (DstStart == OpStart && NarrowTy == MRI.getType(OpReg)) {
5830       // The entire subregister is defined by this insert, forward the new
5831       // value.
5832       DstRegs.push_back(OpReg);
5833       continue;
5834     }
5835 
5836     Register SrcReg = SrcRegs[I];
5837     if (MRI.getType(SrcRegs[I]) == LeftoverTy) {
5838       // The leftover reg is smaller than NarrowTy, so we need to extend it.
5839       SrcReg = MRI.createGenericVirtualRegister(NarrowTy);
5840       MIRBuilder.buildAnyExt(SrcReg, SrcRegs[I]);
5841     }
5842 
5843     if (DstStart + NarrowSize <= OpStart || DstStart >= OpStart + OpSize) {
5844       // No part of the insert affects this subregister, forward the original.
5845       DstRegs.push_back(SrcReg);
5846       continue;
5847     }
5848 
5849     // OpSegStart is where this destination segment would start in OpReg if it
5850     // extended infinitely in both directions.
5851     int64_t ExtractOffset, InsertOffset;
5852     uint64_t SegSize;
5853     if (OpStart < DstStart) {
5854       InsertOffset = 0;
5855       ExtractOffset = DstStart - OpStart;
5856       SegSize = std::min(NarrowSize, OpStart + OpSize - DstStart);
5857     } else {
5858       InsertOffset = OpStart - DstStart;
5859       ExtractOffset = 0;
5860       SegSize =
5861         std::min(NarrowSize - InsertOffset, OpStart + OpSize - DstStart);
5862     }
5863 
5864     Register SegReg = OpReg;
5865     if (ExtractOffset != 0 || SegSize != OpSize) {
5866       // A genuine extract is needed.
5867       SegReg = MRI.createGenericVirtualRegister(LLT::scalar(SegSize));
5868       MIRBuilder.buildExtract(SegReg, OpReg, ExtractOffset);
5869     }
5870 
5871     Register DstReg = MRI.createGenericVirtualRegister(NarrowTy);
5872     MIRBuilder.buildInsert(DstReg, SrcReg, SegReg, InsertOffset);
5873     DstRegs.push_back(DstReg);
5874   }
5875 
5876   uint64_t WideSize = DstRegs.size() * NarrowSize;
5877   Register DstReg = MI.getOperand(0).getReg();
5878   if (WideSize > RegTy.getSizeInBits()) {
5879     Register MergeReg = MRI.createGenericVirtualRegister(LLT::scalar(WideSize));
5880     MIRBuilder.buildMergeLikeInstr(MergeReg, DstRegs);
5881     MIRBuilder.buildTrunc(DstReg, MergeReg);
5882   } else
5883     MIRBuilder.buildMergeLikeInstr(DstReg, DstRegs);
5884 
5885   MI.eraseFromParent();
5886   return Legalized;
5887 }
5888 
5889 LegalizerHelper::LegalizeResult
5890 LegalizerHelper::narrowScalarBasic(MachineInstr &MI, unsigned TypeIdx,
5891                                    LLT NarrowTy) {
5892   Register DstReg = MI.getOperand(0).getReg();
5893   LLT DstTy = MRI.getType(DstReg);
5894 
5895   assert(MI.getNumOperands() == 3 && TypeIdx == 0);
5896 
5897   SmallVector<Register, 4> DstRegs, DstLeftoverRegs;
5898   SmallVector<Register, 4> Src0Regs, Src0LeftoverRegs;
5899   SmallVector<Register, 4> Src1Regs, Src1LeftoverRegs;
5900   LLT LeftoverTy;
5901   if (!extractParts(MI.getOperand(1).getReg(), DstTy, NarrowTy, LeftoverTy,
5902                     Src0Regs, Src0LeftoverRegs))
5903     return UnableToLegalize;
5904 
5905   LLT Unused;
5906   if (!extractParts(MI.getOperand(2).getReg(), DstTy, NarrowTy, Unused,
5907                     Src1Regs, Src1LeftoverRegs))
5908     llvm_unreachable("inconsistent extractParts result");
5909 
5910   for (unsigned I = 0, E = Src1Regs.size(); I != E; ++I) {
5911     auto Inst = MIRBuilder.buildInstr(MI.getOpcode(), {NarrowTy},
5912                                         {Src0Regs[I], Src1Regs[I]});
5913     DstRegs.push_back(Inst.getReg(0));
5914   }
5915 
5916   for (unsigned I = 0, E = Src1LeftoverRegs.size(); I != E; ++I) {
5917     auto Inst = MIRBuilder.buildInstr(
5918       MI.getOpcode(),
5919       {LeftoverTy}, {Src0LeftoverRegs[I], Src1LeftoverRegs[I]});
5920     DstLeftoverRegs.push_back(Inst.getReg(0));
5921   }
5922 
5923   insertParts(DstReg, DstTy, NarrowTy, DstRegs,
5924               LeftoverTy, DstLeftoverRegs);
5925 
5926   MI.eraseFromParent();
5927   return Legalized;
5928 }
5929 
5930 LegalizerHelper::LegalizeResult
5931 LegalizerHelper::narrowScalarExt(MachineInstr &MI, unsigned TypeIdx,
5932                                  LLT NarrowTy) {
5933   if (TypeIdx != 0)
5934     return UnableToLegalize;
5935 
5936   auto [DstReg, SrcReg] = MI.getFirst2Regs();
5937 
5938   LLT DstTy = MRI.getType(DstReg);
5939   if (DstTy.isVector())
5940     return UnableToLegalize;
5941 
5942   SmallVector<Register, 8> Parts;
5943   LLT GCDTy = extractGCDType(Parts, DstTy, NarrowTy, SrcReg);
5944   LLT LCMTy = buildLCMMergePieces(DstTy, NarrowTy, GCDTy, Parts, MI.getOpcode());
5945   buildWidenedRemergeToDst(DstReg, LCMTy, Parts);
5946 
5947   MI.eraseFromParent();
5948   return Legalized;
5949 }
5950 
5951 LegalizerHelper::LegalizeResult
5952 LegalizerHelper::narrowScalarSelect(MachineInstr &MI, unsigned TypeIdx,
5953                                     LLT NarrowTy) {
5954   if (TypeIdx != 0)
5955     return UnableToLegalize;
5956 
5957   Register CondReg = MI.getOperand(1).getReg();
5958   LLT CondTy = MRI.getType(CondReg);
5959   if (CondTy.isVector()) // TODO: Handle vselect
5960     return UnableToLegalize;
5961 
5962   Register DstReg = MI.getOperand(0).getReg();
5963   LLT DstTy = MRI.getType(DstReg);
5964 
5965   SmallVector<Register, 4> DstRegs, DstLeftoverRegs;
5966   SmallVector<Register, 4> Src1Regs, Src1LeftoverRegs;
5967   SmallVector<Register, 4> Src2Regs, Src2LeftoverRegs;
5968   LLT LeftoverTy;
5969   if (!extractParts(MI.getOperand(2).getReg(), DstTy, NarrowTy, LeftoverTy,
5970                     Src1Regs, Src1LeftoverRegs))
5971     return UnableToLegalize;
5972 
5973   LLT Unused;
5974   if (!extractParts(MI.getOperand(3).getReg(), DstTy, NarrowTy, Unused,
5975                     Src2Regs, Src2LeftoverRegs))
5976     llvm_unreachable("inconsistent extractParts result");
5977 
5978   for (unsigned I = 0, E = Src1Regs.size(); I != E; ++I) {
5979     auto Select = MIRBuilder.buildSelect(NarrowTy,
5980                                          CondReg, Src1Regs[I], Src2Regs[I]);
5981     DstRegs.push_back(Select.getReg(0));
5982   }
5983 
5984   for (unsigned I = 0, E = Src1LeftoverRegs.size(); I != E; ++I) {
5985     auto Select = MIRBuilder.buildSelect(
5986       LeftoverTy, CondReg, Src1LeftoverRegs[I], Src2LeftoverRegs[I]);
5987     DstLeftoverRegs.push_back(Select.getReg(0));
5988   }
5989 
5990   insertParts(DstReg, DstTy, NarrowTy, DstRegs,
5991               LeftoverTy, DstLeftoverRegs);
5992 
5993   MI.eraseFromParent();
5994   return Legalized;
5995 }
5996 
5997 LegalizerHelper::LegalizeResult
5998 LegalizerHelper::narrowScalarCTLZ(MachineInstr &MI, unsigned TypeIdx,
5999                                   LLT NarrowTy) {
6000   if (TypeIdx != 1)
6001     return UnableToLegalize;
6002 
6003   auto [DstReg, DstTy, SrcReg, SrcTy] = MI.getFirst2RegLLTs();
6004   unsigned NarrowSize = NarrowTy.getSizeInBits();
6005 
6006   if (SrcTy.isScalar() && SrcTy.getSizeInBits() == 2 * NarrowSize) {
6007     const bool IsUndef = MI.getOpcode() == TargetOpcode::G_CTLZ_ZERO_UNDEF;
6008 
6009     MachineIRBuilder &B = MIRBuilder;
6010     auto UnmergeSrc = B.buildUnmerge(NarrowTy, SrcReg);
6011     // ctlz(Hi:Lo) -> Hi == 0 ? (NarrowSize + ctlz(Lo)) : ctlz(Hi)
6012     auto C_0 = B.buildConstant(NarrowTy, 0);
6013     auto HiIsZero = B.buildICmp(CmpInst::ICMP_EQ, LLT::scalar(1),
6014                                 UnmergeSrc.getReg(1), C_0);
6015     auto LoCTLZ = IsUndef ?
6016       B.buildCTLZ_ZERO_UNDEF(DstTy, UnmergeSrc.getReg(0)) :
6017       B.buildCTLZ(DstTy, UnmergeSrc.getReg(0));
6018     auto C_NarrowSize = B.buildConstant(DstTy, NarrowSize);
6019     auto HiIsZeroCTLZ = B.buildAdd(DstTy, LoCTLZ, C_NarrowSize);
6020     auto HiCTLZ = B.buildCTLZ_ZERO_UNDEF(DstTy, UnmergeSrc.getReg(1));
6021     B.buildSelect(DstReg, HiIsZero, HiIsZeroCTLZ, HiCTLZ);
6022 
6023     MI.eraseFromParent();
6024     return Legalized;
6025   }
6026 
6027   return UnableToLegalize;
6028 }
6029 
6030 LegalizerHelper::LegalizeResult
6031 LegalizerHelper::narrowScalarCTTZ(MachineInstr &MI, unsigned TypeIdx,
6032                                   LLT NarrowTy) {
6033   if (TypeIdx != 1)
6034     return UnableToLegalize;
6035 
6036   auto [DstReg, DstTy, SrcReg, SrcTy] = MI.getFirst2RegLLTs();
6037   unsigned NarrowSize = NarrowTy.getSizeInBits();
6038 
6039   if (SrcTy.isScalar() && SrcTy.getSizeInBits() == 2 * NarrowSize) {
6040     const bool IsUndef = MI.getOpcode() == TargetOpcode::G_CTTZ_ZERO_UNDEF;
6041 
6042     MachineIRBuilder &B = MIRBuilder;
6043     auto UnmergeSrc = B.buildUnmerge(NarrowTy, SrcReg);
6044     // cttz(Hi:Lo) -> Lo == 0 ? (cttz(Hi) + NarrowSize) : cttz(Lo)
6045     auto C_0 = B.buildConstant(NarrowTy, 0);
6046     auto LoIsZero = B.buildICmp(CmpInst::ICMP_EQ, LLT::scalar(1),
6047                                 UnmergeSrc.getReg(0), C_0);
6048     auto HiCTTZ = IsUndef ?
6049       B.buildCTTZ_ZERO_UNDEF(DstTy, UnmergeSrc.getReg(1)) :
6050       B.buildCTTZ(DstTy, UnmergeSrc.getReg(1));
6051     auto C_NarrowSize = B.buildConstant(DstTy, NarrowSize);
6052     auto LoIsZeroCTTZ = B.buildAdd(DstTy, HiCTTZ, C_NarrowSize);
6053     auto LoCTTZ = B.buildCTTZ_ZERO_UNDEF(DstTy, UnmergeSrc.getReg(0));
6054     B.buildSelect(DstReg, LoIsZero, LoIsZeroCTTZ, LoCTTZ);
6055 
6056     MI.eraseFromParent();
6057     return Legalized;
6058   }
6059 
6060   return UnableToLegalize;
6061 }
6062 
6063 LegalizerHelper::LegalizeResult
6064 LegalizerHelper::narrowScalarCTPOP(MachineInstr &MI, unsigned TypeIdx,
6065                                    LLT NarrowTy) {
6066   if (TypeIdx != 1)
6067     return UnableToLegalize;
6068 
6069   auto [DstReg, DstTy, SrcReg, SrcTy] = MI.getFirst2RegLLTs();
6070   unsigned NarrowSize = NarrowTy.getSizeInBits();
6071 
6072   if (SrcTy.isScalar() && SrcTy.getSizeInBits() == 2 * NarrowSize) {
6073     auto UnmergeSrc = MIRBuilder.buildUnmerge(NarrowTy, MI.getOperand(1));
6074 
6075     auto LoCTPOP = MIRBuilder.buildCTPOP(DstTy, UnmergeSrc.getReg(0));
6076     auto HiCTPOP = MIRBuilder.buildCTPOP(DstTy, UnmergeSrc.getReg(1));
6077     MIRBuilder.buildAdd(DstReg, HiCTPOP, LoCTPOP);
6078 
6079     MI.eraseFromParent();
6080     return Legalized;
6081   }
6082 
6083   return UnableToLegalize;
6084 }
6085 
6086 LegalizerHelper::LegalizeResult
6087 LegalizerHelper::narrowScalarFLDEXP(MachineInstr &MI, unsigned TypeIdx,
6088                                     LLT NarrowTy) {
6089   if (TypeIdx != 1)
6090     return UnableToLegalize;
6091 
6092   MachineIRBuilder &B = MIRBuilder;
6093   Register ExpReg = MI.getOperand(2).getReg();
6094   LLT ExpTy = MRI.getType(ExpReg);
6095 
6096   unsigned ClampSize = NarrowTy.getScalarSizeInBits();
6097 
6098   // Clamp the exponent to the range of the target type.
6099   auto MinExp = B.buildConstant(ExpTy, minIntN(ClampSize));
6100   auto ClampMin = B.buildSMax(ExpTy, ExpReg, MinExp);
6101   auto MaxExp = B.buildConstant(ExpTy, maxIntN(ClampSize));
6102   auto Clamp = B.buildSMin(ExpTy, ClampMin, MaxExp);
6103 
6104   auto Trunc = B.buildTrunc(NarrowTy, Clamp);
6105   Observer.changingInstr(MI);
6106   MI.getOperand(2).setReg(Trunc.getReg(0));
6107   Observer.changedInstr(MI);
6108   return Legalized;
6109 }
6110 
6111 LegalizerHelper::LegalizeResult
6112 LegalizerHelper::lowerBitCount(MachineInstr &MI) {
6113   unsigned Opc = MI.getOpcode();
6114   const auto &TII = MIRBuilder.getTII();
6115   auto isSupported = [this](const LegalityQuery &Q) {
6116     auto QAction = LI.getAction(Q).Action;
6117     return QAction == Legal || QAction == Libcall || QAction == Custom;
6118   };
6119   switch (Opc) {
6120   default:
6121     return UnableToLegalize;
6122   case TargetOpcode::G_CTLZ_ZERO_UNDEF: {
6123     // This trivially expands to CTLZ.
6124     Observer.changingInstr(MI);
6125     MI.setDesc(TII.get(TargetOpcode::G_CTLZ));
6126     Observer.changedInstr(MI);
6127     return Legalized;
6128   }
6129   case TargetOpcode::G_CTLZ: {
6130     auto [DstReg, DstTy, SrcReg, SrcTy] = MI.getFirst2RegLLTs();
6131     unsigned Len = SrcTy.getSizeInBits();
6132 
6133     if (isSupported({TargetOpcode::G_CTLZ_ZERO_UNDEF, {DstTy, SrcTy}})) {
6134       // If CTLZ_ZERO_UNDEF is supported, emit that and a select for zero.
6135       auto CtlzZU = MIRBuilder.buildCTLZ_ZERO_UNDEF(DstTy, SrcReg);
6136       auto ZeroSrc = MIRBuilder.buildConstant(SrcTy, 0);
6137       auto ICmp = MIRBuilder.buildICmp(
6138           CmpInst::ICMP_EQ, SrcTy.changeElementSize(1), SrcReg, ZeroSrc);
6139       auto LenConst = MIRBuilder.buildConstant(DstTy, Len);
6140       MIRBuilder.buildSelect(DstReg, ICmp, LenConst, CtlzZU);
6141       MI.eraseFromParent();
6142       return Legalized;
6143     }
6144     // for now, we do this:
6145     // NewLen = NextPowerOf2(Len);
6146     // x = x | (x >> 1);
6147     // x = x | (x >> 2);
6148     // ...
6149     // x = x | (x >>16);
6150     // x = x | (x >>32); // for 64-bit input
6151     // Upto NewLen/2
6152     // return Len - popcount(x);
6153     //
6154     // Ref: "Hacker's Delight" by Henry Warren
6155     Register Op = SrcReg;
6156     unsigned NewLen = PowerOf2Ceil(Len);
6157     for (unsigned i = 0; (1U << i) <= (NewLen / 2); ++i) {
6158       auto MIBShiftAmt = MIRBuilder.buildConstant(SrcTy, 1ULL << i);
6159       auto MIBOp = MIRBuilder.buildOr(
6160           SrcTy, Op, MIRBuilder.buildLShr(SrcTy, Op, MIBShiftAmt));
6161       Op = MIBOp.getReg(0);
6162     }
6163     auto MIBPop = MIRBuilder.buildCTPOP(DstTy, Op);
6164     MIRBuilder.buildSub(MI.getOperand(0), MIRBuilder.buildConstant(DstTy, Len),
6165                         MIBPop);
6166     MI.eraseFromParent();
6167     return Legalized;
6168   }
6169   case TargetOpcode::G_CTTZ_ZERO_UNDEF: {
6170     // This trivially expands to CTTZ.
6171     Observer.changingInstr(MI);
6172     MI.setDesc(TII.get(TargetOpcode::G_CTTZ));
6173     Observer.changedInstr(MI);
6174     return Legalized;
6175   }
6176   case TargetOpcode::G_CTTZ: {
6177     auto [DstReg, DstTy, SrcReg, SrcTy] = MI.getFirst2RegLLTs();
6178 
6179     unsigned Len = SrcTy.getSizeInBits();
6180     if (isSupported({TargetOpcode::G_CTTZ_ZERO_UNDEF, {DstTy, SrcTy}})) {
6181       // If CTTZ_ZERO_UNDEF is legal or custom, emit that and a select with
6182       // zero.
6183       auto CttzZU = MIRBuilder.buildCTTZ_ZERO_UNDEF(DstTy, SrcReg);
6184       auto Zero = MIRBuilder.buildConstant(SrcTy, 0);
6185       auto ICmp = MIRBuilder.buildICmp(
6186           CmpInst::ICMP_EQ, DstTy.changeElementSize(1), SrcReg, Zero);
6187       auto LenConst = MIRBuilder.buildConstant(DstTy, Len);
6188       MIRBuilder.buildSelect(DstReg, ICmp, LenConst, CttzZU);
6189       MI.eraseFromParent();
6190       return Legalized;
6191     }
6192     // for now, we use: { return popcount(~x & (x - 1)); }
6193     // unless the target has ctlz but not ctpop, in which case we use:
6194     // { return 32 - nlz(~x & (x-1)); }
6195     // Ref: "Hacker's Delight" by Henry Warren
6196     auto MIBCstNeg1 = MIRBuilder.buildConstant(SrcTy, -1);
6197     auto MIBNot = MIRBuilder.buildXor(SrcTy, SrcReg, MIBCstNeg1);
6198     auto MIBTmp = MIRBuilder.buildAnd(
6199         SrcTy, MIBNot, MIRBuilder.buildAdd(SrcTy, SrcReg, MIBCstNeg1));
6200     if (!isSupported({TargetOpcode::G_CTPOP, {SrcTy, SrcTy}}) &&
6201         isSupported({TargetOpcode::G_CTLZ, {SrcTy, SrcTy}})) {
6202       auto MIBCstLen = MIRBuilder.buildConstant(SrcTy, Len);
6203       MIRBuilder.buildSub(MI.getOperand(0), MIBCstLen,
6204                           MIRBuilder.buildCTLZ(SrcTy, MIBTmp));
6205       MI.eraseFromParent();
6206       return Legalized;
6207     }
6208     Observer.changingInstr(MI);
6209     MI.setDesc(TII.get(TargetOpcode::G_CTPOP));
6210     MI.getOperand(1).setReg(MIBTmp.getReg(0));
6211     Observer.changedInstr(MI);
6212     return Legalized;
6213   }
6214   case TargetOpcode::G_CTPOP: {
6215     Register SrcReg = MI.getOperand(1).getReg();
6216     LLT Ty = MRI.getType(SrcReg);
6217     unsigned Size = Ty.getSizeInBits();
6218     MachineIRBuilder &B = MIRBuilder;
6219 
6220     // Count set bits in blocks of 2 bits. Default approach would be
6221     // B2Count = { val & 0x55555555 } + { (val >> 1) & 0x55555555 }
6222     // We use following formula instead:
6223     // B2Count = val - { (val >> 1) & 0x55555555 }
6224     // since it gives same result in blocks of 2 with one instruction less.
6225     auto C_1 = B.buildConstant(Ty, 1);
6226     auto B2Set1LoTo1Hi = B.buildLShr(Ty, SrcReg, C_1);
6227     APInt B2Mask1HiTo0 = APInt::getSplat(Size, APInt(8, 0x55));
6228     auto C_B2Mask1HiTo0 = B.buildConstant(Ty, B2Mask1HiTo0);
6229     auto B2Count1Hi = B.buildAnd(Ty, B2Set1LoTo1Hi, C_B2Mask1HiTo0);
6230     auto B2Count = B.buildSub(Ty, SrcReg, B2Count1Hi);
6231 
6232     // In order to get count in blocks of 4 add values from adjacent block of 2.
6233     // B4Count = { B2Count & 0x33333333 } + { (B2Count >> 2) & 0x33333333 }
6234     auto C_2 = B.buildConstant(Ty, 2);
6235     auto B4Set2LoTo2Hi = B.buildLShr(Ty, B2Count, C_2);
6236     APInt B4Mask2HiTo0 = APInt::getSplat(Size, APInt(8, 0x33));
6237     auto C_B4Mask2HiTo0 = B.buildConstant(Ty, B4Mask2HiTo0);
6238     auto B4HiB2Count = B.buildAnd(Ty, B4Set2LoTo2Hi, C_B4Mask2HiTo0);
6239     auto B4LoB2Count = B.buildAnd(Ty, B2Count, C_B4Mask2HiTo0);
6240     auto B4Count = B.buildAdd(Ty, B4HiB2Count, B4LoB2Count);
6241 
6242     // For count in blocks of 8 bits we don't have to mask high 4 bits before
6243     // addition since count value sits in range {0,...,8} and 4 bits are enough
6244     // to hold such binary values. After addition high 4 bits still hold count
6245     // of set bits in high 4 bit block, set them to zero and get 8 bit result.
6246     // B8Count = { B4Count + (B4Count >> 4) } & 0x0F0F0F0F
6247     auto C_4 = B.buildConstant(Ty, 4);
6248     auto B8HiB4Count = B.buildLShr(Ty, B4Count, C_4);
6249     auto B8CountDirty4Hi = B.buildAdd(Ty, B8HiB4Count, B4Count);
6250     APInt B8Mask4HiTo0 = APInt::getSplat(Size, APInt(8, 0x0F));
6251     auto C_B8Mask4HiTo0 = B.buildConstant(Ty, B8Mask4HiTo0);
6252     auto B8Count = B.buildAnd(Ty, B8CountDirty4Hi, C_B8Mask4HiTo0);
6253 
6254     assert(Size<=128 && "Scalar size is too large for CTPOP lower algorithm");
6255     // 8 bits can hold CTPOP result of 128 bit int or smaller. Mul with this
6256     // bitmask will set 8 msb in ResTmp to sum of all B8Counts in 8 bit blocks.
6257     auto MulMask = B.buildConstant(Ty, APInt::getSplat(Size, APInt(8, 0x01)));
6258     auto ResTmp = B.buildMul(Ty, B8Count, MulMask);
6259 
6260     // Shift count result from 8 high bits to low bits.
6261     auto C_SizeM8 = B.buildConstant(Ty, Size - 8);
6262     B.buildLShr(MI.getOperand(0).getReg(), ResTmp, C_SizeM8);
6263 
6264     MI.eraseFromParent();
6265     return Legalized;
6266   }
6267   }
6268 }
6269 
6270 // Check that (every element of) Reg is undef or not an exact multiple of BW.
6271 static bool isNonZeroModBitWidthOrUndef(const MachineRegisterInfo &MRI,
6272                                         Register Reg, unsigned BW) {
6273   return matchUnaryPredicate(
6274       MRI, Reg,
6275       [=](const Constant *C) {
6276         // Null constant here means an undef.
6277         const ConstantInt *CI = dyn_cast_or_null<ConstantInt>(C);
6278         return !CI || CI->getValue().urem(BW) != 0;
6279       },
6280       /*AllowUndefs*/ true);
6281 }
6282 
6283 LegalizerHelper::LegalizeResult
6284 LegalizerHelper::lowerFunnelShiftWithInverse(MachineInstr &MI) {
6285   auto [Dst, X, Y, Z] = MI.getFirst4Regs();
6286   LLT Ty = MRI.getType(Dst);
6287   LLT ShTy = MRI.getType(Z);
6288 
6289   unsigned BW = Ty.getScalarSizeInBits();
6290 
6291   if (!isPowerOf2_32(BW))
6292     return UnableToLegalize;
6293 
6294   const bool IsFSHL = MI.getOpcode() == TargetOpcode::G_FSHL;
6295   unsigned RevOpcode = IsFSHL ? TargetOpcode::G_FSHR : TargetOpcode::G_FSHL;
6296 
6297   if (isNonZeroModBitWidthOrUndef(MRI, Z, BW)) {
6298     // fshl X, Y, Z -> fshr X, Y, -Z
6299     // fshr X, Y, Z -> fshl X, Y, -Z
6300     auto Zero = MIRBuilder.buildConstant(ShTy, 0);
6301     Z = MIRBuilder.buildSub(Ty, Zero, Z).getReg(0);
6302   } else {
6303     // fshl X, Y, Z -> fshr (srl X, 1), (fshr X, Y, 1), ~Z
6304     // fshr X, Y, Z -> fshl (fshl X, Y, 1), (shl Y, 1), ~Z
6305     auto One = MIRBuilder.buildConstant(ShTy, 1);
6306     if (IsFSHL) {
6307       Y = MIRBuilder.buildInstr(RevOpcode, {Ty}, {X, Y, One}).getReg(0);
6308       X = MIRBuilder.buildLShr(Ty, X, One).getReg(0);
6309     } else {
6310       X = MIRBuilder.buildInstr(RevOpcode, {Ty}, {X, Y, One}).getReg(0);
6311       Y = MIRBuilder.buildShl(Ty, Y, One).getReg(0);
6312     }
6313 
6314     Z = MIRBuilder.buildNot(ShTy, Z).getReg(0);
6315   }
6316 
6317   MIRBuilder.buildInstr(RevOpcode, {Dst}, {X, Y, Z});
6318   MI.eraseFromParent();
6319   return Legalized;
6320 }
6321 
6322 LegalizerHelper::LegalizeResult
6323 LegalizerHelper::lowerFunnelShiftAsShifts(MachineInstr &MI) {
6324   auto [Dst, X, Y, Z] = MI.getFirst4Regs();
6325   LLT Ty = MRI.getType(Dst);
6326   LLT ShTy = MRI.getType(Z);
6327 
6328   const unsigned BW = Ty.getScalarSizeInBits();
6329   const bool IsFSHL = MI.getOpcode() == TargetOpcode::G_FSHL;
6330 
6331   Register ShX, ShY;
6332   Register ShAmt, InvShAmt;
6333 
6334   // FIXME: Emit optimized urem by constant instead of letting it expand later.
6335   if (isNonZeroModBitWidthOrUndef(MRI, Z, BW)) {
6336     // fshl: X << C | Y >> (BW - C)
6337     // fshr: X << (BW - C) | Y >> C
6338     // where C = Z % BW is not zero
6339     auto BitWidthC = MIRBuilder.buildConstant(ShTy, BW);
6340     ShAmt = MIRBuilder.buildURem(ShTy, Z, BitWidthC).getReg(0);
6341     InvShAmt = MIRBuilder.buildSub(ShTy, BitWidthC, ShAmt).getReg(0);
6342     ShX = MIRBuilder.buildShl(Ty, X, IsFSHL ? ShAmt : InvShAmt).getReg(0);
6343     ShY = MIRBuilder.buildLShr(Ty, Y, IsFSHL ? InvShAmt : ShAmt).getReg(0);
6344   } else {
6345     // fshl: X << (Z % BW) | Y >> 1 >> (BW - 1 - (Z % BW))
6346     // fshr: X << 1 << (BW - 1 - (Z % BW)) | Y >> (Z % BW)
6347     auto Mask = MIRBuilder.buildConstant(ShTy, BW - 1);
6348     if (isPowerOf2_32(BW)) {
6349       // Z % BW -> Z & (BW - 1)
6350       ShAmt = MIRBuilder.buildAnd(ShTy, Z, Mask).getReg(0);
6351       // (BW - 1) - (Z % BW) -> ~Z & (BW - 1)
6352       auto NotZ = MIRBuilder.buildNot(ShTy, Z);
6353       InvShAmt = MIRBuilder.buildAnd(ShTy, NotZ, Mask).getReg(0);
6354     } else {
6355       auto BitWidthC = MIRBuilder.buildConstant(ShTy, BW);
6356       ShAmt = MIRBuilder.buildURem(ShTy, Z, BitWidthC).getReg(0);
6357       InvShAmt = MIRBuilder.buildSub(ShTy, Mask, ShAmt).getReg(0);
6358     }
6359 
6360     auto One = MIRBuilder.buildConstant(ShTy, 1);
6361     if (IsFSHL) {
6362       ShX = MIRBuilder.buildShl(Ty, X, ShAmt).getReg(0);
6363       auto ShY1 = MIRBuilder.buildLShr(Ty, Y, One);
6364       ShY = MIRBuilder.buildLShr(Ty, ShY1, InvShAmt).getReg(0);
6365     } else {
6366       auto ShX1 = MIRBuilder.buildShl(Ty, X, One);
6367       ShX = MIRBuilder.buildShl(Ty, ShX1, InvShAmt).getReg(0);
6368       ShY = MIRBuilder.buildLShr(Ty, Y, ShAmt).getReg(0);
6369     }
6370   }
6371 
6372   MIRBuilder.buildOr(Dst, ShX, ShY);
6373   MI.eraseFromParent();
6374   return Legalized;
6375 }
6376 
6377 LegalizerHelper::LegalizeResult
6378 LegalizerHelper::lowerFunnelShift(MachineInstr &MI) {
6379   // These operations approximately do the following (while avoiding undefined
6380   // shifts by BW):
6381   // G_FSHL: (X << (Z % BW)) | (Y >> (BW - (Z % BW)))
6382   // G_FSHR: (X << (BW - (Z % BW))) | (Y >> (Z % BW))
6383   Register Dst = MI.getOperand(0).getReg();
6384   LLT Ty = MRI.getType(Dst);
6385   LLT ShTy = MRI.getType(MI.getOperand(3).getReg());
6386 
6387   bool IsFSHL = MI.getOpcode() == TargetOpcode::G_FSHL;
6388   unsigned RevOpcode = IsFSHL ? TargetOpcode::G_FSHR : TargetOpcode::G_FSHL;
6389 
6390   // TODO: Use smarter heuristic that accounts for vector legalization.
6391   if (LI.getAction({RevOpcode, {Ty, ShTy}}).Action == Lower)
6392     return lowerFunnelShiftAsShifts(MI);
6393 
6394   // This only works for powers of 2, fallback to shifts if it fails.
6395   LegalizerHelper::LegalizeResult Result = lowerFunnelShiftWithInverse(MI);
6396   if (Result == UnableToLegalize)
6397     return lowerFunnelShiftAsShifts(MI);
6398   return Result;
6399 }
6400 
6401 LegalizerHelper::LegalizeResult LegalizerHelper::lowerEXT(MachineInstr &MI) {
6402   auto [Dst, Src] = MI.getFirst2Regs();
6403   LLT DstTy = MRI.getType(Dst);
6404   LLT SrcTy = MRI.getType(Src);
6405 
6406   uint32_t DstTySize = DstTy.getSizeInBits();
6407   uint32_t DstTyScalarSize = DstTy.getScalarSizeInBits();
6408   uint32_t SrcTyScalarSize = SrcTy.getScalarSizeInBits();
6409 
6410   if (!isPowerOf2_32(DstTySize) || !isPowerOf2_32(DstTyScalarSize) ||
6411       !isPowerOf2_32(SrcTyScalarSize))
6412     return UnableToLegalize;
6413 
6414   // The step between extend is too large, split it by creating an intermediate
6415   // extend instruction
6416   if (SrcTyScalarSize * 2 < DstTyScalarSize) {
6417     LLT MidTy = SrcTy.changeElementSize(SrcTyScalarSize * 2);
6418     // If the destination type is illegal, split it into multiple statements
6419     // zext x -> zext(merge(zext(unmerge), zext(unmerge)))
6420     auto NewExt = MIRBuilder.buildInstr(MI.getOpcode(), {MidTy}, {Src});
6421     // Unmerge the vector
6422     LLT EltTy = MidTy.changeElementCount(
6423         MidTy.getElementCount().divideCoefficientBy(2));
6424     auto UnmergeSrc = MIRBuilder.buildUnmerge(EltTy, NewExt);
6425 
6426     // ZExt the vectors
6427     LLT ZExtResTy = DstTy.changeElementCount(
6428         DstTy.getElementCount().divideCoefficientBy(2));
6429     auto ZExtRes1 = MIRBuilder.buildInstr(MI.getOpcode(), {ZExtResTy},
6430                                           {UnmergeSrc.getReg(0)});
6431     auto ZExtRes2 = MIRBuilder.buildInstr(MI.getOpcode(), {ZExtResTy},
6432                                           {UnmergeSrc.getReg(1)});
6433 
6434     // Merge the ending vectors
6435     MIRBuilder.buildMergeLikeInstr(Dst, {ZExtRes1, ZExtRes2});
6436 
6437     MI.eraseFromParent();
6438     return Legalized;
6439   }
6440   return UnableToLegalize;
6441 }
6442 
6443 LegalizerHelper::LegalizeResult LegalizerHelper::lowerTRUNC(MachineInstr &MI) {
6444   // MachineIRBuilder &MIRBuilder = Helper.MIRBuilder;
6445   MachineRegisterInfo &MRI = *MIRBuilder.getMRI();
6446   // Similar to how operand splitting is done in SelectiondDAG, we can handle
6447   // %res(v8s8) = G_TRUNC %in(v8s32) by generating:
6448   //   %inlo(<4x s32>), %inhi(<4 x s32>) = G_UNMERGE %in(<8 x s32>)
6449   //   %lo16(<4 x s16>) = G_TRUNC %inlo
6450   //   %hi16(<4 x s16>) = G_TRUNC %inhi
6451   //   %in16(<8 x s16>) = G_CONCAT_VECTORS %lo16, %hi16
6452   //   %res(<8 x s8>) = G_TRUNC %in16
6453 
6454   assert(MI.getOpcode() == TargetOpcode::G_TRUNC);
6455 
6456   Register DstReg = MI.getOperand(0).getReg();
6457   Register SrcReg = MI.getOperand(1).getReg();
6458   LLT DstTy = MRI.getType(DstReg);
6459   LLT SrcTy = MRI.getType(SrcReg);
6460 
6461   if (DstTy.isVector() && isPowerOf2_32(DstTy.getNumElements()) &&
6462       isPowerOf2_32(DstTy.getScalarSizeInBits()) &&
6463       isPowerOf2_32(SrcTy.getNumElements()) &&
6464       isPowerOf2_32(SrcTy.getScalarSizeInBits())) {
6465     // Split input type.
6466     LLT SplitSrcTy = SrcTy.changeElementCount(
6467         SrcTy.getElementCount().divideCoefficientBy(2));
6468 
6469     // First, split the source into two smaller vectors.
6470     SmallVector<Register, 2> SplitSrcs;
6471     extractParts(SrcReg, SplitSrcTy, 2, SplitSrcs);
6472 
6473     // Truncate the splits into intermediate narrower elements.
6474     LLT InterTy;
6475     if (DstTy.getScalarSizeInBits() * 2 < SrcTy.getScalarSizeInBits())
6476       InterTy = SplitSrcTy.changeElementSize(DstTy.getScalarSizeInBits() * 2);
6477     else
6478       InterTy = SplitSrcTy.changeElementSize(DstTy.getScalarSizeInBits());
6479     for (unsigned I = 0; I < SplitSrcs.size(); ++I) {
6480       SplitSrcs[I] = MIRBuilder.buildTrunc(InterTy, SplitSrcs[I]).getReg(0);
6481     }
6482 
6483     // Combine the new truncates into one vector
6484     auto Merge = MIRBuilder.buildMergeLikeInstr(
6485         DstTy.changeElementSize(InterTy.getScalarSizeInBits()), SplitSrcs);
6486 
6487     // Truncate the new vector to the final result type
6488     if (DstTy.getScalarSizeInBits() * 2 < SrcTy.getScalarSizeInBits())
6489       MIRBuilder.buildTrunc(MI.getOperand(0).getReg(), Merge.getReg(0));
6490     else
6491       MIRBuilder.buildCopy(MI.getOperand(0).getReg(), Merge.getReg(0));
6492 
6493     MI.eraseFromParent();
6494 
6495     return Legalized;
6496   }
6497   return UnableToLegalize;
6498 }
6499 
6500 LegalizerHelper::LegalizeResult
6501 LegalizerHelper::lowerRotateWithReverseRotate(MachineInstr &MI) {
6502   auto [Dst, DstTy, Src, SrcTy, Amt, AmtTy] = MI.getFirst3RegLLTs();
6503   auto Zero = MIRBuilder.buildConstant(AmtTy, 0);
6504   bool IsLeft = MI.getOpcode() == TargetOpcode::G_ROTL;
6505   unsigned RevRot = IsLeft ? TargetOpcode::G_ROTR : TargetOpcode::G_ROTL;
6506   auto Neg = MIRBuilder.buildSub(AmtTy, Zero, Amt);
6507   MIRBuilder.buildInstr(RevRot, {Dst}, {Src, Neg});
6508   MI.eraseFromParent();
6509   return Legalized;
6510 }
6511 
6512 LegalizerHelper::LegalizeResult LegalizerHelper::lowerRotate(MachineInstr &MI) {
6513   auto [Dst, DstTy, Src, SrcTy, Amt, AmtTy] = MI.getFirst3RegLLTs();
6514 
6515   unsigned EltSizeInBits = DstTy.getScalarSizeInBits();
6516   bool IsLeft = MI.getOpcode() == TargetOpcode::G_ROTL;
6517 
6518   MIRBuilder.setInstrAndDebugLoc(MI);
6519 
6520   // If a rotate in the other direction is supported, use it.
6521   unsigned RevRot = IsLeft ? TargetOpcode::G_ROTR : TargetOpcode::G_ROTL;
6522   if (LI.isLegalOrCustom({RevRot, {DstTy, SrcTy}}) &&
6523       isPowerOf2_32(EltSizeInBits))
6524     return lowerRotateWithReverseRotate(MI);
6525 
6526   // If a funnel shift is supported, use it.
6527   unsigned FShOpc = IsLeft ? TargetOpcode::G_FSHL : TargetOpcode::G_FSHR;
6528   unsigned RevFsh = !IsLeft ? TargetOpcode::G_FSHL : TargetOpcode::G_FSHR;
6529   bool IsFShLegal = false;
6530   if ((IsFShLegal = LI.isLegalOrCustom({FShOpc, {DstTy, AmtTy}})) ||
6531       LI.isLegalOrCustom({RevFsh, {DstTy, AmtTy}})) {
6532     auto buildFunnelShift = [&](unsigned Opc, Register R1, Register R2,
6533                                 Register R3) {
6534       MIRBuilder.buildInstr(Opc, {R1}, {R2, R2, R3});
6535       MI.eraseFromParent();
6536       return Legalized;
6537     };
6538     // If a funnel shift in the other direction is supported, use it.
6539     if (IsFShLegal) {
6540       return buildFunnelShift(FShOpc, Dst, Src, Amt);
6541     } else if (isPowerOf2_32(EltSizeInBits)) {
6542       Amt = MIRBuilder.buildNeg(DstTy, Amt).getReg(0);
6543       return buildFunnelShift(RevFsh, Dst, Src, Amt);
6544     }
6545   }
6546 
6547   auto Zero = MIRBuilder.buildConstant(AmtTy, 0);
6548   unsigned ShOpc = IsLeft ? TargetOpcode::G_SHL : TargetOpcode::G_LSHR;
6549   unsigned RevShiftOpc = IsLeft ? TargetOpcode::G_LSHR : TargetOpcode::G_SHL;
6550   auto BitWidthMinusOneC = MIRBuilder.buildConstant(AmtTy, EltSizeInBits - 1);
6551   Register ShVal;
6552   Register RevShiftVal;
6553   if (isPowerOf2_32(EltSizeInBits)) {
6554     // (rotl x, c) -> x << (c & (w - 1)) | x >> (-c & (w - 1))
6555     // (rotr x, c) -> x >> (c & (w - 1)) | x << (-c & (w - 1))
6556     auto NegAmt = MIRBuilder.buildSub(AmtTy, Zero, Amt);
6557     auto ShAmt = MIRBuilder.buildAnd(AmtTy, Amt, BitWidthMinusOneC);
6558     ShVal = MIRBuilder.buildInstr(ShOpc, {DstTy}, {Src, ShAmt}).getReg(0);
6559     auto RevAmt = MIRBuilder.buildAnd(AmtTy, NegAmt, BitWidthMinusOneC);
6560     RevShiftVal =
6561         MIRBuilder.buildInstr(RevShiftOpc, {DstTy}, {Src, RevAmt}).getReg(0);
6562   } else {
6563     // (rotl x, c) -> x << (c % w) | x >> 1 >> (w - 1 - (c % w))
6564     // (rotr x, c) -> x >> (c % w) | x << 1 << (w - 1 - (c % w))
6565     auto BitWidthC = MIRBuilder.buildConstant(AmtTy, EltSizeInBits);
6566     auto ShAmt = MIRBuilder.buildURem(AmtTy, Amt, BitWidthC);
6567     ShVal = MIRBuilder.buildInstr(ShOpc, {DstTy}, {Src, ShAmt}).getReg(0);
6568     auto RevAmt = MIRBuilder.buildSub(AmtTy, BitWidthMinusOneC, ShAmt);
6569     auto One = MIRBuilder.buildConstant(AmtTy, 1);
6570     auto Inner = MIRBuilder.buildInstr(RevShiftOpc, {DstTy}, {Src, One});
6571     RevShiftVal =
6572         MIRBuilder.buildInstr(RevShiftOpc, {DstTy}, {Inner, RevAmt}).getReg(0);
6573   }
6574   MIRBuilder.buildOr(Dst, ShVal, RevShiftVal);
6575   MI.eraseFromParent();
6576   return Legalized;
6577 }
6578 
6579 // Expand s32 = G_UITOFP s64 using bit operations to an IEEE float
6580 // representation.
6581 LegalizerHelper::LegalizeResult
6582 LegalizerHelper::lowerU64ToF32BitOps(MachineInstr &MI) {
6583   auto [Dst, Src] = MI.getFirst2Regs();
6584   const LLT S64 = LLT::scalar(64);
6585   const LLT S32 = LLT::scalar(32);
6586   const LLT S1 = LLT::scalar(1);
6587 
6588   assert(MRI.getType(Src) == S64 && MRI.getType(Dst) == S32);
6589 
6590   // unsigned cul2f(ulong u) {
6591   //   uint lz = clz(u);
6592   //   uint e = (u != 0) ? 127U + 63U - lz : 0;
6593   //   u = (u << lz) & 0x7fffffffffffffffUL;
6594   //   ulong t = u & 0xffffffffffUL;
6595   //   uint v = (e << 23) | (uint)(u >> 40);
6596   //   uint r = t > 0x8000000000UL ? 1U : (t == 0x8000000000UL ? v & 1U : 0U);
6597   //   return as_float(v + r);
6598   // }
6599 
6600   auto Zero32 = MIRBuilder.buildConstant(S32, 0);
6601   auto Zero64 = MIRBuilder.buildConstant(S64, 0);
6602 
6603   auto LZ = MIRBuilder.buildCTLZ_ZERO_UNDEF(S32, Src);
6604 
6605   auto K = MIRBuilder.buildConstant(S32, 127U + 63U);
6606   auto Sub = MIRBuilder.buildSub(S32, K, LZ);
6607 
6608   auto NotZero = MIRBuilder.buildICmp(CmpInst::ICMP_NE, S1, Src, Zero64);
6609   auto E = MIRBuilder.buildSelect(S32, NotZero, Sub, Zero32);
6610 
6611   auto Mask0 = MIRBuilder.buildConstant(S64, (-1ULL) >> 1);
6612   auto ShlLZ = MIRBuilder.buildShl(S64, Src, LZ);
6613 
6614   auto U = MIRBuilder.buildAnd(S64, ShlLZ, Mask0);
6615 
6616   auto Mask1 = MIRBuilder.buildConstant(S64, 0xffffffffffULL);
6617   auto T = MIRBuilder.buildAnd(S64, U, Mask1);
6618 
6619   auto UShl = MIRBuilder.buildLShr(S64, U, MIRBuilder.buildConstant(S64, 40));
6620   auto ShlE = MIRBuilder.buildShl(S32, E, MIRBuilder.buildConstant(S32, 23));
6621   auto V = MIRBuilder.buildOr(S32, ShlE, MIRBuilder.buildTrunc(S32, UShl));
6622 
6623   auto C = MIRBuilder.buildConstant(S64, 0x8000000000ULL);
6624   auto RCmp = MIRBuilder.buildICmp(CmpInst::ICMP_UGT, S1, T, C);
6625   auto TCmp = MIRBuilder.buildICmp(CmpInst::ICMP_EQ, S1, T, C);
6626   auto One = MIRBuilder.buildConstant(S32, 1);
6627 
6628   auto VTrunc1 = MIRBuilder.buildAnd(S32, V, One);
6629   auto Select0 = MIRBuilder.buildSelect(S32, TCmp, VTrunc1, Zero32);
6630   auto R = MIRBuilder.buildSelect(S32, RCmp, One, Select0);
6631   MIRBuilder.buildAdd(Dst, V, R);
6632 
6633   MI.eraseFromParent();
6634   return Legalized;
6635 }
6636 
6637 LegalizerHelper::LegalizeResult LegalizerHelper::lowerUITOFP(MachineInstr &MI) {
6638   auto [Dst, DstTy, Src, SrcTy] = MI.getFirst2RegLLTs();
6639 
6640   if (SrcTy == LLT::scalar(1)) {
6641     auto True = MIRBuilder.buildFConstant(DstTy, 1.0);
6642     auto False = MIRBuilder.buildFConstant(DstTy, 0.0);
6643     MIRBuilder.buildSelect(Dst, Src, True, False);
6644     MI.eraseFromParent();
6645     return Legalized;
6646   }
6647 
6648   if (SrcTy != LLT::scalar(64))
6649     return UnableToLegalize;
6650 
6651   if (DstTy == LLT::scalar(32)) {
6652     // TODO: SelectionDAG has several alternative expansions to port which may
6653     // be more reasonble depending on the available instructions. If a target
6654     // has sitofp, does not have CTLZ, or can efficiently use f64 as an
6655     // intermediate type, this is probably worse.
6656     return lowerU64ToF32BitOps(MI);
6657   }
6658 
6659   return UnableToLegalize;
6660 }
6661 
6662 LegalizerHelper::LegalizeResult LegalizerHelper::lowerSITOFP(MachineInstr &MI) {
6663   auto [Dst, DstTy, Src, SrcTy] = MI.getFirst2RegLLTs();
6664 
6665   const LLT S64 = LLT::scalar(64);
6666   const LLT S32 = LLT::scalar(32);
6667   const LLT S1 = LLT::scalar(1);
6668 
6669   if (SrcTy == S1) {
6670     auto True = MIRBuilder.buildFConstant(DstTy, -1.0);
6671     auto False = MIRBuilder.buildFConstant(DstTy, 0.0);
6672     MIRBuilder.buildSelect(Dst, Src, True, False);
6673     MI.eraseFromParent();
6674     return Legalized;
6675   }
6676 
6677   if (SrcTy != S64)
6678     return UnableToLegalize;
6679 
6680   if (DstTy == S32) {
6681     // signed cl2f(long l) {
6682     //   long s = l >> 63;
6683     //   float r = cul2f((l + s) ^ s);
6684     //   return s ? -r : r;
6685     // }
6686     Register L = Src;
6687     auto SignBit = MIRBuilder.buildConstant(S64, 63);
6688     auto S = MIRBuilder.buildAShr(S64, L, SignBit);
6689 
6690     auto LPlusS = MIRBuilder.buildAdd(S64, L, S);
6691     auto Xor = MIRBuilder.buildXor(S64, LPlusS, S);
6692     auto R = MIRBuilder.buildUITOFP(S32, Xor);
6693 
6694     auto RNeg = MIRBuilder.buildFNeg(S32, R);
6695     auto SignNotZero = MIRBuilder.buildICmp(CmpInst::ICMP_NE, S1, S,
6696                                             MIRBuilder.buildConstant(S64, 0));
6697     MIRBuilder.buildSelect(Dst, SignNotZero, RNeg, R);
6698     MI.eraseFromParent();
6699     return Legalized;
6700   }
6701 
6702   return UnableToLegalize;
6703 }
6704 
6705 LegalizerHelper::LegalizeResult LegalizerHelper::lowerFPTOUI(MachineInstr &MI) {
6706   auto [Dst, DstTy, Src, SrcTy] = MI.getFirst2RegLLTs();
6707   const LLT S64 = LLT::scalar(64);
6708   const LLT S32 = LLT::scalar(32);
6709 
6710   if (SrcTy != S64 && SrcTy != S32)
6711     return UnableToLegalize;
6712   if (DstTy != S32 && DstTy != S64)
6713     return UnableToLegalize;
6714 
6715   // FPTOSI gives same result as FPTOUI for positive signed integers.
6716   // FPTOUI needs to deal with fp values that convert to unsigned integers
6717   // greater or equal to 2^31 for float or 2^63 for double. For brevity 2^Exp.
6718 
6719   APInt TwoPExpInt = APInt::getSignMask(DstTy.getSizeInBits());
6720   APFloat TwoPExpFP(SrcTy.getSizeInBits() == 32 ? APFloat::IEEEsingle()
6721                                                 : APFloat::IEEEdouble(),
6722                     APInt::getZero(SrcTy.getSizeInBits()));
6723   TwoPExpFP.convertFromAPInt(TwoPExpInt, false, APFloat::rmNearestTiesToEven);
6724 
6725   MachineInstrBuilder FPTOSI = MIRBuilder.buildFPTOSI(DstTy, Src);
6726 
6727   MachineInstrBuilder Threshold = MIRBuilder.buildFConstant(SrcTy, TwoPExpFP);
6728   // For fp Value greater or equal to Threshold(2^Exp), we use FPTOSI on
6729   // (Value - 2^Exp) and add 2^Exp by setting highest bit in result to 1.
6730   MachineInstrBuilder FSub = MIRBuilder.buildFSub(SrcTy, Src, Threshold);
6731   MachineInstrBuilder ResLowBits = MIRBuilder.buildFPTOSI(DstTy, FSub);
6732   MachineInstrBuilder ResHighBit = MIRBuilder.buildConstant(DstTy, TwoPExpInt);
6733   MachineInstrBuilder Res = MIRBuilder.buildXor(DstTy, ResLowBits, ResHighBit);
6734 
6735   const LLT S1 = LLT::scalar(1);
6736 
6737   MachineInstrBuilder FCMP =
6738       MIRBuilder.buildFCmp(CmpInst::FCMP_ULT, S1, Src, Threshold);
6739   MIRBuilder.buildSelect(Dst, FCMP, FPTOSI, Res);
6740 
6741   MI.eraseFromParent();
6742   return Legalized;
6743 }
6744 
6745 LegalizerHelper::LegalizeResult LegalizerHelper::lowerFPTOSI(MachineInstr &MI) {
6746   auto [Dst, DstTy, Src, SrcTy] = MI.getFirst2RegLLTs();
6747   const LLT S64 = LLT::scalar(64);
6748   const LLT S32 = LLT::scalar(32);
6749 
6750   // FIXME: Only f32 to i64 conversions are supported.
6751   if (SrcTy.getScalarType() != S32 || DstTy.getScalarType() != S64)
6752     return UnableToLegalize;
6753 
6754   // Expand f32 -> i64 conversion
6755   // This algorithm comes from compiler-rt's implementation of fixsfdi:
6756   // https://github.com/llvm/llvm-project/blob/main/compiler-rt/lib/builtins/fixsfdi.c
6757 
6758   unsigned SrcEltBits = SrcTy.getScalarSizeInBits();
6759 
6760   auto ExponentMask = MIRBuilder.buildConstant(SrcTy, 0x7F800000);
6761   auto ExponentLoBit = MIRBuilder.buildConstant(SrcTy, 23);
6762 
6763   auto AndExpMask = MIRBuilder.buildAnd(SrcTy, Src, ExponentMask);
6764   auto ExponentBits = MIRBuilder.buildLShr(SrcTy, AndExpMask, ExponentLoBit);
6765 
6766   auto SignMask = MIRBuilder.buildConstant(SrcTy,
6767                                            APInt::getSignMask(SrcEltBits));
6768   auto AndSignMask = MIRBuilder.buildAnd(SrcTy, Src, SignMask);
6769   auto SignLowBit = MIRBuilder.buildConstant(SrcTy, SrcEltBits - 1);
6770   auto Sign = MIRBuilder.buildAShr(SrcTy, AndSignMask, SignLowBit);
6771   Sign = MIRBuilder.buildSExt(DstTy, Sign);
6772 
6773   auto MantissaMask = MIRBuilder.buildConstant(SrcTy, 0x007FFFFF);
6774   auto AndMantissaMask = MIRBuilder.buildAnd(SrcTy, Src, MantissaMask);
6775   auto K = MIRBuilder.buildConstant(SrcTy, 0x00800000);
6776 
6777   auto R = MIRBuilder.buildOr(SrcTy, AndMantissaMask, K);
6778   R = MIRBuilder.buildZExt(DstTy, R);
6779 
6780   auto Bias = MIRBuilder.buildConstant(SrcTy, 127);
6781   auto Exponent = MIRBuilder.buildSub(SrcTy, ExponentBits, Bias);
6782   auto SubExponent = MIRBuilder.buildSub(SrcTy, Exponent, ExponentLoBit);
6783   auto ExponentSub = MIRBuilder.buildSub(SrcTy, ExponentLoBit, Exponent);
6784 
6785   auto Shl = MIRBuilder.buildShl(DstTy, R, SubExponent);
6786   auto Srl = MIRBuilder.buildLShr(DstTy, R, ExponentSub);
6787 
6788   const LLT S1 = LLT::scalar(1);
6789   auto CmpGt = MIRBuilder.buildICmp(CmpInst::ICMP_SGT,
6790                                     S1, Exponent, ExponentLoBit);
6791 
6792   R = MIRBuilder.buildSelect(DstTy, CmpGt, Shl, Srl);
6793 
6794   auto XorSign = MIRBuilder.buildXor(DstTy, R, Sign);
6795   auto Ret = MIRBuilder.buildSub(DstTy, XorSign, Sign);
6796 
6797   auto ZeroSrcTy = MIRBuilder.buildConstant(SrcTy, 0);
6798 
6799   auto ExponentLt0 = MIRBuilder.buildICmp(CmpInst::ICMP_SLT,
6800                                           S1, Exponent, ZeroSrcTy);
6801 
6802   auto ZeroDstTy = MIRBuilder.buildConstant(DstTy, 0);
6803   MIRBuilder.buildSelect(Dst, ExponentLt0, ZeroDstTy, Ret);
6804 
6805   MI.eraseFromParent();
6806   return Legalized;
6807 }
6808 
6809 // f64 -> f16 conversion using round-to-nearest-even rounding mode.
6810 LegalizerHelper::LegalizeResult
6811 LegalizerHelper::lowerFPTRUNC_F64_TO_F16(MachineInstr &MI) {
6812   const LLT S1 = LLT::scalar(1);
6813   const LLT S32 = LLT::scalar(32);
6814 
6815   auto [Dst, Src] = MI.getFirst2Regs();
6816   assert(MRI.getType(Dst).getScalarType() == LLT::scalar(16) &&
6817          MRI.getType(Src).getScalarType() == LLT::scalar(64));
6818 
6819   if (MRI.getType(Src).isVector()) // TODO: Handle vectors directly.
6820     return UnableToLegalize;
6821 
6822   if (MIRBuilder.getMF().getTarget().Options.UnsafeFPMath) {
6823     unsigned Flags = MI.getFlags();
6824     auto Src32 = MIRBuilder.buildFPTrunc(S32, Src, Flags);
6825     MIRBuilder.buildFPTrunc(Dst, Src32, Flags);
6826     MI.eraseFromParent();
6827     return Legalized;
6828   }
6829 
6830   const unsigned ExpMask = 0x7ff;
6831   const unsigned ExpBiasf64 = 1023;
6832   const unsigned ExpBiasf16 = 15;
6833 
6834   auto Unmerge = MIRBuilder.buildUnmerge(S32, Src);
6835   Register U = Unmerge.getReg(0);
6836   Register UH = Unmerge.getReg(1);
6837 
6838   auto E = MIRBuilder.buildLShr(S32, UH, MIRBuilder.buildConstant(S32, 20));
6839   E = MIRBuilder.buildAnd(S32, E, MIRBuilder.buildConstant(S32, ExpMask));
6840 
6841   // Subtract the fp64 exponent bias (1023) to get the real exponent and
6842   // add the f16 bias (15) to get the biased exponent for the f16 format.
6843   E = MIRBuilder.buildAdd(
6844     S32, E, MIRBuilder.buildConstant(S32, -ExpBiasf64 + ExpBiasf16));
6845 
6846   auto M = MIRBuilder.buildLShr(S32, UH, MIRBuilder.buildConstant(S32, 8));
6847   M = MIRBuilder.buildAnd(S32, M, MIRBuilder.buildConstant(S32, 0xffe));
6848 
6849   auto MaskedSig = MIRBuilder.buildAnd(S32, UH,
6850                                        MIRBuilder.buildConstant(S32, 0x1ff));
6851   MaskedSig = MIRBuilder.buildOr(S32, MaskedSig, U);
6852 
6853   auto Zero = MIRBuilder.buildConstant(S32, 0);
6854   auto SigCmpNE0 = MIRBuilder.buildICmp(CmpInst::ICMP_NE, S1, MaskedSig, Zero);
6855   auto Lo40Set = MIRBuilder.buildZExt(S32, SigCmpNE0);
6856   M = MIRBuilder.buildOr(S32, M, Lo40Set);
6857 
6858   // (M != 0 ? 0x0200 : 0) | 0x7c00;
6859   auto Bits0x200 = MIRBuilder.buildConstant(S32, 0x0200);
6860   auto CmpM_NE0 = MIRBuilder.buildICmp(CmpInst::ICMP_NE, S1, M, Zero);
6861   auto SelectCC = MIRBuilder.buildSelect(S32, CmpM_NE0, Bits0x200, Zero);
6862 
6863   auto Bits0x7c00 = MIRBuilder.buildConstant(S32, 0x7c00);
6864   auto I = MIRBuilder.buildOr(S32, SelectCC, Bits0x7c00);
6865 
6866   // N = M | (E << 12);
6867   auto EShl12 = MIRBuilder.buildShl(S32, E, MIRBuilder.buildConstant(S32, 12));
6868   auto N = MIRBuilder.buildOr(S32, M, EShl12);
6869 
6870   // B = clamp(1-E, 0, 13);
6871   auto One = MIRBuilder.buildConstant(S32, 1);
6872   auto OneSubExp = MIRBuilder.buildSub(S32, One, E);
6873   auto B = MIRBuilder.buildSMax(S32, OneSubExp, Zero);
6874   B = MIRBuilder.buildSMin(S32, B, MIRBuilder.buildConstant(S32, 13));
6875 
6876   auto SigSetHigh = MIRBuilder.buildOr(S32, M,
6877                                        MIRBuilder.buildConstant(S32, 0x1000));
6878 
6879   auto D = MIRBuilder.buildLShr(S32, SigSetHigh, B);
6880   auto D0 = MIRBuilder.buildShl(S32, D, B);
6881 
6882   auto D0_NE_SigSetHigh = MIRBuilder.buildICmp(CmpInst::ICMP_NE, S1,
6883                                              D0, SigSetHigh);
6884   auto D1 = MIRBuilder.buildZExt(S32, D0_NE_SigSetHigh);
6885   D = MIRBuilder.buildOr(S32, D, D1);
6886 
6887   auto CmpELtOne = MIRBuilder.buildICmp(CmpInst::ICMP_SLT, S1, E, One);
6888   auto V = MIRBuilder.buildSelect(S32, CmpELtOne, D, N);
6889 
6890   auto VLow3 = MIRBuilder.buildAnd(S32, V, MIRBuilder.buildConstant(S32, 7));
6891   V = MIRBuilder.buildLShr(S32, V, MIRBuilder.buildConstant(S32, 2));
6892 
6893   auto VLow3Eq3 = MIRBuilder.buildICmp(CmpInst::ICMP_EQ, S1, VLow3,
6894                                        MIRBuilder.buildConstant(S32, 3));
6895   auto V0 = MIRBuilder.buildZExt(S32, VLow3Eq3);
6896 
6897   auto VLow3Gt5 = MIRBuilder.buildICmp(CmpInst::ICMP_SGT, S1, VLow3,
6898                                        MIRBuilder.buildConstant(S32, 5));
6899   auto V1 = MIRBuilder.buildZExt(S32, VLow3Gt5);
6900 
6901   V1 = MIRBuilder.buildOr(S32, V0, V1);
6902   V = MIRBuilder.buildAdd(S32, V, V1);
6903 
6904   auto CmpEGt30 = MIRBuilder.buildICmp(CmpInst::ICMP_SGT,  S1,
6905                                        E, MIRBuilder.buildConstant(S32, 30));
6906   V = MIRBuilder.buildSelect(S32, CmpEGt30,
6907                              MIRBuilder.buildConstant(S32, 0x7c00), V);
6908 
6909   auto CmpEGt1039 = MIRBuilder.buildICmp(CmpInst::ICMP_EQ, S1,
6910                                          E, MIRBuilder.buildConstant(S32, 1039));
6911   V = MIRBuilder.buildSelect(S32, CmpEGt1039, I, V);
6912 
6913   // Extract the sign bit.
6914   auto Sign = MIRBuilder.buildLShr(S32, UH, MIRBuilder.buildConstant(S32, 16));
6915   Sign = MIRBuilder.buildAnd(S32, Sign, MIRBuilder.buildConstant(S32, 0x8000));
6916 
6917   // Insert the sign bit
6918   V = MIRBuilder.buildOr(S32, Sign, V);
6919 
6920   MIRBuilder.buildTrunc(Dst, V);
6921   MI.eraseFromParent();
6922   return Legalized;
6923 }
6924 
6925 LegalizerHelper::LegalizeResult
6926 LegalizerHelper::lowerFPTRUNC(MachineInstr &MI) {
6927   auto [DstTy, SrcTy] = MI.getFirst2LLTs();
6928   const LLT S64 = LLT::scalar(64);
6929   const LLT S16 = LLT::scalar(16);
6930 
6931   if (DstTy.getScalarType() == S16 && SrcTy.getScalarType() == S64)
6932     return lowerFPTRUNC_F64_TO_F16(MI);
6933 
6934   return UnableToLegalize;
6935 }
6936 
6937 // TODO: If RHS is a constant SelectionDAGBuilder expands this into a
6938 // multiplication tree.
6939 LegalizerHelper::LegalizeResult LegalizerHelper::lowerFPOWI(MachineInstr &MI) {
6940   auto [Dst, Src0, Src1] = MI.getFirst3Regs();
6941   LLT Ty = MRI.getType(Dst);
6942 
6943   auto CvtSrc1 = MIRBuilder.buildSITOFP(Ty, Src1);
6944   MIRBuilder.buildFPow(Dst, Src0, CvtSrc1, MI.getFlags());
6945   MI.eraseFromParent();
6946   return Legalized;
6947 }
6948 
6949 static CmpInst::Predicate minMaxToCompare(unsigned Opc) {
6950   switch (Opc) {
6951   case TargetOpcode::G_SMIN:
6952     return CmpInst::ICMP_SLT;
6953   case TargetOpcode::G_SMAX:
6954     return CmpInst::ICMP_SGT;
6955   case TargetOpcode::G_UMIN:
6956     return CmpInst::ICMP_ULT;
6957   case TargetOpcode::G_UMAX:
6958     return CmpInst::ICMP_UGT;
6959   default:
6960     llvm_unreachable("not in integer min/max");
6961   }
6962 }
6963 
6964 LegalizerHelper::LegalizeResult LegalizerHelper::lowerMinMax(MachineInstr &MI) {
6965   auto [Dst, Src0, Src1] = MI.getFirst3Regs();
6966 
6967   const CmpInst::Predicate Pred = minMaxToCompare(MI.getOpcode());
6968   LLT CmpType = MRI.getType(Dst).changeElementSize(1);
6969 
6970   auto Cmp = MIRBuilder.buildICmp(Pred, CmpType, Src0, Src1);
6971   MIRBuilder.buildSelect(Dst, Cmp, Src0, Src1);
6972 
6973   MI.eraseFromParent();
6974   return Legalized;
6975 }
6976 
6977 LegalizerHelper::LegalizeResult
6978 LegalizerHelper::lowerFCopySign(MachineInstr &MI) {
6979   auto [Dst, DstTy, Src0, Src0Ty, Src1, Src1Ty] = MI.getFirst3RegLLTs();
6980   const int Src0Size = Src0Ty.getScalarSizeInBits();
6981   const int Src1Size = Src1Ty.getScalarSizeInBits();
6982 
6983   auto SignBitMask = MIRBuilder.buildConstant(
6984     Src0Ty, APInt::getSignMask(Src0Size));
6985 
6986   auto NotSignBitMask = MIRBuilder.buildConstant(
6987     Src0Ty, APInt::getLowBitsSet(Src0Size, Src0Size - 1));
6988 
6989   Register And0 = MIRBuilder.buildAnd(Src0Ty, Src0, NotSignBitMask).getReg(0);
6990   Register And1;
6991   if (Src0Ty == Src1Ty) {
6992     And1 = MIRBuilder.buildAnd(Src1Ty, Src1, SignBitMask).getReg(0);
6993   } else if (Src0Size > Src1Size) {
6994     auto ShiftAmt = MIRBuilder.buildConstant(Src0Ty, Src0Size - Src1Size);
6995     auto Zext = MIRBuilder.buildZExt(Src0Ty, Src1);
6996     auto Shift = MIRBuilder.buildShl(Src0Ty, Zext, ShiftAmt);
6997     And1 = MIRBuilder.buildAnd(Src0Ty, Shift, SignBitMask).getReg(0);
6998   } else {
6999     auto ShiftAmt = MIRBuilder.buildConstant(Src1Ty, Src1Size - Src0Size);
7000     auto Shift = MIRBuilder.buildLShr(Src1Ty, Src1, ShiftAmt);
7001     auto Trunc = MIRBuilder.buildTrunc(Src0Ty, Shift);
7002     And1 = MIRBuilder.buildAnd(Src0Ty, Trunc, SignBitMask).getReg(0);
7003   }
7004 
7005   // Be careful about setting nsz/nnan/ninf on every instruction, since the
7006   // constants are a nan and -0.0, but the final result should preserve
7007   // everything.
7008   unsigned Flags = MI.getFlags();
7009   MIRBuilder.buildOr(Dst, And0, And1, Flags);
7010 
7011   MI.eraseFromParent();
7012   return Legalized;
7013 }
7014 
7015 LegalizerHelper::LegalizeResult
7016 LegalizerHelper::lowerFMinNumMaxNum(MachineInstr &MI) {
7017   unsigned NewOp = MI.getOpcode() == TargetOpcode::G_FMINNUM ?
7018     TargetOpcode::G_FMINNUM_IEEE : TargetOpcode::G_FMAXNUM_IEEE;
7019 
7020   auto [Dst, Src0, Src1] = MI.getFirst3Regs();
7021   LLT Ty = MRI.getType(Dst);
7022 
7023   if (!MI.getFlag(MachineInstr::FmNoNans)) {
7024     // Insert canonicalizes if it's possible we need to quiet to get correct
7025     // sNaN behavior.
7026 
7027     // Note this must be done here, and not as an optimization combine in the
7028     // absence of a dedicate quiet-snan instruction as we're using an
7029     // omni-purpose G_FCANONICALIZE.
7030     if (!isKnownNeverSNaN(Src0, MRI))
7031       Src0 = MIRBuilder.buildFCanonicalize(Ty, Src0, MI.getFlags()).getReg(0);
7032 
7033     if (!isKnownNeverSNaN(Src1, MRI))
7034       Src1 = MIRBuilder.buildFCanonicalize(Ty, Src1, MI.getFlags()).getReg(0);
7035   }
7036 
7037   // If there are no nans, it's safe to simply replace this with the non-IEEE
7038   // version.
7039   MIRBuilder.buildInstr(NewOp, {Dst}, {Src0, Src1}, MI.getFlags());
7040   MI.eraseFromParent();
7041   return Legalized;
7042 }
7043 
7044 LegalizerHelper::LegalizeResult LegalizerHelper::lowerFMad(MachineInstr &MI) {
7045   // Expand G_FMAD a, b, c -> G_FADD (G_FMUL a, b), c
7046   Register DstReg = MI.getOperand(0).getReg();
7047   LLT Ty = MRI.getType(DstReg);
7048   unsigned Flags = MI.getFlags();
7049 
7050   auto Mul = MIRBuilder.buildFMul(Ty, MI.getOperand(1), MI.getOperand(2),
7051                                   Flags);
7052   MIRBuilder.buildFAdd(DstReg, Mul, MI.getOperand(3), Flags);
7053   MI.eraseFromParent();
7054   return Legalized;
7055 }
7056 
7057 LegalizerHelper::LegalizeResult
7058 LegalizerHelper::lowerIntrinsicRound(MachineInstr &MI) {
7059   auto [DstReg, X] = MI.getFirst2Regs();
7060   const unsigned Flags = MI.getFlags();
7061   const LLT Ty = MRI.getType(DstReg);
7062   const LLT CondTy = Ty.changeElementSize(1);
7063 
7064   // round(x) =>
7065   //  t = trunc(x);
7066   //  d = fabs(x - t);
7067   //  o = copysign(d >= 0.5 ? 1.0 : 0.0, x);
7068   //  return t + o;
7069 
7070   auto T = MIRBuilder.buildIntrinsicTrunc(Ty, X, Flags);
7071 
7072   auto Diff = MIRBuilder.buildFSub(Ty, X, T, Flags);
7073   auto AbsDiff = MIRBuilder.buildFAbs(Ty, Diff, Flags);
7074 
7075   auto Half = MIRBuilder.buildFConstant(Ty, 0.5);
7076   auto Cmp =
7077       MIRBuilder.buildFCmp(CmpInst::FCMP_OGE, CondTy, AbsDiff, Half, Flags);
7078 
7079   // Could emit G_UITOFP instead
7080   auto One = MIRBuilder.buildFConstant(Ty, 1.0);
7081   auto Zero = MIRBuilder.buildFConstant(Ty, 0.0);
7082   auto BoolFP = MIRBuilder.buildSelect(Ty, Cmp, One, Zero);
7083   auto SignedOffset = MIRBuilder.buildFCopysign(Ty, BoolFP, X);
7084 
7085   MIRBuilder.buildFAdd(DstReg, T, SignedOffset, Flags);
7086 
7087   MI.eraseFromParent();
7088   return Legalized;
7089 }
7090 
7091 LegalizerHelper::LegalizeResult LegalizerHelper::lowerFFloor(MachineInstr &MI) {
7092   auto [DstReg, SrcReg] = MI.getFirst2Regs();
7093   unsigned Flags = MI.getFlags();
7094   LLT Ty = MRI.getType(DstReg);
7095   const LLT CondTy = Ty.changeElementSize(1);
7096 
7097   // result = trunc(src);
7098   // if (src < 0.0 && src != result)
7099   //   result += -1.0.
7100 
7101   auto Trunc = MIRBuilder.buildIntrinsicTrunc(Ty, SrcReg, Flags);
7102   auto Zero = MIRBuilder.buildFConstant(Ty, 0.0);
7103 
7104   auto Lt0 = MIRBuilder.buildFCmp(CmpInst::FCMP_OLT, CondTy,
7105                                   SrcReg, Zero, Flags);
7106   auto NeTrunc = MIRBuilder.buildFCmp(CmpInst::FCMP_ONE, CondTy,
7107                                       SrcReg, Trunc, Flags);
7108   auto And = MIRBuilder.buildAnd(CondTy, Lt0, NeTrunc);
7109   auto AddVal = MIRBuilder.buildSITOFP(Ty, And);
7110 
7111   MIRBuilder.buildFAdd(DstReg, Trunc, AddVal, Flags);
7112   MI.eraseFromParent();
7113   return Legalized;
7114 }
7115 
7116 LegalizerHelper::LegalizeResult
7117 LegalizerHelper::lowerMergeValues(MachineInstr &MI) {
7118   const unsigned NumOps = MI.getNumOperands();
7119   auto [DstReg, DstTy, Src0Reg, Src0Ty] = MI.getFirst2RegLLTs();
7120   unsigned PartSize = Src0Ty.getSizeInBits();
7121 
7122   LLT WideTy = LLT::scalar(DstTy.getSizeInBits());
7123   Register ResultReg = MIRBuilder.buildZExt(WideTy, Src0Reg).getReg(0);
7124 
7125   for (unsigned I = 2; I != NumOps; ++I) {
7126     const unsigned Offset = (I - 1) * PartSize;
7127 
7128     Register SrcReg = MI.getOperand(I).getReg();
7129     auto ZextInput = MIRBuilder.buildZExt(WideTy, SrcReg);
7130 
7131     Register NextResult = I + 1 == NumOps && WideTy == DstTy ? DstReg :
7132       MRI.createGenericVirtualRegister(WideTy);
7133 
7134     auto ShiftAmt = MIRBuilder.buildConstant(WideTy, Offset);
7135     auto Shl = MIRBuilder.buildShl(WideTy, ZextInput, ShiftAmt);
7136     MIRBuilder.buildOr(NextResult, ResultReg, Shl);
7137     ResultReg = NextResult;
7138   }
7139 
7140   if (DstTy.isPointer()) {
7141     if (MIRBuilder.getDataLayout().isNonIntegralAddressSpace(
7142           DstTy.getAddressSpace())) {
7143       LLVM_DEBUG(dbgs() << "Not casting nonintegral address space\n");
7144       return UnableToLegalize;
7145     }
7146 
7147     MIRBuilder.buildIntToPtr(DstReg, ResultReg);
7148   }
7149 
7150   MI.eraseFromParent();
7151   return Legalized;
7152 }
7153 
7154 LegalizerHelper::LegalizeResult
7155 LegalizerHelper::lowerUnmergeValues(MachineInstr &MI) {
7156   const unsigned NumDst = MI.getNumOperands() - 1;
7157   Register SrcReg = MI.getOperand(NumDst).getReg();
7158   Register Dst0Reg = MI.getOperand(0).getReg();
7159   LLT DstTy = MRI.getType(Dst0Reg);
7160   if (DstTy.isPointer())
7161     return UnableToLegalize; // TODO
7162 
7163   SrcReg = coerceToScalar(SrcReg);
7164   if (!SrcReg)
7165     return UnableToLegalize;
7166 
7167   // Expand scalarizing unmerge as bitcast to integer and shift.
7168   LLT IntTy = MRI.getType(SrcReg);
7169 
7170   MIRBuilder.buildTrunc(Dst0Reg, SrcReg);
7171 
7172   const unsigned DstSize = DstTy.getSizeInBits();
7173   unsigned Offset = DstSize;
7174   for (unsigned I = 1; I != NumDst; ++I, Offset += DstSize) {
7175     auto ShiftAmt = MIRBuilder.buildConstant(IntTy, Offset);
7176     auto Shift = MIRBuilder.buildLShr(IntTy, SrcReg, ShiftAmt);
7177     MIRBuilder.buildTrunc(MI.getOperand(I), Shift);
7178   }
7179 
7180   MI.eraseFromParent();
7181   return Legalized;
7182 }
7183 
7184 /// Lower a vector extract or insert by writing the vector to a stack temporary
7185 /// and reloading the element or vector.
7186 ///
7187 /// %dst = G_EXTRACT_VECTOR_ELT %vec, %idx
7188 ///  =>
7189 ///  %stack_temp = G_FRAME_INDEX
7190 ///  G_STORE %vec, %stack_temp
7191 ///  %idx = clamp(%idx, %vec.getNumElements())
7192 ///  %element_ptr = G_PTR_ADD %stack_temp, %idx
7193 ///  %dst = G_LOAD %element_ptr
7194 LegalizerHelper::LegalizeResult
7195 LegalizerHelper::lowerExtractInsertVectorElt(MachineInstr &MI) {
7196   Register DstReg = MI.getOperand(0).getReg();
7197   Register SrcVec = MI.getOperand(1).getReg();
7198   Register InsertVal;
7199   if (MI.getOpcode() == TargetOpcode::G_INSERT_VECTOR_ELT)
7200     InsertVal = MI.getOperand(2).getReg();
7201 
7202   Register Idx = MI.getOperand(MI.getNumOperands() - 1).getReg();
7203 
7204   LLT VecTy = MRI.getType(SrcVec);
7205   LLT EltTy = VecTy.getElementType();
7206   unsigned NumElts = VecTy.getNumElements();
7207 
7208   int64_t IdxVal;
7209   if (mi_match(Idx, MRI, m_ICst(IdxVal)) && IdxVal <= NumElts) {
7210     SmallVector<Register, 8> SrcRegs;
7211     extractParts(SrcVec, EltTy, NumElts, SrcRegs);
7212 
7213     if (InsertVal) {
7214       SrcRegs[IdxVal] = MI.getOperand(2).getReg();
7215       MIRBuilder.buildMergeLikeInstr(DstReg, SrcRegs);
7216     } else {
7217       MIRBuilder.buildCopy(DstReg, SrcRegs[IdxVal]);
7218     }
7219 
7220     MI.eraseFromParent();
7221     return Legalized;
7222   }
7223 
7224   if (!EltTy.isByteSized()) { // Not implemented.
7225     LLVM_DEBUG(dbgs() << "Can't handle non-byte element vectors yet\n");
7226     return UnableToLegalize;
7227   }
7228 
7229   unsigned EltBytes = EltTy.getSizeInBytes();
7230   Align VecAlign = getStackTemporaryAlignment(VecTy);
7231   Align EltAlign;
7232 
7233   MachinePointerInfo PtrInfo;
7234   auto StackTemp = createStackTemporary(
7235       TypeSize::getFixed(VecTy.getSizeInBytes()), VecAlign, PtrInfo);
7236   MIRBuilder.buildStore(SrcVec, StackTemp, PtrInfo, VecAlign);
7237 
7238   // Get the pointer to the element, and be sure not to hit undefined behavior
7239   // if the index is out of bounds.
7240   Register EltPtr = getVectorElementPointer(StackTemp.getReg(0), VecTy, Idx);
7241 
7242   if (mi_match(Idx, MRI, m_ICst(IdxVal))) {
7243     int64_t Offset = IdxVal * EltBytes;
7244     PtrInfo = PtrInfo.getWithOffset(Offset);
7245     EltAlign = commonAlignment(VecAlign, Offset);
7246   } else {
7247     // We lose information with a variable offset.
7248     EltAlign = getStackTemporaryAlignment(EltTy);
7249     PtrInfo = MachinePointerInfo(MRI.getType(EltPtr).getAddressSpace());
7250   }
7251 
7252   if (InsertVal) {
7253     // Write the inserted element
7254     MIRBuilder.buildStore(InsertVal, EltPtr, PtrInfo, EltAlign);
7255 
7256     // Reload the whole vector.
7257     MIRBuilder.buildLoad(DstReg, StackTemp, PtrInfo, VecAlign);
7258   } else {
7259     MIRBuilder.buildLoad(DstReg, EltPtr, PtrInfo, EltAlign);
7260   }
7261 
7262   MI.eraseFromParent();
7263   return Legalized;
7264 }
7265 
7266 LegalizerHelper::LegalizeResult
7267 LegalizerHelper::lowerShuffleVector(MachineInstr &MI) {
7268   auto [DstReg, DstTy, Src0Reg, Src0Ty, Src1Reg, Src1Ty] =
7269       MI.getFirst3RegLLTs();
7270   LLT IdxTy = LLT::scalar(32);
7271 
7272   ArrayRef<int> Mask = MI.getOperand(3).getShuffleMask();
7273   Register Undef;
7274   SmallVector<Register, 32> BuildVec;
7275   LLT EltTy = DstTy.getScalarType();
7276 
7277   for (int Idx : Mask) {
7278     if (Idx < 0) {
7279       if (!Undef.isValid())
7280         Undef = MIRBuilder.buildUndef(EltTy).getReg(0);
7281       BuildVec.push_back(Undef);
7282       continue;
7283     }
7284 
7285     if (Src0Ty.isScalar()) {
7286       BuildVec.push_back(Idx == 0 ? Src0Reg : Src1Reg);
7287     } else {
7288       int NumElts = Src0Ty.getNumElements();
7289       Register SrcVec = Idx < NumElts ? Src0Reg : Src1Reg;
7290       int ExtractIdx = Idx < NumElts ? Idx : Idx - NumElts;
7291       auto IdxK = MIRBuilder.buildConstant(IdxTy, ExtractIdx);
7292       auto Extract = MIRBuilder.buildExtractVectorElement(EltTy, SrcVec, IdxK);
7293       BuildVec.push_back(Extract.getReg(0));
7294     }
7295   }
7296 
7297   if (DstTy.isScalar())
7298     MIRBuilder.buildCopy(DstReg, BuildVec[0]);
7299   else
7300     MIRBuilder.buildBuildVector(DstReg, BuildVec);
7301   MI.eraseFromParent();
7302   return Legalized;
7303 }
7304 
7305 Register LegalizerHelper::getDynStackAllocTargetPtr(Register SPReg,
7306                                                     Register AllocSize,
7307                                                     Align Alignment,
7308                                                     LLT PtrTy) {
7309   LLT IntPtrTy = LLT::scalar(PtrTy.getSizeInBits());
7310 
7311   auto SPTmp = MIRBuilder.buildCopy(PtrTy, SPReg);
7312   SPTmp = MIRBuilder.buildCast(IntPtrTy, SPTmp);
7313 
7314   // Subtract the final alloc from the SP. We use G_PTRTOINT here so we don't
7315   // have to generate an extra instruction to negate the alloc and then use
7316   // G_PTR_ADD to add the negative offset.
7317   auto Alloc = MIRBuilder.buildSub(IntPtrTy, SPTmp, AllocSize);
7318   if (Alignment > Align(1)) {
7319     APInt AlignMask(IntPtrTy.getSizeInBits(), Alignment.value(), true);
7320     AlignMask.negate();
7321     auto AlignCst = MIRBuilder.buildConstant(IntPtrTy, AlignMask);
7322     Alloc = MIRBuilder.buildAnd(IntPtrTy, Alloc, AlignCst);
7323   }
7324 
7325   return MIRBuilder.buildCast(PtrTy, Alloc).getReg(0);
7326 }
7327 
7328 LegalizerHelper::LegalizeResult
7329 LegalizerHelper::lowerDynStackAlloc(MachineInstr &MI) {
7330   const auto &MF = *MI.getMF();
7331   const auto &TFI = *MF.getSubtarget().getFrameLowering();
7332   if (TFI.getStackGrowthDirection() == TargetFrameLowering::StackGrowsUp)
7333     return UnableToLegalize;
7334 
7335   Register Dst = MI.getOperand(0).getReg();
7336   Register AllocSize = MI.getOperand(1).getReg();
7337   Align Alignment = assumeAligned(MI.getOperand(2).getImm());
7338 
7339   LLT PtrTy = MRI.getType(Dst);
7340   Register SPReg = TLI.getStackPointerRegisterToSaveRestore();
7341   Register SPTmp =
7342       getDynStackAllocTargetPtr(SPReg, AllocSize, Alignment, PtrTy);
7343 
7344   MIRBuilder.buildCopy(SPReg, SPTmp);
7345   MIRBuilder.buildCopy(Dst, SPTmp);
7346 
7347   MI.eraseFromParent();
7348   return Legalized;
7349 }
7350 
7351 LegalizerHelper::LegalizeResult
7352 LegalizerHelper::lowerStackSave(MachineInstr &MI) {
7353   Register StackPtr = TLI.getStackPointerRegisterToSaveRestore();
7354   if (!StackPtr)
7355     return UnableToLegalize;
7356 
7357   MIRBuilder.buildCopy(MI.getOperand(0), StackPtr);
7358   MI.eraseFromParent();
7359   return Legalized;
7360 }
7361 
7362 LegalizerHelper::LegalizeResult
7363 LegalizerHelper::lowerStackRestore(MachineInstr &MI) {
7364   Register StackPtr = TLI.getStackPointerRegisterToSaveRestore();
7365   if (!StackPtr)
7366     return UnableToLegalize;
7367 
7368   MIRBuilder.buildCopy(StackPtr, MI.getOperand(0));
7369   MI.eraseFromParent();
7370   return Legalized;
7371 }
7372 
7373 LegalizerHelper::LegalizeResult
7374 LegalizerHelper::lowerExtract(MachineInstr &MI) {
7375   auto [DstReg, DstTy, SrcReg, SrcTy] = MI.getFirst2RegLLTs();
7376   unsigned Offset = MI.getOperand(2).getImm();
7377 
7378   // Extract sub-vector or one element
7379   if (SrcTy.isVector()) {
7380     unsigned SrcEltSize = SrcTy.getElementType().getSizeInBits();
7381     unsigned DstSize = DstTy.getSizeInBits();
7382 
7383     if ((Offset % SrcEltSize == 0) && (DstSize % SrcEltSize == 0) &&
7384         (Offset + DstSize <= SrcTy.getSizeInBits())) {
7385       // Unmerge and allow access to each Src element for the artifact combiner.
7386       auto Unmerge = MIRBuilder.buildUnmerge(SrcTy.getElementType(), SrcReg);
7387 
7388       // Take element(s) we need to extract and copy it (merge them).
7389       SmallVector<Register, 8> SubVectorElts;
7390       for (unsigned Idx = Offset / SrcEltSize;
7391            Idx < (Offset + DstSize) / SrcEltSize; ++Idx) {
7392         SubVectorElts.push_back(Unmerge.getReg(Idx));
7393       }
7394       if (SubVectorElts.size() == 1)
7395         MIRBuilder.buildCopy(DstReg, SubVectorElts[0]);
7396       else
7397         MIRBuilder.buildMergeLikeInstr(DstReg, SubVectorElts);
7398 
7399       MI.eraseFromParent();
7400       return Legalized;
7401     }
7402   }
7403 
7404   if (DstTy.isScalar() &&
7405       (SrcTy.isScalar() ||
7406        (SrcTy.isVector() && DstTy == SrcTy.getElementType()))) {
7407     LLT SrcIntTy = SrcTy;
7408     if (!SrcTy.isScalar()) {
7409       SrcIntTy = LLT::scalar(SrcTy.getSizeInBits());
7410       SrcReg = MIRBuilder.buildBitcast(SrcIntTy, SrcReg).getReg(0);
7411     }
7412 
7413     if (Offset == 0)
7414       MIRBuilder.buildTrunc(DstReg, SrcReg);
7415     else {
7416       auto ShiftAmt = MIRBuilder.buildConstant(SrcIntTy, Offset);
7417       auto Shr = MIRBuilder.buildLShr(SrcIntTy, SrcReg, ShiftAmt);
7418       MIRBuilder.buildTrunc(DstReg, Shr);
7419     }
7420 
7421     MI.eraseFromParent();
7422     return Legalized;
7423   }
7424 
7425   return UnableToLegalize;
7426 }
7427 
7428 LegalizerHelper::LegalizeResult LegalizerHelper::lowerInsert(MachineInstr &MI) {
7429   auto [Dst, Src, InsertSrc] = MI.getFirst3Regs();
7430   uint64_t Offset = MI.getOperand(3).getImm();
7431 
7432   LLT DstTy = MRI.getType(Src);
7433   LLT InsertTy = MRI.getType(InsertSrc);
7434 
7435   // Insert sub-vector or one element
7436   if (DstTy.isVector() && !InsertTy.isPointer()) {
7437     LLT EltTy = DstTy.getElementType();
7438     unsigned EltSize = EltTy.getSizeInBits();
7439     unsigned InsertSize = InsertTy.getSizeInBits();
7440 
7441     if ((Offset % EltSize == 0) && (InsertSize % EltSize == 0) &&
7442         (Offset + InsertSize <= DstTy.getSizeInBits())) {
7443       auto UnmergeSrc = MIRBuilder.buildUnmerge(EltTy, Src);
7444       SmallVector<Register, 8> DstElts;
7445       unsigned Idx = 0;
7446       // Elements from Src before insert start Offset
7447       for (; Idx < Offset / EltSize; ++Idx) {
7448         DstElts.push_back(UnmergeSrc.getReg(Idx));
7449       }
7450 
7451       // Replace elements in Src with elements from InsertSrc
7452       if (InsertTy.getSizeInBits() > EltSize) {
7453         auto UnmergeInsertSrc = MIRBuilder.buildUnmerge(EltTy, InsertSrc);
7454         for (unsigned i = 0; Idx < (Offset + InsertSize) / EltSize;
7455              ++Idx, ++i) {
7456           DstElts.push_back(UnmergeInsertSrc.getReg(i));
7457         }
7458       } else {
7459         DstElts.push_back(InsertSrc);
7460         ++Idx;
7461       }
7462 
7463       // Remaining elements from Src after insert
7464       for (; Idx < DstTy.getNumElements(); ++Idx) {
7465         DstElts.push_back(UnmergeSrc.getReg(Idx));
7466       }
7467 
7468       MIRBuilder.buildMergeLikeInstr(Dst, DstElts);
7469       MI.eraseFromParent();
7470       return Legalized;
7471     }
7472   }
7473 
7474   if (InsertTy.isVector() ||
7475       (DstTy.isVector() && DstTy.getElementType() != InsertTy))
7476     return UnableToLegalize;
7477 
7478   const DataLayout &DL = MIRBuilder.getDataLayout();
7479   if ((DstTy.isPointer() &&
7480        DL.isNonIntegralAddressSpace(DstTy.getAddressSpace())) ||
7481       (InsertTy.isPointer() &&
7482        DL.isNonIntegralAddressSpace(InsertTy.getAddressSpace()))) {
7483     LLVM_DEBUG(dbgs() << "Not casting non-integral address space integer\n");
7484     return UnableToLegalize;
7485   }
7486 
7487   LLT IntDstTy = DstTy;
7488 
7489   if (!DstTy.isScalar()) {
7490     IntDstTy = LLT::scalar(DstTy.getSizeInBits());
7491     Src = MIRBuilder.buildCast(IntDstTy, Src).getReg(0);
7492   }
7493 
7494   if (!InsertTy.isScalar()) {
7495     const LLT IntInsertTy = LLT::scalar(InsertTy.getSizeInBits());
7496     InsertSrc = MIRBuilder.buildPtrToInt(IntInsertTy, InsertSrc).getReg(0);
7497   }
7498 
7499   Register ExtInsSrc = MIRBuilder.buildZExt(IntDstTy, InsertSrc).getReg(0);
7500   if (Offset != 0) {
7501     auto ShiftAmt = MIRBuilder.buildConstant(IntDstTy, Offset);
7502     ExtInsSrc = MIRBuilder.buildShl(IntDstTy, ExtInsSrc, ShiftAmt).getReg(0);
7503   }
7504 
7505   APInt MaskVal = APInt::getBitsSetWithWrap(
7506       DstTy.getSizeInBits(), Offset + InsertTy.getSizeInBits(), Offset);
7507 
7508   auto Mask = MIRBuilder.buildConstant(IntDstTy, MaskVal);
7509   auto MaskedSrc = MIRBuilder.buildAnd(IntDstTy, Src, Mask);
7510   auto Or = MIRBuilder.buildOr(IntDstTy, MaskedSrc, ExtInsSrc);
7511 
7512   MIRBuilder.buildCast(Dst, Or);
7513   MI.eraseFromParent();
7514   return Legalized;
7515 }
7516 
7517 LegalizerHelper::LegalizeResult
7518 LegalizerHelper::lowerSADDO_SSUBO(MachineInstr &MI) {
7519   auto [Dst0, Dst0Ty, Dst1, Dst1Ty, LHS, LHSTy, RHS, RHSTy] =
7520       MI.getFirst4RegLLTs();
7521   const bool IsAdd = MI.getOpcode() == TargetOpcode::G_SADDO;
7522 
7523   LLT Ty = Dst0Ty;
7524   LLT BoolTy = Dst1Ty;
7525 
7526   if (IsAdd)
7527     MIRBuilder.buildAdd(Dst0, LHS, RHS);
7528   else
7529     MIRBuilder.buildSub(Dst0, LHS, RHS);
7530 
7531   // TODO: If SADDSAT/SSUBSAT is legal, compare results to detect overflow.
7532 
7533   auto Zero = MIRBuilder.buildConstant(Ty, 0);
7534 
7535   // For an addition, the result should be less than one of the operands (LHS)
7536   // if and only if the other operand (RHS) is negative, otherwise there will
7537   // be overflow.
7538   // For a subtraction, the result should be less than one of the operands
7539   // (LHS) if and only if the other operand (RHS) is (non-zero) positive,
7540   // otherwise there will be overflow.
7541   auto ResultLowerThanLHS =
7542       MIRBuilder.buildICmp(CmpInst::ICMP_SLT, BoolTy, Dst0, LHS);
7543   auto ConditionRHS = MIRBuilder.buildICmp(
7544       IsAdd ? CmpInst::ICMP_SLT : CmpInst::ICMP_SGT, BoolTy, RHS, Zero);
7545 
7546   MIRBuilder.buildXor(Dst1, ConditionRHS, ResultLowerThanLHS);
7547   MI.eraseFromParent();
7548   return Legalized;
7549 }
7550 
7551 LegalizerHelper::LegalizeResult
7552 LegalizerHelper::lowerAddSubSatToMinMax(MachineInstr &MI) {
7553   auto [Res, LHS, RHS] = MI.getFirst3Regs();
7554   LLT Ty = MRI.getType(Res);
7555   bool IsSigned;
7556   bool IsAdd;
7557   unsigned BaseOp;
7558   switch (MI.getOpcode()) {
7559   default:
7560     llvm_unreachable("unexpected addsat/subsat opcode");
7561   case TargetOpcode::G_UADDSAT:
7562     IsSigned = false;
7563     IsAdd = true;
7564     BaseOp = TargetOpcode::G_ADD;
7565     break;
7566   case TargetOpcode::G_SADDSAT:
7567     IsSigned = true;
7568     IsAdd = true;
7569     BaseOp = TargetOpcode::G_ADD;
7570     break;
7571   case TargetOpcode::G_USUBSAT:
7572     IsSigned = false;
7573     IsAdd = false;
7574     BaseOp = TargetOpcode::G_SUB;
7575     break;
7576   case TargetOpcode::G_SSUBSAT:
7577     IsSigned = true;
7578     IsAdd = false;
7579     BaseOp = TargetOpcode::G_SUB;
7580     break;
7581   }
7582 
7583   if (IsSigned) {
7584     // sadd.sat(a, b) ->
7585     //   hi = 0x7fffffff - smax(a, 0)
7586     //   lo = 0x80000000 - smin(a, 0)
7587     //   a + smin(smax(lo, b), hi)
7588     // ssub.sat(a, b) ->
7589     //   lo = smax(a, -1) - 0x7fffffff
7590     //   hi = smin(a, -1) - 0x80000000
7591     //   a - smin(smax(lo, b), hi)
7592     // TODO: AMDGPU can use a "median of 3" instruction here:
7593     //   a +/- med3(lo, b, hi)
7594     uint64_t NumBits = Ty.getScalarSizeInBits();
7595     auto MaxVal =
7596         MIRBuilder.buildConstant(Ty, APInt::getSignedMaxValue(NumBits));
7597     auto MinVal =
7598         MIRBuilder.buildConstant(Ty, APInt::getSignedMinValue(NumBits));
7599     MachineInstrBuilder Hi, Lo;
7600     if (IsAdd) {
7601       auto Zero = MIRBuilder.buildConstant(Ty, 0);
7602       Hi = MIRBuilder.buildSub(Ty, MaxVal, MIRBuilder.buildSMax(Ty, LHS, Zero));
7603       Lo = MIRBuilder.buildSub(Ty, MinVal, MIRBuilder.buildSMin(Ty, LHS, Zero));
7604     } else {
7605       auto NegOne = MIRBuilder.buildConstant(Ty, -1);
7606       Lo = MIRBuilder.buildSub(Ty, MIRBuilder.buildSMax(Ty, LHS, NegOne),
7607                                MaxVal);
7608       Hi = MIRBuilder.buildSub(Ty, MIRBuilder.buildSMin(Ty, LHS, NegOne),
7609                                MinVal);
7610     }
7611     auto RHSClamped =
7612         MIRBuilder.buildSMin(Ty, MIRBuilder.buildSMax(Ty, Lo, RHS), Hi);
7613     MIRBuilder.buildInstr(BaseOp, {Res}, {LHS, RHSClamped});
7614   } else {
7615     // uadd.sat(a, b) -> a + umin(~a, b)
7616     // usub.sat(a, b) -> a - umin(a, b)
7617     Register Not = IsAdd ? MIRBuilder.buildNot(Ty, LHS).getReg(0) : LHS;
7618     auto Min = MIRBuilder.buildUMin(Ty, Not, RHS);
7619     MIRBuilder.buildInstr(BaseOp, {Res}, {LHS, Min});
7620   }
7621 
7622   MI.eraseFromParent();
7623   return Legalized;
7624 }
7625 
7626 LegalizerHelper::LegalizeResult
7627 LegalizerHelper::lowerAddSubSatToAddoSubo(MachineInstr &MI) {
7628   auto [Res, LHS, RHS] = MI.getFirst3Regs();
7629   LLT Ty = MRI.getType(Res);
7630   LLT BoolTy = Ty.changeElementSize(1);
7631   bool IsSigned;
7632   bool IsAdd;
7633   unsigned OverflowOp;
7634   switch (MI.getOpcode()) {
7635   default:
7636     llvm_unreachable("unexpected addsat/subsat opcode");
7637   case TargetOpcode::G_UADDSAT:
7638     IsSigned = false;
7639     IsAdd = true;
7640     OverflowOp = TargetOpcode::G_UADDO;
7641     break;
7642   case TargetOpcode::G_SADDSAT:
7643     IsSigned = true;
7644     IsAdd = true;
7645     OverflowOp = TargetOpcode::G_SADDO;
7646     break;
7647   case TargetOpcode::G_USUBSAT:
7648     IsSigned = false;
7649     IsAdd = false;
7650     OverflowOp = TargetOpcode::G_USUBO;
7651     break;
7652   case TargetOpcode::G_SSUBSAT:
7653     IsSigned = true;
7654     IsAdd = false;
7655     OverflowOp = TargetOpcode::G_SSUBO;
7656     break;
7657   }
7658 
7659   auto OverflowRes =
7660       MIRBuilder.buildInstr(OverflowOp, {Ty, BoolTy}, {LHS, RHS});
7661   Register Tmp = OverflowRes.getReg(0);
7662   Register Ov = OverflowRes.getReg(1);
7663   MachineInstrBuilder Clamp;
7664   if (IsSigned) {
7665     // sadd.sat(a, b) ->
7666     //   {tmp, ov} = saddo(a, b)
7667     //   ov ? (tmp >>s 31) + 0x80000000 : r
7668     // ssub.sat(a, b) ->
7669     //   {tmp, ov} = ssubo(a, b)
7670     //   ov ? (tmp >>s 31) + 0x80000000 : r
7671     uint64_t NumBits = Ty.getScalarSizeInBits();
7672     auto ShiftAmount = MIRBuilder.buildConstant(Ty, NumBits - 1);
7673     auto Sign = MIRBuilder.buildAShr(Ty, Tmp, ShiftAmount);
7674     auto MinVal =
7675         MIRBuilder.buildConstant(Ty, APInt::getSignedMinValue(NumBits));
7676     Clamp = MIRBuilder.buildAdd(Ty, Sign, MinVal);
7677   } else {
7678     // uadd.sat(a, b) ->
7679     //   {tmp, ov} = uaddo(a, b)
7680     //   ov ? 0xffffffff : tmp
7681     // usub.sat(a, b) ->
7682     //   {tmp, ov} = usubo(a, b)
7683     //   ov ? 0 : tmp
7684     Clamp = MIRBuilder.buildConstant(Ty, IsAdd ? -1 : 0);
7685   }
7686   MIRBuilder.buildSelect(Res, Ov, Clamp, Tmp);
7687 
7688   MI.eraseFromParent();
7689   return Legalized;
7690 }
7691 
7692 LegalizerHelper::LegalizeResult
7693 LegalizerHelper::lowerShlSat(MachineInstr &MI) {
7694   assert((MI.getOpcode() == TargetOpcode::G_SSHLSAT ||
7695           MI.getOpcode() == TargetOpcode::G_USHLSAT) &&
7696          "Expected shlsat opcode!");
7697   bool IsSigned = MI.getOpcode() == TargetOpcode::G_SSHLSAT;
7698   auto [Res, LHS, RHS] = MI.getFirst3Regs();
7699   LLT Ty = MRI.getType(Res);
7700   LLT BoolTy = Ty.changeElementSize(1);
7701 
7702   unsigned BW = Ty.getScalarSizeInBits();
7703   auto Result = MIRBuilder.buildShl(Ty, LHS, RHS);
7704   auto Orig = IsSigned ? MIRBuilder.buildAShr(Ty, Result, RHS)
7705                        : MIRBuilder.buildLShr(Ty, Result, RHS);
7706 
7707   MachineInstrBuilder SatVal;
7708   if (IsSigned) {
7709     auto SatMin = MIRBuilder.buildConstant(Ty, APInt::getSignedMinValue(BW));
7710     auto SatMax = MIRBuilder.buildConstant(Ty, APInt::getSignedMaxValue(BW));
7711     auto Cmp = MIRBuilder.buildICmp(CmpInst::ICMP_SLT, BoolTy, LHS,
7712                                     MIRBuilder.buildConstant(Ty, 0));
7713     SatVal = MIRBuilder.buildSelect(Ty, Cmp, SatMin, SatMax);
7714   } else {
7715     SatVal = MIRBuilder.buildConstant(Ty, APInt::getMaxValue(BW));
7716   }
7717   auto Ov = MIRBuilder.buildICmp(CmpInst::ICMP_NE, BoolTy, LHS, Orig);
7718   MIRBuilder.buildSelect(Res, Ov, SatVal, Result);
7719 
7720   MI.eraseFromParent();
7721   return Legalized;
7722 }
7723 
7724 LegalizerHelper::LegalizeResult LegalizerHelper::lowerBswap(MachineInstr &MI) {
7725   auto [Dst, Src] = MI.getFirst2Regs();
7726   const LLT Ty = MRI.getType(Src);
7727   unsigned SizeInBytes = (Ty.getScalarSizeInBits() + 7) / 8;
7728   unsigned BaseShiftAmt = (SizeInBytes - 1) * 8;
7729 
7730   // Swap most and least significant byte, set remaining bytes in Res to zero.
7731   auto ShiftAmt = MIRBuilder.buildConstant(Ty, BaseShiftAmt);
7732   auto LSByteShiftedLeft = MIRBuilder.buildShl(Ty, Src, ShiftAmt);
7733   auto MSByteShiftedRight = MIRBuilder.buildLShr(Ty, Src, ShiftAmt);
7734   auto Res = MIRBuilder.buildOr(Ty, MSByteShiftedRight, LSByteShiftedLeft);
7735 
7736   // Set i-th high/low byte in Res to i-th low/high byte from Src.
7737   for (unsigned i = 1; i < SizeInBytes / 2; ++i) {
7738     // AND with Mask leaves byte i unchanged and sets remaining bytes to 0.
7739     APInt APMask(SizeInBytes * 8, 0xFF << (i * 8));
7740     auto Mask = MIRBuilder.buildConstant(Ty, APMask);
7741     auto ShiftAmt = MIRBuilder.buildConstant(Ty, BaseShiftAmt - 16 * i);
7742     // Low byte shifted left to place of high byte: (Src & Mask) << ShiftAmt.
7743     auto LoByte = MIRBuilder.buildAnd(Ty, Src, Mask);
7744     auto LoShiftedLeft = MIRBuilder.buildShl(Ty, LoByte, ShiftAmt);
7745     Res = MIRBuilder.buildOr(Ty, Res, LoShiftedLeft);
7746     // High byte shifted right to place of low byte: (Src >> ShiftAmt) & Mask.
7747     auto SrcShiftedRight = MIRBuilder.buildLShr(Ty, Src, ShiftAmt);
7748     auto HiShiftedRight = MIRBuilder.buildAnd(Ty, SrcShiftedRight, Mask);
7749     Res = MIRBuilder.buildOr(Ty, Res, HiShiftedRight);
7750   }
7751   Res.getInstr()->getOperand(0).setReg(Dst);
7752 
7753   MI.eraseFromParent();
7754   return Legalized;
7755 }
7756 
7757 //{ (Src & Mask) >> N } | { (Src << N) & Mask }
7758 static MachineInstrBuilder SwapN(unsigned N, DstOp Dst, MachineIRBuilder &B,
7759                                  MachineInstrBuilder Src, APInt Mask) {
7760   const LLT Ty = Dst.getLLTTy(*B.getMRI());
7761   MachineInstrBuilder C_N = B.buildConstant(Ty, N);
7762   MachineInstrBuilder MaskLoNTo0 = B.buildConstant(Ty, Mask);
7763   auto LHS = B.buildLShr(Ty, B.buildAnd(Ty, Src, MaskLoNTo0), C_N);
7764   auto RHS = B.buildAnd(Ty, B.buildShl(Ty, Src, C_N), MaskLoNTo0);
7765   return B.buildOr(Dst, LHS, RHS);
7766 }
7767 
7768 LegalizerHelper::LegalizeResult
7769 LegalizerHelper::lowerBitreverse(MachineInstr &MI) {
7770   auto [Dst, Src] = MI.getFirst2Regs();
7771   const LLT Ty = MRI.getType(Src);
7772   unsigned Size = Ty.getSizeInBits();
7773 
7774   MachineInstrBuilder BSWAP =
7775       MIRBuilder.buildInstr(TargetOpcode::G_BSWAP, {Ty}, {Src});
7776 
7777   // swap high and low 4 bits in 8 bit blocks 7654|3210 -> 3210|7654
7778   //    [(val & 0xF0F0F0F0) >> 4] | [(val & 0x0F0F0F0F) << 4]
7779   // -> [(val & 0xF0F0F0F0) >> 4] | [(val << 4) & 0xF0F0F0F0]
7780   MachineInstrBuilder Swap4 =
7781       SwapN(4, Ty, MIRBuilder, BSWAP, APInt::getSplat(Size, APInt(8, 0xF0)));
7782 
7783   // swap high and low 2 bits in 4 bit blocks 32|10 76|54 -> 10|32 54|76
7784   //    [(val & 0xCCCCCCCC) >> 2] & [(val & 0x33333333) << 2]
7785   // -> [(val & 0xCCCCCCCC) >> 2] & [(val << 2) & 0xCCCCCCCC]
7786   MachineInstrBuilder Swap2 =
7787       SwapN(2, Ty, MIRBuilder, Swap4, APInt::getSplat(Size, APInt(8, 0xCC)));
7788 
7789   // swap high and low 1 bit in 2 bit blocks 1|0 3|2 5|4 7|6 -> 0|1 2|3 4|5 6|7
7790   //    [(val & 0xAAAAAAAA) >> 1] & [(val & 0x55555555) << 1]
7791   // -> [(val & 0xAAAAAAAA) >> 1] & [(val << 1) & 0xAAAAAAAA]
7792   SwapN(1, Dst, MIRBuilder, Swap2, APInt::getSplat(Size, APInt(8, 0xAA)));
7793 
7794   MI.eraseFromParent();
7795   return Legalized;
7796 }
7797 
7798 LegalizerHelper::LegalizeResult
7799 LegalizerHelper::lowerReadWriteRegister(MachineInstr &MI) {
7800   MachineFunction &MF = MIRBuilder.getMF();
7801 
7802   bool IsRead = MI.getOpcode() == TargetOpcode::G_READ_REGISTER;
7803   int NameOpIdx = IsRead ? 1 : 0;
7804   int ValRegIndex = IsRead ? 0 : 1;
7805 
7806   Register ValReg = MI.getOperand(ValRegIndex).getReg();
7807   const LLT Ty = MRI.getType(ValReg);
7808   const MDString *RegStr = cast<MDString>(
7809     cast<MDNode>(MI.getOperand(NameOpIdx).getMetadata())->getOperand(0));
7810 
7811   Register PhysReg = TLI.getRegisterByName(RegStr->getString().data(), Ty, MF);
7812   if (!PhysReg.isValid())
7813     return UnableToLegalize;
7814 
7815   if (IsRead)
7816     MIRBuilder.buildCopy(ValReg, PhysReg);
7817   else
7818     MIRBuilder.buildCopy(PhysReg, ValReg);
7819 
7820   MI.eraseFromParent();
7821   return Legalized;
7822 }
7823 
7824 LegalizerHelper::LegalizeResult
7825 LegalizerHelper::lowerSMULH_UMULH(MachineInstr &MI) {
7826   bool IsSigned = MI.getOpcode() == TargetOpcode::G_SMULH;
7827   unsigned ExtOp = IsSigned ? TargetOpcode::G_SEXT : TargetOpcode::G_ZEXT;
7828   Register Result = MI.getOperand(0).getReg();
7829   LLT OrigTy = MRI.getType(Result);
7830   auto SizeInBits = OrigTy.getScalarSizeInBits();
7831   LLT WideTy = OrigTy.changeElementSize(SizeInBits * 2);
7832 
7833   auto LHS = MIRBuilder.buildInstr(ExtOp, {WideTy}, {MI.getOperand(1)});
7834   auto RHS = MIRBuilder.buildInstr(ExtOp, {WideTy}, {MI.getOperand(2)});
7835   auto Mul = MIRBuilder.buildMul(WideTy, LHS, RHS);
7836   unsigned ShiftOp = IsSigned ? TargetOpcode::G_ASHR : TargetOpcode::G_LSHR;
7837 
7838   auto ShiftAmt = MIRBuilder.buildConstant(WideTy, SizeInBits);
7839   auto Shifted = MIRBuilder.buildInstr(ShiftOp, {WideTy}, {Mul, ShiftAmt});
7840   MIRBuilder.buildTrunc(Result, Shifted);
7841 
7842   MI.eraseFromParent();
7843   return Legalized;
7844 }
7845 
7846 LegalizerHelper::LegalizeResult
7847 LegalizerHelper::lowerISFPCLASS(MachineInstr &MI) {
7848   auto [DstReg, DstTy, SrcReg, SrcTy] = MI.getFirst2RegLLTs();
7849   FPClassTest Mask = static_cast<FPClassTest>(MI.getOperand(2).getImm());
7850 
7851   if (Mask == fcNone) {
7852     MIRBuilder.buildConstant(DstReg, 0);
7853     MI.eraseFromParent();
7854     return Legalized;
7855   }
7856   if (Mask == fcAllFlags) {
7857     MIRBuilder.buildConstant(DstReg, 1);
7858     MI.eraseFromParent();
7859     return Legalized;
7860   }
7861 
7862   // TODO: Try inverting the test with getInvertedFPClassTest like the DAG
7863   // version
7864 
7865   unsigned BitSize = SrcTy.getScalarSizeInBits();
7866   const fltSemantics &Semantics = getFltSemanticForLLT(SrcTy.getScalarType());
7867 
7868   LLT IntTy = LLT::scalar(BitSize);
7869   if (SrcTy.isVector())
7870     IntTy = LLT::vector(SrcTy.getElementCount(), IntTy);
7871   auto AsInt = MIRBuilder.buildCopy(IntTy, SrcReg);
7872 
7873   // Various masks.
7874   APInt SignBit = APInt::getSignMask(BitSize);
7875   APInt ValueMask = APInt::getSignedMaxValue(BitSize);     // All bits but sign.
7876   APInt Inf = APFloat::getInf(Semantics).bitcastToAPInt(); // Exp and int bit.
7877   APInt ExpMask = Inf;
7878   APInt AllOneMantissa = APFloat::getLargest(Semantics).bitcastToAPInt() & ~Inf;
7879   APInt QNaNBitMask =
7880       APInt::getOneBitSet(BitSize, AllOneMantissa.getActiveBits() - 1);
7881   APInt InvertionMask = APInt::getAllOnes(DstTy.getScalarSizeInBits());
7882 
7883   auto SignBitC = MIRBuilder.buildConstant(IntTy, SignBit);
7884   auto ValueMaskC = MIRBuilder.buildConstant(IntTy, ValueMask);
7885   auto InfC = MIRBuilder.buildConstant(IntTy, Inf);
7886   auto ExpMaskC = MIRBuilder.buildConstant(IntTy, ExpMask);
7887   auto ZeroC = MIRBuilder.buildConstant(IntTy, 0);
7888 
7889   auto Abs = MIRBuilder.buildAnd(IntTy, AsInt, ValueMaskC);
7890   auto Sign =
7891       MIRBuilder.buildICmp(CmpInst::Predicate::ICMP_NE, DstTy, AsInt, Abs);
7892 
7893   auto Res = MIRBuilder.buildConstant(DstTy, 0);
7894   // Clang doesn't support capture of structured bindings:
7895   LLT DstTyCopy = DstTy;
7896   const auto appendToRes = [&](MachineInstrBuilder ToAppend) {
7897     Res = MIRBuilder.buildOr(DstTyCopy, Res, ToAppend);
7898   };
7899 
7900   // Tests that involve more than one class should be processed first.
7901   if ((Mask & fcFinite) == fcFinite) {
7902     // finite(V) ==> abs(V) u< exp_mask
7903     appendToRes(MIRBuilder.buildICmp(CmpInst::Predicate::ICMP_ULT, DstTy, Abs,
7904                                      ExpMaskC));
7905     Mask &= ~fcFinite;
7906   } else if ((Mask & fcFinite) == fcPosFinite) {
7907     // finite(V) && V > 0 ==> V u< exp_mask
7908     appendToRes(MIRBuilder.buildICmp(CmpInst::Predicate::ICMP_ULT, DstTy, AsInt,
7909                                      ExpMaskC));
7910     Mask &= ~fcPosFinite;
7911   } else if ((Mask & fcFinite) == fcNegFinite) {
7912     // finite(V) && V < 0 ==> abs(V) u< exp_mask && signbit == 1
7913     auto Cmp = MIRBuilder.buildICmp(CmpInst::Predicate::ICMP_ULT, DstTy, Abs,
7914                                     ExpMaskC);
7915     auto And = MIRBuilder.buildAnd(DstTy, Cmp, Sign);
7916     appendToRes(And);
7917     Mask &= ~fcNegFinite;
7918   }
7919 
7920   if (FPClassTest PartialCheck = Mask & (fcZero | fcSubnormal)) {
7921     // fcZero | fcSubnormal => test all exponent bits are 0
7922     // TODO: Handle sign bit specific cases
7923     // TODO: Handle inverted case
7924     if (PartialCheck == (fcZero | fcSubnormal)) {
7925       auto ExpBits = MIRBuilder.buildAnd(IntTy, AsInt, ExpMaskC);
7926       appendToRes(MIRBuilder.buildICmp(CmpInst::Predicate::ICMP_EQ, DstTy,
7927                                        ExpBits, ZeroC));
7928       Mask &= ~PartialCheck;
7929     }
7930   }
7931 
7932   // Check for individual classes.
7933   if (FPClassTest PartialCheck = Mask & fcZero) {
7934     if (PartialCheck == fcPosZero)
7935       appendToRes(MIRBuilder.buildICmp(CmpInst::Predicate::ICMP_EQ, DstTy,
7936                                        AsInt, ZeroC));
7937     else if (PartialCheck == fcZero)
7938       appendToRes(
7939           MIRBuilder.buildICmp(CmpInst::Predicate::ICMP_EQ, DstTy, Abs, ZeroC));
7940     else // fcNegZero
7941       appendToRes(MIRBuilder.buildICmp(CmpInst::Predicate::ICMP_EQ, DstTy,
7942                                        AsInt, SignBitC));
7943   }
7944 
7945   if (FPClassTest PartialCheck = Mask & fcSubnormal) {
7946     // issubnormal(V) ==> unsigned(abs(V) - 1) u< (all mantissa bits set)
7947     // issubnormal(V) && V>0 ==> unsigned(V - 1) u< (all mantissa bits set)
7948     auto V = (PartialCheck == fcPosSubnormal) ? AsInt : Abs;
7949     auto OneC = MIRBuilder.buildConstant(IntTy, 1);
7950     auto VMinusOne = MIRBuilder.buildSub(IntTy, V, OneC);
7951     auto SubnormalRes =
7952         MIRBuilder.buildICmp(CmpInst::Predicate::ICMP_ULT, DstTy, VMinusOne,
7953                              MIRBuilder.buildConstant(IntTy, AllOneMantissa));
7954     if (PartialCheck == fcNegSubnormal)
7955       SubnormalRes = MIRBuilder.buildAnd(DstTy, SubnormalRes, Sign);
7956     appendToRes(SubnormalRes);
7957   }
7958 
7959   if (FPClassTest PartialCheck = Mask & fcInf) {
7960     if (PartialCheck == fcPosInf)
7961       appendToRes(MIRBuilder.buildICmp(CmpInst::Predicate::ICMP_EQ, DstTy,
7962                                        AsInt, InfC));
7963     else if (PartialCheck == fcInf)
7964       appendToRes(
7965           MIRBuilder.buildICmp(CmpInst::Predicate::ICMP_EQ, DstTy, Abs, InfC));
7966     else { // fcNegInf
7967       APInt NegInf = APFloat::getInf(Semantics, true).bitcastToAPInt();
7968       auto NegInfC = MIRBuilder.buildConstant(IntTy, NegInf);
7969       appendToRes(MIRBuilder.buildICmp(CmpInst::Predicate::ICMP_EQ, DstTy,
7970                                        AsInt, NegInfC));
7971     }
7972   }
7973 
7974   if (FPClassTest PartialCheck = Mask & fcNan) {
7975     auto InfWithQnanBitC = MIRBuilder.buildConstant(IntTy, Inf | QNaNBitMask);
7976     if (PartialCheck == fcNan) {
7977       // isnan(V) ==> abs(V) u> int(inf)
7978       appendToRes(
7979           MIRBuilder.buildICmp(CmpInst::Predicate::ICMP_UGT, DstTy, Abs, InfC));
7980     } else if (PartialCheck == fcQNan) {
7981       // isquiet(V) ==> abs(V) u>= (unsigned(Inf) | quiet_bit)
7982       appendToRes(MIRBuilder.buildICmp(CmpInst::Predicate::ICMP_UGE, DstTy, Abs,
7983                                        InfWithQnanBitC));
7984     } else { // fcSNan
7985       // issignaling(V) ==> abs(V) u> unsigned(Inf) &&
7986       //                    abs(V) u< (unsigned(Inf) | quiet_bit)
7987       auto IsNan =
7988           MIRBuilder.buildICmp(CmpInst::Predicate::ICMP_UGT, DstTy, Abs, InfC);
7989       auto IsNotQnan = MIRBuilder.buildICmp(CmpInst::Predicate::ICMP_ULT, DstTy,
7990                                             Abs, InfWithQnanBitC);
7991       appendToRes(MIRBuilder.buildAnd(DstTy, IsNan, IsNotQnan));
7992     }
7993   }
7994 
7995   if (FPClassTest PartialCheck = Mask & fcNormal) {
7996     // isnormal(V) ==> (0 u< exp u< max_exp) ==> (unsigned(exp-1) u<
7997     // (max_exp-1))
7998     APInt ExpLSB = ExpMask & ~(ExpMask.shl(1));
7999     auto ExpMinusOne = MIRBuilder.buildSub(
8000         IntTy, Abs, MIRBuilder.buildConstant(IntTy, ExpLSB));
8001     APInt MaxExpMinusOne = ExpMask - ExpLSB;
8002     auto NormalRes =
8003         MIRBuilder.buildICmp(CmpInst::Predicate::ICMP_ULT, DstTy, ExpMinusOne,
8004                              MIRBuilder.buildConstant(IntTy, MaxExpMinusOne));
8005     if (PartialCheck == fcNegNormal)
8006       NormalRes = MIRBuilder.buildAnd(DstTy, NormalRes, Sign);
8007     else if (PartialCheck == fcPosNormal) {
8008       auto PosSign = MIRBuilder.buildXor(
8009           DstTy, Sign, MIRBuilder.buildConstant(DstTy, InvertionMask));
8010       NormalRes = MIRBuilder.buildAnd(DstTy, NormalRes, PosSign);
8011     }
8012     appendToRes(NormalRes);
8013   }
8014 
8015   MIRBuilder.buildCopy(DstReg, Res);
8016   MI.eraseFromParent();
8017   return Legalized;
8018 }
8019 
8020 LegalizerHelper::LegalizeResult LegalizerHelper::lowerSelect(MachineInstr &MI) {
8021   // Implement vector G_SELECT in terms of XOR, AND, OR.
8022   auto [DstReg, DstTy, MaskReg, MaskTy, Op1Reg, Op1Ty, Op2Reg, Op2Ty] =
8023       MI.getFirst4RegLLTs();
8024   if (!DstTy.isVector())
8025     return UnableToLegalize;
8026 
8027   bool IsEltPtr = DstTy.getElementType().isPointer();
8028   if (IsEltPtr) {
8029     LLT ScalarPtrTy = LLT::scalar(DstTy.getScalarSizeInBits());
8030     LLT NewTy = DstTy.changeElementType(ScalarPtrTy);
8031     Op1Reg = MIRBuilder.buildPtrToInt(NewTy, Op1Reg).getReg(0);
8032     Op2Reg = MIRBuilder.buildPtrToInt(NewTy, Op2Reg).getReg(0);
8033     DstTy = NewTy;
8034   }
8035 
8036   if (MaskTy.isScalar()) {
8037     // Turn the scalar condition into a vector condition mask.
8038 
8039     Register MaskElt = MaskReg;
8040 
8041     // The condition was potentially zero extended before, but we want a sign
8042     // extended boolean.
8043     if (MaskTy != LLT::scalar(1))
8044       MaskElt = MIRBuilder.buildSExtInReg(MaskTy, MaskElt, 1).getReg(0);
8045 
8046     // Continue the sign extension (or truncate) to match the data type.
8047     MaskElt = MIRBuilder.buildSExtOrTrunc(DstTy.getElementType(),
8048                                           MaskElt).getReg(0);
8049 
8050     // Generate a vector splat idiom.
8051     auto ShufSplat = MIRBuilder.buildShuffleSplat(DstTy, MaskElt);
8052     MaskReg = ShufSplat.getReg(0);
8053     MaskTy = DstTy;
8054   }
8055 
8056   if (MaskTy.getSizeInBits() != DstTy.getSizeInBits()) {
8057     return UnableToLegalize;
8058   }
8059 
8060   auto NotMask = MIRBuilder.buildNot(MaskTy, MaskReg);
8061   auto NewOp1 = MIRBuilder.buildAnd(MaskTy, Op1Reg, MaskReg);
8062   auto NewOp2 = MIRBuilder.buildAnd(MaskTy, Op2Reg, NotMask);
8063   if (IsEltPtr) {
8064     auto Or = MIRBuilder.buildOr(DstTy, NewOp1, NewOp2);
8065     MIRBuilder.buildIntToPtr(DstReg, Or);
8066   } else {
8067     MIRBuilder.buildOr(DstReg, NewOp1, NewOp2);
8068   }
8069   MI.eraseFromParent();
8070   return Legalized;
8071 }
8072 
8073 LegalizerHelper::LegalizeResult LegalizerHelper::lowerDIVREM(MachineInstr &MI) {
8074   // Split DIVREM into individual instructions.
8075   unsigned Opcode = MI.getOpcode();
8076 
8077   MIRBuilder.buildInstr(
8078       Opcode == TargetOpcode::G_SDIVREM ? TargetOpcode::G_SDIV
8079                                         : TargetOpcode::G_UDIV,
8080       {MI.getOperand(0).getReg()}, {MI.getOperand(2), MI.getOperand(3)});
8081   MIRBuilder.buildInstr(
8082       Opcode == TargetOpcode::G_SDIVREM ? TargetOpcode::G_SREM
8083                                         : TargetOpcode::G_UREM,
8084       {MI.getOperand(1).getReg()}, {MI.getOperand(2), MI.getOperand(3)});
8085   MI.eraseFromParent();
8086   return Legalized;
8087 }
8088 
8089 LegalizerHelper::LegalizeResult
8090 LegalizerHelper::lowerAbsToAddXor(MachineInstr &MI) {
8091   // Expand %res = G_ABS %a into:
8092   // %v1 = G_ASHR %a, scalar_size-1
8093   // %v2 = G_ADD %a, %v1
8094   // %res = G_XOR %v2, %v1
8095   LLT DstTy = MRI.getType(MI.getOperand(0).getReg());
8096   Register OpReg = MI.getOperand(1).getReg();
8097   auto ShiftAmt =
8098       MIRBuilder.buildConstant(DstTy, DstTy.getScalarSizeInBits() - 1);
8099   auto Shift = MIRBuilder.buildAShr(DstTy, OpReg, ShiftAmt);
8100   auto Add = MIRBuilder.buildAdd(DstTy, OpReg, Shift);
8101   MIRBuilder.buildXor(MI.getOperand(0).getReg(), Add, Shift);
8102   MI.eraseFromParent();
8103   return Legalized;
8104 }
8105 
8106 LegalizerHelper::LegalizeResult
8107 LegalizerHelper::lowerAbsToMaxNeg(MachineInstr &MI) {
8108   // Expand %res = G_ABS %a into:
8109   // %v1 = G_CONSTANT 0
8110   // %v2 = G_SUB %v1, %a
8111   // %res = G_SMAX %a, %v2
8112   Register SrcReg = MI.getOperand(1).getReg();
8113   LLT Ty = MRI.getType(SrcReg);
8114   auto Zero = MIRBuilder.buildConstant(Ty, 0).getReg(0);
8115   auto Sub = MIRBuilder.buildSub(Ty, Zero, SrcReg).getReg(0);
8116   MIRBuilder.buildSMax(MI.getOperand(0), SrcReg, Sub);
8117   MI.eraseFromParent();
8118   return Legalized;
8119 }
8120 
8121 LegalizerHelper::LegalizeResult
8122 LegalizerHelper::lowerVectorReduction(MachineInstr &MI) {
8123   Register SrcReg = MI.getOperand(1).getReg();
8124   LLT SrcTy = MRI.getType(SrcReg);
8125   LLT DstTy = MRI.getType(SrcReg);
8126 
8127   // The source could be a scalar if the IR type was <1 x sN>.
8128   if (SrcTy.isScalar()) {
8129     if (DstTy.getSizeInBits() > SrcTy.getSizeInBits())
8130       return UnableToLegalize; // FIXME: handle extension.
8131     // This can be just a plain copy.
8132     Observer.changingInstr(MI);
8133     MI.setDesc(MIRBuilder.getTII().get(TargetOpcode::COPY));
8134     Observer.changedInstr(MI);
8135     return Legalized;
8136   }
8137   return UnableToLegalize;
8138 }
8139 
8140 static Type *getTypeForLLT(LLT Ty, LLVMContext &C);
8141 
8142 LegalizerHelper::LegalizeResult LegalizerHelper::lowerVAArg(MachineInstr &MI) {
8143   MachineFunction &MF = *MI.getMF();
8144   const DataLayout &DL = MIRBuilder.getDataLayout();
8145   LLVMContext &Ctx = MF.getFunction().getContext();
8146   Register ListPtr = MI.getOperand(1).getReg();
8147   LLT PtrTy = MRI.getType(ListPtr);
8148 
8149   // LstPtr is a pointer to the head of the list. Get the address
8150   // of the head of the list.
8151   Align PtrAlignment = DL.getABITypeAlign(getTypeForLLT(PtrTy, Ctx));
8152   MachineMemOperand *PtrLoadMMO = MF.getMachineMemOperand(
8153       MachinePointerInfo(), MachineMemOperand::MOLoad, PtrTy, PtrAlignment);
8154   auto VAList = MIRBuilder.buildLoad(PtrTy, ListPtr, *PtrLoadMMO).getReg(0);
8155 
8156   const Align A(MI.getOperand(2).getImm());
8157   LLT PtrTyAsScalarTy = LLT::scalar(PtrTy.getSizeInBits());
8158   if (A > TLI.getMinStackArgumentAlignment()) {
8159     Register AlignAmt =
8160         MIRBuilder.buildConstant(PtrTyAsScalarTy, A.value() - 1).getReg(0);
8161     auto AddDst = MIRBuilder.buildPtrAdd(PtrTy, VAList, AlignAmt);
8162     auto AndDst = MIRBuilder.buildMaskLowPtrBits(PtrTy, AddDst, Log2(A));
8163     VAList = AndDst.getReg(0);
8164   }
8165 
8166   // Increment the pointer, VAList, to the next vaarg
8167   // The list should be bumped by the size of element in the current head of
8168   // list.
8169   Register Dst = MI.getOperand(0).getReg();
8170   LLT LLTTy = MRI.getType(Dst);
8171   Type *Ty = getTypeForLLT(LLTTy, Ctx);
8172   auto IncAmt =
8173       MIRBuilder.buildConstant(PtrTyAsScalarTy, DL.getTypeAllocSize(Ty));
8174   auto Succ = MIRBuilder.buildPtrAdd(PtrTy, VAList, IncAmt);
8175 
8176   // Store the increment VAList to the legalized pointer
8177   MachineMemOperand *StoreMMO = MF.getMachineMemOperand(
8178       MachinePointerInfo(), MachineMemOperand::MOStore, PtrTy, PtrAlignment);
8179   MIRBuilder.buildStore(Succ, ListPtr, *StoreMMO);
8180   // Load the actual argument out of the pointer VAList
8181   Align EltAlignment = DL.getABITypeAlign(Ty);
8182   MachineMemOperand *EltLoadMMO = MF.getMachineMemOperand(
8183       MachinePointerInfo(), MachineMemOperand::MOLoad, LLTTy, EltAlignment);
8184   MIRBuilder.buildLoad(Dst, VAList, *EltLoadMMO);
8185 
8186   MI.eraseFromParent();
8187   return Legalized;
8188 }
8189 
8190 static bool shouldLowerMemFuncForSize(const MachineFunction &MF) {
8191   // On Darwin, -Os means optimize for size without hurting performance, so
8192   // only really optimize for size when -Oz (MinSize) is used.
8193   if (MF.getTarget().getTargetTriple().isOSDarwin())
8194     return MF.getFunction().hasMinSize();
8195   return MF.getFunction().hasOptSize();
8196 }
8197 
8198 // Returns a list of types to use for memory op lowering in MemOps. A partial
8199 // port of findOptimalMemOpLowering in TargetLowering.
8200 static bool findGISelOptimalMemOpLowering(std::vector<LLT> &MemOps,
8201                                           unsigned Limit, const MemOp &Op,
8202                                           unsigned DstAS, unsigned SrcAS,
8203                                           const AttributeList &FuncAttributes,
8204                                           const TargetLowering &TLI) {
8205   if (Op.isMemcpyWithFixedDstAlign() && Op.getSrcAlign() < Op.getDstAlign())
8206     return false;
8207 
8208   LLT Ty = TLI.getOptimalMemOpLLT(Op, FuncAttributes);
8209 
8210   if (Ty == LLT()) {
8211     // Use the largest scalar type whose alignment constraints are satisfied.
8212     // We only need to check DstAlign here as SrcAlign is always greater or
8213     // equal to DstAlign (or zero).
8214     Ty = LLT::scalar(64);
8215     if (Op.isFixedDstAlign())
8216       while (Op.getDstAlign() < Ty.getSizeInBytes() &&
8217              !TLI.allowsMisalignedMemoryAccesses(Ty, DstAS, Op.getDstAlign()))
8218         Ty = LLT::scalar(Ty.getSizeInBytes());
8219     assert(Ty.getSizeInBits() > 0 && "Could not find valid type");
8220     // FIXME: check for the largest legal type we can load/store to.
8221   }
8222 
8223   unsigned NumMemOps = 0;
8224   uint64_t Size = Op.size();
8225   while (Size) {
8226     unsigned TySize = Ty.getSizeInBytes();
8227     while (TySize > Size) {
8228       // For now, only use non-vector load / store's for the left-over pieces.
8229       LLT NewTy = Ty;
8230       // FIXME: check for mem op safety and legality of the types. Not all of
8231       // SDAGisms map cleanly to GISel concepts.
8232       if (NewTy.isVector())
8233         NewTy = NewTy.getSizeInBits() > 64 ? LLT::scalar(64) : LLT::scalar(32);
8234       NewTy = LLT::scalar(llvm::bit_floor(NewTy.getSizeInBits() - 1));
8235       unsigned NewTySize = NewTy.getSizeInBytes();
8236       assert(NewTySize > 0 && "Could not find appropriate type");
8237 
8238       // If the new LLT cannot cover all of the remaining bits, then consider
8239       // issuing a (or a pair of) unaligned and overlapping load / store.
8240       unsigned Fast;
8241       // Need to get a VT equivalent for allowMisalignedMemoryAccesses().
8242       MVT VT = getMVTForLLT(Ty);
8243       if (NumMemOps && Op.allowOverlap() && NewTySize < Size &&
8244           TLI.allowsMisalignedMemoryAccesses(
8245               VT, DstAS, Op.isFixedDstAlign() ? Op.getDstAlign() : Align(1),
8246               MachineMemOperand::MONone, &Fast) &&
8247           Fast)
8248         TySize = Size;
8249       else {
8250         Ty = NewTy;
8251         TySize = NewTySize;
8252       }
8253     }
8254 
8255     if (++NumMemOps > Limit)
8256       return false;
8257 
8258     MemOps.push_back(Ty);
8259     Size -= TySize;
8260   }
8261 
8262   return true;
8263 }
8264 
8265 static Type *getTypeForLLT(LLT Ty, LLVMContext &C) {
8266   if (Ty.isVector())
8267     return FixedVectorType::get(IntegerType::get(C, Ty.getScalarSizeInBits()),
8268                                 Ty.getNumElements());
8269   return IntegerType::get(C, Ty.getSizeInBits());
8270 }
8271 
8272 // Get a vectorized representation of the memset value operand, GISel edition.
8273 static Register getMemsetValue(Register Val, LLT Ty, MachineIRBuilder &MIB) {
8274   MachineRegisterInfo &MRI = *MIB.getMRI();
8275   unsigned NumBits = Ty.getScalarSizeInBits();
8276   auto ValVRegAndVal = getIConstantVRegValWithLookThrough(Val, MRI);
8277   if (!Ty.isVector() && ValVRegAndVal) {
8278     APInt Scalar = ValVRegAndVal->Value.trunc(8);
8279     APInt SplatVal = APInt::getSplat(NumBits, Scalar);
8280     return MIB.buildConstant(Ty, SplatVal).getReg(0);
8281   }
8282 
8283   // Extend the byte value to the larger type, and then multiply by a magic
8284   // value 0x010101... in order to replicate it across every byte.
8285   // Unless it's zero, in which case just emit a larger G_CONSTANT 0.
8286   if (ValVRegAndVal && ValVRegAndVal->Value == 0) {
8287     return MIB.buildConstant(Ty, 0).getReg(0);
8288   }
8289 
8290   LLT ExtType = Ty.getScalarType();
8291   auto ZExt = MIB.buildZExtOrTrunc(ExtType, Val);
8292   if (NumBits > 8) {
8293     APInt Magic = APInt::getSplat(NumBits, APInt(8, 0x01));
8294     auto MagicMI = MIB.buildConstant(ExtType, Magic);
8295     Val = MIB.buildMul(ExtType, ZExt, MagicMI).getReg(0);
8296   }
8297 
8298   // For vector types create a G_BUILD_VECTOR.
8299   if (Ty.isVector())
8300     Val = MIB.buildSplatVector(Ty, Val).getReg(0);
8301 
8302   return Val;
8303 }
8304 
8305 LegalizerHelper::LegalizeResult
8306 LegalizerHelper::lowerMemset(MachineInstr &MI, Register Dst, Register Val,
8307                              uint64_t KnownLen, Align Alignment,
8308                              bool IsVolatile) {
8309   auto &MF = *MI.getParent()->getParent();
8310   const auto &TLI = *MF.getSubtarget().getTargetLowering();
8311   auto &DL = MF.getDataLayout();
8312   LLVMContext &C = MF.getFunction().getContext();
8313 
8314   assert(KnownLen != 0 && "Have a zero length memset length!");
8315 
8316   bool DstAlignCanChange = false;
8317   MachineFrameInfo &MFI = MF.getFrameInfo();
8318   bool OptSize = shouldLowerMemFuncForSize(MF);
8319 
8320   MachineInstr *FIDef = getOpcodeDef(TargetOpcode::G_FRAME_INDEX, Dst, MRI);
8321   if (FIDef && !MFI.isFixedObjectIndex(FIDef->getOperand(1).getIndex()))
8322     DstAlignCanChange = true;
8323 
8324   unsigned Limit = TLI.getMaxStoresPerMemset(OptSize);
8325   std::vector<LLT> MemOps;
8326 
8327   const auto &DstMMO = **MI.memoperands_begin();
8328   MachinePointerInfo DstPtrInfo = DstMMO.getPointerInfo();
8329 
8330   auto ValVRegAndVal = getIConstantVRegValWithLookThrough(Val, MRI);
8331   bool IsZeroVal = ValVRegAndVal && ValVRegAndVal->Value == 0;
8332 
8333   if (!findGISelOptimalMemOpLowering(MemOps, Limit,
8334                                      MemOp::Set(KnownLen, DstAlignCanChange,
8335                                                 Alignment,
8336                                                 /*IsZeroMemset=*/IsZeroVal,
8337                                                 /*IsVolatile=*/IsVolatile),
8338                                      DstPtrInfo.getAddrSpace(), ~0u,
8339                                      MF.getFunction().getAttributes(), TLI))
8340     return UnableToLegalize;
8341 
8342   if (DstAlignCanChange) {
8343     // Get an estimate of the type from the LLT.
8344     Type *IRTy = getTypeForLLT(MemOps[0], C);
8345     Align NewAlign = DL.getABITypeAlign(IRTy);
8346     if (NewAlign > Alignment) {
8347       Alignment = NewAlign;
8348       unsigned FI = FIDef->getOperand(1).getIndex();
8349       // Give the stack frame object a larger alignment if needed.
8350       if (MFI.getObjectAlign(FI) < Alignment)
8351         MFI.setObjectAlignment(FI, Alignment);
8352     }
8353   }
8354 
8355   MachineIRBuilder MIB(MI);
8356   // Find the largest store and generate the bit pattern for it.
8357   LLT LargestTy = MemOps[0];
8358   for (unsigned i = 1; i < MemOps.size(); i++)
8359     if (MemOps[i].getSizeInBits() > LargestTy.getSizeInBits())
8360       LargestTy = MemOps[i];
8361 
8362   // The memset stored value is always defined as an s8, so in order to make it
8363   // work with larger store types we need to repeat the bit pattern across the
8364   // wider type.
8365   Register MemSetValue = getMemsetValue(Val, LargestTy, MIB);
8366 
8367   if (!MemSetValue)
8368     return UnableToLegalize;
8369 
8370   // Generate the stores. For each store type in the list, we generate the
8371   // matching store of that type to the destination address.
8372   LLT PtrTy = MRI.getType(Dst);
8373   unsigned DstOff = 0;
8374   unsigned Size = KnownLen;
8375   for (unsigned I = 0; I < MemOps.size(); I++) {
8376     LLT Ty = MemOps[I];
8377     unsigned TySize = Ty.getSizeInBytes();
8378     if (TySize > Size) {
8379       // Issuing an unaligned load / store pair that overlaps with the previous
8380       // pair. Adjust the offset accordingly.
8381       assert(I == MemOps.size() - 1 && I != 0);
8382       DstOff -= TySize - Size;
8383     }
8384 
8385     // If this store is smaller than the largest store see whether we can get
8386     // the smaller value for free with a truncate.
8387     Register Value = MemSetValue;
8388     if (Ty.getSizeInBits() < LargestTy.getSizeInBits()) {
8389       MVT VT = getMVTForLLT(Ty);
8390       MVT LargestVT = getMVTForLLT(LargestTy);
8391       if (!LargestTy.isVector() && !Ty.isVector() &&
8392           TLI.isTruncateFree(LargestVT, VT))
8393         Value = MIB.buildTrunc(Ty, MemSetValue).getReg(0);
8394       else
8395         Value = getMemsetValue(Val, Ty, MIB);
8396       if (!Value)
8397         return UnableToLegalize;
8398     }
8399 
8400     auto *StoreMMO = MF.getMachineMemOperand(&DstMMO, DstOff, Ty);
8401 
8402     Register Ptr = Dst;
8403     if (DstOff != 0) {
8404       auto Offset =
8405           MIB.buildConstant(LLT::scalar(PtrTy.getSizeInBits()), DstOff);
8406       Ptr = MIB.buildPtrAdd(PtrTy, Dst, Offset).getReg(0);
8407     }
8408 
8409     MIB.buildStore(Value, Ptr, *StoreMMO);
8410     DstOff += Ty.getSizeInBytes();
8411     Size -= TySize;
8412   }
8413 
8414   MI.eraseFromParent();
8415   return Legalized;
8416 }
8417 
8418 LegalizerHelper::LegalizeResult
8419 LegalizerHelper::lowerMemcpyInline(MachineInstr &MI) {
8420   assert(MI.getOpcode() == TargetOpcode::G_MEMCPY_INLINE);
8421 
8422   auto [Dst, Src, Len] = MI.getFirst3Regs();
8423 
8424   const auto *MMOIt = MI.memoperands_begin();
8425   const MachineMemOperand *MemOp = *MMOIt;
8426   bool IsVolatile = MemOp->isVolatile();
8427 
8428   // See if this is a constant length copy
8429   auto LenVRegAndVal = getIConstantVRegValWithLookThrough(Len, MRI);
8430   // FIXME: support dynamically sized G_MEMCPY_INLINE
8431   assert(LenVRegAndVal &&
8432          "inline memcpy with dynamic size is not yet supported");
8433   uint64_t KnownLen = LenVRegAndVal->Value.getZExtValue();
8434   if (KnownLen == 0) {
8435     MI.eraseFromParent();
8436     return Legalized;
8437   }
8438 
8439   const auto &DstMMO = **MI.memoperands_begin();
8440   const auto &SrcMMO = **std::next(MI.memoperands_begin());
8441   Align DstAlign = DstMMO.getBaseAlign();
8442   Align SrcAlign = SrcMMO.getBaseAlign();
8443 
8444   return lowerMemcpyInline(MI, Dst, Src, KnownLen, DstAlign, SrcAlign,
8445                            IsVolatile);
8446 }
8447 
8448 LegalizerHelper::LegalizeResult
8449 LegalizerHelper::lowerMemcpyInline(MachineInstr &MI, Register Dst, Register Src,
8450                                    uint64_t KnownLen, Align DstAlign,
8451                                    Align SrcAlign, bool IsVolatile) {
8452   assert(MI.getOpcode() == TargetOpcode::G_MEMCPY_INLINE);
8453   return lowerMemcpy(MI, Dst, Src, KnownLen,
8454                      std::numeric_limits<uint64_t>::max(), DstAlign, SrcAlign,
8455                      IsVolatile);
8456 }
8457 
8458 LegalizerHelper::LegalizeResult
8459 LegalizerHelper::lowerMemcpy(MachineInstr &MI, Register Dst, Register Src,
8460                              uint64_t KnownLen, uint64_t Limit, Align DstAlign,
8461                              Align SrcAlign, bool IsVolatile) {
8462   auto &MF = *MI.getParent()->getParent();
8463   const auto &TLI = *MF.getSubtarget().getTargetLowering();
8464   auto &DL = MF.getDataLayout();
8465   LLVMContext &C = MF.getFunction().getContext();
8466 
8467   assert(KnownLen != 0 && "Have a zero length memcpy length!");
8468 
8469   bool DstAlignCanChange = false;
8470   MachineFrameInfo &MFI = MF.getFrameInfo();
8471   Align Alignment = std::min(DstAlign, SrcAlign);
8472 
8473   MachineInstr *FIDef = getOpcodeDef(TargetOpcode::G_FRAME_INDEX, Dst, MRI);
8474   if (FIDef && !MFI.isFixedObjectIndex(FIDef->getOperand(1).getIndex()))
8475     DstAlignCanChange = true;
8476 
8477   // FIXME: infer better src pointer alignment like SelectionDAG does here.
8478   // FIXME: also use the equivalent of isMemSrcFromConstant and alwaysinlining
8479   // if the memcpy is in a tail call position.
8480 
8481   std::vector<LLT> MemOps;
8482 
8483   const auto &DstMMO = **MI.memoperands_begin();
8484   const auto &SrcMMO = **std::next(MI.memoperands_begin());
8485   MachinePointerInfo DstPtrInfo = DstMMO.getPointerInfo();
8486   MachinePointerInfo SrcPtrInfo = SrcMMO.getPointerInfo();
8487 
8488   if (!findGISelOptimalMemOpLowering(
8489           MemOps, Limit,
8490           MemOp::Copy(KnownLen, DstAlignCanChange, Alignment, SrcAlign,
8491                       IsVolatile),
8492           DstPtrInfo.getAddrSpace(), SrcPtrInfo.getAddrSpace(),
8493           MF.getFunction().getAttributes(), TLI))
8494     return UnableToLegalize;
8495 
8496   if (DstAlignCanChange) {
8497     // Get an estimate of the type from the LLT.
8498     Type *IRTy = getTypeForLLT(MemOps[0], C);
8499     Align NewAlign = DL.getABITypeAlign(IRTy);
8500 
8501     // Don't promote to an alignment that would require dynamic stack
8502     // realignment.
8503     const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
8504     if (!TRI->hasStackRealignment(MF))
8505       while (NewAlign > Alignment && DL.exceedsNaturalStackAlignment(NewAlign))
8506         NewAlign = NewAlign.previous();
8507 
8508     if (NewAlign > Alignment) {
8509       Alignment = NewAlign;
8510       unsigned FI = FIDef->getOperand(1).getIndex();
8511       // Give the stack frame object a larger alignment if needed.
8512       if (MFI.getObjectAlign(FI) < Alignment)
8513         MFI.setObjectAlignment(FI, Alignment);
8514     }
8515   }
8516 
8517   LLVM_DEBUG(dbgs() << "Inlining memcpy: " << MI << " into loads & stores\n");
8518 
8519   MachineIRBuilder MIB(MI);
8520   // Now we need to emit a pair of load and stores for each of the types we've
8521   // collected. I.e. for each type, generate a load from the source pointer of
8522   // that type width, and then generate a corresponding store to the dest buffer
8523   // of that value loaded. This can result in a sequence of loads and stores
8524   // mixed types, depending on what the target specifies as good types to use.
8525   unsigned CurrOffset = 0;
8526   unsigned Size = KnownLen;
8527   for (auto CopyTy : MemOps) {
8528     // Issuing an unaligned load / store pair  that overlaps with the previous
8529     // pair. Adjust the offset accordingly.
8530     if (CopyTy.getSizeInBytes() > Size)
8531       CurrOffset -= CopyTy.getSizeInBytes() - Size;
8532 
8533     // Construct MMOs for the accesses.
8534     auto *LoadMMO =
8535         MF.getMachineMemOperand(&SrcMMO, CurrOffset, CopyTy.getSizeInBytes());
8536     auto *StoreMMO =
8537         MF.getMachineMemOperand(&DstMMO, CurrOffset, CopyTy.getSizeInBytes());
8538 
8539     // Create the load.
8540     Register LoadPtr = Src;
8541     Register Offset;
8542     if (CurrOffset != 0) {
8543       LLT SrcTy = MRI.getType(Src);
8544       Offset = MIB.buildConstant(LLT::scalar(SrcTy.getSizeInBits()), CurrOffset)
8545                    .getReg(0);
8546       LoadPtr = MIB.buildPtrAdd(SrcTy, Src, Offset).getReg(0);
8547     }
8548     auto LdVal = MIB.buildLoad(CopyTy, LoadPtr, *LoadMMO);
8549 
8550     // Create the store.
8551     Register StorePtr = Dst;
8552     if (CurrOffset != 0) {
8553       LLT DstTy = MRI.getType(Dst);
8554       StorePtr = MIB.buildPtrAdd(DstTy, Dst, Offset).getReg(0);
8555     }
8556     MIB.buildStore(LdVal, StorePtr, *StoreMMO);
8557     CurrOffset += CopyTy.getSizeInBytes();
8558     Size -= CopyTy.getSizeInBytes();
8559   }
8560 
8561   MI.eraseFromParent();
8562   return Legalized;
8563 }
8564 
8565 LegalizerHelper::LegalizeResult
8566 LegalizerHelper::lowerMemmove(MachineInstr &MI, Register Dst, Register Src,
8567                               uint64_t KnownLen, Align DstAlign, Align SrcAlign,
8568                               bool IsVolatile) {
8569   auto &MF = *MI.getParent()->getParent();
8570   const auto &TLI = *MF.getSubtarget().getTargetLowering();
8571   auto &DL = MF.getDataLayout();
8572   LLVMContext &C = MF.getFunction().getContext();
8573 
8574   assert(KnownLen != 0 && "Have a zero length memmove length!");
8575 
8576   bool DstAlignCanChange = false;
8577   MachineFrameInfo &MFI = MF.getFrameInfo();
8578   bool OptSize = shouldLowerMemFuncForSize(MF);
8579   Align Alignment = std::min(DstAlign, SrcAlign);
8580 
8581   MachineInstr *FIDef = getOpcodeDef(TargetOpcode::G_FRAME_INDEX, Dst, MRI);
8582   if (FIDef && !MFI.isFixedObjectIndex(FIDef->getOperand(1).getIndex()))
8583     DstAlignCanChange = true;
8584 
8585   unsigned Limit = TLI.getMaxStoresPerMemmove(OptSize);
8586   std::vector<LLT> MemOps;
8587 
8588   const auto &DstMMO = **MI.memoperands_begin();
8589   const auto &SrcMMO = **std::next(MI.memoperands_begin());
8590   MachinePointerInfo DstPtrInfo = DstMMO.getPointerInfo();
8591   MachinePointerInfo SrcPtrInfo = SrcMMO.getPointerInfo();
8592 
8593   // FIXME: SelectionDAG always passes false for 'AllowOverlap', apparently due
8594   // to a bug in it's findOptimalMemOpLowering implementation. For now do the
8595   // same thing here.
8596   if (!findGISelOptimalMemOpLowering(
8597           MemOps, Limit,
8598           MemOp::Copy(KnownLen, DstAlignCanChange, Alignment, SrcAlign,
8599                       /*IsVolatile*/ true),
8600           DstPtrInfo.getAddrSpace(), SrcPtrInfo.getAddrSpace(),
8601           MF.getFunction().getAttributes(), TLI))
8602     return UnableToLegalize;
8603 
8604   if (DstAlignCanChange) {
8605     // Get an estimate of the type from the LLT.
8606     Type *IRTy = getTypeForLLT(MemOps[0], C);
8607     Align NewAlign = DL.getABITypeAlign(IRTy);
8608 
8609     // Don't promote to an alignment that would require dynamic stack
8610     // realignment.
8611     const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
8612     if (!TRI->hasStackRealignment(MF))
8613       while (NewAlign > Alignment && DL.exceedsNaturalStackAlignment(NewAlign))
8614         NewAlign = NewAlign.previous();
8615 
8616     if (NewAlign > Alignment) {
8617       Alignment = NewAlign;
8618       unsigned FI = FIDef->getOperand(1).getIndex();
8619       // Give the stack frame object a larger alignment if needed.
8620       if (MFI.getObjectAlign(FI) < Alignment)
8621         MFI.setObjectAlignment(FI, Alignment);
8622     }
8623   }
8624 
8625   LLVM_DEBUG(dbgs() << "Inlining memmove: " << MI << " into loads & stores\n");
8626 
8627   MachineIRBuilder MIB(MI);
8628   // Memmove requires that we perform the loads first before issuing the stores.
8629   // Apart from that, this loop is pretty much doing the same thing as the
8630   // memcpy codegen function.
8631   unsigned CurrOffset = 0;
8632   SmallVector<Register, 16> LoadVals;
8633   for (auto CopyTy : MemOps) {
8634     // Construct MMO for the load.
8635     auto *LoadMMO =
8636         MF.getMachineMemOperand(&SrcMMO, CurrOffset, CopyTy.getSizeInBytes());
8637 
8638     // Create the load.
8639     Register LoadPtr = Src;
8640     if (CurrOffset != 0) {
8641       LLT SrcTy = MRI.getType(Src);
8642       auto Offset =
8643           MIB.buildConstant(LLT::scalar(SrcTy.getSizeInBits()), CurrOffset);
8644       LoadPtr = MIB.buildPtrAdd(SrcTy, Src, Offset).getReg(0);
8645     }
8646     LoadVals.push_back(MIB.buildLoad(CopyTy, LoadPtr, *LoadMMO).getReg(0));
8647     CurrOffset += CopyTy.getSizeInBytes();
8648   }
8649 
8650   CurrOffset = 0;
8651   for (unsigned I = 0; I < MemOps.size(); ++I) {
8652     LLT CopyTy = MemOps[I];
8653     // Now store the values loaded.
8654     auto *StoreMMO =
8655         MF.getMachineMemOperand(&DstMMO, CurrOffset, CopyTy.getSizeInBytes());
8656 
8657     Register StorePtr = Dst;
8658     if (CurrOffset != 0) {
8659       LLT DstTy = MRI.getType(Dst);
8660       auto Offset =
8661           MIB.buildConstant(LLT::scalar(DstTy.getSizeInBits()), CurrOffset);
8662       StorePtr = MIB.buildPtrAdd(DstTy, Dst, Offset).getReg(0);
8663     }
8664     MIB.buildStore(LoadVals[I], StorePtr, *StoreMMO);
8665     CurrOffset += CopyTy.getSizeInBytes();
8666   }
8667   MI.eraseFromParent();
8668   return Legalized;
8669 }
8670 
8671 LegalizerHelper::LegalizeResult
8672 LegalizerHelper::lowerMemCpyFamily(MachineInstr &MI, unsigned MaxLen) {
8673   const unsigned Opc = MI.getOpcode();
8674   // This combine is fairly complex so it's not written with a separate
8675   // matcher function.
8676   assert((Opc == TargetOpcode::G_MEMCPY || Opc == TargetOpcode::G_MEMMOVE ||
8677           Opc == TargetOpcode::G_MEMSET) &&
8678          "Expected memcpy like instruction");
8679 
8680   auto MMOIt = MI.memoperands_begin();
8681   const MachineMemOperand *MemOp = *MMOIt;
8682 
8683   Align DstAlign = MemOp->getBaseAlign();
8684   Align SrcAlign;
8685   auto [Dst, Src, Len] = MI.getFirst3Regs();
8686 
8687   if (Opc != TargetOpcode::G_MEMSET) {
8688     assert(MMOIt != MI.memoperands_end() && "Expected a second MMO on MI");
8689     MemOp = *(++MMOIt);
8690     SrcAlign = MemOp->getBaseAlign();
8691   }
8692 
8693   // See if this is a constant length copy
8694   auto LenVRegAndVal = getIConstantVRegValWithLookThrough(Len, MRI);
8695   if (!LenVRegAndVal)
8696     return UnableToLegalize;
8697   uint64_t KnownLen = LenVRegAndVal->Value.getZExtValue();
8698 
8699   if (KnownLen == 0) {
8700     MI.eraseFromParent();
8701     return Legalized;
8702   }
8703 
8704   bool IsVolatile = MemOp->isVolatile();
8705   if (Opc == TargetOpcode::G_MEMCPY_INLINE)
8706     return lowerMemcpyInline(MI, Dst, Src, KnownLen, DstAlign, SrcAlign,
8707                              IsVolatile);
8708 
8709   // Don't try to optimize volatile.
8710   if (IsVolatile)
8711     return UnableToLegalize;
8712 
8713   if (MaxLen && KnownLen > MaxLen)
8714     return UnableToLegalize;
8715 
8716   if (Opc == TargetOpcode::G_MEMCPY) {
8717     auto &MF = *MI.getParent()->getParent();
8718     const auto &TLI = *MF.getSubtarget().getTargetLowering();
8719     bool OptSize = shouldLowerMemFuncForSize(MF);
8720     uint64_t Limit = TLI.getMaxStoresPerMemcpy(OptSize);
8721     return lowerMemcpy(MI, Dst, Src, KnownLen, Limit, DstAlign, SrcAlign,
8722                        IsVolatile);
8723   }
8724   if (Opc == TargetOpcode::G_MEMMOVE)
8725     return lowerMemmove(MI, Dst, Src, KnownLen, DstAlign, SrcAlign, IsVolatile);
8726   if (Opc == TargetOpcode::G_MEMSET)
8727     return lowerMemset(MI, Dst, Src, KnownLen, DstAlign, IsVolatile);
8728   return UnableToLegalize;
8729 }
8730