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/LegalizerInfo.h"
19 #include "llvm/CodeGen/MachineRegisterInfo.h"
20 #include "llvm/CodeGen/TargetInstrInfo.h"
21 #include "llvm/CodeGen/TargetLowering.h"
22 #include "llvm/CodeGen/TargetSubtargetInfo.h"
23 #include "llvm/Support/Debug.h"
24 #include "llvm/Support/MathExtras.h"
25 #include "llvm/Support/raw_ostream.h"
26 
27 #define DEBUG_TYPE "legalizer"
28 
29 using namespace llvm;
30 using namespace LegalizeActions;
31 
32 LegalizerHelper::LegalizerHelper(MachineFunction &MF,
33                                  GISelChangeObserver &Observer,
34                                  MachineIRBuilder &Builder)
35     : MIRBuilder(Builder), MRI(MF.getRegInfo()),
36       LI(*MF.getSubtarget().getLegalizerInfo()), Observer(Observer) {
37   MIRBuilder.setMF(MF);
38   MIRBuilder.setChangeObserver(Observer);
39 }
40 
41 LegalizerHelper::LegalizerHelper(MachineFunction &MF, const LegalizerInfo &LI,
42                                  GISelChangeObserver &Observer,
43                                  MachineIRBuilder &B)
44     : MIRBuilder(B), MRI(MF.getRegInfo()), LI(LI), Observer(Observer) {
45   MIRBuilder.setMF(MF);
46   MIRBuilder.setChangeObserver(Observer);
47 }
48 LegalizerHelper::LegalizeResult
49 LegalizerHelper::legalizeInstrStep(MachineInstr &MI) {
50   LLVM_DEBUG(dbgs() << "Legalizing: "; MI.print(dbgs()));
51 
52   auto Step = LI.getAction(MI, MRI);
53   switch (Step.Action) {
54   case Legal:
55     LLVM_DEBUG(dbgs() << ".. Already legal\n");
56     return AlreadyLegal;
57   case Libcall:
58     LLVM_DEBUG(dbgs() << ".. Convert to libcall\n");
59     return libcall(MI);
60   case NarrowScalar:
61     LLVM_DEBUG(dbgs() << ".. Narrow scalar\n");
62     return narrowScalar(MI, Step.TypeIdx, Step.NewType);
63   case WidenScalar:
64     LLVM_DEBUG(dbgs() << ".. Widen scalar\n");
65     return widenScalar(MI, Step.TypeIdx, Step.NewType);
66   case Lower:
67     LLVM_DEBUG(dbgs() << ".. Lower\n");
68     return lower(MI, Step.TypeIdx, Step.NewType);
69   case FewerElements:
70     LLVM_DEBUG(dbgs() << ".. Reduce number of elements\n");
71     return fewerElementsVector(MI, Step.TypeIdx, Step.NewType);
72   case Custom:
73     LLVM_DEBUG(dbgs() << ".. Custom legalization\n");
74     return LI.legalizeCustom(MI, MRI, MIRBuilder, Observer) ? Legalized
75                                                             : UnableToLegalize;
76   default:
77     LLVM_DEBUG(dbgs() << ".. Unable to legalize\n");
78     return UnableToLegalize;
79   }
80 }
81 
82 void LegalizerHelper::extractParts(unsigned Reg, LLT Ty, int NumParts,
83                                    SmallVectorImpl<unsigned> &VRegs) {
84   for (int i = 0; i < NumParts; ++i)
85     VRegs.push_back(MRI.createGenericVirtualRegister(Ty));
86   MIRBuilder.buildUnmerge(VRegs, Reg);
87 }
88 
89 bool LegalizerHelper::extractParts(unsigned Reg, LLT RegTy,
90                                    LLT MainTy, LLT &LeftoverTy,
91                                    SmallVectorImpl<unsigned> &VRegs,
92                                    SmallVectorImpl<unsigned> &LeftoverRegs) {
93   assert(!LeftoverTy.isValid() && "this is an out argument");
94 
95   unsigned RegSize = RegTy.getSizeInBits();
96   unsigned MainSize = MainTy.getSizeInBits();
97   unsigned NumParts = RegSize / MainSize;
98   unsigned LeftoverSize = RegSize - NumParts * MainSize;
99 
100   // Use an unmerge when possible.
101   if (LeftoverSize == 0) {
102     for (unsigned I = 0; I < NumParts; ++I)
103       VRegs.push_back(MRI.createGenericVirtualRegister(MainTy));
104     MIRBuilder.buildUnmerge(VRegs, Reg);
105     return true;
106   }
107 
108   if (MainTy.isVector()) {
109     unsigned EltSize = MainTy.getScalarSizeInBits();
110     if (LeftoverSize % EltSize != 0)
111       return false;
112     LeftoverTy = LLT::scalarOrVector(LeftoverSize / EltSize, EltSize);
113   } else {
114     LeftoverTy = LLT::scalar(LeftoverSize);
115   }
116 
117   // For irregular sizes, extract the individual parts.
118   for (unsigned I = 0; I != NumParts; ++I) {
119     unsigned NewReg = MRI.createGenericVirtualRegister(MainTy);
120     VRegs.push_back(NewReg);
121     MIRBuilder.buildExtract(NewReg, Reg, MainSize * I);
122   }
123 
124   for (unsigned Offset = MainSize * NumParts; Offset < RegSize;
125        Offset += LeftoverSize) {
126     unsigned NewReg = MRI.createGenericVirtualRegister(LeftoverTy);
127     LeftoverRegs.push_back(NewReg);
128     MIRBuilder.buildExtract(NewReg, Reg, Offset);
129   }
130 
131   return true;
132 }
133 
134 void LegalizerHelper::insertParts(unsigned DstReg,
135                                   LLT ResultTy, LLT PartTy,
136                                   ArrayRef<unsigned> PartRegs,
137                                   LLT LeftoverTy,
138                                   ArrayRef<unsigned> LeftoverRegs) {
139   if (!LeftoverTy.isValid()) {
140     assert(LeftoverRegs.empty());
141 
142     if (!ResultTy.isVector()) {
143       MIRBuilder.buildMerge(DstReg, PartRegs);
144       return;
145     }
146 
147     if (PartTy.isVector())
148       MIRBuilder.buildConcatVectors(DstReg, PartRegs);
149     else
150       MIRBuilder.buildBuildVector(DstReg, PartRegs);
151     return;
152   }
153 
154   unsigned PartSize = PartTy.getSizeInBits();
155   unsigned LeftoverPartSize = LeftoverTy.getSizeInBits();
156 
157   unsigned CurResultReg = MRI.createGenericVirtualRegister(ResultTy);
158   MIRBuilder.buildUndef(CurResultReg);
159 
160   unsigned Offset = 0;
161   for (unsigned PartReg : PartRegs) {
162     unsigned NewResultReg = MRI.createGenericVirtualRegister(ResultTy);
163     MIRBuilder.buildInsert(NewResultReg, CurResultReg, PartReg, Offset);
164     CurResultReg = NewResultReg;
165     Offset += PartSize;
166   }
167 
168   for (unsigned I = 0, E = LeftoverRegs.size(); I != E; ++I) {
169     // Use the original output register for the final insert to avoid a copy.
170     unsigned NewResultReg = (I + 1 == E) ?
171       DstReg : MRI.createGenericVirtualRegister(ResultTy);
172 
173     MIRBuilder.buildInsert(NewResultReg, CurResultReg, LeftoverRegs[I], Offset);
174     CurResultReg = NewResultReg;
175     Offset += LeftoverPartSize;
176   }
177 }
178 
179 static RTLIB::Libcall getRTLibDesc(unsigned Opcode, unsigned Size) {
180   switch (Opcode) {
181   case TargetOpcode::G_SDIV:
182     assert((Size == 32 || Size == 64) && "Unsupported size");
183     return Size == 64 ? RTLIB::SDIV_I64 : RTLIB::SDIV_I32;
184   case TargetOpcode::G_UDIV:
185     assert((Size == 32 || Size == 64) && "Unsupported size");
186     return Size == 64 ? RTLIB::UDIV_I64 : RTLIB::UDIV_I32;
187   case TargetOpcode::G_SREM:
188     assert((Size == 32 || Size == 64) && "Unsupported size");
189     return Size == 64 ? RTLIB::SREM_I64 : RTLIB::SREM_I32;
190   case TargetOpcode::G_UREM:
191     assert((Size == 32 || Size == 64) && "Unsupported size");
192     return Size == 64 ? RTLIB::UREM_I64 : RTLIB::UREM_I32;
193   case TargetOpcode::G_CTLZ_ZERO_UNDEF:
194     assert(Size == 32 && "Unsupported size");
195     return RTLIB::CTLZ_I32;
196   case TargetOpcode::G_FADD:
197     assert((Size == 32 || Size == 64) && "Unsupported size");
198     return Size == 64 ? RTLIB::ADD_F64 : RTLIB::ADD_F32;
199   case TargetOpcode::G_FSUB:
200     assert((Size == 32 || Size == 64) && "Unsupported size");
201     return Size == 64 ? RTLIB::SUB_F64 : RTLIB::SUB_F32;
202   case TargetOpcode::G_FMUL:
203     assert((Size == 32 || Size == 64) && "Unsupported size");
204     return Size == 64 ? RTLIB::MUL_F64 : RTLIB::MUL_F32;
205   case TargetOpcode::G_FDIV:
206     assert((Size == 32 || Size == 64) && "Unsupported size");
207     return Size == 64 ? RTLIB::DIV_F64 : RTLIB::DIV_F32;
208   case TargetOpcode::G_FEXP:
209     assert((Size == 32 || Size == 64) && "Unsupported size");
210     return Size == 64 ? RTLIB::EXP_F64 : RTLIB::EXP_F32;
211   case TargetOpcode::G_FREM:
212     return Size == 64 ? RTLIB::REM_F64 : RTLIB::REM_F32;
213   case TargetOpcode::G_FPOW:
214     return Size == 64 ? RTLIB::POW_F64 : RTLIB::POW_F32;
215   case TargetOpcode::G_FMA:
216     assert((Size == 32 || Size == 64) && "Unsupported size");
217     return Size == 64 ? RTLIB::FMA_F64 : RTLIB::FMA_F32;
218   case TargetOpcode::G_FSIN:
219     assert((Size == 32 || Size == 64 || Size == 128) && "Unsupported size");
220     return Size == 128 ? RTLIB::SIN_F128
221                        : Size == 64 ? RTLIB::SIN_F64 : RTLIB::SIN_F32;
222   case TargetOpcode::G_FCOS:
223     assert((Size == 32 || Size == 64 || Size == 128) && "Unsupported size");
224     return Size == 128 ? RTLIB::COS_F128
225                        : Size == 64 ? RTLIB::COS_F64 : RTLIB::COS_F32;
226   case TargetOpcode::G_FLOG10:
227     assert((Size == 32 || Size == 64 || Size == 128) && "Unsupported size");
228     return Size == 128 ? RTLIB::LOG10_F128
229                        : Size == 64 ? RTLIB::LOG10_F64 : RTLIB::LOG10_F32;
230   case TargetOpcode::G_FLOG:
231     assert((Size == 32 || Size == 64 || Size == 128) && "Unsupported size");
232     return Size == 128 ? RTLIB::LOG_F128
233                        : Size == 64 ? RTLIB::LOG_F64 : RTLIB::LOG_F32;
234   case TargetOpcode::G_FLOG2:
235     assert((Size == 32 || Size == 64 || Size == 128) && "Unsupported size");
236     return Size == 128 ? RTLIB::LOG2_F128
237                        : Size == 64 ? RTLIB::LOG2_F64 : RTLIB::LOG2_F32;
238   }
239   llvm_unreachable("Unknown libcall function");
240 }
241 
242 LegalizerHelper::LegalizeResult
243 llvm::createLibcall(MachineIRBuilder &MIRBuilder, RTLIB::Libcall Libcall,
244                     const CallLowering::ArgInfo &Result,
245                     ArrayRef<CallLowering::ArgInfo> Args) {
246   auto &CLI = *MIRBuilder.getMF().getSubtarget().getCallLowering();
247   auto &TLI = *MIRBuilder.getMF().getSubtarget().getTargetLowering();
248   const char *Name = TLI.getLibcallName(Libcall);
249 
250   MIRBuilder.getMF().getFrameInfo().setHasCalls(true);
251   if (!CLI.lowerCall(MIRBuilder, TLI.getLibcallCallingConv(Libcall),
252                      MachineOperand::CreateES(Name), Result, Args))
253     return LegalizerHelper::UnableToLegalize;
254 
255   return LegalizerHelper::Legalized;
256 }
257 
258 // Useful for libcalls where all operands have the same type.
259 static LegalizerHelper::LegalizeResult
260 simpleLibcall(MachineInstr &MI, MachineIRBuilder &MIRBuilder, unsigned Size,
261               Type *OpType) {
262   auto Libcall = getRTLibDesc(MI.getOpcode(), Size);
263 
264   SmallVector<CallLowering::ArgInfo, 3> Args;
265   for (unsigned i = 1; i < MI.getNumOperands(); i++)
266     Args.push_back({MI.getOperand(i).getReg(), OpType});
267   return createLibcall(MIRBuilder, Libcall, {MI.getOperand(0).getReg(), OpType},
268                        Args);
269 }
270 
271 static RTLIB::Libcall getConvRTLibDesc(unsigned Opcode, Type *ToType,
272                                        Type *FromType) {
273   auto ToMVT = MVT::getVT(ToType);
274   auto FromMVT = MVT::getVT(FromType);
275 
276   switch (Opcode) {
277   case TargetOpcode::G_FPEXT:
278     return RTLIB::getFPEXT(FromMVT, ToMVT);
279   case TargetOpcode::G_FPTRUNC:
280     return RTLIB::getFPROUND(FromMVT, ToMVT);
281   case TargetOpcode::G_FPTOSI:
282     return RTLIB::getFPTOSINT(FromMVT, ToMVT);
283   case TargetOpcode::G_FPTOUI:
284     return RTLIB::getFPTOUINT(FromMVT, ToMVT);
285   case TargetOpcode::G_SITOFP:
286     return RTLIB::getSINTTOFP(FromMVT, ToMVT);
287   case TargetOpcode::G_UITOFP:
288     return RTLIB::getUINTTOFP(FromMVT, ToMVT);
289   }
290   llvm_unreachable("Unsupported libcall function");
291 }
292 
293 static LegalizerHelper::LegalizeResult
294 conversionLibcall(MachineInstr &MI, MachineIRBuilder &MIRBuilder, Type *ToType,
295                   Type *FromType) {
296   RTLIB::Libcall Libcall = getConvRTLibDesc(MI.getOpcode(), ToType, FromType);
297   return createLibcall(MIRBuilder, Libcall, {MI.getOperand(0).getReg(), ToType},
298                        {{MI.getOperand(1).getReg(), FromType}});
299 }
300 
301 LegalizerHelper::LegalizeResult
302 LegalizerHelper::libcall(MachineInstr &MI) {
303   LLT LLTy = MRI.getType(MI.getOperand(0).getReg());
304   unsigned Size = LLTy.getSizeInBits();
305   auto &Ctx = MIRBuilder.getMF().getFunction().getContext();
306 
307   MIRBuilder.setInstr(MI);
308 
309   switch (MI.getOpcode()) {
310   default:
311     return UnableToLegalize;
312   case TargetOpcode::G_SDIV:
313   case TargetOpcode::G_UDIV:
314   case TargetOpcode::G_SREM:
315   case TargetOpcode::G_UREM:
316   case TargetOpcode::G_CTLZ_ZERO_UNDEF: {
317     Type *HLTy = IntegerType::get(Ctx, Size);
318     auto Status = simpleLibcall(MI, MIRBuilder, Size, HLTy);
319     if (Status != Legalized)
320       return Status;
321     break;
322   }
323   case TargetOpcode::G_FADD:
324   case TargetOpcode::G_FSUB:
325   case TargetOpcode::G_FMUL:
326   case TargetOpcode::G_FDIV:
327   case TargetOpcode::G_FMA:
328   case TargetOpcode::G_FPOW:
329   case TargetOpcode::G_FREM:
330   case TargetOpcode::G_FCOS:
331   case TargetOpcode::G_FSIN:
332   case TargetOpcode::G_FLOG10:
333   case TargetOpcode::G_FLOG:
334   case TargetOpcode::G_FLOG2:
335   case TargetOpcode::G_FEXP: {
336     if (Size > 64) {
337       LLVM_DEBUG(dbgs() << "Size " << Size << " too large to legalize.\n");
338       return UnableToLegalize;
339     }
340     Type *HLTy = Size == 64 ? Type::getDoubleTy(Ctx) : Type::getFloatTy(Ctx);
341     auto Status = simpleLibcall(MI, MIRBuilder, Size, HLTy);
342     if (Status != Legalized)
343       return Status;
344     break;
345   }
346   case TargetOpcode::G_FPEXT: {
347     // FIXME: Support other floating point types (half, fp128 etc)
348     unsigned FromSize = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits();
349     unsigned ToSize = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
350     if (ToSize != 64 || FromSize != 32)
351       return UnableToLegalize;
352     LegalizeResult Status = conversionLibcall(
353         MI, MIRBuilder, Type::getDoubleTy(Ctx), Type::getFloatTy(Ctx));
354     if (Status != Legalized)
355       return Status;
356     break;
357   }
358   case TargetOpcode::G_FPTRUNC: {
359     // FIXME: Support other floating point types (half, fp128 etc)
360     unsigned FromSize = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits();
361     unsigned ToSize = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
362     if (ToSize != 32 || FromSize != 64)
363       return UnableToLegalize;
364     LegalizeResult Status = conversionLibcall(
365         MI, MIRBuilder, Type::getFloatTy(Ctx), Type::getDoubleTy(Ctx));
366     if (Status != Legalized)
367       return Status;
368     break;
369   }
370   case TargetOpcode::G_FPTOSI:
371   case TargetOpcode::G_FPTOUI: {
372     // FIXME: Support other types
373     unsigned FromSize = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits();
374     unsigned ToSize = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
375     if (ToSize != 32 || (FromSize != 32 && FromSize != 64))
376       return UnableToLegalize;
377     LegalizeResult Status = conversionLibcall(
378         MI, MIRBuilder, Type::getInt32Ty(Ctx),
379         FromSize == 64 ? Type::getDoubleTy(Ctx) : Type::getFloatTy(Ctx));
380     if (Status != Legalized)
381       return Status;
382     break;
383   }
384   case TargetOpcode::G_SITOFP:
385   case TargetOpcode::G_UITOFP: {
386     // FIXME: Support other types
387     unsigned FromSize = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits();
388     unsigned ToSize = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
389     if (FromSize != 32 || (ToSize != 32 && ToSize != 64))
390       return UnableToLegalize;
391     LegalizeResult Status = conversionLibcall(
392         MI, MIRBuilder,
393         ToSize == 64 ? Type::getDoubleTy(Ctx) : Type::getFloatTy(Ctx),
394         Type::getInt32Ty(Ctx));
395     if (Status != Legalized)
396       return Status;
397     break;
398   }
399   }
400 
401   MI.eraseFromParent();
402   return Legalized;
403 }
404 
405 LegalizerHelper::LegalizeResult LegalizerHelper::narrowScalar(MachineInstr &MI,
406                                                               unsigned TypeIdx,
407                                                               LLT NarrowTy) {
408   MIRBuilder.setInstr(MI);
409 
410   uint64_t SizeOp0 = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
411   uint64_t NarrowSize = NarrowTy.getSizeInBits();
412 
413   switch (MI.getOpcode()) {
414   default:
415     return UnableToLegalize;
416   case TargetOpcode::G_IMPLICIT_DEF: {
417     // FIXME: add support for when SizeOp0 isn't an exact multiple of
418     // NarrowSize.
419     if (SizeOp0 % NarrowSize != 0)
420       return UnableToLegalize;
421     int NumParts = SizeOp0 / NarrowSize;
422 
423     SmallVector<unsigned, 2> DstRegs;
424     for (int i = 0; i < NumParts; ++i)
425       DstRegs.push_back(
426           MIRBuilder.buildUndef(NarrowTy)->getOperand(0).getReg());
427 
428     unsigned DstReg = MI.getOperand(0).getReg();
429     if(MRI.getType(DstReg).isVector())
430       MIRBuilder.buildBuildVector(DstReg, DstRegs);
431     else
432       MIRBuilder.buildMerge(DstReg, DstRegs);
433     MI.eraseFromParent();
434     return Legalized;
435   }
436   case TargetOpcode::G_ADD: {
437     // FIXME: add support for when SizeOp0 isn't an exact multiple of
438     // NarrowSize.
439     if (SizeOp0 % NarrowSize != 0)
440       return UnableToLegalize;
441     // Expand in terms of carry-setting/consuming G_ADDE instructions.
442     int NumParts = SizeOp0 / NarrowTy.getSizeInBits();
443 
444     SmallVector<unsigned, 2> Src1Regs, Src2Regs, DstRegs;
445     extractParts(MI.getOperand(1).getReg(), NarrowTy, NumParts, Src1Regs);
446     extractParts(MI.getOperand(2).getReg(), NarrowTy, NumParts, Src2Regs);
447 
448     unsigned CarryIn = MRI.createGenericVirtualRegister(LLT::scalar(1));
449     MIRBuilder.buildConstant(CarryIn, 0);
450 
451     for (int i = 0; i < NumParts; ++i) {
452       unsigned DstReg = MRI.createGenericVirtualRegister(NarrowTy);
453       unsigned CarryOut = MRI.createGenericVirtualRegister(LLT::scalar(1));
454 
455       MIRBuilder.buildUAdde(DstReg, CarryOut, Src1Regs[i],
456                             Src2Regs[i], CarryIn);
457 
458       DstRegs.push_back(DstReg);
459       CarryIn = CarryOut;
460     }
461     unsigned DstReg = MI.getOperand(0).getReg();
462     if(MRI.getType(DstReg).isVector())
463       MIRBuilder.buildBuildVector(DstReg, DstRegs);
464     else
465       MIRBuilder.buildMerge(DstReg, DstRegs);
466     MI.eraseFromParent();
467     return Legalized;
468   }
469   case TargetOpcode::G_SUB: {
470     // FIXME: add support for when SizeOp0 isn't an exact multiple of
471     // NarrowSize.
472     if (SizeOp0 % NarrowSize != 0)
473       return UnableToLegalize;
474 
475     int NumParts = SizeOp0 / NarrowTy.getSizeInBits();
476 
477     SmallVector<unsigned, 2> Src1Regs, Src2Regs, DstRegs;
478     extractParts(MI.getOperand(1).getReg(), NarrowTy, NumParts, Src1Regs);
479     extractParts(MI.getOperand(2).getReg(), NarrowTy, NumParts, Src2Regs);
480 
481     unsigned DstReg = MRI.createGenericVirtualRegister(NarrowTy);
482     unsigned BorrowOut = MRI.createGenericVirtualRegister(LLT::scalar(1));
483     MIRBuilder.buildInstr(TargetOpcode::G_USUBO, {DstReg, BorrowOut},
484                           {Src1Regs[0], Src2Regs[0]});
485     DstRegs.push_back(DstReg);
486     unsigned BorrowIn = BorrowOut;
487     for (int i = 1; i < NumParts; ++i) {
488       DstReg = MRI.createGenericVirtualRegister(NarrowTy);
489       BorrowOut = MRI.createGenericVirtualRegister(LLT::scalar(1));
490 
491       MIRBuilder.buildInstr(TargetOpcode::G_USUBE, {DstReg, BorrowOut},
492                             {Src1Regs[i], Src2Regs[i], BorrowIn});
493 
494       DstRegs.push_back(DstReg);
495       BorrowIn = BorrowOut;
496     }
497     MIRBuilder.buildMerge(MI.getOperand(0).getReg(), DstRegs);
498     MI.eraseFromParent();
499     return Legalized;
500   }
501   case TargetOpcode::G_MUL:
502     return narrowScalarMul(MI, TypeIdx, NarrowTy);
503   case TargetOpcode::G_EXTRACT: {
504     if (TypeIdx != 1)
505       return UnableToLegalize;
506 
507     int64_t SizeOp1 = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits();
508     // FIXME: add support for when SizeOp1 isn't an exact multiple of
509     // NarrowSize.
510     if (SizeOp1 % NarrowSize != 0)
511       return UnableToLegalize;
512     int NumParts = SizeOp1 / NarrowSize;
513 
514     SmallVector<unsigned, 2> SrcRegs, DstRegs;
515     SmallVector<uint64_t, 2> Indexes;
516     extractParts(MI.getOperand(1).getReg(), NarrowTy, NumParts, SrcRegs);
517 
518     unsigned OpReg = MI.getOperand(0).getReg();
519     uint64_t OpStart = MI.getOperand(2).getImm();
520     uint64_t OpSize = MRI.getType(OpReg).getSizeInBits();
521     for (int i = 0; i < NumParts; ++i) {
522       unsigned SrcStart = i * NarrowSize;
523 
524       if (SrcStart + NarrowSize <= OpStart || SrcStart >= OpStart + OpSize) {
525         // No part of the extract uses this subregister, ignore it.
526         continue;
527       } else if (SrcStart == OpStart && NarrowTy == MRI.getType(OpReg)) {
528         // The entire subregister is extracted, forward the value.
529         DstRegs.push_back(SrcRegs[i]);
530         continue;
531       }
532 
533       // OpSegStart is where this destination segment would start in OpReg if it
534       // extended infinitely in both directions.
535       int64_t ExtractOffset;
536       uint64_t SegSize;
537       if (OpStart < SrcStart) {
538         ExtractOffset = 0;
539         SegSize = std::min(NarrowSize, OpStart + OpSize - SrcStart);
540       } else {
541         ExtractOffset = OpStart - SrcStart;
542         SegSize = std::min(SrcStart + NarrowSize - OpStart, OpSize);
543       }
544 
545       unsigned SegReg = SrcRegs[i];
546       if (ExtractOffset != 0 || SegSize != NarrowSize) {
547         // A genuine extract is needed.
548         SegReg = MRI.createGenericVirtualRegister(LLT::scalar(SegSize));
549         MIRBuilder.buildExtract(SegReg, SrcRegs[i], ExtractOffset);
550       }
551 
552       DstRegs.push_back(SegReg);
553     }
554 
555     unsigned DstReg = MI.getOperand(0).getReg();
556     if(MRI.getType(DstReg).isVector())
557       MIRBuilder.buildBuildVector(DstReg, DstRegs);
558     else
559       MIRBuilder.buildMerge(DstReg, DstRegs);
560     MI.eraseFromParent();
561     return Legalized;
562   }
563   case TargetOpcode::G_INSERT: {
564     // FIXME: Don't know how to handle secondary types yet.
565     if (TypeIdx != 0)
566       return UnableToLegalize;
567 
568     // FIXME: add support for when SizeOp0 isn't an exact multiple of
569     // NarrowSize.
570     if (SizeOp0 % NarrowSize != 0)
571       return UnableToLegalize;
572 
573     int NumParts = SizeOp0 / NarrowSize;
574 
575     SmallVector<unsigned, 2> SrcRegs, DstRegs;
576     SmallVector<uint64_t, 2> Indexes;
577     extractParts(MI.getOperand(1).getReg(), NarrowTy, NumParts, SrcRegs);
578 
579     unsigned OpReg = MI.getOperand(2).getReg();
580     uint64_t OpStart = MI.getOperand(3).getImm();
581     uint64_t OpSize = MRI.getType(OpReg).getSizeInBits();
582     for (int i = 0; i < NumParts; ++i) {
583       unsigned DstStart = i * NarrowSize;
584 
585       if (DstStart + NarrowSize <= OpStart || DstStart >= OpStart + OpSize) {
586         // No part of the insert affects this subregister, forward the original.
587         DstRegs.push_back(SrcRegs[i]);
588         continue;
589       } else if (DstStart == OpStart && NarrowTy == MRI.getType(OpReg)) {
590         // The entire subregister is defined by this insert, forward the new
591         // value.
592         DstRegs.push_back(OpReg);
593         continue;
594       }
595 
596       // OpSegStart is where this destination segment would start in OpReg if it
597       // extended infinitely in both directions.
598       int64_t ExtractOffset, InsertOffset;
599       uint64_t SegSize;
600       if (OpStart < DstStart) {
601         InsertOffset = 0;
602         ExtractOffset = DstStart - OpStart;
603         SegSize = std::min(NarrowSize, OpStart + OpSize - DstStart);
604       } else {
605         InsertOffset = OpStart - DstStart;
606         ExtractOffset = 0;
607         SegSize =
608             std::min(NarrowSize - InsertOffset, OpStart + OpSize - DstStart);
609       }
610 
611       unsigned SegReg = OpReg;
612       if (ExtractOffset != 0 || SegSize != OpSize) {
613         // A genuine extract is needed.
614         SegReg = MRI.createGenericVirtualRegister(LLT::scalar(SegSize));
615         MIRBuilder.buildExtract(SegReg, OpReg, ExtractOffset);
616       }
617 
618       unsigned DstReg = MRI.createGenericVirtualRegister(NarrowTy);
619       MIRBuilder.buildInsert(DstReg, SrcRegs[i], SegReg, InsertOffset);
620       DstRegs.push_back(DstReg);
621     }
622 
623     assert(DstRegs.size() == (unsigned)NumParts && "not all parts covered");
624     unsigned DstReg = MI.getOperand(0).getReg();
625     if(MRI.getType(DstReg).isVector())
626       MIRBuilder.buildBuildVector(DstReg, DstRegs);
627     else
628       MIRBuilder.buildMerge(DstReg, DstRegs);
629     MI.eraseFromParent();
630     return Legalized;
631   }
632   case TargetOpcode::G_LOAD: {
633     const auto &MMO = **MI.memoperands_begin();
634     unsigned DstReg = MI.getOperand(0).getReg();
635     LLT DstTy = MRI.getType(DstReg);
636     if (DstTy.isVector())
637       return UnableToLegalize;
638 
639     if (8 * MMO.getSize() != DstTy.getSizeInBits()) {
640       unsigned TmpReg = MRI.createGenericVirtualRegister(NarrowTy);
641       auto &MMO = **MI.memoperands_begin();
642       MIRBuilder.buildLoad(TmpReg, MI.getOperand(1).getReg(), MMO);
643       MIRBuilder.buildAnyExt(DstReg, TmpReg);
644       MI.eraseFromParent();
645       return Legalized;
646     }
647 
648     return reduceLoadStoreWidth(MI, TypeIdx, NarrowTy);
649   }
650   case TargetOpcode::G_ZEXTLOAD:
651   case TargetOpcode::G_SEXTLOAD: {
652     bool ZExt = MI.getOpcode() == TargetOpcode::G_ZEXTLOAD;
653     unsigned DstReg = MI.getOperand(0).getReg();
654     unsigned PtrReg = MI.getOperand(1).getReg();
655 
656     unsigned TmpReg = MRI.createGenericVirtualRegister(NarrowTy);
657     auto &MMO = **MI.memoperands_begin();
658     if (MMO.getSize() * 8 == NarrowSize) {
659       MIRBuilder.buildLoad(TmpReg, PtrReg, MMO);
660     } else {
661       unsigned ExtLoad = ZExt ? TargetOpcode::G_ZEXTLOAD
662         : TargetOpcode::G_SEXTLOAD;
663       MIRBuilder.buildInstr(ExtLoad)
664         .addDef(TmpReg)
665         .addUse(PtrReg)
666         .addMemOperand(&MMO);
667     }
668 
669     if (ZExt)
670       MIRBuilder.buildZExt(DstReg, TmpReg);
671     else
672       MIRBuilder.buildSExt(DstReg, TmpReg);
673 
674     MI.eraseFromParent();
675     return Legalized;
676   }
677   case TargetOpcode::G_STORE: {
678     const auto &MMO = **MI.memoperands_begin();
679 
680     unsigned SrcReg = MI.getOperand(0).getReg();
681     LLT SrcTy = MRI.getType(SrcReg);
682     if (SrcTy.isVector())
683       return UnableToLegalize;
684 
685     int NumParts = SizeOp0 / NarrowSize;
686     unsigned HandledSize = NumParts * NarrowTy.getSizeInBits();
687     unsigned LeftoverBits = SrcTy.getSizeInBits() - HandledSize;
688     if (SrcTy.isVector() && LeftoverBits != 0)
689       return UnableToLegalize;
690 
691     if (8 * MMO.getSize() != SrcTy.getSizeInBits()) {
692       unsigned TmpReg = MRI.createGenericVirtualRegister(NarrowTy);
693       auto &MMO = **MI.memoperands_begin();
694       MIRBuilder.buildTrunc(TmpReg, SrcReg);
695       MIRBuilder.buildStore(TmpReg, MI.getOperand(1).getReg(), MMO);
696       MI.eraseFromParent();
697       return Legalized;
698     }
699 
700     return reduceLoadStoreWidth(MI, 0, NarrowTy);
701   }
702   case TargetOpcode::G_CONSTANT: {
703     // FIXME: add support for when SizeOp0 isn't an exact multiple of
704     // NarrowSize.
705     if (SizeOp0 % NarrowSize != 0)
706       return UnableToLegalize;
707     int NumParts = SizeOp0 / NarrowSize;
708     const APInt &Cst = MI.getOperand(1).getCImm()->getValue();
709     LLVMContext &Ctx = MIRBuilder.getMF().getFunction().getContext();
710 
711     SmallVector<unsigned, 2> DstRegs;
712     for (int i = 0; i < NumParts; ++i) {
713       unsigned DstReg = MRI.createGenericVirtualRegister(NarrowTy);
714       ConstantInt *CI =
715           ConstantInt::get(Ctx, Cst.lshr(NarrowSize * i).trunc(NarrowSize));
716       MIRBuilder.buildConstant(DstReg, *CI);
717       DstRegs.push_back(DstReg);
718     }
719     unsigned DstReg = MI.getOperand(0).getReg();
720     if(MRI.getType(DstReg).isVector())
721       MIRBuilder.buildBuildVector(DstReg, DstRegs);
722     else
723       MIRBuilder.buildMerge(DstReg, DstRegs);
724     MI.eraseFromParent();
725     return Legalized;
726   }
727   case TargetOpcode::G_SELECT:
728     return narrowScalarSelect(MI, TypeIdx, NarrowTy);
729   case TargetOpcode::G_AND:
730   case TargetOpcode::G_OR:
731   case TargetOpcode::G_XOR: {
732     // Legalize bitwise operation:
733     // A = BinOp<Ty> B, C
734     // into:
735     // B1, ..., BN = G_UNMERGE_VALUES B
736     // C1, ..., CN = G_UNMERGE_VALUES C
737     // A1 = BinOp<Ty/N> B1, C2
738     // ...
739     // AN = BinOp<Ty/N> BN, CN
740     // A = G_MERGE_VALUES A1, ..., AN
741 
742     // FIXME: add support for when SizeOp0 isn't an exact multiple of
743     // NarrowSize.
744     if (SizeOp0 % NarrowSize != 0)
745       return UnableToLegalize;
746     int NumParts = SizeOp0 / NarrowSize;
747 
748     // List the registers where the destination will be scattered.
749     SmallVector<unsigned, 2> DstRegs;
750     // List the registers where the first argument will be split.
751     SmallVector<unsigned, 2> SrcsReg1;
752     // List the registers where the second argument will be split.
753     SmallVector<unsigned, 2> SrcsReg2;
754     // Create all the temporary registers.
755     for (int i = 0; i < NumParts; ++i) {
756       unsigned DstReg = MRI.createGenericVirtualRegister(NarrowTy);
757       unsigned SrcReg1 = MRI.createGenericVirtualRegister(NarrowTy);
758       unsigned SrcReg2 = MRI.createGenericVirtualRegister(NarrowTy);
759 
760       DstRegs.push_back(DstReg);
761       SrcsReg1.push_back(SrcReg1);
762       SrcsReg2.push_back(SrcReg2);
763     }
764     // Explode the big arguments into smaller chunks.
765     MIRBuilder.buildUnmerge(SrcsReg1, MI.getOperand(1).getReg());
766     MIRBuilder.buildUnmerge(SrcsReg2, MI.getOperand(2).getReg());
767 
768     // Do the operation on each small part.
769     for (int i = 0; i < NumParts; ++i)
770       MIRBuilder.buildInstr(MI.getOpcode(), {DstRegs[i]},
771                             {SrcsReg1[i], SrcsReg2[i]});
772 
773     // Gather the destination registers into the final destination.
774     unsigned DstReg = MI.getOperand(0).getReg();
775     if(MRI.getType(DstReg).isVector())
776       MIRBuilder.buildBuildVector(DstReg, DstRegs);
777     else
778       MIRBuilder.buildMerge(DstReg, DstRegs);
779     MI.eraseFromParent();
780     return Legalized;
781   }
782   case TargetOpcode::G_SHL:
783   case TargetOpcode::G_LSHR:
784   case TargetOpcode::G_ASHR: {
785     if (TypeIdx != 1)
786       return UnableToLegalize; // TODO
787     Observer.changingInstr(MI);
788     narrowScalarSrc(MI, NarrowTy, 2);
789     Observer.changedInstr(MI);
790     return Legalized;
791   }
792   case TargetOpcode::G_CTLZ:
793   case TargetOpcode::G_CTLZ_ZERO_UNDEF:
794   case TargetOpcode::G_CTTZ:
795   case TargetOpcode::G_CTTZ_ZERO_UNDEF:
796   case TargetOpcode::G_CTPOP:
797     if (TypeIdx != 0)
798       return UnableToLegalize; // TODO
799 
800     Observer.changingInstr(MI);
801     narrowScalarDst(MI, NarrowTy, 0, TargetOpcode::G_ZEXT);
802     Observer.changedInstr(MI);
803     return Legalized;
804   case TargetOpcode::G_INTTOPTR:
805     if (TypeIdx != 1)
806       return UnableToLegalize;
807 
808     Observer.changingInstr(MI);
809     narrowScalarSrc(MI, NarrowTy, 1);
810     Observer.changedInstr(MI);
811     return Legalized;
812   case TargetOpcode::G_PTRTOINT:
813     if (TypeIdx != 0)
814       return UnableToLegalize;
815 
816     Observer.changingInstr(MI);
817     narrowScalarDst(MI, NarrowTy, 0, TargetOpcode::G_ZEXT);
818     Observer.changedInstr(MI);
819     return Legalized;
820   }
821 }
822 
823 void LegalizerHelper::widenScalarSrc(MachineInstr &MI, LLT WideTy,
824                                      unsigned OpIdx, unsigned ExtOpcode) {
825   MachineOperand &MO = MI.getOperand(OpIdx);
826   auto ExtB = MIRBuilder.buildInstr(ExtOpcode, {WideTy}, {MO.getReg()});
827   MO.setReg(ExtB->getOperand(0).getReg());
828 }
829 
830 void LegalizerHelper::narrowScalarSrc(MachineInstr &MI, LLT NarrowTy,
831                                       unsigned OpIdx) {
832   MachineOperand &MO = MI.getOperand(OpIdx);
833   auto ExtB = MIRBuilder.buildInstr(TargetOpcode::G_TRUNC, {NarrowTy},
834                                     {MO.getReg()});
835   MO.setReg(ExtB->getOperand(0).getReg());
836 }
837 
838 void LegalizerHelper::widenScalarDst(MachineInstr &MI, LLT WideTy,
839                                      unsigned OpIdx, unsigned TruncOpcode) {
840   MachineOperand &MO = MI.getOperand(OpIdx);
841   unsigned DstExt = MRI.createGenericVirtualRegister(WideTy);
842   MIRBuilder.setInsertPt(MIRBuilder.getMBB(), ++MIRBuilder.getInsertPt());
843   MIRBuilder.buildInstr(TruncOpcode, {MO.getReg()}, {DstExt});
844   MO.setReg(DstExt);
845 }
846 
847 void LegalizerHelper::narrowScalarDst(MachineInstr &MI, LLT NarrowTy,
848                                       unsigned OpIdx, unsigned ExtOpcode) {
849   MachineOperand &MO = MI.getOperand(OpIdx);
850   unsigned DstTrunc = MRI.createGenericVirtualRegister(NarrowTy);
851   MIRBuilder.setInsertPt(MIRBuilder.getMBB(), ++MIRBuilder.getInsertPt());
852   MIRBuilder.buildInstr(ExtOpcode, {MO.getReg()}, {DstTrunc});
853   MO.setReg(DstTrunc);
854 }
855 
856 LegalizerHelper::LegalizeResult
857 LegalizerHelper::widenScalarMergeValues(MachineInstr &MI, unsigned TypeIdx,
858                                         LLT WideTy) {
859   if (TypeIdx != 1)
860     return UnableToLegalize;
861 
862   unsigned DstReg = MI.getOperand(0).getReg();
863   LLT DstTy = MRI.getType(DstReg);
864   if (!DstTy.isScalar())
865     return UnableToLegalize;
866 
867   unsigned NumOps = MI.getNumOperands();
868   unsigned NumSrc = MI.getNumOperands() - 1;
869   unsigned PartSize = DstTy.getSizeInBits() / NumSrc;
870 
871   unsigned Src1 = MI.getOperand(1).getReg();
872   unsigned ResultReg = MIRBuilder.buildZExt(DstTy, Src1)->getOperand(0).getReg();
873 
874   for (unsigned I = 2; I != NumOps; ++I) {
875     const unsigned Offset = (I - 1) * PartSize;
876 
877     unsigned SrcReg = MI.getOperand(I).getReg();
878     assert(MRI.getType(SrcReg) == LLT::scalar(PartSize));
879 
880     auto ZextInput = MIRBuilder.buildZExt(DstTy, SrcReg);
881 
882     unsigned NextResult = I + 1 == NumOps ? DstReg :
883       MRI.createGenericVirtualRegister(DstTy);
884 
885     auto ShiftAmt = MIRBuilder.buildConstant(DstTy, Offset);
886     auto Shl = MIRBuilder.buildShl(DstTy, ZextInput, ShiftAmt);
887     MIRBuilder.buildOr(NextResult, ResultReg, Shl);
888     ResultReg = NextResult;
889   }
890 
891   MI.eraseFromParent();
892   return Legalized;
893 }
894 
895 LegalizerHelper::LegalizeResult
896 LegalizerHelper::widenScalarUnmergeValues(MachineInstr &MI, unsigned TypeIdx,
897                                           LLT WideTy) {
898   if (TypeIdx != 0)
899     return UnableToLegalize;
900 
901   unsigned NumDst = MI.getNumOperands() - 1;
902   unsigned SrcReg = MI.getOperand(NumDst).getReg();
903   LLT SrcTy = MRI.getType(SrcReg);
904   if (!SrcTy.isScalar())
905     return UnableToLegalize;
906 
907   unsigned Dst0Reg = MI.getOperand(0).getReg();
908   LLT DstTy = MRI.getType(Dst0Reg);
909   if (!DstTy.isScalar())
910     return UnableToLegalize;
911 
912   unsigned NewSrcSize = NumDst * WideTy.getSizeInBits();
913   LLT NewSrcTy = LLT::scalar(NewSrcSize);
914   unsigned SizeDiff = WideTy.getSizeInBits() - DstTy.getSizeInBits();
915 
916   auto WideSrc = MIRBuilder.buildZExt(NewSrcTy, SrcReg);
917 
918   for (unsigned I = 1; I != NumDst; ++I) {
919     auto ShiftAmt = MIRBuilder.buildConstant(NewSrcTy, SizeDiff * I);
920     auto Shl = MIRBuilder.buildShl(NewSrcTy, WideSrc, ShiftAmt);
921     WideSrc = MIRBuilder.buildOr(NewSrcTy, WideSrc, Shl);
922   }
923 
924   Observer.changingInstr(MI);
925 
926   MI.getOperand(NumDst).setReg(WideSrc->getOperand(0).getReg());
927   for (unsigned I = 0; I != NumDst; ++I)
928     widenScalarDst(MI, WideTy, I);
929 
930   Observer.changedInstr(MI);
931 
932   return Legalized;
933 }
934 
935 LegalizerHelper::LegalizeResult
936 LegalizerHelper::widenScalar(MachineInstr &MI, unsigned TypeIdx, LLT WideTy) {
937   MIRBuilder.setInstr(MI);
938 
939   switch (MI.getOpcode()) {
940   default:
941     return UnableToLegalize;
942   case TargetOpcode::G_EXTRACT: {
943     if (TypeIdx != 1)
944       return UnableToLegalize;
945 
946     unsigned SrcReg = MI.getOperand(1).getReg();
947     LLT SrcTy = MRI.getType(SrcReg);
948     if (!SrcTy.isVector())
949       return UnableToLegalize;
950 
951     unsigned DstReg = MI.getOperand(0).getReg();
952     LLT DstTy = MRI.getType(DstReg);
953     if (DstTy != SrcTy.getElementType())
954       return UnableToLegalize;
955 
956     unsigned Offset = MI.getOperand(2).getImm();
957     if (Offset % SrcTy.getScalarSizeInBits() != 0)
958       return UnableToLegalize;
959 
960     widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_ANYEXT);
961 
962     MI.getOperand(2).setImm((WideTy.getSizeInBits() / SrcTy.getSizeInBits()) *
963                             Offset);
964     widenScalarDst(MI, WideTy.getScalarType(), 0);
965 
966     return Legalized;
967   }
968   case TargetOpcode::G_MERGE_VALUES:
969     return widenScalarMergeValues(MI, TypeIdx, WideTy);
970   case TargetOpcode::G_UNMERGE_VALUES:
971     return widenScalarUnmergeValues(MI, TypeIdx, WideTy);
972   case TargetOpcode::G_UADDO:
973   case TargetOpcode::G_USUBO: {
974     if (TypeIdx == 1)
975       return UnableToLegalize; // TODO
976     auto LHSZext = MIRBuilder.buildInstr(TargetOpcode::G_ZEXT, {WideTy},
977                                          {MI.getOperand(2).getReg()});
978     auto RHSZext = MIRBuilder.buildInstr(TargetOpcode::G_ZEXT, {WideTy},
979                                          {MI.getOperand(3).getReg()});
980     unsigned Opcode = MI.getOpcode() == TargetOpcode::G_UADDO
981                           ? TargetOpcode::G_ADD
982                           : TargetOpcode::G_SUB;
983     // Do the arithmetic in the larger type.
984     auto NewOp = MIRBuilder.buildInstr(Opcode, {WideTy}, {LHSZext, RHSZext});
985     LLT OrigTy = MRI.getType(MI.getOperand(0).getReg());
986     APInt Mask = APInt::getAllOnesValue(OrigTy.getSizeInBits());
987     auto AndOp = MIRBuilder.buildInstr(
988         TargetOpcode::G_AND, {WideTy},
989         {NewOp, MIRBuilder.buildConstant(WideTy, Mask.getZExtValue())});
990     // There is no overflow if the AndOp is the same as NewOp.
991     MIRBuilder.buildICmp(CmpInst::ICMP_NE, MI.getOperand(1).getReg(), NewOp,
992                          AndOp);
993     // Now trunc the NewOp to the original result.
994     MIRBuilder.buildTrunc(MI.getOperand(0).getReg(), NewOp);
995     MI.eraseFromParent();
996     return Legalized;
997   }
998   case TargetOpcode::G_CTTZ:
999   case TargetOpcode::G_CTTZ_ZERO_UNDEF:
1000   case TargetOpcode::G_CTLZ:
1001   case TargetOpcode::G_CTLZ_ZERO_UNDEF:
1002   case TargetOpcode::G_CTPOP: {
1003     if (TypeIdx == 0) {
1004       Observer.changingInstr(MI);
1005       widenScalarDst(MI, WideTy, 0);
1006       Observer.changedInstr(MI);
1007       return Legalized;
1008     }
1009 
1010     unsigned SrcReg = MI.getOperand(1).getReg();
1011 
1012     // First ZEXT the input.
1013     auto MIBSrc = MIRBuilder.buildZExt(WideTy, SrcReg);
1014     LLT CurTy = MRI.getType(SrcReg);
1015     if (MI.getOpcode() == TargetOpcode::G_CTTZ) {
1016       // The count is the same in the larger type except if the original
1017       // value was zero.  This can be handled by setting the bit just off
1018       // the top of the original type.
1019       auto TopBit =
1020           APInt::getOneBitSet(WideTy.getSizeInBits(), CurTy.getSizeInBits());
1021       MIBSrc = MIRBuilder.buildOr(
1022         WideTy, MIBSrc, MIRBuilder.buildConstant(WideTy, TopBit));
1023     }
1024 
1025     // Perform the operation at the larger size.
1026     auto MIBNewOp = MIRBuilder.buildInstr(MI.getOpcode(), {WideTy}, {MIBSrc});
1027     // This is already the correct result for CTPOP and CTTZs
1028     if (MI.getOpcode() == TargetOpcode::G_CTLZ ||
1029         MI.getOpcode() == TargetOpcode::G_CTLZ_ZERO_UNDEF) {
1030       // The correct result is NewOp - (Difference in widety and current ty).
1031       unsigned SizeDiff = WideTy.getSizeInBits() - CurTy.getSizeInBits();
1032       MIBNewOp = MIRBuilder.buildInstr(
1033           TargetOpcode::G_SUB, {WideTy},
1034           {MIBNewOp, MIRBuilder.buildConstant(WideTy, SizeDiff)});
1035     }
1036 
1037     MIRBuilder.buildZExtOrTrunc(MI.getOperand(0), MIBNewOp);
1038     MI.eraseFromParent();
1039     return Legalized;
1040   }
1041   case TargetOpcode::G_BSWAP: {
1042     Observer.changingInstr(MI);
1043     unsigned DstReg = MI.getOperand(0).getReg();
1044 
1045     unsigned ShrReg = MRI.createGenericVirtualRegister(WideTy);
1046     unsigned DstExt = MRI.createGenericVirtualRegister(WideTy);
1047     unsigned ShiftAmtReg = MRI.createGenericVirtualRegister(WideTy);
1048     widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_ANYEXT);
1049 
1050     MI.getOperand(0).setReg(DstExt);
1051 
1052     MIRBuilder.setInsertPt(MIRBuilder.getMBB(), ++MIRBuilder.getInsertPt());
1053 
1054     LLT Ty = MRI.getType(DstReg);
1055     unsigned DiffBits = WideTy.getScalarSizeInBits() - Ty.getScalarSizeInBits();
1056     MIRBuilder.buildConstant(ShiftAmtReg, DiffBits);
1057     MIRBuilder.buildInstr(TargetOpcode::G_LSHR)
1058       .addDef(ShrReg)
1059       .addUse(DstExt)
1060       .addUse(ShiftAmtReg);
1061 
1062     MIRBuilder.buildTrunc(DstReg, ShrReg);
1063     Observer.changedInstr(MI);
1064     return Legalized;
1065   }
1066   case TargetOpcode::G_ADD:
1067   case TargetOpcode::G_AND:
1068   case TargetOpcode::G_MUL:
1069   case TargetOpcode::G_OR:
1070   case TargetOpcode::G_XOR:
1071   case TargetOpcode::G_SUB:
1072     // Perform operation at larger width (any extension is fine here, high bits
1073     // don't affect the result) and then truncate the result back to the
1074     // original type.
1075     Observer.changingInstr(MI);
1076     widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_ANYEXT);
1077     widenScalarSrc(MI, WideTy, 2, TargetOpcode::G_ANYEXT);
1078     widenScalarDst(MI, WideTy);
1079     Observer.changedInstr(MI);
1080     return Legalized;
1081 
1082   case TargetOpcode::G_SHL:
1083       Observer.changingInstr(MI);
1084 
1085     if (TypeIdx == 0) {
1086       widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_ANYEXT);
1087       widenScalarDst(MI, WideTy);
1088     } else {
1089       assert(TypeIdx == 1);
1090       // The "number of bits to shift" operand must preserve its value as an
1091       // unsigned integer:
1092       widenScalarSrc(MI, WideTy, 2, TargetOpcode::G_ZEXT);
1093     }
1094 
1095     Observer.changedInstr(MI);
1096     return Legalized;
1097 
1098   case TargetOpcode::G_SDIV:
1099   case TargetOpcode::G_SREM:
1100     Observer.changingInstr(MI);
1101     widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_SEXT);
1102     widenScalarSrc(MI, WideTy, 2, TargetOpcode::G_SEXT);
1103     widenScalarDst(MI, WideTy);
1104     Observer.changedInstr(MI);
1105     return Legalized;
1106 
1107   case TargetOpcode::G_ASHR:
1108   case TargetOpcode::G_LSHR:
1109     Observer.changingInstr(MI);
1110 
1111     if (TypeIdx == 0) {
1112       unsigned CvtOp = MI.getOpcode() == TargetOpcode::G_ASHR ?
1113         TargetOpcode::G_SEXT : TargetOpcode::G_ZEXT;
1114 
1115       widenScalarSrc(MI, WideTy, 1, CvtOp);
1116       widenScalarDst(MI, WideTy);
1117     } else {
1118       assert(TypeIdx == 1);
1119       // The "number of bits to shift" operand must preserve its value as an
1120       // unsigned integer:
1121       widenScalarSrc(MI, WideTy, 2, TargetOpcode::G_ZEXT);
1122     }
1123 
1124     Observer.changedInstr(MI);
1125     return Legalized;
1126   case TargetOpcode::G_UDIV:
1127   case TargetOpcode::G_UREM:
1128     Observer.changingInstr(MI);
1129     widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_ZEXT);
1130     widenScalarSrc(MI, WideTy, 2, TargetOpcode::G_ZEXT);
1131     widenScalarDst(MI, WideTy);
1132     Observer.changedInstr(MI);
1133     return Legalized;
1134 
1135   case TargetOpcode::G_SELECT:
1136     Observer.changingInstr(MI);
1137     if (TypeIdx == 0) {
1138       // Perform operation at larger width (any extension is fine here, high
1139       // bits don't affect the result) and then truncate the result back to the
1140       // original type.
1141       widenScalarSrc(MI, WideTy, 2, TargetOpcode::G_ANYEXT);
1142       widenScalarSrc(MI, WideTy, 3, TargetOpcode::G_ANYEXT);
1143       widenScalarDst(MI, WideTy);
1144     } else {
1145       bool IsVec = MRI.getType(MI.getOperand(1).getReg()).isVector();
1146       // Explicit extension is required here since high bits affect the result.
1147       widenScalarSrc(MI, WideTy, 1, MIRBuilder.getBoolExtOp(IsVec, false));
1148     }
1149     Observer.changedInstr(MI);
1150     return Legalized;
1151 
1152   case TargetOpcode::G_FPTOSI:
1153   case TargetOpcode::G_FPTOUI:
1154     if (TypeIdx != 0)
1155       return UnableToLegalize;
1156     Observer.changingInstr(MI);
1157     widenScalarDst(MI, WideTy);
1158     Observer.changedInstr(MI);
1159     return Legalized;
1160 
1161   case TargetOpcode::G_SITOFP:
1162     if (TypeIdx != 1)
1163       return UnableToLegalize;
1164     Observer.changingInstr(MI);
1165     widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_SEXT);
1166     Observer.changedInstr(MI);
1167     return Legalized;
1168 
1169   case TargetOpcode::G_UITOFP:
1170     if (TypeIdx != 1)
1171       return UnableToLegalize;
1172     Observer.changingInstr(MI);
1173     widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_ZEXT);
1174     Observer.changedInstr(MI);
1175     return Legalized;
1176 
1177   case TargetOpcode::G_INSERT:
1178     if (TypeIdx != 0)
1179       return UnableToLegalize;
1180     Observer.changingInstr(MI);
1181     widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_ANYEXT);
1182     widenScalarDst(MI, WideTy);
1183     Observer.changedInstr(MI);
1184     return Legalized;
1185 
1186   case TargetOpcode::G_LOAD:
1187     // For some types like i24, we might try to widen to i32. To properly handle
1188     // this we should be using a dedicated extending load, until then avoid
1189     // trying to legalize.
1190     if (alignTo(MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(), 8) !=
1191         WideTy.getSizeInBits())
1192       return UnableToLegalize;
1193     LLVM_FALLTHROUGH;
1194   case TargetOpcode::G_SEXTLOAD:
1195   case TargetOpcode::G_ZEXTLOAD:
1196     Observer.changingInstr(MI);
1197     widenScalarDst(MI, WideTy);
1198     Observer.changedInstr(MI);
1199     return Legalized;
1200 
1201   case TargetOpcode::G_STORE: {
1202     if (TypeIdx != 0)
1203       return UnableToLegalize;
1204 
1205     LLT Ty = MRI.getType(MI.getOperand(0).getReg());
1206     if (!isPowerOf2_32(Ty.getSizeInBits()))
1207       return UnableToLegalize;
1208 
1209     Observer.changingInstr(MI);
1210 
1211     unsigned ExtType = Ty.getScalarSizeInBits() == 1 ?
1212       TargetOpcode::G_ZEXT : TargetOpcode::G_ANYEXT;
1213     widenScalarSrc(MI, WideTy, 0, ExtType);
1214 
1215     Observer.changedInstr(MI);
1216     return Legalized;
1217   }
1218   case TargetOpcode::G_CONSTANT: {
1219     MachineOperand &SrcMO = MI.getOperand(1);
1220     LLVMContext &Ctx = MIRBuilder.getMF().getFunction().getContext();
1221     const APInt &Val = SrcMO.getCImm()->getValue().sext(WideTy.getSizeInBits());
1222     Observer.changingInstr(MI);
1223     SrcMO.setCImm(ConstantInt::get(Ctx, Val));
1224 
1225     widenScalarDst(MI, WideTy);
1226     Observer.changedInstr(MI);
1227     return Legalized;
1228   }
1229   case TargetOpcode::G_FCONSTANT: {
1230     MachineOperand &SrcMO = MI.getOperand(1);
1231     LLVMContext &Ctx = MIRBuilder.getMF().getFunction().getContext();
1232     APFloat Val = SrcMO.getFPImm()->getValueAPF();
1233     bool LosesInfo;
1234     switch (WideTy.getSizeInBits()) {
1235     case 32:
1236       Val.convert(APFloat::IEEEsingle(), APFloat::rmTowardZero, &LosesInfo);
1237       break;
1238     case 64:
1239       Val.convert(APFloat::IEEEdouble(), APFloat::rmTowardZero, &LosesInfo);
1240       break;
1241     default:
1242       llvm_unreachable("Unhandled fp widen type");
1243     }
1244     Observer.changingInstr(MI);
1245     SrcMO.setFPImm(ConstantFP::get(Ctx, Val));
1246 
1247     widenScalarDst(MI, WideTy, 0, TargetOpcode::G_FPTRUNC);
1248     Observer.changedInstr(MI);
1249     return Legalized;
1250   }
1251   case TargetOpcode::G_IMPLICIT_DEF: {
1252     Observer.changingInstr(MI);
1253     widenScalarDst(MI, WideTy);
1254     Observer.changedInstr(MI);
1255     return Legalized;
1256   }
1257   case TargetOpcode::G_BRCOND:
1258     Observer.changingInstr(MI);
1259     widenScalarSrc(MI, WideTy, 0, TargetOpcode::G_ANYEXT);
1260     Observer.changedInstr(MI);
1261     return Legalized;
1262 
1263   case TargetOpcode::G_FCMP:
1264     Observer.changingInstr(MI);
1265     if (TypeIdx == 0)
1266       widenScalarDst(MI, WideTy);
1267     else {
1268       widenScalarSrc(MI, WideTy, 2, TargetOpcode::G_FPEXT);
1269       widenScalarSrc(MI, WideTy, 3, TargetOpcode::G_FPEXT);
1270     }
1271     Observer.changedInstr(MI);
1272     return Legalized;
1273 
1274   case TargetOpcode::G_ICMP:
1275     Observer.changingInstr(MI);
1276     if (TypeIdx == 0)
1277       widenScalarDst(MI, WideTy);
1278     else {
1279       unsigned ExtOpcode = CmpInst::isSigned(static_cast<CmpInst::Predicate>(
1280                                MI.getOperand(1).getPredicate()))
1281                                ? TargetOpcode::G_SEXT
1282                                : TargetOpcode::G_ZEXT;
1283       widenScalarSrc(MI, WideTy, 2, ExtOpcode);
1284       widenScalarSrc(MI, WideTy, 3, ExtOpcode);
1285     }
1286     Observer.changedInstr(MI);
1287     return Legalized;
1288 
1289   case TargetOpcode::G_GEP:
1290     assert(TypeIdx == 1 && "unable to legalize pointer of GEP");
1291     Observer.changingInstr(MI);
1292     widenScalarSrc(MI, WideTy, 2, TargetOpcode::G_SEXT);
1293     Observer.changedInstr(MI);
1294     return Legalized;
1295 
1296   case TargetOpcode::G_PHI: {
1297     assert(TypeIdx == 0 && "Expecting only Idx 0");
1298 
1299     Observer.changingInstr(MI);
1300     for (unsigned I = 1; I < MI.getNumOperands(); I += 2) {
1301       MachineBasicBlock &OpMBB = *MI.getOperand(I + 1).getMBB();
1302       MIRBuilder.setInsertPt(OpMBB, OpMBB.getFirstTerminator());
1303       widenScalarSrc(MI, WideTy, I, TargetOpcode::G_ANYEXT);
1304     }
1305 
1306     MachineBasicBlock &MBB = *MI.getParent();
1307     MIRBuilder.setInsertPt(MBB, --MBB.getFirstNonPHI());
1308     widenScalarDst(MI, WideTy);
1309     Observer.changedInstr(MI);
1310     return Legalized;
1311   }
1312   case TargetOpcode::G_EXTRACT_VECTOR_ELT: {
1313     if (TypeIdx == 0) {
1314       unsigned VecReg = MI.getOperand(1).getReg();
1315       LLT VecTy = MRI.getType(VecReg);
1316       Observer.changingInstr(MI);
1317 
1318       widenScalarSrc(MI, LLT::vector(VecTy.getNumElements(),
1319                                      WideTy.getSizeInBits()),
1320                      1, TargetOpcode::G_SEXT);
1321 
1322       widenScalarDst(MI, WideTy, 0);
1323       Observer.changedInstr(MI);
1324       return Legalized;
1325     }
1326 
1327     if (TypeIdx != 2)
1328       return UnableToLegalize;
1329     Observer.changingInstr(MI);
1330     widenScalarSrc(MI, WideTy, 2, TargetOpcode::G_SEXT);
1331     Observer.changedInstr(MI);
1332     return Legalized;
1333   }
1334   case TargetOpcode::G_FADD:
1335   case TargetOpcode::G_FMUL:
1336   case TargetOpcode::G_FSUB:
1337   case TargetOpcode::G_FMA:
1338   case TargetOpcode::G_FNEG:
1339   case TargetOpcode::G_FABS:
1340   case TargetOpcode::G_FDIV:
1341   case TargetOpcode::G_FREM:
1342   case TargetOpcode::G_FCEIL:
1343   case TargetOpcode::G_FCOS:
1344   case TargetOpcode::G_FSIN:
1345   case TargetOpcode::G_FLOG10:
1346   case TargetOpcode::G_FLOG:
1347   case TargetOpcode::G_FLOG2:
1348   case TargetOpcode::G_FSQRT:
1349   case TargetOpcode::G_FEXP:
1350     assert(TypeIdx == 0);
1351     Observer.changingInstr(MI);
1352 
1353     for (unsigned I = 1, E = MI.getNumOperands(); I != E; ++I)
1354       widenScalarSrc(MI, WideTy, I, TargetOpcode::G_FPEXT);
1355 
1356     widenScalarDst(MI, WideTy, 0, TargetOpcode::G_FPTRUNC);
1357     Observer.changedInstr(MI);
1358     return Legalized;
1359   case TargetOpcode::G_INTTOPTR:
1360     if (TypeIdx != 1)
1361       return UnableToLegalize;
1362 
1363     Observer.changingInstr(MI);
1364     widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_ZEXT);
1365     Observer.changedInstr(MI);
1366     return Legalized;
1367   case TargetOpcode::G_PTRTOINT:
1368     if (TypeIdx != 0)
1369       return UnableToLegalize;
1370 
1371     Observer.changingInstr(MI);
1372     widenScalarDst(MI, WideTy, 0);
1373     Observer.changedInstr(MI);
1374     return Legalized;
1375   }
1376 }
1377 
1378 LegalizerHelper::LegalizeResult
1379 LegalizerHelper::lower(MachineInstr &MI, unsigned TypeIdx, LLT Ty) {
1380   using namespace TargetOpcode;
1381   MIRBuilder.setInstr(MI);
1382 
1383   switch(MI.getOpcode()) {
1384   default:
1385     return UnableToLegalize;
1386   case TargetOpcode::G_SREM:
1387   case TargetOpcode::G_UREM: {
1388     unsigned QuotReg = MRI.createGenericVirtualRegister(Ty);
1389     MIRBuilder.buildInstr(MI.getOpcode() == G_SREM ? G_SDIV : G_UDIV)
1390         .addDef(QuotReg)
1391         .addUse(MI.getOperand(1).getReg())
1392         .addUse(MI.getOperand(2).getReg());
1393 
1394     unsigned ProdReg = MRI.createGenericVirtualRegister(Ty);
1395     MIRBuilder.buildMul(ProdReg, QuotReg, MI.getOperand(2).getReg());
1396     MIRBuilder.buildSub(MI.getOperand(0).getReg(), MI.getOperand(1).getReg(),
1397                         ProdReg);
1398     MI.eraseFromParent();
1399     return Legalized;
1400   }
1401   case TargetOpcode::G_SMULO:
1402   case TargetOpcode::G_UMULO: {
1403     // Generate G_UMULH/G_SMULH to check for overflow and a normal G_MUL for the
1404     // result.
1405     unsigned Res = MI.getOperand(0).getReg();
1406     unsigned Overflow = MI.getOperand(1).getReg();
1407     unsigned LHS = MI.getOperand(2).getReg();
1408     unsigned RHS = MI.getOperand(3).getReg();
1409 
1410     MIRBuilder.buildMul(Res, LHS, RHS);
1411 
1412     unsigned Opcode = MI.getOpcode() == TargetOpcode::G_SMULO
1413                           ? TargetOpcode::G_SMULH
1414                           : TargetOpcode::G_UMULH;
1415 
1416     unsigned HiPart = MRI.createGenericVirtualRegister(Ty);
1417     MIRBuilder.buildInstr(Opcode)
1418       .addDef(HiPart)
1419       .addUse(LHS)
1420       .addUse(RHS);
1421 
1422     unsigned Zero = MRI.createGenericVirtualRegister(Ty);
1423     MIRBuilder.buildConstant(Zero, 0);
1424 
1425     // For *signed* multiply, overflow is detected by checking:
1426     // (hi != (lo >> bitwidth-1))
1427     if (Opcode == TargetOpcode::G_SMULH) {
1428       unsigned Shifted = MRI.createGenericVirtualRegister(Ty);
1429       unsigned ShiftAmt = MRI.createGenericVirtualRegister(Ty);
1430       MIRBuilder.buildConstant(ShiftAmt, Ty.getSizeInBits() - 1);
1431       MIRBuilder.buildInstr(TargetOpcode::G_ASHR)
1432         .addDef(Shifted)
1433         .addUse(Res)
1434         .addUse(ShiftAmt);
1435       MIRBuilder.buildICmp(CmpInst::ICMP_NE, Overflow, HiPart, Shifted);
1436     } else {
1437       MIRBuilder.buildICmp(CmpInst::ICMP_NE, Overflow, HiPart, Zero);
1438     }
1439     MI.eraseFromParent();
1440     return Legalized;
1441   }
1442   case TargetOpcode::G_FNEG: {
1443     // TODO: Handle vector types once we are able to
1444     // represent them.
1445     if (Ty.isVector())
1446       return UnableToLegalize;
1447     unsigned Res = MI.getOperand(0).getReg();
1448     Type *ZeroTy;
1449     LLVMContext &Ctx = MIRBuilder.getMF().getFunction().getContext();
1450     switch (Ty.getSizeInBits()) {
1451     case 16:
1452       ZeroTy = Type::getHalfTy(Ctx);
1453       break;
1454     case 32:
1455       ZeroTy = Type::getFloatTy(Ctx);
1456       break;
1457     case 64:
1458       ZeroTy = Type::getDoubleTy(Ctx);
1459       break;
1460     case 128:
1461       ZeroTy = Type::getFP128Ty(Ctx);
1462       break;
1463     default:
1464       llvm_unreachable("unexpected floating-point type");
1465     }
1466     ConstantFP &ZeroForNegation =
1467         *cast<ConstantFP>(ConstantFP::getZeroValueForNegation(ZeroTy));
1468     auto Zero = MIRBuilder.buildFConstant(Ty, ZeroForNegation);
1469     MIRBuilder.buildInstr(TargetOpcode::G_FSUB)
1470         .addDef(Res)
1471         .addUse(Zero->getOperand(0).getReg())
1472         .addUse(MI.getOperand(1).getReg());
1473     MI.eraseFromParent();
1474     return Legalized;
1475   }
1476   case TargetOpcode::G_FSUB: {
1477     // Lower (G_FSUB LHS, RHS) to (G_FADD LHS, (G_FNEG RHS)).
1478     // First, check if G_FNEG is marked as Lower. If so, we may
1479     // end up with an infinite loop as G_FSUB is used to legalize G_FNEG.
1480     if (LI.getAction({G_FNEG, {Ty}}).Action == Lower)
1481       return UnableToLegalize;
1482     unsigned Res = MI.getOperand(0).getReg();
1483     unsigned LHS = MI.getOperand(1).getReg();
1484     unsigned RHS = MI.getOperand(2).getReg();
1485     unsigned Neg = MRI.createGenericVirtualRegister(Ty);
1486     MIRBuilder.buildInstr(TargetOpcode::G_FNEG).addDef(Neg).addUse(RHS);
1487     MIRBuilder.buildInstr(TargetOpcode::G_FADD)
1488         .addDef(Res)
1489         .addUse(LHS)
1490         .addUse(Neg);
1491     MI.eraseFromParent();
1492     return Legalized;
1493   }
1494   case TargetOpcode::G_ATOMIC_CMPXCHG_WITH_SUCCESS: {
1495     unsigned OldValRes = MI.getOperand(0).getReg();
1496     unsigned SuccessRes = MI.getOperand(1).getReg();
1497     unsigned Addr = MI.getOperand(2).getReg();
1498     unsigned CmpVal = MI.getOperand(3).getReg();
1499     unsigned NewVal = MI.getOperand(4).getReg();
1500     MIRBuilder.buildAtomicCmpXchg(OldValRes, Addr, CmpVal, NewVal,
1501                                   **MI.memoperands_begin());
1502     MIRBuilder.buildICmp(CmpInst::ICMP_EQ, SuccessRes, OldValRes, CmpVal);
1503     MI.eraseFromParent();
1504     return Legalized;
1505   }
1506   case TargetOpcode::G_LOAD:
1507   case TargetOpcode::G_SEXTLOAD:
1508   case TargetOpcode::G_ZEXTLOAD: {
1509     // Lower to a memory-width G_LOAD and a G_SEXT/G_ZEXT/G_ANYEXT
1510     unsigned DstReg = MI.getOperand(0).getReg();
1511     unsigned PtrReg = MI.getOperand(1).getReg();
1512     LLT DstTy = MRI.getType(DstReg);
1513     auto &MMO = **MI.memoperands_begin();
1514 
1515     if (DstTy.getSizeInBits() == MMO.getSize() /* in bytes */ * 8) {
1516       // In the case of G_LOAD, this was a non-extending load already and we're
1517       // about to lower to the same instruction.
1518       if (MI.getOpcode() == TargetOpcode::G_LOAD)
1519           return UnableToLegalize;
1520       MIRBuilder.buildLoad(DstReg, PtrReg, MMO);
1521       MI.eraseFromParent();
1522       return Legalized;
1523     }
1524 
1525     if (DstTy.isScalar()) {
1526       unsigned TmpReg = MRI.createGenericVirtualRegister(
1527           LLT::scalar(MMO.getSize() /* in bytes */ * 8));
1528       MIRBuilder.buildLoad(TmpReg, PtrReg, MMO);
1529       switch (MI.getOpcode()) {
1530       default:
1531         llvm_unreachable("Unexpected opcode");
1532       case TargetOpcode::G_LOAD:
1533         MIRBuilder.buildAnyExt(DstReg, TmpReg);
1534         break;
1535       case TargetOpcode::G_SEXTLOAD:
1536         MIRBuilder.buildSExt(DstReg, TmpReg);
1537         break;
1538       case TargetOpcode::G_ZEXTLOAD:
1539         MIRBuilder.buildZExt(DstReg, TmpReg);
1540         break;
1541       }
1542       MI.eraseFromParent();
1543       return Legalized;
1544     }
1545 
1546     return UnableToLegalize;
1547   }
1548   case TargetOpcode::G_CTLZ_ZERO_UNDEF:
1549   case TargetOpcode::G_CTTZ_ZERO_UNDEF:
1550   case TargetOpcode::G_CTLZ:
1551   case TargetOpcode::G_CTTZ:
1552   case TargetOpcode::G_CTPOP:
1553     return lowerBitCount(MI, TypeIdx, Ty);
1554   case G_UADDE: {
1555     unsigned Res = MI.getOperand(0).getReg();
1556     unsigned CarryOut = MI.getOperand(1).getReg();
1557     unsigned LHS = MI.getOperand(2).getReg();
1558     unsigned RHS = MI.getOperand(3).getReg();
1559     unsigned CarryIn = MI.getOperand(4).getReg();
1560 
1561     unsigned TmpRes = MRI.createGenericVirtualRegister(Ty);
1562     unsigned ZExtCarryIn = MRI.createGenericVirtualRegister(Ty);
1563 
1564     MIRBuilder.buildAdd(TmpRes, LHS, RHS);
1565     MIRBuilder.buildZExt(ZExtCarryIn, CarryIn);
1566     MIRBuilder.buildAdd(Res, TmpRes, ZExtCarryIn);
1567     MIRBuilder.buildICmp(CmpInst::ICMP_ULT, CarryOut, Res, LHS);
1568 
1569     MI.eraseFromParent();
1570     return Legalized;
1571   }
1572   case G_USUBO: {
1573     unsigned Res = MI.getOperand(0).getReg();
1574     unsigned BorrowOut = MI.getOperand(1).getReg();
1575     unsigned LHS = MI.getOperand(2).getReg();
1576     unsigned RHS = MI.getOperand(3).getReg();
1577 
1578     MIRBuilder.buildSub(Res, LHS, RHS);
1579     MIRBuilder.buildICmp(CmpInst::ICMP_ULT, BorrowOut, LHS, RHS);
1580 
1581     MI.eraseFromParent();
1582     return Legalized;
1583   }
1584   case G_USUBE: {
1585     unsigned Res = MI.getOperand(0).getReg();
1586     unsigned BorrowOut = MI.getOperand(1).getReg();
1587     unsigned LHS = MI.getOperand(2).getReg();
1588     unsigned RHS = MI.getOperand(3).getReg();
1589     unsigned BorrowIn = MI.getOperand(4).getReg();
1590 
1591     unsigned TmpRes = MRI.createGenericVirtualRegister(Ty);
1592     unsigned ZExtBorrowIn = MRI.createGenericVirtualRegister(Ty);
1593     unsigned LHS_EQ_RHS = MRI.createGenericVirtualRegister(LLT::scalar(1));
1594     unsigned LHS_ULT_RHS = MRI.createGenericVirtualRegister(LLT::scalar(1));
1595 
1596     MIRBuilder.buildSub(TmpRes, LHS, RHS);
1597     MIRBuilder.buildZExt(ZExtBorrowIn, BorrowIn);
1598     MIRBuilder.buildSub(Res, TmpRes, ZExtBorrowIn);
1599     MIRBuilder.buildICmp(CmpInst::ICMP_EQ, LHS_EQ_RHS, LHS, RHS);
1600     MIRBuilder.buildICmp(CmpInst::ICMP_ULT, LHS_ULT_RHS, LHS, RHS);
1601     MIRBuilder.buildSelect(BorrowOut, LHS_EQ_RHS, BorrowIn, LHS_ULT_RHS);
1602 
1603     MI.eraseFromParent();
1604     return Legalized;
1605   }
1606   }
1607 }
1608 
1609 LegalizerHelper::LegalizeResult LegalizerHelper::fewerElementsVectorImplicitDef(
1610     MachineInstr &MI, unsigned TypeIdx, LLT NarrowTy) {
1611   SmallVector<unsigned, 2> DstRegs;
1612 
1613   unsigned NarrowSize = NarrowTy.getSizeInBits();
1614   unsigned DstReg = MI.getOperand(0).getReg();
1615   unsigned Size = MRI.getType(DstReg).getSizeInBits();
1616   int NumParts = Size / NarrowSize;
1617   // FIXME: Don't know how to handle the situation where the small vectors
1618   // aren't all the same size yet.
1619   if (Size % NarrowSize != 0)
1620     return UnableToLegalize;
1621 
1622   for (int i = 0; i < NumParts; ++i) {
1623     unsigned TmpReg = MRI.createGenericVirtualRegister(NarrowTy);
1624     MIRBuilder.buildUndef(TmpReg);
1625     DstRegs.push_back(TmpReg);
1626   }
1627 
1628   if (NarrowTy.isVector())
1629     MIRBuilder.buildConcatVectors(DstReg, DstRegs);
1630   else
1631     MIRBuilder.buildBuildVector(DstReg, DstRegs);
1632 
1633   MI.eraseFromParent();
1634   return Legalized;
1635 }
1636 
1637 LegalizerHelper::LegalizeResult
1638 LegalizerHelper::fewerElementsVectorBasic(MachineInstr &MI, unsigned TypeIdx,
1639                                           LLT NarrowTy) {
1640   const unsigned Opc = MI.getOpcode();
1641   const unsigned NumOps = MI.getNumOperands() - 1;
1642   const unsigned NarrowSize = NarrowTy.getSizeInBits();
1643   const unsigned DstReg = MI.getOperand(0).getReg();
1644   const unsigned Flags = MI.getFlags();
1645   const LLT DstTy = MRI.getType(DstReg);
1646   const unsigned Size = DstTy.getSizeInBits();
1647   const int NumParts = Size / NarrowSize;
1648   const LLT EltTy = DstTy.getElementType();
1649   const unsigned EltSize = EltTy.getSizeInBits();
1650   const unsigned BitsForNumParts = NarrowSize * NumParts;
1651 
1652   // Check if we have any leftovers. If we do, then only handle the case where
1653   // the leftover is one element.
1654   if (BitsForNumParts != Size && BitsForNumParts + EltSize != Size)
1655     return UnableToLegalize;
1656 
1657   if (BitsForNumParts != Size) {
1658     unsigned AccumDstReg = MRI.createGenericVirtualRegister(DstTy);
1659     MIRBuilder.buildUndef(AccumDstReg);
1660 
1661     // Handle the pieces which evenly divide into the requested type with
1662     // extract/op/insert sequence.
1663     for (unsigned Offset = 0; Offset < BitsForNumParts; Offset += NarrowSize) {
1664       SmallVector<SrcOp, 4> SrcOps;
1665       for (unsigned I = 1, E = MI.getNumOperands(); I != E; ++I) {
1666         unsigned PartOpReg = MRI.createGenericVirtualRegister(NarrowTy);
1667         MIRBuilder.buildExtract(PartOpReg, MI.getOperand(I).getReg(), Offset);
1668         SrcOps.push_back(PartOpReg);
1669       }
1670 
1671       unsigned PartDstReg = MRI.createGenericVirtualRegister(NarrowTy);
1672       MIRBuilder.buildInstr(Opc, {PartDstReg}, SrcOps, Flags);
1673 
1674       unsigned PartInsertReg = MRI.createGenericVirtualRegister(DstTy);
1675       MIRBuilder.buildInsert(PartInsertReg, AccumDstReg, PartDstReg, Offset);
1676       AccumDstReg = PartInsertReg;
1677       Offset += NarrowSize;
1678     }
1679 
1680     // Handle the remaining element sized leftover piece.
1681     SmallVector<SrcOp, 4> SrcOps;
1682     for (unsigned I = 1, E = MI.getNumOperands(); I != E; ++I) {
1683       unsigned PartOpReg = MRI.createGenericVirtualRegister(EltTy);
1684       MIRBuilder.buildExtract(PartOpReg, MI.getOperand(I).getReg(),
1685                               BitsForNumParts);
1686       SrcOps.push_back(PartOpReg);
1687     }
1688 
1689     unsigned PartDstReg = MRI.createGenericVirtualRegister(EltTy);
1690     MIRBuilder.buildInstr(Opc, {PartDstReg}, SrcOps, Flags);
1691     MIRBuilder.buildInsert(DstReg, AccumDstReg, PartDstReg, BitsForNumParts);
1692     MI.eraseFromParent();
1693 
1694     return Legalized;
1695   }
1696 
1697   SmallVector<unsigned, 2> DstRegs, Src0Regs, Src1Regs, Src2Regs;
1698 
1699   extractParts(MI.getOperand(1).getReg(), NarrowTy, NumParts, Src0Regs);
1700 
1701   if (NumOps >= 2)
1702     extractParts(MI.getOperand(2).getReg(), NarrowTy, NumParts, Src1Regs);
1703 
1704   if (NumOps >= 3)
1705     extractParts(MI.getOperand(3).getReg(), NarrowTy, NumParts, Src2Regs);
1706 
1707   for (int i = 0; i < NumParts; ++i) {
1708     unsigned DstReg = MRI.createGenericVirtualRegister(NarrowTy);
1709 
1710     if (NumOps == 1)
1711       MIRBuilder.buildInstr(Opc, {DstReg}, {Src0Regs[i]}, Flags);
1712     else if (NumOps == 2) {
1713       MIRBuilder.buildInstr(Opc, {DstReg}, {Src0Regs[i], Src1Regs[i]}, Flags);
1714     } else if (NumOps == 3) {
1715       MIRBuilder.buildInstr(Opc, {DstReg},
1716                             {Src0Regs[i], Src1Regs[i], Src2Regs[i]}, Flags);
1717     }
1718 
1719     DstRegs.push_back(DstReg);
1720   }
1721 
1722   if (NarrowTy.isVector())
1723     MIRBuilder.buildConcatVectors(DstReg, DstRegs);
1724   else
1725     MIRBuilder.buildBuildVector(DstReg, DstRegs);
1726 
1727   MI.eraseFromParent();
1728   return Legalized;
1729 }
1730 
1731 LegalizerHelper::LegalizeResult
1732 LegalizerHelper::fewerElementsVectorCasts(MachineInstr &MI, unsigned TypeIdx,
1733                                           LLT NarrowTy) {
1734   if (TypeIdx != 0)
1735     return UnableToLegalize;
1736 
1737   unsigned DstReg = MI.getOperand(0).getReg();
1738   unsigned SrcReg = MI.getOperand(1).getReg();
1739   LLT DstTy = MRI.getType(DstReg);
1740   LLT SrcTy = MRI.getType(SrcReg);
1741 
1742   LLT NarrowTy0 = NarrowTy;
1743   LLT NarrowTy1;
1744   unsigned NumParts;
1745 
1746   if (NarrowTy.isVector()) {
1747     // Uneven breakdown not handled.
1748     NumParts = DstTy.getNumElements() / NarrowTy.getNumElements();
1749     if (NumParts * NarrowTy.getNumElements() != DstTy.getNumElements())
1750       return UnableToLegalize;
1751 
1752     NarrowTy1 = LLT::vector(NumParts, SrcTy.getElementType().getSizeInBits());
1753   } else {
1754     NumParts = DstTy.getNumElements();
1755     NarrowTy1 = SrcTy.getElementType();
1756   }
1757 
1758   SmallVector<unsigned, 4> SrcRegs, DstRegs;
1759   extractParts(SrcReg, NarrowTy1, NumParts, SrcRegs);
1760 
1761   for (unsigned I = 0; I < NumParts; ++I) {
1762     unsigned DstReg = MRI.createGenericVirtualRegister(NarrowTy0);
1763     MachineInstr *NewInst = MIRBuilder.buildInstr(MI.getOpcode())
1764       .addDef(DstReg)
1765       .addUse(SrcRegs[I]);
1766 
1767     NewInst->setFlags(MI.getFlags());
1768     DstRegs.push_back(DstReg);
1769   }
1770 
1771   if (NarrowTy.isVector())
1772     MIRBuilder.buildConcatVectors(DstReg, DstRegs);
1773   else
1774     MIRBuilder.buildBuildVector(DstReg, DstRegs);
1775 
1776   MI.eraseFromParent();
1777   return Legalized;
1778 }
1779 
1780 LegalizerHelper::LegalizeResult
1781 LegalizerHelper::fewerElementsVectorCmp(MachineInstr &MI, unsigned TypeIdx,
1782                                         LLT NarrowTy) {
1783   unsigned DstReg = MI.getOperand(0).getReg();
1784   unsigned Src0Reg = MI.getOperand(2).getReg();
1785   LLT DstTy = MRI.getType(DstReg);
1786   LLT SrcTy = MRI.getType(Src0Reg);
1787 
1788   unsigned NumParts;
1789   LLT NarrowTy0, NarrowTy1;
1790 
1791   if (TypeIdx == 0) {
1792     unsigned NewElts = NarrowTy.isVector() ? NarrowTy.getNumElements() : 1;
1793     unsigned OldElts = DstTy.getNumElements();
1794 
1795     NarrowTy0 = NarrowTy;
1796     NumParts = NarrowTy.isVector() ? (OldElts / NewElts) : DstTy.getNumElements();
1797     NarrowTy1 = NarrowTy.isVector() ?
1798       LLT::vector(NarrowTy.getNumElements(), SrcTy.getScalarSizeInBits()) :
1799       SrcTy.getElementType();
1800 
1801   } else {
1802     unsigned NewElts = NarrowTy.isVector() ? NarrowTy.getNumElements() : 1;
1803     unsigned OldElts = SrcTy.getNumElements();
1804 
1805     NumParts = NarrowTy.isVector() ? (OldElts / NewElts) :
1806       NarrowTy.getNumElements();
1807     NarrowTy0 = LLT::vector(NarrowTy.getNumElements(),
1808                             DstTy.getScalarSizeInBits());
1809     NarrowTy1 = NarrowTy;
1810   }
1811 
1812   // FIXME: Don't know how to handle the situation where the small vectors
1813   // aren't all the same size yet.
1814   if (NarrowTy1.isVector() &&
1815       NarrowTy1.getNumElements() * NumParts != DstTy.getNumElements())
1816     return UnableToLegalize;
1817 
1818   CmpInst::Predicate Pred
1819     = static_cast<CmpInst::Predicate>(MI.getOperand(1).getPredicate());
1820 
1821   SmallVector<unsigned, 2> Src1Regs, Src2Regs, DstRegs;
1822   extractParts(MI.getOperand(2).getReg(), NarrowTy1, NumParts, Src1Regs);
1823   extractParts(MI.getOperand(3).getReg(), NarrowTy1, NumParts, Src2Regs);
1824 
1825   for (unsigned I = 0; I < NumParts; ++I) {
1826     unsigned DstReg = MRI.createGenericVirtualRegister(NarrowTy0);
1827     DstRegs.push_back(DstReg);
1828 
1829     if (MI.getOpcode() == TargetOpcode::G_ICMP)
1830       MIRBuilder.buildICmp(Pred, DstReg, Src1Regs[I], Src2Regs[I]);
1831     else {
1832       MachineInstr *NewCmp
1833         = MIRBuilder.buildFCmp(Pred, DstReg, Src1Regs[I], Src2Regs[I]);
1834       NewCmp->setFlags(MI.getFlags());
1835     }
1836   }
1837 
1838   if (NarrowTy1.isVector())
1839     MIRBuilder.buildConcatVectors(DstReg, DstRegs);
1840   else
1841     MIRBuilder.buildBuildVector(DstReg, DstRegs);
1842 
1843   MI.eraseFromParent();
1844   return Legalized;
1845 }
1846 
1847 LegalizerHelper::LegalizeResult
1848 LegalizerHelper::fewerElementsVectorSelect(MachineInstr &MI, unsigned TypeIdx,
1849                                            LLT NarrowTy) {
1850   unsigned DstReg = MI.getOperand(0).getReg();
1851   unsigned CondReg = MI.getOperand(1).getReg();
1852 
1853   unsigned NumParts = 0;
1854   LLT NarrowTy0, NarrowTy1;
1855 
1856   LLT DstTy = MRI.getType(DstReg);
1857   LLT CondTy = MRI.getType(CondReg);
1858   unsigned Size = DstTy.getSizeInBits();
1859 
1860   assert(TypeIdx == 0 || CondTy.isVector());
1861 
1862   if (TypeIdx == 0) {
1863     NarrowTy0 = NarrowTy;
1864     NarrowTy1 = CondTy;
1865 
1866     unsigned NarrowSize = NarrowTy0.getSizeInBits();
1867     // FIXME: Don't know how to handle the situation where the small vectors
1868     // aren't all the same size yet.
1869     if (Size % NarrowSize != 0)
1870       return UnableToLegalize;
1871 
1872     NumParts = Size / NarrowSize;
1873 
1874     // Need to break down the condition type
1875     if (CondTy.isVector()) {
1876       if (CondTy.getNumElements() == NumParts)
1877         NarrowTy1 = CondTy.getElementType();
1878       else
1879         NarrowTy1 = LLT::vector(CondTy.getNumElements() / NumParts,
1880                                 CondTy.getScalarSizeInBits());
1881     }
1882   } else {
1883     NumParts = CondTy.getNumElements();
1884     if (NarrowTy.isVector()) {
1885       // TODO: Handle uneven breakdown.
1886       if (NumParts * NarrowTy.getNumElements() != CondTy.getNumElements())
1887         return UnableToLegalize;
1888 
1889       return UnableToLegalize;
1890     } else {
1891       NarrowTy0 = DstTy.getElementType();
1892       NarrowTy1 = NarrowTy;
1893     }
1894   }
1895 
1896   SmallVector<unsigned, 2> DstRegs, Src0Regs, Src1Regs, Src2Regs;
1897   if (CondTy.isVector())
1898     extractParts(MI.getOperand(1).getReg(), NarrowTy1, NumParts, Src0Regs);
1899 
1900   extractParts(MI.getOperand(2).getReg(), NarrowTy0, NumParts, Src1Regs);
1901   extractParts(MI.getOperand(3).getReg(), NarrowTy0, NumParts, Src2Regs);
1902 
1903   for (unsigned i = 0; i < NumParts; ++i) {
1904     unsigned DstReg = MRI.createGenericVirtualRegister(NarrowTy0);
1905     MIRBuilder.buildSelect(DstReg, CondTy.isVector() ? Src0Regs[i] : CondReg,
1906                            Src1Regs[i], Src2Regs[i]);
1907     DstRegs.push_back(DstReg);
1908   }
1909 
1910   if (NarrowTy0.isVector())
1911     MIRBuilder.buildConcatVectors(DstReg, DstRegs);
1912   else
1913     MIRBuilder.buildBuildVector(DstReg, DstRegs);
1914 
1915   MI.eraseFromParent();
1916   return Legalized;
1917 }
1918 
1919 /// Try to break down \p OrigTy into \p NarrowTy sized pieces.
1920 ///
1921 /// Returns the number of \p NarrowTy elements needed to reconstruct \p OrigTy,
1922 /// with any leftover piece as type \p LeftoverTy
1923 ///
1924 /// Returns -1 if the breakdown is not satisfiable.
1925 static int getNarrowTypeBreakDown(LLT OrigTy, LLT NarrowTy, LLT &LeftoverTy) {
1926   assert(!LeftoverTy.isValid() && "this is an out argument");
1927 
1928   unsigned Size = OrigTy.getSizeInBits();
1929   unsigned NarrowSize = NarrowTy.getSizeInBits();
1930   unsigned NumParts = Size / NarrowSize;
1931   unsigned LeftoverSize = Size - NumParts * NarrowSize;
1932   assert(Size > NarrowSize);
1933 
1934   if (LeftoverSize == 0)
1935     return NumParts;
1936 
1937   if (NarrowTy.isVector()) {
1938     unsigned EltSize = OrigTy.getScalarSizeInBits();
1939     if (LeftoverSize % EltSize != 0)
1940       return -1;
1941     LeftoverTy = LLT::scalarOrVector(LeftoverSize / EltSize, EltSize);
1942   } else {
1943     LeftoverTy = LLT::scalar(LeftoverSize);
1944   }
1945 
1946   return NumParts;
1947 }
1948 
1949 LegalizerHelper::LegalizeResult
1950 LegalizerHelper::reduceLoadStoreWidth(MachineInstr &MI, unsigned TypeIdx,
1951                                       LLT NarrowTy) {
1952   // FIXME: Don't know how to handle secondary types yet.
1953   if (TypeIdx != 0)
1954     return UnableToLegalize;
1955 
1956   MachineMemOperand *MMO = *MI.memoperands_begin();
1957 
1958   // This implementation doesn't work for atomics. Give up instead of doing
1959   // something invalid.
1960   if (MMO->getOrdering() != AtomicOrdering::NotAtomic ||
1961       MMO->getFailureOrdering() != AtomicOrdering::NotAtomic)
1962     return UnableToLegalize;
1963 
1964   bool IsLoad = MI.getOpcode() == TargetOpcode::G_LOAD;
1965   unsigned ValReg = MI.getOperand(0).getReg();
1966   unsigned AddrReg = MI.getOperand(1).getReg();
1967   LLT ValTy = MRI.getType(ValReg);
1968 
1969   int NumParts = -1;
1970   LLT LeftoverTy;
1971   SmallVector<unsigned, 8> NarrowRegs, NarrowLeftoverRegs;
1972   if (IsLoad) {
1973     NumParts = getNarrowTypeBreakDown(ValTy, NarrowTy, LeftoverTy);
1974   } else {
1975     if (extractParts(ValReg, ValTy, NarrowTy, LeftoverTy, NarrowRegs,
1976                      NarrowLeftoverRegs))
1977       NumParts = NarrowRegs.size();
1978   }
1979 
1980   if (NumParts == -1)
1981     return UnableToLegalize;
1982 
1983   const LLT OffsetTy = LLT::scalar(MRI.getType(AddrReg).getScalarSizeInBits());
1984 
1985   unsigned TotalSize = ValTy.getSizeInBits();
1986 
1987   // Split the load/store into PartTy sized pieces starting at Offset. If this
1988   // is a load, return the new registers in ValRegs. For a store, each elements
1989   // of ValRegs should be PartTy. Returns the next offset that needs to be
1990   // handled.
1991   auto splitTypePieces = [=](LLT PartTy, SmallVectorImpl<unsigned> &ValRegs,
1992                              unsigned Offset) -> unsigned {
1993     MachineFunction &MF = MIRBuilder.getMF();
1994     unsigned PartSize = PartTy.getSizeInBits();
1995     for (unsigned Idx = 0, E = NumParts; Idx != E && Offset < TotalSize;
1996          Offset += PartSize, ++Idx) {
1997       unsigned ByteSize = PartSize / 8;
1998       unsigned ByteOffset = Offset / 8;
1999       unsigned NewAddrReg = 0;
2000 
2001       MIRBuilder.materializeGEP(NewAddrReg, AddrReg, OffsetTy, ByteOffset);
2002 
2003       MachineMemOperand *NewMMO =
2004         MF.getMachineMemOperand(MMO, ByteOffset, ByteSize);
2005 
2006       if (IsLoad) {
2007         unsigned Dst = MRI.createGenericVirtualRegister(PartTy);
2008         ValRegs.push_back(Dst);
2009         MIRBuilder.buildLoad(Dst, NewAddrReg, *NewMMO);
2010       } else {
2011         MIRBuilder.buildStore(ValRegs[Idx], NewAddrReg, *NewMMO);
2012       }
2013     }
2014 
2015     return Offset;
2016   };
2017 
2018   unsigned HandledOffset = splitTypePieces(NarrowTy, NarrowRegs, 0);
2019 
2020   // Handle the rest of the register if this isn't an even type breakdown.
2021   if (LeftoverTy.isValid())
2022     splitTypePieces(LeftoverTy, NarrowLeftoverRegs, HandledOffset);
2023 
2024   if (IsLoad) {
2025     insertParts(ValReg, ValTy, NarrowTy, NarrowRegs,
2026                 LeftoverTy, NarrowLeftoverRegs);
2027   }
2028 
2029   MI.eraseFromParent();
2030   return Legalized;
2031 }
2032 
2033 LegalizerHelper::LegalizeResult
2034 LegalizerHelper::fewerElementsVector(MachineInstr &MI, unsigned TypeIdx,
2035                                      LLT NarrowTy) {
2036   using namespace TargetOpcode;
2037 
2038   MIRBuilder.setInstr(MI);
2039   switch (MI.getOpcode()) {
2040   case G_IMPLICIT_DEF:
2041     return fewerElementsVectorImplicitDef(MI, TypeIdx, NarrowTy);
2042   case G_AND:
2043   case G_OR:
2044   case G_XOR:
2045   case G_ADD:
2046   case G_SUB:
2047   case G_MUL:
2048   case G_SMULH:
2049   case G_UMULH:
2050   case G_FADD:
2051   case G_FMUL:
2052   case G_FSUB:
2053   case G_FNEG:
2054   case G_FABS:
2055   case G_FDIV:
2056   case G_FREM:
2057   case G_FMA:
2058   case G_FPOW:
2059   case G_FEXP:
2060   case G_FEXP2:
2061   case G_FLOG:
2062   case G_FLOG2:
2063   case G_FLOG10:
2064   case G_FCEIL:
2065   case G_INTRINSIC_ROUND:
2066   case G_INTRINSIC_TRUNC:
2067   case G_FCOS:
2068   case G_FSIN:
2069   case G_FSQRT:
2070   case G_BSWAP:
2071     return fewerElementsVectorBasic(MI, TypeIdx, NarrowTy);
2072   case G_ZEXT:
2073   case G_SEXT:
2074   case G_ANYEXT:
2075   case G_FPEXT:
2076   case G_FPTRUNC:
2077   case G_SITOFP:
2078   case G_UITOFP:
2079   case G_FPTOSI:
2080   case G_FPTOUI:
2081   case G_INTTOPTR:
2082   case G_PTRTOINT:
2083     return fewerElementsVectorCasts(MI, TypeIdx, NarrowTy);
2084   case G_ICMP:
2085   case G_FCMP:
2086     return fewerElementsVectorCmp(MI, TypeIdx, NarrowTy);
2087   case G_SELECT:
2088     return fewerElementsVectorSelect(MI, TypeIdx, NarrowTy);
2089   case G_LOAD:
2090   case G_STORE:
2091     return reduceLoadStoreWidth(MI, TypeIdx, NarrowTy);
2092   default:
2093     return UnableToLegalize;
2094   }
2095 }
2096 
2097 LegalizerHelper::LegalizeResult
2098 LegalizerHelper::narrowScalarMul(MachineInstr &MI, unsigned TypeIdx, LLT NewTy) {
2099   unsigned DstReg = MI.getOperand(0).getReg();
2100   unsigned Src0 = MI.getOperand(1).getReg();
2101   unsigned Src1 = MI.getOperand(2).getReg();
2102   LLT Ty = MRI.getType(DstReg);
2103   if (Ty.isVector())
2104     return UnableToLegalize;
2105 
2106   unsigned Size = Ty.getSizeInBits();
2107   unsigned NewSize = Size / 2;
2108   if (Size != 2 * NewSize)
2109     return UnableToLegalize;
2110 
2111   LLT HalfTy = LLT::scalar(NewSize);
2112   // TODO: if HalfTy != NewTy, handle the breakdown all at once?
2113 
2114   unsigned ShiftAmt = MRI.createGenericVirtualRegister(Ty);
2115   unsigned Lo = MRI.createGenericVirtualRegister(HalfTy);
2116   unsigned Hi = MRI.createGenericVirtualRegister(HalfTy);
2117   unsigned ExtLo = MRI.createGenericVirtualRegister(Ty);
2118   unsigned ExtHi = MRI.createGenericVirtualRegister(Ty);
2119   unsigned ShiftedHi = MRI.createGenericVirtualRegister(Ty);
2120 
2121   SmallVector<unsigned, 2> Src0Parts;
2122   SmallVector<unsigned, 2> Src1Parts;
2123 
2124   extractParts(Src0, HalfTy, 2, Src0Parts);
2125   extractParts(Src1, HalfTy, 2, Src1Parts);
2126 
2127   MIRBuilder.buildMul(Lo, Src0Parts[0], Src1Parts[0]);
2128 
2129   // TODO: Use smulh or umulh depending on what the target has.
2130   MIRBuilder.buildUMulH(Hi, Src0Parts[1], Src1Parts[1]);
2131 
2132   MIRBuilder.buildConstant(ShiftAmt, NewSize);
2133   MIRBuilder.buildAnyExt(ExtHi, Hi);
2134   MIRBuilder.buildShl(ShiftedHi, ExtHi, ShiftAmt);
2135 
2136   MIRBuilder.buildZExt(ExtLo, Lo);
2137   MIRBuilder.buildOr(DstReg, ExtLo, ShiftedHi);
2138   MI.eraseFromParent();
2139   return Legalized;
2140 }
2141 
2142 LegalizerHelper::LegalizeResult
2143 LegalizerHelper::narrowScalarSelect(MachineInstr &MI, unsigned TypeIdx,
2144                                     LLT NarrowTy) {
2145   if (TypeIdx != 0)
2146     return UnableToLegalize;
2147 
2148   unsigned CondReg = MI.getOperand(1).getReg();
2149   LLT CondTy = MRI.getType(CondReg);
2150   if (CondTy.isVector()) // TODO: Handle vselect
2151     return UnableToLegalize;
2152 
2153   unsigned DstReg = MI.getOperand(0).getReg();
2154   LLT DstTy = MRI.getType(DstReg);
2155 
2156   SmallVector<unsigned, 4> DstRegs, DstLeftoverRegs;
2157   SmallVector<unsigned, 4> Src1Regs, Src1LeftoverRegs;
2158   SmallVector<unsigned, 4> Src2Regs, Src2LeftoverRegs;
2159   LLT LeftoverTy;
2160   if (!extractParts(MI.getOperand(2).getReg(), DstTy, NarrowTy, LeftoverTy,
2161                     Src1Regs, Src1LeftoverRegs))
2162     return UnableToLegalize;
2163 
2164   LLT Unused;
2165   if (!extractParts(MI.getOperand(3).getReg(), DstTy, NarrowTy, Unused,
2166                     Src2Regs, Src2LeftoverRegs))
2167     llvm_unreachable("inconsistent extractParts result");
2168 
2169   for (unsigned I = 0, E = Src1Regs.size(); I != E; ++I) {
2170     auto Select = MIRBuilder.buildSelect(NarrowTy,
2171                                          CondReg, Src1Regs[I], Src2Regs[I]);
2172     DstRegs.push_back(Select->getOperand(0).getReg());
2173   }
2174 
2175   for (unsigned I = 0, E = Src1LeftoverRegs.size(); I != E; ++I) {
2176     auto Select = MIRBuilder.buildSelect(
2177       LeftoverTy, CondReg, Src1LeftoverRegs[I], Src2LeftoverRegs[I]);
2178     DstLeftoverRegs.push_back(Select->getOperand(0).getReg());
2179   }
2180 
2181   insertParts(DstReg, DstTy, NarrowTy, DstRegs,
2182               LeftoverTy, DstLeftoverRegs);
2183 
2184   MI.eraseFromParent();
2185   return Legalized;
2186 }
2187 
2188 LegalizerHelper::LegalizeResult
2189 LegalizerHelper::lowerBitCount(MachineInstr &MI, unsigned TypeIdx, LLT Ty) {
2190   unsigned Opc = MI.getOpcode();
2191   auto &TII = *MI.getMF()->getSubtarget().getInstrInfo();
2192   auto isSupported = [this](const LegalityQuery &Q) {
2193     auto QAction = LI.getAction(Q).Action;
2194     return QAction == Legal || QAction == Libcall || QAction == Custom;
2195   };
2196   switch (Opc) {
2197   default:
2198     return UnableToLegalize;
2199   case TargetOpcode::G_CTLZ_ZERO_UNDEF: {
2200     // This trivially expands to CTLZ.
2201     Observer.changingInstr(MI);
2202     MI.setDesc(TII.get(TargetOpcode::G_CTLZ));
2203     Observer.changedInstr(MI);
2204     return Legalized;
2205   }
2206   case TargetOpcode::G_CTLZ: {
2207     unsigned SrcReg = MI.getOperand(1).getReg();
2208     unsigned Len = Ty.getSizeInBits();
2209     if (isSupported({TargetOpcode::G_CTLZ_ZERO_UNDEF, {Ty, Ty}})) {
2210       // If CTLZ_ZERO_UNDEF is supported, emit that and a select for zero.
2211       auto MIBCtlzZU = MIRBuilder.buildInstr(TargetOpcode::G_CTLZ_ZERO_UNDEF,
2212                                              {Ty}, {SrcReg});
2213       auto MIBZero = MIRBuilder.buildConstant(Ty, 0);
2214       auto MIBLen = MIRBuilder.buildConstant(Ty, Len);
2215       auto MIBICmp = MIRBuilder.buildICmp(CmpInst::ICMP_EQ, LLT::scalar(1),
2216                                           SrcReg, MIBZero);
2217       MIRBuilder.buildSelect(MI.getOperand(0).getReg(), MIBICmp, MIBLen,
2218                              MIBCtlzZU);
2219       MI.eraseFromParent();
2220       return Legalized;
2221     }
2222     // for now, we do this:
2223     // NewLen = NextPowerOf2(Len);
2224     // x = x | (x >> 1);
2225     // x = x | (x >> 2);
2226     // ...
2227     // x = x | (x >>16);
2228     // x = x | (x >>32); // for 64-bit input
2229     // Upto NewLen/2
2230     // return Len - popcount(x);
2231     //
2232     // Ref: "Hacker's Delight" by Henry Warren
2233     unsigned Op = SrcReg;
2234     unsigned NewLen = PowerOf2Ceil(Len);
2235     for (unsigned i = 0; (1U << i) <= (NewLen / 2); ++i) {
2236       auto MIBShiftAmt = MIRBuilder.buildConstant(Ty, 1ULL << i);
2237       auto MIBOp = MIRBuilder.buildInstr(
2238           TargetOpcode::G_OR, {Ty},
2239           {Op, MIRBuilder.buildInstr(TargetOpcode::G_LSHR, {Ty},
2240                                      {Op, MIBShiftAmt})});
2241       Op = MIBOp->getOperand(0).getReg();
2242     }
2243     auto MIBPop = MIRBuilder.buildInstr(TargetOpcode::G_CTPOP, {Ty}, {Op});
2244     MIRBuilder.buildInstr(TargetOpcode::G_SUB, {MI.getOperand(0).getReg()},
2245                           {MIRBuilder.buildConstant(Ty, Len), MIBPop});
2246     MI.eraseFromParent();
2247     return Legalized;
2248   }
2249   case TargetOpcode::G_CTTZ_ZERO_UNDEF: {
2250     // This trivially expands to CTTZ.
2251     Observer.changingInstr(MI);
2252     MI.setDesc(TII.get(TargetOpcode::G_CTTZ));
2253     Observer.changedInstr(MI);
2254     return Legalized;
2255   }
2256   case TargetOpcode::G_CTTZ: {
2257     unsigned SrcReg = MI.getOperand(1).getReg();
2258     unsigned Len = Ty.getSizeInBits();
2259     if (isSupported({TargetOpcode::G_CTTZ_ZERO_UNDEF, {Ty, Ty}})) {
2260       // If CTTZ_ZERO_UNDEF is legal or custom, emit that and a select with
2261       // zero.
2262       auto MIBCttzZU = MIRBuilder.buildInstr(TargetOpcode::G_CTTZ_ZERO_UNDEF,
2263                                              {Ty}, {SrcReg});
2264       auto MIBZero = MIRBuilder.buildConstant(Ty, 0);
2265       auto MIBLen = MIRBuilder.buildConstant(Ty, Len);
2266       auto MIBICmp = MIRBuilder.buildICmp(CmpInst::ICMP_EQ, LLT::scalar(1),
2267                                           SrcReg, MIBZero);
2268       MIRBuilder.buildSelect(MI.getOperand(0).getReg(), MIBICmp, MIBLen,
2269                              MIBCttzZU);
2270       MI.eraseFromParent();
2271       return Legalized;
2272     }
2273     // for now, we use: { return popcount(~x & (x - 1)); }
2274     // unless the target has ctlz but not ctpop, in which case we use:
2275     // { return 32 - nlz(~x & (x-1)); }
2276     // Ref: "Hacker's Delight" by Henry Warren
2277     auto MIBCstNeg1 = MIRBuilder.buildConstant(Ty, -1);
2278     auto MIBNot =
2279         MIRBuilder.buildInstr(TargetOpcode::G_XOR, {Ty}, {SrcReg, MIBCstNeg1});
2280     auto MIBTmp = MIRBuilder.buildInstr(
2281         TargetOpcode::G_AND, {Ty},
2282         {MIBNot, MIRBuilder.buildInstr(TargetOpcode::G_ADD, {Ty},
2283                                        {SrcReg, MIBCstNeg1})});
2284     if (!isSupported({TargetOpcode::G_CTPOP, {Ty, Ty}}) &&
2285         isSupported({TargetOpcode::G_CTLZ, {Ty, Ty}})) {
2286       auto MIBCstLen = MIRBuilder.buildConstant(Ty, Len);
2287       MIRBuilder.buildInstr(
2288           TargetOpcode::G_SUB, {MI.getOperand(0).getReg()},
2289           {MIBCstLen,
2290            MIRBuilder.buildInstr(TargetOpcode::G_CTLZ, {Ty}, {MIBTmp})});
2291       MI.eraseFromParent();
2292       return Legalized;
2293     }
2294     MI.setDesc(TII.get(TargetOpcode::G_CTPOP));
2295     MI.getOperand(1).setReg(MIBTmp->getOperand(0).getReg());
2296     return Legalized;
2297   }
2298   }
2299 }
2300