1 //===-- lib/CodeGen/GlobalISel/GICombinerHelper.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 #include "llvm/CodeGen/GlobalISel/CombinerHelper.h"
9 #include "llvm/CodeGen/GlobalISel/Combiner.h"
10 #include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h"
11 #include "llvm/CodeGen/GlobalISel/GISelKnownBits.h"
12 #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
13 #include "llvm/CodeGen/GlobalISel/Utils.h"
14 #include "llvm/CodeGen/MachineDominators.h"
15 #include "llvm/CodeGen/MachineFrameInfo.h"
16 #include "llvm/CodeGen/MachineInstr.h"
17 #include "llvm/CodeGen/MachineRegisterInfo.h"
18 #include "llvm/CodeGen/TargetInstrInfo.h"
19 #include "llvm/CodeGen/TargetLowering.h"
20 #include "llvm/Target/TargetMachine.h"
21 
22 #define DEBUG_TYPE "gi-combiner"
23 
24 using namespace llvm;
25 
26 // Option to allow testing of the combiner while no targets know about indexed
27 // addressing.
28 static cl::opt<bool>
29     ForceLegalIndexing("force-legal-indexing", cl::Hidden, cl::init(false),
30                        cl::desc("Force all indexed operations to be "
31                                 "legal for the GlobalISel combiner"));
32 
33 
34 CombinerHelper::CombinerHelper(GISelChangeObserver &Observer,
35                                MachineIRBuilder &B, GISelKnownBits *KB,
36                                MachineDominatorTree *MDT)
37     : Builder(B), MRI(Builder.getMF().getRegInfo()), Observer(Observer),
38       KB(KB), MDT(MDT) {
39   (void)this->KB;
40 }
41 
42 void CombinerHelper::replaceRegWith(MachineRegisterInfo &MRI, Register FromReg,
43                                     Register ToReg) const {
44   Observer.changingAllUsesOfReg(MRI, FromReg);
45 
46   if (MRI.constrainRegAttrs(ToReg, FromReg))
47     MRI.replaceRegWith(FromReg, ToReg);
48   else
49     Builder.buildCopy(ToReg, FromReg);
50 
51   Observer.finishedChangingAllUsesOfReg();
52 }
53 
54 void CombinerHelper::replaceRegOpWith(MachineRegisterInfo &MRI,
55                                       MachineOperand &FromRegOp,
56                                       Register ToReg) const {
57   assert(FromRegOp.getParent() && "Expected an operand in an MI");
58   Observer.changingInstr(*FromRegOp.getParent());
59 
60   FromRegOp.setReg(ToReg);
61 
62   Observer.changedInstr(*FromRegOp.getParent());
63 }
64 
65 bool CombinerHelper::tryCombineCopy(MachineInstr &MI) {
66   if (matchCombineCopy(MI)) {
67     applyCombineCopy(MI);
68     return true;
69   }
70   return false;
71 }
72 bool CombinerHelper::matchCombineCopy(MachineInstr &MI) {
73   if (MI.getOpcode() != TargetOpcode::COPY)
74     return false;
75   Register DstReg = MI.getOperand(0).getReg();
76   Register SrcReg = MI.getOperand(1).getReg();
77   LLT DstTy = MRI.getType(DstReg);
78   LLT SrcTy = MRI.getType(SrcReg);
79   // Simple Copy Propagation.
80   // a(sx) = COPY b(sx) -> Replace all uses of a with b.
81   if (DstTy.isValid() && SrcTy.isValid() && DstTy == SrcTy)
82     return true;
83   return false;
84 }
85 void CombinerHelper::applyCombineCopy(MachineInstr &MI) {
86   Register DstReg = MI.getOperand(0).getReg();
87   Register SrcReg = MI.getOperand(1).getReg();
88   MI.eraseFromParent();
89   replaceRegWith(MRI, DstReg, SrcReg);
90 }
91 
92 namespace {
93 
94 /// Select a preference between two uses. CurrentUse is the current preference
95 /// while *ForCandidate is attributes of the candidate under consideration.
96 PreferredTuple ChoosePreferredUse(PreferredTuple &CurrentUse,
97                                   const LLT &TyForCandidate,
98                                   unsigned OpcodeForCandidate,
99                                   MachineInstr *MIForCandidate) {
100   if (!CurrentUse.Ty.isValid()) {
101     if (CurrentUse.ExtendOpcode == OpcodeForCandidate ||
102         CurrentUse.ExtendOpcode == TargetOpcode::G_ANYEXT)
103       return {TyForCandidate, OpcodeForCandidate, MIForCandidate};
104     return CurrentUse;
105   }
106 
107   // We permit the extend to hoist through basic blocks but this is only
108   // sensible if the target has extending loads. If you end up lowering back
109   // into a load and extend during the legalizer then the end result is
110   // hoisting the extend up to the load.
111 
112   // Prefer defined extensions to undefined extensions as these are more
113   // likely to reduce the number of instructions.
114   if (OpcodeForCandidate == TargetOpcode::G_ANYEXT &&
115       CurrentUse.ExtendOpcode != TargetOpcode::G_ANYEXT)
116     return CurrentUse;
117   else if (CurrentUse.ExtendOpcode == TargetOpcode::G_ANYEXT &&
118            OpcodeForCandidate != TargetOpcode::G_ANYEXT)
119     return {TyForCandidate, OpcodeForCandidate, MIForCandidate};
120 
121   // Prefer sign extensions to zero extensions as sign-extensions tend to be
122   // more expensive.
123   if (CurrentUse.Ty == TyForCandidate) {
124     if (CurrentUse.ExtendOpcode == TargetOpcode::G_SEXT &&
125         OpcodeForCandidate == TargetOpcode::G_ZEXT)
126       return CurrentUse;
127     else if (CurrentUse.ExtendOpcode == TargetOpcode::G_ZEXT &&
128              OpcodeForCandidate == TargetOpcode::G_SEXT)
129       return {TyForCandidate, OpcodeForCandidate, MIForCandidate};
130   }
131 
132   // This is potentially target specific. We've chosen the largest type
133   // because G_TRUNC is usually free. One potential catch with this is that
134   // some targets have a reduced number of larger registers than smaller
135   // registers and this choice potentially increases the live-range for the
136   // larger value.
137   if (TyForCandidate.getSizeInBits() > CurrentUse.Ty.getSizeInBits()) {
138     return {TyForCandidate, OpcodeForCandidate, MIForCandidate};
139   }
140   return CurrentUse;
141 }
142 
143 /// Find a suitable place to insert some instructions and insert them. This
144 /// function accounts for special cases like inserting before a PHI node.
145 /// The current strategy for inserting before PHI's is to duplicate the
146 /// instructions for each predecessor. However, while that's ok for G_TRUNC
147 /// on most targets since it generally requires no code, other targets/cases may
148 /// want to try harder to find a dominating block.
149 static void InsertInsnsWithoutSideEffectsBeforeUse(
150     MachineIRBuilder &Builder, MachineInstr &DefMI, MachineOperand &UseMO,
151     std::function<void(MachineBasicBlock *, MachineBasicBlock::iterator,
152                        MachineOperand &UseMO)>
153         Inserter) {
154   MachineInstr &UseMI = *UseMO.getParent();
155 
156   MachineBasicBlock *InsertBB = UseMI.getParent();
157 
158   // If the use is a PHI then we want the predecessor block instead.
159   if (UseMI.isPHI()) {
160     MachineOperand *PredBB = std::next(&UseMO);
161     InsertBB = PredBB->getMBB();
162   }
163 
164   // If the block is the same block as the def then we want to insert just after
165   // the def instead of at the start of the block.
166   if (InsertBB == DefMI.getParent()) {
167     MachineBasicBlock::iterator InsertPt = &DefMI;
168     Inserter(InsertBB, std::next(InsertPt), UseMO);
169     return;
170   }
171 
172   // Otherwise we want the start of the BB
173   Inserter(InsertBB, InsertBB->getFirstNonPHI(), UseMO);
174 }
175 } // end anonymous namespace
176 
177 bool CombinerHelper::tryCombineExtendingLoads(MachineInstr &MI) {
178   PreferredTuple Preferred;
179   if (matchCombineExtendingLoads(MI, Preferred)) {
180     applyCombineExtendingLoads(MI, Preferred);
181     return true;
182   }
183   return false;
184 }
185 
186 bool CombinerHelper::matchCombineExtendingLoads(MachineInstr &MI,
187                                                 PreferredTuple &Preferred) {
188   // We match the loads and follow the uses to the extend instead of matching
189   // the extends and following the def to the load. This is because the load
190   // must remain in the same position for correctness (unless we also add code
191   // to find a safe place to sink it) whereas the extend is freely movable.
192   // It also prevents us from duplicating the load for the volatile case or just
193   // for performance.
194 
195   if (MI.getOpcode() != TargetOpcode::G_LOAD &&
196       MI.getOpcode() != TargetOpcode::G_SEXTLOAD &&
197       MI.getOpcode() != TargetOpcode::G_ZEXTLOAD)
198     return false;
199 
200   auto &LoadValue = MI.getOperand(0);
201   assert(LoadValue.isReg() && "Result wasn't a register?");
202 
203   LLT LoadValueTy = MRI.getType(LoadValue.getReg());
204   if (!LoadValueTy.isScalar())
205     return false;
206 
207   // Most architectures are going to legalize <s8 loads into at least a 1 byte
208   // load, and the MMOs can only describe memory accesses in multiples of bytes.
209   // If we try to perform extload combining on those, we can end up with
210   // %a(s8) = extload %ptr (load 1 byte from %ptr)
211   // ... which is an illegal extload instruction.
212   if (LoadValueTy.getSizeInBits() < 8)
213     return false;
214 
215   // For non power-of-2 types, they will very likely be legalized into multiple
216   // loads. Don't bother trying to match them into extending loads.
217   if (!isPowerOf2_32(LoadValueTy.getSizeInBits()))
218     return false;
219 
220   // Find the preferred type aside from the any-extends (unless it's the only
221   // one) and non-extending ops. We'll emit an extending load to that type and
222   // and emit a variant of (extend (trunc X)) for the others according to the
223   // relative type sizes. At the same time, pick an extend to use based on the
224   // extend involved in the chosen type.
225   unsigned PreferredOpcode = MI.getOpcode() == TargetOpcode::G_LOAD
226                                  ? TargetOpcode::G_ANYEXT
227                                  : MI.getOpcode() == TargetOpcode::G_SEXTLOAD
228                                        ? TargetOpcode::G_SEXT
229                                        : TargetOpcode::G_ZEXT;
230   Preferred = {LLT(), PreferredOpcode, nullptr};
231   for (auto &UseMI : MRI.use_instructions(LoadValue.getReg())) {
232     if (UseMI.getOpcode() == TargetOpcode::G_SEXT ||
233         UseMI.getOpcode() == TargetOpcode::G_ZEXT ||
234         UseMI.getOpcode() == TargetOpcode::G_ANYEXT) {
235       Preferred = ChoosePreferredUse(Preferred,
236                                      MRI.getType(UseMI.getOperand(0).getReg()),
237                                      UseMI.getOpcode(), &UseMI);
238     }
239   }
240 
241   // There were no extends
242   if (!Preferred.MI)
243     return false;
244   // It should be impossible to chose an extend without selecting a different
245   // type since by definition the result of an extend is larger.
246   assert(Preferred.Ty != LoadValueTy && "Extending to same type?");
247 
248   LLVM_DEBUG(dbgs() << "Preferred use is: " << *Preferred.MI);
249   return true;
250 }
251 
252 void CombinerHelper::applyCombineExtendingLoads(MachineInstr &MI,
253                                                 PreferredTuple &Preferred) {
254   // Rewrite the load to the chosen extending load.
255   Register ChosenDstReg = Preferred.MI->getOperand(0).getReg();
256 
257   // Inserter to insert a truncate back to the original type at a given point
258   // with some basic CSE to limit truncate duplication to one per BB.
259   DenseMap<MachineBasicBlock *, MachineInstr *> EmittedInsns;
260   auto InsertTruncAt = [&](MachineBasicBlock *InsertIntoBB,
261                            MachineBasicBlock::iterator InsertBefore,
262                            MachineOperand &UseMO) {
263     MachineInstr *PreviouslyEmitted = EmittedInsns.lookup(InsertIntoBB);
264     if (PreviouslyEmitted) {
265       Observer.changingInstr(*UseMO.getParent());
266       UseMO.setReg(PreviouslyEmitted->getOperand(0).getReg());
267       Observer.changedInstr(*UseMO.getParent());
268       return;
269     }
270 
271     Builder.setInsertPt(*InsertIntoBB, InsertBefore);
272     Register NewDstReg = MRI.cloneVirtualRegister(MI.getOperand(0).getReg());
273     MachineInstr *NewMI = Builder.buildTrunc(NewDstReg, ChosenDstReg);
274     EmittedInsns[InsertIntoBB] = NewMI;
275     replaceRegOpWith(MRI, UseMO, NewDstReg);
276   };
277 
278   Observer.changingInstr(MI);
279   MI.setDesc(
280       Builder.getTII().get(Preferred.ExtendOpcode == TargetOpcode::G_SEXT
281                                ? TargetOpcode::G_SEXTLOAD
282                                : Preferred.ExtendOpcode == TargetOpcode::G_ZEXT
283                                      ? TargetOpcode::G_ZEXTLOAD
284                                      : TargetOpcode::G_LOAD));
285 
286   // Rewrite all the uses to fix up the types.
287   auto &LoadValue = MI.getOperand(0);
288   SmallVector<MachineOperand *, 4> Uses;
289   for (auto &UseMO : MRI.use_operands(LoadValue.getReg()))
290     Uses.push_back(&UseMO);
291 
292   for (auto *UseMO : Uses) {
293     MachineInstr *UseMI = UseMO->getParent();
294 
295     // If the extend is compatible with the preferred extend then we should fix
296     // up the type and extend so that it uses the preferred use.
297     if (UseMI->getOpcode() == Preferred.ExtendOpcode ||
298         UseMI->getOpcode() == TargetOpcode::G_ANYEXT) {
299       Register UseDstReg = UseMI->getOperand(0).getReg();
300       MachineOperand &UseSrcMO = UseMI->getOperand(1);
301       const LLT &UseDstTy = MRI.getType(UseDstReg);
302       if (UseDstReg != ChosenDstReg) {
303         if (Preferred.Ty == UseDstTy) {
304           // If the use has the same type as the preferred use, then merge
305           // the vregs and erase the extend. For example:
306           //    %1:_(s8) = G_LOAD ...
307           //    %2:_(s32) = G_SEXT %1(s8)
308           //    %3:_(s32) = G_ANYEXT %1(s8)
309           //    ... = ... %3(s32)
310           // rewrites to:
311           //    %2:_(s32) = G_SEXTLOAD ...
312           //    ... = ... %2(s32)
313           replaceRegWith(MRI, UseDstReg, ChosenDstReg);
314           Observer.erasingInstr(*UseMO->getParent());
315           UseMO->getParent()->eraseFromParent();
316         } else if (Preferred.Ty.getSizeInBits() < UseDstTy.getSizeInBits()) {
317           // If the preferred size is smaller, then keep the extend but extend
318           // from the result of the extending load. For example:
319           //    %1:_(s8) = G_LOAD ...
320           //    %2:_(s32) = G_SEXT %1(s8)
321           //    %3:_(s64) = G_ANYEXT %1(s8)
322           //    ... = ... %3(s64)
323           /// rewrites to:
324           //    %2:_(s32) = G_SEXTLOAD ...
325           //    %3:_(s64) = G_ANYEXT %2:_(s32)
326           //    ... = ... %3(s64)
327           replaceRegOpWith(MRI, UseSrcMO, ChosenDstReg);
328         } else {
329           // If the preferred size is large, then insert a truncate. For
330           // example:
331           //    %1:_(s8) = G_LOAD ...
332           //    %2:_(s64) = G_SEXT %1(s8)
333           //    %3:_(s32) = G_ZEXT %1(s8)
334           //    ... = ... %3(s32)
335           /// rewrites to:
336           //    %2:_(s64) = G_SEXTLOAD ...
337           //    %4:_(s8) = G_TRUNC %2:_(s32)
338           //    %3:_(s64) = G_ZEXT %2:_(s8)
339           //    ... = ... %3(s64)
340           InsertInsnsWithoutSideEffectsBeforeUse(Builder, MI, *UseMO,
341                                                  InsertTruncAt);
342         }
343         continue;
344       }
345       // The use is (one of) the uses of the preferred use we chose earlier.
346       // We're going to update the load to def this value later so just erase
347       // the old extend.
348       Observer.erasingInstr(*UseMO->getParent());
349       UseMO->getParent()->eraseFromParent();
350       continue;
351     }
352 
353     // The use isn't an extend. Truncate back to the type we originally loaded.
354     // This is free on many targets.
355     InsertInsnsWithoutSideEffectsBeforeUse(Builder, MI, *UseMO, InsertTruncAt);
356   }
357 
358   MI.getOperand(0).setReg(ChosenDstReg);
359   Observer.changedInstr(MI);
360 }
361 
362 bool CombinerHelper::isPredecessor(MachineInstr &DefMI, MachineInstr &UseMI) {
363   assert(DefMI.getParent() == UseMI.getParent());
364   if (&DefMI == &UseMI)
365     return false;
366 
367   // Loop through the basic block until we find one of the instructions.
368   MachineBasicBlock::const_iterator I = DefMI.getParent()->begin();
369   for (; &*I != &DefMI && &*I != &UseMI; ++I)
370     return &*I == &DefMI;
371 
372   llvm_unreachable("Block must contain instructions");
373 }
374 
375 bool CombinerHelper::dominates(MachineInstr &DefMI, MachineInstr &UseMI) {
376   if (MDT)
377     return MDT->dominates(&DefMI, &UseMI);
378   else if (DefMI.getParent() != UseMI.getParent())
379     return false;
380 
381   return isPredecessor(DefMI, UseMI);
382 }
383 
384 bool CombinerHelper::findPostIndexCandidate(MachineInstr &MI, Register &Addr,
385                                             Register &Base, Register &Offset) {
386   auto &MF = *MI.getParent()->getParent();
387   const auto &TLI = *MF.getSubtarget().getTargetLowering();
388 
389 #ifndef NDEBUG
390   unsigned Opcode = MI.getOpcode();
391   assert(Opcode == TargetOpcode::G_LOAD || Opcode == TargetOpcode::G_SEXTLOAD ||
392          Opcode == TargetOpcode::G_ZEXTLOAD || Opcode == TargetOpcode::G_STORE);
393 #endif
394 
395   Base = MI.getOperand(1).getReg();
396   MachineInstr *BaseDef = MRI.getUniqueVRegDef(Base);
397   if (BaseDef && BaseDef->getOpcode() == TargetOpcode::G_FRAME_INDEX)
398     return false;
399 
400   LLVM_DEBUG(dbgs() << "Searching for post-indexing opportunity for: " << MI);
401 
402   for (auto &Use : MRI.use_instructions(Base)) {
403     if (Use.getOpcode() != TargetOpcode::G_GEP)
404       continue;
405 
406     Offset = Use.getOperand(2).getReg();
407     if (!ForceLegalIndexing &&
408         !TLI.isIndexingLegal(MI, Base, Offset, /*IsPre*/ false, MRI)) {
409       LLVM_DEBUG(dbgs() << "    Ignoring candidate with illegal addrmode: "
410                         << Use);
411       continue;
412     }
413 
414     // Make sure the offset calculation is before the potentially indexed op.
415     // FIXME: we really care about dependency here. The offset calculation might
416     // be movable.
417     MachineInstr *OffsetDef = MRI.getUniqueVRegDef(Offset);
418     if (!OffsetDef || !dominates(*OffsetDef, MI)) {
419       LLVM_DEBUG(dbgs() << "    Ignoring candidate with offset after mem-op: "
420                         << Use);
421       continue;
422     }
423 
424     // FIXME: check whether all uses of Base are load/store with foldable
425     // addressing modes. If so, using the normal addr-modes is better than
426     // forming an indexed one.
427 
428     bool MemOpDominatesAddrUses = true;
429     for (auto &GEPUse : MRI.use_instructions(Use.getOperand(0).getReg())) {
430       if (!dominates(MI, GEPUse)) {
431         MemOpDominatesAddrUses = false;
432         break;
433       }
434     }
435 
436     if (!MemOpDominatesAddrUses) {
437       LLVM_DEBUG(
438           dbgs() << "    Ignoring candidate as memop does not dominate uses: "
439                  << Use);
440       continue;
441     }
442 
443     LLVM_DEBUG(dbgs() << "    Found match: " << Use);
444     Addr = Use.getOperand(0).getReg();
445     return true;
446   }
447 
448   return false;
449 }
450 
451 bool CombinerHelper::findPreIndexCandidate(MachineInstr &MI, Register &Addr,
452                                            Register &Base, Register &Offset) {
453   auto &MF = *MI.getParent()->getParent();
454   const auto &TLI = *MF.getSubtarget().getTargetLowering();
455 
456 #ifndef NDEBUG
457   unsigned Opcode = MI.getOpcode();
458   assert(Opcode == TargetOpcode::G_LOAD || Opcode == TargetOpcode::G_SEXTLOAD ||
459          Opcode == TargetOpcode::G_ZEXTLOAD || Opcode == TargetOpcode::G_STORE);
460 #endif
461 
462   Addr = MI.getOperand(1).getReg();
463   MachineInstr *AddrDef = getOpcodeDef(TargetOpcode::G_GEP, Addr, MRI);
464   if (!AddrDef || MRI.hasOneUse(Addr))
465     return false;
466 
467   Base = AddrDef->getOperand(1).getReg();
468   Offset = AddrDef->getOperand(2).getReg();
469 
470   LLVM_DEBUG(dbgs() << "Found potential pre-indexed load_store: " << MI);
471 
472   if (!ForceLegalIndexing &&
473       !TLI.isIndexingLegal(MI, Base, Offset, /*IsPre*/ true, MRI)) {
474     LLVM_DEBUG(dbgs() << "    Skipping, not legal for target");
475     return false;
476   }
477 
478   MachineInstr *BaseDef = getDefIgnoringCopies(Base, MRI);
479   if (BaseDef->getOpcode() == TargetOpcode::G_FRAME_INDEX) {
480     LLVM_DEBUG(dbgs() << "    Skipping, frame index would need copy anyway.");
481     return false;
482   }
483 
484   if (MI.getOpcode() == TargetOpcode::G_STORE) {
485     // Would require a copy.
486     if (Base == MI.getOperand(0).getReg()) {
487       LLVM_DEBUG(dbgs() << "    Skipping, storing base so need copy anyway.");
488       return false;
489     }
490 
491     // We're expecting one use of Addr in MI, but it could also be the
492     // value stored, which isn't actually dominated by the instruction.
493     if (MI.getOperand(0).getReg() == Addr) {
494       LLVM_DEBUG(dbgs() << "    Skipping, does not dominate all addr uses");
495       return false;
496     }
497   }
498 
499   // FIXME: check whether all uses of the base pointer are constant GEPs. That
500   // might allow us to end base's liveness here by adjusting the constant.
501 
502   for (auto &UseMI : MRI.use_instructions(Addr)) {
503     if (!dominates(MI, UseMI)) {
504       LLVM_DEBUG(dbgs() << "    Skipping, does not dominate all addr uses.");
505       return false;
506     }
507   }
508 
509   return true;
510 }
511 
512 bool CombinerHelper::tryCombineIndexedLoadStore(MachineInstr &MI) {
513   unsigned Opcode = MI.getOpcode();
514   if (Opcode != TargetOpcode::G_LOAD && Opcode != TargetOpcode::G_SEXTLOAD &&
515       Opcode != TargetOpcode::G_ZEXTLOAD && Opcode != TargetOpcode::G_STORE)
516     return false;
517 
518   bool IsStore = Opcode == TargetOpcode::G_STORE;
519   Register Addr, Base, Offset;
520   bool IsPre = findPreIndexCandidate(MI, Addr, Base, Offset);
521   if (!IsPre && !findPostIndexCandidate(MI, Addr, Base, Offset))
522     return false;
523 
524 
525   unsigned NewOpcode;
526   switch (Opcode) {
527   case TargetOpcode::G_LOAD:
528     NewOpcode = TargetOpcode::G_INDEXED_LOAD;
529     break;
530   case TargetOpcode::G_SEXTLOAD:
531     NewOpcode = TargetOpcode::G_INDEXED_SEXTLOAD;
532     break;
533   case TargetOpcode::G_ZEXTLOAD:
534     NewOpcode = TargetOpcode::G_INDEXED_ZEXTLOAD;
535     break;
536   case TargetOpcode::G_STORE:
537     NewOpcode = TargetOpcode::G_INDEXED_STORE;
538     break;
539   default:
540     llvm_unreachable("Unknown load/store opcode");
541   }
542 
543   MachineInstr &AddrDef = *MRI.getUniqueVRegDef(Addr);
544   MachineIRBuilder MIRBuilder(MI);
545   auto MIB = MIRBuilder.buildInstr(NewOpcode);
546   if (IsStore) {
547     MIB.addDef(Addr);
548     MIB.addUse(MI.getOperand(0).getReg());
549   } else {
550     MIB.addDef(MI.getOperand(0).getReg());
551     MIB.addDef(Addr);
552   }
553 
554   MIB.addUse(Base);
555   MIB.addUse(Offset);
556   MIB.addImm(IsPre);
557   MI.eraseFromParent();
558   AddrDef.eraseFromParent();
559 
560   LLVM_DEBUG(dbgs() << "    Combinined to indexed operation");
561   return true;
562 }
563 
564 bool CombinerHelper::matchElideBrByInvertingCond(MachineInstr &MI) {
565   if (MI.getOpcode() != TargetOpcode::G_BR)
566     return false;
567 
568   // Try to match the following:
569   // bb1:
570   //   %c(s32) = G_ICMP pred, %a, %b
571   //   %c1(s1) = G_TRUNC %c(s32)
572   //   G_BRCOND %c1, %bb2
573   //   G_BR %bb3
574   // bb2:
575   // ...
576   // bb3:
577 
578   // The above pattern does not have a fall through to the successor bb2, always
579   // resulting in a branch no matter which path is taken. Here we try to find
580   // and replace that pattern with conditional branch to bb3 and otherwise
581   // fallthrough to bb2.
582 
583   MachineBasicBlock *MBB = MI.getParent();
584   MachineBasicBlock::iterator BrIt(MI);
585   if (BrIt == MBB->begin())
586     return false;
587   assert(std::next(BrIt) == MBB->end() && "expected G_BR to be a terminator");
588 
589   MachineInstr *BrCond = &*std::prev(BrIt);
590   if (BrCond->getOpcode() != TargetOpcode::G_BRCOND)
591     return false;
592 
593   // Check that the next block is the conditional branch target.
594   if (!MBB->isLayoutSuccessor(BrCond->getOperand(1).getMBB()))
595     return false;
596 
597   MachineInstr *CmpMI = MRI.getVRegDef(BrCond->getOperand(0).getReg());
598   if (!CmpMI || CmpMI->getOpcode() != TargetOpcode::G_ICMP ||
599       !MRI.hasOneUse(CmpMI->getOperand(0).getReg()))
600     return false;
601   return true;
602 }
603 
604 bool CombinerHelper::tryElideBrByInvertingCond(MachineInstr &MI) {
605   if (!matchElideBrByInvertingCond(MI))
606     return false;
607   applyElideBrByInvertingCond(MI);
608   return true;
609 }
610 
611 void CombinerHelper::applyElideBrByInvertingCond(MachineInstr &MI) {
612   MachineBasicBlock *BrTarget = MI.getOperand(0).getMBB();
613   MachineBasicBlock::iterator BrIt(MI);
614   MachineInstr *BrCond = &*std::prev(BrIt);
615   MachineInstr *CmpMI = MRI.getVRegDef(BrCond->getOperand(0).getReg());
616 
617   CmpInst::Predicate InversePred = CmpInst::getInversePredicate(
618       (CmpInst::Predicate)CmpMI->getOperand(1).getPredicate());
619 
620   // Invert the G_ICMP condition.
621   Observer.changingInstr(*CmpMI);
622   CmpMI->getOperand(1).setPredicate(InversePred);
623   Observer.changedInstr(*CmpMI);
624 
625   // Change the conditional branch target.
626   Observer.changingInstr(*BrCond);
627   BrCond->getOperand(1).setMBB(BrTarget);
628   Observer.changedInstr(*BrCond);
629   MI.eraseFromParent();
630 }
631 
632 static bool shouldLowerMemFuncForSize(const MachineFunction &MF) {
633   // On Darwin, -Os means optimize for size without hurting performance, so
634   // only really optimize for size when -Oz (MinSize) is used.
635   if (MF.getTarget().getTargetTriple().isOSDarwin())
636     return MF.getFunction().hasMinSize();
637   return MF.getFunction().hasOptSize();
638 }
639 
640 // Returns a list of types to use for memory op lowering in MemOps. A partial
641 // port of findOptimalMemOpLowering in TargetLowering.
642 static bool findGISelOptimalMemOpLowering(
643     std::vector<LLT> &MemOps, unsigned Limit, uint64_t Size, unsigned DstAlign,
644     unsigned SrcAlign, bool IsMemset, bool ZeroMemset, bool MemcpyStrSrc,
645     bool AllowOverlap, unsigned DstAS, unsigned SrcAS,
646     const AttributeList &FuncAttributes, const TargetLowering &TLI) {
647   // If 'SrcAlign' is zero, that means the memory operation does not need to
648   // load the value, i.e. memset or memcpy from constant string. Otherwise,
649   // it's the inferred alignment of the source. 'DstAlign', on the other hand,
650   // is the specified alignment of the memory operation. If it is zero, that
651   // means it's possible to change the alignment of the destination.
652   // 'MemcpyStrSrc' indicates whether the memcpy source is constant so it does
653   // not need to be loaded.
654   if (SrcAlign != 0 && SrcAlign < DstAlign)
655     return false;
656 
657   LLT Ty = TLI.getOptimalMemOpLLT(Size, DstAlign, SrcAlign, IsMemset,
658                                   ZeroMemset, MemcpyStrSrc, FuncAttributes);
659 
660   if (Ty == LLT()) {
661     // Use the largest scalar type whose alignment constraints are satisfied.
662     // We only need to check DstAlign here as SrcAlign is always greater or
663     // equal to DstAlign (or zero).
664     Ty = LLT::scalar(64);
665     while (DstAlign && DstAlign < Ty.getSizeInBytes() &&
666            !TLI.allowsMisalignedMemoryAccesses(Ty, DstAS, DstAlign))
667       Ty = LLT::scalar(Ty.getSizeInBytes());
668     assert(Ty.getSizeInBits() > 0 && "Could not find valid type");
669     // FIXME: check for the largest legal type we can load/store to.
670   }
671 
672   unsigned NumMemOps = 0;
673   while (Size != 0) {
674     unsigned TySize = Ty.getSizeInBytes();
675     while (TySize > Size) {
676       // For now, only use non-vector load / store's for the left-over pieces.
677       LLT NewTy = Ty;
678       // FIXME: check for mem op safety and legality of the types. Not all of
679       // SDAGisms map cleanly to GISel concepts.
680       if (NewTy.isVector())
681         NewTy = NewTy.getSizeInBits() > 64 ? LLT::scalar(64) : LLT::scalar(32);
682       NewTy = LLT::scalar(PowerOf2Floor(NewTy.getSizeInBits() - 1));
683       unsigned NewTySize = NewTy.getSizeInBytes();
684       assert(NewTySize > 0 && "Could not find appropriate type");
685 
686       // If the new LLT cannot cover all of the remaining bits, then consider
687       // issuing a (or a pair of) unaligned and overlapping load / store.
688       bool Fast;
689       // Need to get a VT equivalent for allowMisalignedMemoryAccesses().
690       MVT VT = getMVTForLLT(Ty);
691       if (NumMemOps && AllowOverlap && NewTySize < Size &&
692           TLI.allowsMisalignedMemoryAccesses(
693               VT, DstAS, DstAlign, MachineMemOperand::MONone, &Fast) &&
694           Fast)
695         TySize = Size;
696       else {
697         Ty = NewTy;
698         TySize = NewTySize;
699       }
700     }
701 
702     if (++NumMemOps > Limit)
703       return false;
704 
705     MemOps.push_back(Ty);
706     Size -= TySize;
707   }
708 
709   return true;
710 }
711 
712 static Type *getTypeForLLT(LLT Ty, LLVMContext &C) {
713   if (Ty.isVector())
714     return VectorType::get(IntegerType::get(C, Ty.getScalarSizeInBits()),
715                            Ty.getNumElements());
716   return IntegerType::get(C, Ty.getSizeInBits());
717 }
718 
719 // Get a vectorized representation of the memset value operand, GISel edition.
720 static Register getMemsetValue(Register Val, LLT Ty, MachineIRBuilder &MIB) {
721   MachineRegisterInfo &MRI = *MIB.getMRI();
722   unsigned NumBits = Ty.getScalarSizeInBits();
723   auto ValVRegAndVal = getConstantVRegValWithLookThrough(Val, MRI);
724   if (!Ty.isVector() && ValVRegAndVal) {
725     unsigned KnownVal = ValVRegAndVal->Value;
726     APInt Scalar = APInt(8, KnownVal);
727     APInt SplatVal = APInt::getSplat(NumBits, Scalar);
728     return MIB.buildConstant(Ty, SplatVal).getReg(0);
729   }
730   // FIXME: for vector types create a G_BUILD_VECTOR.
731   if (Ty.isVector())
732     return Register();
733 
734   // Extend the byte value to the larger type, and then multiply by a magic
735   // value 0x010101... in order to replicate it across every byte.
736   LLT ExtType = Ty.getScalarType();
737   auto ZExt = MIB.buildZExtOrTrunc(ExtType, Val);
738   if (NumBits > 8) {
739     APInt Magic = APInt::getSplat(NumBits, APInt(8, 0x01));
740     auto MagicMI = MIB.buildConstant(ExtType, Magic);
741     Val = MIB.buildMul(ExtType, ZExt, MagicMI).getReg(0);
742   }
743 
744   assert(ExtType == Ty && "Vector memset value type not supported yet");
745   return Val;
746 }
747 
748 bool CombinerHelper::optimizeMemset(MachineInstr &MI, Register Dst, Register Val,
749                                     unsigned KnownLen, unsigned Align,
750                                     bool IsVolatile) {
751   auto &MF = *MI.getParent()->getParent();
752   const auto &TLI = *MF.getSubtarget().getTargetLowering();
753   auto &DL = MF.getDataLayout();
754   LLVMContext &C = MF.getFunction().getContext();
755 
756   assert(KnownLen != 0 && "Have a zero length memset length!");
757 
758   bool DstAlignCanChange = false;
759   MachineFrameInfo &MFI = MF.getFrameInfo();
760   bool OptSize = shouldLowerMemFuncForSize(MF);
761 
762   MachineInstr *FIDef = getOpcodeDef(TargetOpcode::G_FRAME_INDEX, Dst, MRI);
763   if (FIDef && !MFI.isFixedObjectIndex(FIDef->getOperand(1).getIndex()))
764     DstAlignCanChange = true;
765 
766   unsigned Limit = TLI.getMaxStoresPerMemset(OptSize);
767   std::vector<LLT> MemOps;
768 
769   const auto &DstMMO = **MI.memoperands_begin();
770   MachinePointerInfo DstPtrInfo = DstMMO.getPointerInfo();
771 
772   auto ValVRegAndVal = getConstantVRegValWithLookThrough(Val, MRI);
773   bool IsZeroVal = ValVRegAndVal && ValVRegAndVal->Value == 0;
774 
775   if (!findGISelOptimalMemOpLowering(
776           MemOps, Limit, KnownLen, (DstAlignCanChange ? 0 : Align), 0,
777           /*IsMemset=*/true,
778           /*ZeroMemset=*/IsZeroVal, /*MemcpyStrSrc=*/false,
779           /*AllowOverlap=*/!IsVolatile, DstPtrInfo.getAddrSpace(), ~0u,
780           MF.getFunction().getAttributes(), TLI))
781     return false;
782 
783   if (DstAlignCanChange) {
784     // Get an estimate of the type from the LLT.
785     Type *IRTy = getTypeForLLT(MemOps[0], C);
786     unsigned NewAlign = (unsigned)DL.getABITypeAlignment(IRTy);
787     if (NewAlign > Align) {
788       Align = NewAlign;
789       unsigned FI = FIDef->getOperand(1).getIndex();
790       // Give the stack frame object a larger alignment if needed.
791       if (MFI.getObjectAlignment(FI) < Align)
792         MFI.setObjectAlignment(FI, Align);
793     }
794   }
795 
796   MachineIRBuilder MIB(MI);
797   // Find the largest store and generate the bit pattern for it.
798   LLT LargestTy = MemOps[0];
799   for (unsigned i = 1; i < MemOps.size(); i++)
800     if (MemOps[i].getSizeInBits() > LargestTy.getSizeInBits())
801       LargestTy = MemOps[i];
802 
803   // The memset stored value is always defined as an s8, so in order to make it
804   // work with larger store types we need to repeat the bit pattern across the
805   // wider type.
806   Register MemSetValue = getMemsetValue(Val, LargestTy, MIB);
807 
808   if (!MemSetValue)
809     return false;
810 
811   // Generate the stores. For each store type in the list, we generate the
812   // matching store of that type to the destination address.
813   LLT PtrTy = MRI.getType(Dst);
814   unsigned DstOff = 0;
815   unsigned Size = KnownLen;
816   for (unsigned I = 0; I < MemOps.size(); I++) {
817     LLT Ty = MemOps[I];
818     unsigned TySize = Ty.getSizeInBytes();
819     if (TySize > Size) {
820       // Issuing an unaligned load / store pair that overlaps with the previous
821       // pair. Adjust the offset accordingly.
822       assert(I == MemOps.size() - 1 && I != 0);
823       DstOff -= TySize - Size;
824     }
825 
826     // If this store is smaller than the largest store see whether we can get
827     // the smaller value for free with a truncate.
828     Register Value = MemSetValue;
829     if (Ty.getSizeInBits() < LargestTy.getSizeInBits()) {
830       MVT VT = getMVTForLLT(Ty);
831       MVT LargestVT = getMVTForLLT(LargestTy);
832       if (!LargestTy.isVector() && !Ty.isVector() &&
833           TLI.isTruncateFree(LargestVT, VT))
834         Value = MIB.buildTrunc(Ty, MemSetValue).getReg(0);
835       else
836         Value = getMemsetValue(Val, Ty, MIB);
837       if (!Value)
838         return false;
839     }
840 
841     auto *StoreMMO =
842         MF.getMachineMemOperand(&DstMMO, DstOff, Ty.getSizeInBytes());
843 
844     Register Ptr = Dst;
845     if (DstOff != 0) {
846       auto Offset =
847           MIB.buildConstant(LLT::scalar(PtrTy.getSizeInBits()), DstOff);
848       Ptr = MIB.buildGEP(PtrTy, Dst, Offset).getReg(0);
849     }
850 
851     MIB.buildStore(Value, Ptr, *StoreMMO);
852     DstOff += Ty.getSizeInBytes();
853     Size -= TySize;
854   }
855 
856   MI.eraseFromParent();
857   return true;
858 }
859 
860 
861 bool CombinerHelper::optimizeMemcpy(MachineInstr &MI, Register Dst,
862                                     Register Src, unsigned KnownLen,
863                                     unsigned DstAlign, unsigned SrcAlign,
864                                     bool IsVolatile) {
865   auto &MF = *MI.getParent()->getParent();
866   const auto &TLI = *MF.getSubtarget().getTargetLowering();
867   auto &DL = MF.getDataLayout();
868   LLVMContext &C = MF.getFunction().getContext();
869 
870   assert(KnownLen != 0 && "Have a zero length memcpy length!");
871 
872   bool DstAlignCanChange = false;
873   MachineFrameInfo &MFI = MF.getFrameInfo();
874   bool OptSize = shouldLowerMemFuncForSize(MF);
875   unsigned Alignment = MinAlign(DstAlign, SrcAlign);
876 
877   MachineInstr *FIDef = getOpcodeDef(TargetOpcode::G_FRAME_INDEX, Dst, MRI);
878   if (FIDef && !MFI.isFixedObjectIndex(FIDef->getOperand(1).getIndex()))
879     DstAlignCanChange = true;
880 
881   // FIXME: infer better src pointer alignment like SelectionDAG does here.
882   // FIXME: also use the equivalent of isMemSrcFromConstant and alwaysinlining
883   // if the memcpy is in a tail call position.
884 
885   unsigned Limit = TLI.getMaxStoresPerMemcpy(OptSize);
886   std::vector<LLT> MemOps;
887 
888   const auto &DstMMO = **MI.memoperands_begin();
889   const auto &SrcMMO = **std::next(MI.memoperands_begin());
890   MachinePointerInfo DstPtrInfo = DstMMO.getPointerInfo();
891   MachinePointerInfo SrcPtrInfo = SrcMMO.getPointerInfo();
892 
893   if (!findGISelOptimalMemOpLowering(
894           MemOps, Limit, KnownLen, (DstAlignCanChange ? 0 : Alignment),
895           SrcAlign,
896           /*IsMemset=*/false,
897           /*ZeroMemset=*/false, /*MemcpyStrSrc=*/false,
898           /*AllowOverlap=*/!IsVolatile, DstPtrInfo.getAddrSpace(),
899           SrcPtrInfo.getAddrSpace(), MF.getFunction().getAttributes(), TLI))
900     return false;
901 
902   if (DstAlignCanChange) {
903     // Get an estimate of the type from the LLT.
904     Type *IRTy = getTypeForLLT(MemOps[0], C);
905     unsigned NewAlign = (unsigned)DL.getABITypeAlignment(IRTy);
906 
907     // Don't promote to an alignment that would require dynamic stack
908     // realignment.
909     const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
910     if (!TRI->needsStackRealignment(MF))
911       while (NewAlign > Alignment &&
912              DL.exceedsNaturalStackAlignment(Align(NewAlign)))
913         NewAlign /= 2;
914 
915     if (NewAlign > Alignment) {
916       Alignment = NewAlign;
917       unsigned FI = FIDef->getOperand(1).getIndex();
918       // Give the stack frame object a larger alignment if needed.
919       if (MFI.getObjectAlignment(FI) < Alignment)
920         MFI.setObjectAlignment(FI, Alignment);
921     }
922   }
923 
924   LLVM_DEBUG(dbgs() << "Inlining memcpy: " << MI << " into loads & stores\n");
925 
926   MachineIRBuilder MIB(MI);
927   // Now we need to emit a pair of load and stores for each of the types we've
928   // collected. I.e. for each type, generate a load from the source pointer of
929   // that type width, and then generate a corresponding store to the dest buffer
930   // of that value loaded. This can result in a sequence of loads and stores
931   // mixed types, depending on what the target specifies as good types to use.
932   unsigned CurrOffset = 0;
933   LLT PtrTy = MRI.getType(Src);
934   unsigned Size = KnownLen;
935   for (auto CopyTy : MemOps) {
936     // Issuing an unaligned load / store pair  that overlaps with the previous
937     // pair. Adjust the offset accordingly.
938     if (CopyTy.getSizeInBytes() > Size)
939       CurrOffset -= CopyTy.getSizeInBytes() - Size;
940 
941     // Construct MMOs for the accesses.
942     auto *LoadMMO =
943         MF.getMachineMemOperand(&SrcMMO, CurrOffset, CopyTy.getSizeInBytes());
944     auto *StoreMMO =
945         MF.getMachineMemOperand(&DstMMO, CurrOffset, CopyTy.getSizeInBytes());
946 
947     // Create the load.
948     Register LoadPtr = Src;
949     Register Offset;
950     if (CurrOffset != 0) {
951       Offset = MIB.buildConstant(LLT::scalar(PtrTy.getSizeInBits()), CurrOffset)
952                    .getReg(0);
953       LoadPtr = MIB.buildGEP(PtrTy, Src, Offset).getReg(0);
954     }
955     auto LdVal = MIB.buildLoad(CopyTy, LoadPtr, *LoadMMO);
956 
957     // Create the store.
958     Register StorePtr =
959         CurrOffset == 0 ? Dst : MIB.buildGEP(PtrTy, Dst, Offset).getReg(0);
960     MIB.buildStore(LdVal, StorePtr, *StoreMMO);
961     CurrOffset += CopyTy.getSizeInBytes();
962     Size -= CopyTy.getSizeInBytes();
963   }
964 
965   MI.eraseFromParent();
966   return true;
967 }
968 
969 bool CombinerHelper::optimizeMemmove(MachineInstr &MI, Register Dst,
970                                     Register Src, unsigned KnownLen,
971                                     unsigned DstAlign, unsigned SrcAlign,
972                                     bool IsVolatile) {
973   auto &MF = *MI.getParent()->getParent();
974   const auto &TLI = *MF.getSubtarget().getTargetLowering();
975   auto &DL = MF.getDataLayout();
976   LLVMContext &C = MF.getFunction().getContext();
977 
978   assert(KnownLen != 0 && "Have a zero length memmove length!");
979 
980   bool DstAlignCanChange = false;
981   MachineFrameInfo &MFI = MF.getFrameInfo();
982   bool OptSize = shouldLowerMemFuncForSize(MF);
983   unsigned Alignment = MinAlign(DstAlign, SrcAlign);
984 
985   MachineInstr *FIDef = getOpcodeDef(TargetOpcode::G_FRAME_INDEX, Dst, MRI);
986   if (FIDef && !MFI.isFixedObjectIndex(FIDef->getOperand(1).getIndex()))
987     DstAlignCanChange = true;
988 
989   unsigned Limit = TLI.getMaxStoresPerMemmove(OptSize);
990   std::vector<LLT> MemOps;
991 
992   const auto &DstMMO = **MI.memoperands_begin();
993   const auto &SrcMMO = **std::next(MI.memoperands_begin());
994   MachinePointerInfo DstPtrInfo = DstMMO.getPointerInfo();
995   MachinePointerInfo SrcPtrInfo = SrcMMO.getPointerInfo();
996 
997   // FIXME: SelectionDAG always passes false for 'AllowOverlap', apparently due
998   // to a bug in it's findOptimalMemOpLowering implementation. For now do the
999   // same thing here.
1000   if (!findGISelOptimalMemOpLowering(
1001           MemOps, Limit, KnownLen, (DstAlignCanChange ? 0 : Alignment),
1002           SrcAlign,
1003           /*IsMemset=*/false,
1004           /*ZeroMemset=*/false, /*MemcpyStrSrc=*/false,
1005           /*AllowOverlap=*/false, DstPtrInfo.getAddrSpace(),
1006           SrcPtrInfo.getAddrSpace(), MF.getFunction().getAttributes(), TLI))
1007     return false;
1008 
1009   if (DstAlignCanChange) {
1010     // Get an estimate of the type from the LLT.
1011     Type *IRTy = getTypeForLLT(MemOps[0], C);
1012     unsigned NewAlign = (unsigned)DL.getABITypeAlignment(IRTy);
1013 
1014     // Don't promote to an alignment that would require dynamic stack
1015     // realignment.
1016     const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
1017     if (!TRI->needsStackRealignment(MF))
1018       while (NewAlign > Alignment &&
1019              DL.exceedsNaturalStackAlignment(Align(NewAlign)))
1020         NewAlign /= 2;
1021 
1022     if (NewAlign > Alignment) {
1023       Alignment = NewAlign;
1024       unsigned FI = FIDef->getOperand(1).getIndex();
1025       // Give the stack frame object a larger alignment if needed.
1026       if (MFI.getObjectAlignment(FI) < Alignment)
1027         MFI.setObjectAlignment(FI, Alignment);
1028     }
1029   }
1030 
1031   LLVM_DEBUG(dbgs() << "Inlining memmove: " << MI << " into loads & stores\n");
1032 
1033   MachineIRBuilder MIB(MI);
1034   // Memmove requires that we perform the loads first before issuing the stores.
1035   // Apart from that, this loop is pretty much doing the same thing as the
1036   // memcpy codegen function.
1037   unsigned CurrOffset = 0;
1038   LLT PtrTy = MRI.getType(Src);
1039   SmallVector<Register, 16> LoadVals;
1040   for (auto CopyTy : MemOps) {
1041     // Construct MMO for the load.
1042     auto *LoadMMO =
1043         MF.getMachineMemOperand(&SrcMMO, CurrOffset, CopyTy.getSizeInBytes());
1044 
1045     // Create the load.
1046     Register LoadPtr = Src;
1047     if (CurrOffset != 0) {
1048       auto Offset =
1049           MIB.buildConstant(LLT::scalar(PtrTy.getSizeInBits()), CurrOffset);
1050       LoadPtr = MIB.buildGEP(PtrTy, Src, Offset).getReg(0);
1051     }
1052     LoadVals.push_back(MIB.buildLoad(CopyTy, LoadPtr, *LoadMMO).getReg(0));
1053     CurrOffset += CopyTy.getSizeInBytes();
1054   }
1055 
1056   CurrOffset = 0;
1057   for (unsigned I = 0; I < MemOps.size(); ++I) {
1058     LLT CopyTy = MemOps[I];
1059     // Now store the values loaded.
1060     auto *StoreMMO =
1061         MF.getMachineMemOperand(&DstMMO, CurrOffset, CopyTy.getSizeInBytes());
1062 
1063     Register StorePtr = Dst;
1064     if (CurrOffset != 0) {
1065       auto Offset =
1066           MIB.buildConstant(LLT::scalar(PtrTy.getSizeInBits()), CurrOffset);
1067       StorePtr = MIB.buildGEP(PtrTy, Dst, Offset).getReg(0);
1068     }
1069     MIB.buildStore(LoadVals[I], StorePtr, *StoreMMO);
1070     CurrOffset += CopyTy.getSizeInBytes();
1071   }
1072   MI.eraseFromParent();
1073   return true;
1074 }
1075 
1076 bool CombinerHelper::tryCombineMemCpyFamily(MachineInstr &MI, unsigned MaxLen) {
1077   // This combine is fairly complex so it's not written with a separate
1078   // matcher function.
1079   assert(MI.getOpcode() == TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS);
1080   Intrinsic::ID ID = (Intrinsic::ID)MI.getIntrinsicID();
1081   assert((ID == Intrinsic::memcpy || ID == Intrinsic::memmove ||
1082           ID == Intrinsic::memset) &&
1083          "Expected a memcpy like intrinsic");
1084 
1085   auto MMOIt = MI.memoperands_begin();
1086   const MachineMemOperand *MemOp = *MMOIt;
1087   bool IsVolatile = MemOp->isVolatile();
1088   // Don't try to optimize volatile.
1089   if (IsVolatile)
1090     return false;
1091 
1092   unsigned DstAlign = MemOp->getBaseAlignment();
1093   unsigned SrcAlign = 0;
1094   Register Dst = MI.getOperand(1).getReg();
1095   Register Src = MI.getOperand(2).getReg();
1096   Register Len = MI.getOperand(3).getReg();
1097 
1098   if (ID != Intrinsic::memset) {
1099     assert(MMOIt != MI.memoperands_end() && "Expected a second MMO on MI");
1100     MemOp = *(++MMOIt);
1101     SrcAlign = MemOp->getBaseAlignment();
1102   }
1103 
1104   // See if this is a constant length copy
1105   auto LenVRegAndVal = getConstantVRegValWithLookThrough(Len, MRI);
1106   if (!LenVRegAndVal)
1107     return false; // Leave it to the legalizer to lower it to a libcall.
1108   unsigned KnownLen = LenVRegAndVal->Value;
1109 
1110   if (KnownLen == 0) {
1111     MI.eraseFromParent();
1112     return true;
1113   }
1114 
1115   if (MaxLen && KnownLen > MaxLen)
1116     return false;
1117 
1118   if (ID == Intrinsic::memcpy)
1119     return optimizeMemcpy(MI, Dst, Src, KnownLen, DstAlign, SrcAlign, IsVolatile);
1120   if (ID == Intrinsic::memmove)
1121     return optimizeMemmove(MI, Dst, Src, KnownLen, DstAlign, SrcAlign, IsVolatile);
1122   if (ID == Intrinsic::memset)
1123     return optimizeMemset(MI, Dst, Src, KnownLen, DstAlign, IsVolatile);
1124   return false;
1125 }
1126 
1127 bool CombinerHelper::tryCombine(MachineInstr &MI) {
1128   if (tryCombineCopy(MI))
1129     return true;
1130   if (tryCombineExtendingLoads(MI))
1131     return true;
1132   if (tryCombineIndexedLoadStore(MI))
1133     return true;
1134   return false;
1135 }
1136