LLVM 24.0.0git
Utils.cpp
Go to the documentation of this file.
1//===- llvm/CodeGen/GlobalISel/Utils.cpp -------------------------*- C++ -*-==//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8/// \file This file implements the utility functions used by the GlobalISel
9/// pipeline.
10//===----------------------------------------------------------------------===//
11
13#include "llvm/ADT/APFloat.h"
14#include "llvm/ADT/APInt.h"
36#include "llvm/IR/Constants.h"
40#include <limits>
41#include <numeric>
42#include <optional>
43#include <tuple>
44
45#define DEBUG_TYPE "globalisel-utils"
46
47using namespace llvm;
48using namespace MIPatternMatch;
49
51 const TargetInstrInfo &TII,
52 const RegisterBankInfo &RBI, Register Reg,
53 const TargetRegisterClass &RegClass) {
54 if (!RBI.constrainGenericRegister(Reg, RegClass, MRI))
55 return MRI.createVirtualRegister(&RegClass);
56
57 return Reg;
58}
59
61 const MachineFunction &MF, const TargetRegisterInfo &TRI,
63 const RegisterBankInfo &RBI, MachineInstr &InsertPt,
64 const TargetRegisterClass &RegClass, MachineOperand &RegMO) {
65 Register Reg = RegMO.getReg();
66 // Assume physical registers are properly constrained.
67 assert(Reg.isVirtual() && "PhysReg not implemented");
68
69 // Save the old register class to check whether
70 // the change notifications will be required.
71 // TODO: A better approach would be to pass
72 // the observers to constrainRegToClass().
73 auto *OldRegClass = MRI.getRegClassOrNull(Reg);
74 Register ConstrainedReg = constrainRegToClass(MRI, TII, RBI, Reg, RegClass);
75 // If we created a new virtual register because the class is not compatible
76 // then create a copy between the new and the old register.
77 if (ConstrainedReg != Reg) {
78 MachineBasicBlock::iterator InsertIt(&InsertPt);
79 MachineBasicBlock &MBB = *InsertPt.getParent();
80 // FIXME: The copy needs to have the classes constrained for its operands.
81 // Use operand's regbank to get the class for old register (Reg).
82 if (RegMO.isUse()) {
83 BuildMI(MBB, InsertIt, InsertPt.getDebugLoc(),
84 TII.get(TargetOpcode::COPY), ConstrainedReg)
85 .addReg(Reg);
86 } else {
87 assert(RegMO.isDef() && "Must be a definition");
88 BuildMI(MBB, std::next(InsertIt), InsertPt.getDebugLoc(),
89 TII.get(TargetOpcode::COPY), Reg)
90 .addReg(ConstrainedReg);
91 }
92 if (GISelChangeObserver *Observer = MF.getObserver()) {
93 Observer->changingInstr(*RegMO.getParent());
94 }
95 RegMO.setReg(ConstrainedReg);
96 if (GISelChangeObserver *Observer = MF.getObserver()) {
97 Observer->changedInstr(*RegMO.getParent());
98 }
99 } else if (OldRegClass != MRI.getRegClassOrNull(Reg)) {
100 if (GISelChangeObserver *Observer = MF.getObserver()) {
101 if (!RegMO.isDef()) {
102 MachineInstr *RegDef = MRI.getVRegDef(Reg);
103 Observer->changedInstr(*RegDef);
104 }
105 Observer->changingAllUsesOfReg(MRI, Reg);
106 Observer->finishedChangingAllUsesOfReg();
107 }
108 }
109 return ConstrainedReg;
110}
111
113 const MachineFunction &MF, const TargetRegisterInfo &TRI,
115 const RegisterBankInfo &RBI, MachineInstr &InsertPt, const MCInstrDesc &II,
116 MachineOperand &RegMO, unsigned OpIdx) {
117 Register Reg = RegMO.getReg();
118 // Assume physical registers are properly constrained.
119 assert(Reg.isVirtual() && "PhysReg not implemented");
120
121 const TargetRegisterClass *OpRC = TII.getRegClass(II, OpIdx);
122 // Some of the target independent instructions, like COPY, may not impose any
123 // register class constraints on some of their operands: If it's a use, we can
124 // skip constraining as the instruction defining the register would constrain
125 // it.
126
127 if (OpRC) {
128 // Obtain the RC from incoming regbank if it is a proper sub-class. Operands
129 // can have multiple regbanks for a superclass that combine different
130 // register types (E.g., AMDGPU's VGPR and AGPR). The regbank ambiguity
131 // resolved by targets during regbankselect should not be overridden.
132 if (const auto *SubRC = TRI.getCommonSubClass(
133 OpRC, TRI.getConstrainedRegClassForReg(Reg, MRI)))
134 OpRC = SubRC;
135
136 OpRC = TRI.getAllocatableClass(OpRC);
137 }
138
139 if (!OpRC) {
140 assert((!isTargetSpecificOpcode(II.getOpcode()) || RegMO.isUse()) &&
141 "Register class constraint is required unless either the "
142 "instruction is target independent or the operand is a use");
143 // FIXME: Just bailing out like this here could be not enough, unless we
144 // expect the users of this function to do the right thing for PHIs and
145 // COPY:
146 // v1 = COPY v0
147 // v2 = COPY v1
148 // v1 here may end up not being constrained at all. Please notice that to
149 // reproduce the issue we likely need a destination pattern of a selection
150 // rule producing such extra copies, not just an input GMIR with them as
151 // every existing target using selectImpl handles copies before calling it
152 // and they never reach this function.
153 return Reg;
154 }
155 return constrainOperandRegClass(MF, TRI, MRI, TII, RBI, InsertPt, *OpRC,
156 RegMO);
157}
158
160 const TargetInstrInfo &TII,
161 const TargetRegisterInfo &TRI,
162 const RegisterBankInfo &RBI) {
163 assert(!isPreISelGenericOpcode(I.getOpcode()) &&
164 "A selected instruction is expected");
165 MachineBasicBlock &MBB = *I.getParent();
166 MachineFunction &MF = *MBB.getParent();
168
169 for (unsigned OpI = 0, OpE = I.getNumExplicitOperands(); OpI != OpE; ++OpI) {
170 MachineOperand &MO = I.getOperand(OpI);
171
172 // There's nothing to be done on non-register operands.
173 if (!MO.isReg())
174 continue;
175
176 LLVM_DEBUG(dbgs() << "Converting operand: " << MO << '\n');
177
178 Register Reg = MO.getReg();
179 // Physical registers don't need to be constrained.
180 if (Reg.isPhysical())
181 continue;
182
183 // Register operands with a value of 0 (e.g. predicate operands) don't need
184 // to be constrained.
185 if (Reg == 0)
186 continue;
187
188 // If the operand is a vreg, we should constrain its regclass, and only
189 // insert COPYs if that's impossible.
190 // constrainOperandRegClass does that for us.
191 constrainOperandRegClass(MF, TRI, MRI, TII, RBI, I, I.getDesc(), MO, OpI);
192
193 // Tie uses to defs as indicated in MCInstrDesc if this hasn't already been
194 // done.
195 if (MO.isUse()) {
196 int DefIdx = I.getDesc().getOperandConstraint(OpI, MCOI::TIED_TO);
197 if (DefIdx != -1 && !I.isRegTiedToUseOperand(DefIdx))
198 I.tieOperands(DefIdx, OpI);
199 }
200 }
201}
202
205 // Give up if either DstReg or SrcReg is a physical register.
206 if (DstReg.isPhysical() || SrcReg.isPhysical())
207 return false;
208 // Give up if the types don't match.
209 if (MRI.getType(DstReg) != MRI.getType(SrcReg))
210 return false;
211 // Replace if either DstReg has no constraints or the register
212 // constraints match.
213 const auto &DstRBC = MRI.getRegClassOrRegBank(DstReg);
214 if (!DstRBC || DstRBC == MRI.getRegClassOrRegBank(SrcReg))
215 return true;
216
217 // Otherwise match if the Src is already a regclass that is covered by the Dst
218 // RegBank.
219 return isa<const RegisterBank *>(DstRBC) && MRI.getRegClassOrNull(SrcReg) &&
220 cast<const RegisterBank *>(DstRBC)->covers(
221 *MRI.getRegClassOrNull(SrcReg));
222}
223
225 const MachineRegisterInfo &MRI) {
226 // Instructions without side-effects are dead iff they only define dead regs.
227 // This function is hot and this loop returns early in the common case,
228 // so only perform additional checks before this if absolutely necessary.
229 for (const auto &MO : MI.all_defs()) {
230 Register Reg = MO.getReg();
231 if (Reg.isPhysical() || !MRI.use_nodbg_empty(Reg))
232 return false;
233 }
234 return MI.wouldBeTriviallyDead();
235}
236
238 MachineFunction &MF,
241 bool IsGlobalISelAbortEnabled =
243 bool IsFatal = Severity == DS_Error && IsGlobalISelAbortEnabled;
244 // Print the function name explicitly if we don't have a debug location (which
245 // makes the diagnostic less useful) or if we're going to emit a raw error.
246 if (!R.getLocation().isValid() || IsFatal)
247 R << (" (in function: " + MF.getName() + ")").str();
248
249 if (IsFatal)
250 reportFatalUsageError(Twine(R.getMsg()));
251 else
252 MORE.emit(R);
253}
254
260
267
270 const char *PassName, StringRef Msg,
271 const MachineInstr &MI) {
272 MachineOptimizationRemarkMissed R(PassName, "GISelFailure: ",
273 MI.getDebugLoc(), MI.getParent());
274 R << Msg;
275 // Printing MI is expensive; only do it if expensive remarks are enabled.
277 MORE.allowExtraAnalysis(PassName))
278 R << ": " << ore::MNV("Inst", MI);
279 reportGISelFailure(MF, MORE, R);
280}
281
282unsigned llvm::getInverseGMinMaxOpcode(unsigned MinMaxOpc) {
283 switch (MinMaxOpc) {
284 case TargetOpcode::G_SMIN:
285 return TargetOpcode::G_SMAX;
286 case TargetOpcode::G_SMAX:
287 return TargetOpcode::G_SMIN;
288 case TargetOpcode::G_UMIN:
289 return TargetOpcode::G_UMAX;
290 case TargetOpcode::G_UMAX:
291 return TargetOpcode::G_UMIN;
292 default:
293 llvm_unreachable("unrecognized opcode");
294 }
295}
296
297std::optional<APInt> llvm::getIConstantVRegVal(Register VReg,
298 const MachineRegisterInfo &MRI) {
299 std::optional<ValueAndVReg> ValAndVReg = getIConstantVRegValWithLookThrough(
300 VReg, MRI, /*LookThroughInstrs*/ false);
301 assert((!ValAndVReg || ValAndVReg->VReg == VReg) &&
302 "Value found while looking through instrs");
303 if (!ValAndVReg)
304 return std::nullopt;
305 return ValAndVReg->Value;
306}
307
309 const MachineRegisterInfo &MRI) {
310 MachineInstr *Const = MRI.getVRegDef(Reg);
311 assert((Const && Const->getOpcode() == TargetOpcode::G_CONSTANT) &&
312 "expected a G_CONSTANT on Reg");
313 return Const->getOperand(1).getCImm()->getValue();
314}
315
316std::optional<int64_t>
318 std::optional<APInt> Val = getIConstantVRegVal(VReg, MRI);
319 if (Val && Val->getBitWidth() <= 64)
320 return Val->getSExtValue();
321 return std::nullopt;
322}
323
324namespace {
325
326// This function is used in many places, and as such, it has some
327// micro-optimizations to try and make it as fast as it can be.
328//
329// - We use template arguments to avoid an indirect call caused by passing a
330// function_ref/std::function
331// - GetAPCstValue does not return std::optional<APInt> as that's expensive.
332// Instead it returns true/false and places the result in a pre-constructed
333// APInt.
334//
335// Please change this function carefully and benchmark your changes.
336template <bool (*IsConstantOpcode)(const MachineInstr *),
337 bool (*GetAPCstValue)(const MachineInstr *MI, APInt &)>
338std::optional<ValueAndVReg>
339getConstantVRegValWithLookThrough(Register VReg, const MachineRegisterInfo &MRI,
340 bool LookThroughInstrs = true,
341 bool LookThroughAnyExt = false) {
344
345 while ((MI = MRI.getVRegDef(VReg)) && !IsConstantOpcode(MI) &&
346 LookThroughInstrs) {
347 switch (MI->getOpcode()) {
348 case TargetOpcode::G_ANYEXT:
349 if (!LookThroughAnyExt)
350 return std::nullopt;
351 [[fallthrough]];
352 case TargetOpcode::G_TRUNC:
353 case TargetOpcode::G_SEXT:
354 case TargetOpcode::G_ZEXT:
355 SeenOpcodes.push_back(std::make_pair(
356 MI->getOpcode(),
357 MRI.getType(MI->getOperand(0).getReg()).getSizeInBits()));
358 VReg = MI->getOperand(1).getReg();
359 break;
360 case TargetOpcode::COPY:
361 VReg = MI->getOperand(1).getReg();
362 if (VReg.isPhysical())
363 return std::nullopt;
364 break;
365 case TargetOpcode::G_INTTOPTR:
366 VReg = MI->getOperand(1).getReg();
367 break;
368 default:
369 return std::nullopt;
370 }
371 }
372 if (!MI || !IsConstantOpcode(MI))
373 return std::nullopt;
374
375 APInt Val;
376 if (!GetAPCstValue(MI, Val))
377 return std::nullopt;
378 for (auto &Pair : reverse(SeenOpcodes)) {
379 switch (Pair.first) {
380 case TargetOpcode::G_TRUNC:
381 Val = Val.trunc(Pair.second);
382 break;
383 case TargetOpcode::G_ANYEXT:
384 case TargetOpcode::G_SEXT:
385 Val = Val.sext(Pair.second);
386 break;
387 case TargetOpcode::G_ZEXT:
388 Val = Val.zext(Pair.second);
389 break;
390 }
391 }
392
393 return ValueAndVReg{std::move(Val), VReg};
394}
395
396bool isIConstant(const MachineInstr *MI) {
397 if (!MI)
398 return false;
399 return MI->getOpcode() == TargetOpcode::G_CONSTANT;
400}
401
402bool isFConstant(const MachineInstr *MI) {
403 if (!MI)
404 return false;
405 return MI->getOpcode() == TargetOpcode::G_FCONSTANT;
406}
407
408bool isAnyConstant(const MachineInstr *MI) {
409 if (!MI)
410 return false;
411 unsigned Opc = MI->getOpcode();
412 return Opc == TargetOpcode::G_CONSTANT || Opc == TargetOpcode::G_FCONSTANT;
413}
414
415bool getCImmAsAPInt(const MachineInstr *MI, APInt &Result) {
416 const MachineOperand &CstVal = MI->getOperand(1);
417 if (!CstVal.isCImm())
418 return false;
419 Result = CstVal.getCImm()->getValue();
420 return true;
421}
422
423bool getCImmOrFPImmAsAPInt(const MachineInstr *MI, APInt &Result) {
424 const MachineOperand &CstVal = MI->getOperand(1);
425 if (CstVal.isCImm())
426 Result = CstVal.getCImm()->getValue();
427 else if (CstVal.isFPImm())
429 else
430 return false;
431 return true;
432}
433
434} // end anonymous namespace
435
437 Register VReg, const MachineRegisterInfo &MRI, bool LookThroughInstrs) {
438 return getConstantVRegValWithLookThrough<isIConstant, getCImmAsAPInt>(
439 VReg, MRI, LookThroughInstrs);
440}
441
443 Register VReg, const MachineRegisterInfo &MRI, bool LookThroughInstrs,
444 bool LookThroughAnyExt) {
445 return getConstantVRegValWithLookThrough<isAnyConstant,
446 getCImmOrFPImmAsAPInt>(
447 VReg, MRI, LookThroughInstrs, LookThroughAnyExt);
448}
449
450std::optional<FPValueAndVReg> llvm::getFConstantVRegValWithLookThrough(
451 Register VReg, const MachineRegisterInfo &MRI, bool LookThroughInstrs) {
452 auto Reg =
453 getConstantVRegValWithLookThrough<isFConstant, getCImmOrFPImmAsAPInt>(
454 VReg, MRI, LookThroughInstrs);
455 if (!Reg)
456 return std::nullopt;
457
458 unsigned Width = Reg->Value.getBitWidth();
459 LLT Ty = MRI.getType(VReg);
460 if (Ty.isValid())
461 Ty = Ty.getScalarType();
462 // An FP-typed VReg is the format its users read, which a looked-through
463 // G_ZEXT/G_TRUNC round trip can make differ from the G_FCONSTANT's.
464 if (Ty.isFloat() && Ty.getSizeInBits() == Width)
465 return FPValueAndVReg{APFloat(getFltSemanticForLLT(Ty), Reg->Value),
466 Reg->VReg};
467
468 // Width alone can't tell half from bfloat, or identify x87/PPC formats.
469 const fltSemantics &CstSem =
471 if (APFloat::getSizeInBits(CstSem) == Width)
472 return FPValueAndVReg{APFloat(CstSem, Reg->Value), Reg->VReg};
473
474 // Resized by a looked-through G_TRUNC/G_SEXT/G_ZEXT: only the width is left,
475 // and it only identifies IEEE formats.
476 if (Width != 16 && Width != 32 && Width != 64 && Width != 128)
477 return std::nullopt;
478 return FPValueAndVReg{
479 APFloat(getFltSemanticForLLT(LLT::scalar(Width)), Reg->Value), Reg->VReg};
480}
481
482const ConstantFP *
484 MachineInstr *MI = MRI.getVRegDef(VReg);
485 if (TargetOpcode::G_FCONSTANT != MI->getOpcode())
486 return nullptr;
487 return MI->getOperand(1).getFPImm();
488}
489
490std::optional<DefinitionAndSourceRegister>
492 Register DefSrcReg = Reg;
493 // This assumes that the code is in SSA form, so there should only be one
494 // definition.
495 auto DefIt = MRI.def_begin(Reg);
496 if (DefIt == MRI.def_end())
497 return {};
498 MachineOperand &DefOpnd = *DefIt;
499 MachineInstr *DefMI = DefOpnd.getParent();
500 auto DstTy = MRI.getType(DefOpnd.getReg());
501 if (!DstTy.isValid())
502 return std::nullopt;
503 unsigned Opc = DefMI->getOpcode();
504 while (Opc == TargetOpcode::COPY || isPreISelGenericOptimizationHint(Opc)) {
505 Register SrcReg = DefMI->getOperand(1).getReg();
506 auto SrcTy = MRI.getType(SrcReg);
507 if (!SrcTy.isValid())
508 break;
509 DefMI = MRI.getVRegDef(SrcReg);
510 DefSrcReg = SrcReg;
511 Opc = DefMI->getOpcode();
512 }
513 return DefinitionAndSourceRegister{DefMI, DefSrcReg};
514}
515
517 const MachineRegisterInfo &MRI) {
518 std::optional<DefinitionAndSourceRegister> DefSrcReg =
520 return DefSrcReg ? DefSrcReg->MI : nullptr;
521}
522
524 const MachineRegisterInfo &MRI) {
525 std::optional<DefinitionAndSourceRegister> DefSrcReg =
527 return DefSrcReg ? DefSrcReg->Reg : Register();
528}
529
530void llvm::extractParts(Register Reg, LLT Ty, int NumParts,
532 MachineIRBuilder &MIRBuilder,
534 for (int i = 0; i < NumParts; ++i)
535 VRegs.push_back(MRI.createGenericVirtualRegister(Ty));
536 MIRBuilder.buildUnmerge(VRegs, Reg);
537}
538
539bool llvm::extractParts(Register Reg, LLT RegTy, LLT MainTy, LLT &LeftoverTy,
541 SmallVectorImpl<Register> &LeftoverRegs,
542 MachineIRBuilder &MIRBuilder,
544 assert(!LeftoverTy.isValid() && "this is an out argument");
545
546 unsigned RegSize = RegTy.getSizeInBits();
547 unsigned MainSize = MainTy.getSizeInBits();
548 unsigned NumParts = RegSize / MainSize;
549 unsigned LeftoverSize = RegSize - NumParts * MainSize;
550
551 // Use an unmerge when possible.
552 if (LeftoverSize == 0) {
553 for (unsigned I = 0; I < NumParts; ++I)
554 VRegs.push_back(MRI.createGenericVirtualRegister(MainTy));
555 MIRBuilder.buildUnmerge(VRegs, Reg);
556 return true;
557 }
558
559 // Try to use unmerge for irregular vector split where possible
560 // For example when splitting a <6 x i32> into <4 x i32> with <2 x i32>
561 // leftover, it becomes:
562 // <2 x i32> %2, <2 x i32>%3, <2 x i32> %4 = G_UNMERGE_VALUE <6 x i32> %1
563 // <4 x i32> %5 = G_CONCAT_VECTOR <2 x i32> %2, <2 x i32> %3
564 if (RegTy.isVector() && MainTy.isVector()) {
565 unsigned RegNumElts = RegTy.getNumElements();
566 unsigned MainNumElts = MainTy.getNumElements();
567 unsigned LeftoverNumElts = RegNumElts % MainNumElts;
568 // If can unmerge to LeftoverTy, do it
569 if (MainNumElts % LeftoverNumElts == 0 &&
570 RegNumElts % LeftoverNumElts == 0 &&
571 RegTy.getScalarSizeInBits() == MainTy.getScalarSizeInBits() &&
572 LeftoverNumElts > 1) {
573 LeftoverTy = LLT::fixed_vector(LeftoverNumElts, RegTy.getElementType());
574
575 // Unmerge the SrcReg to LeftoverTy vectors
576 SmallVector<Register, 4> UnmergeValues;
577 extractParts(Reg, LeftoverTy, RegNumElts / LeftoverNumElts, UnmergeValues,
578 MIRBuilder, MRI);
579
580 // Find how many LeftoverTy makes one MainTy
581 unsigned LeftoverPerMain = MainNumElts / LeftoverNumElts;
582 unsigned NumOfLeftoverVal =
583 ((RegNumElts % MainNumElts) / LeftoverNumElts);
584
585 // Create as many MainTy as possible using unmerged value
586 SmallVector<Register, 4> MergeValues;
587 for (unsigned I = 0; I < UnmergeValues.size() - NumOfLeftoverVal; I++) {
588 MergeValues.push_back(UnmergeValues[I]);
589 if (MergeValues.size() == LeftoverPerMain) {
590 VRegs.push_back(
591 MIRBuilder.buildMergeLikeInstr(MainTy, MergeValues).getReg(0));
592 MergeValues.clear();
593 }
594 }
595 // Populate LeftoverRegs with the leftovers
596 for (unsigned I = UnmergeValues.size() - NumOfLeftoverVal;
597 I < UnmergeValues.size(); I++) {
598 LeftoverRegs.push_back(UnmergeValues[I]);
599 }
600 return true;
601 }
602 }
603 // Perform irregular split. Leftover is last element of RegPieces.
604 if (MainTy.isVector()) {
605 SmallVector<Register, 8> RegPieces;
606 extractVectorParts(Reg, MainTy.getNumElements(), RegPieces, MIRBuilder,
607 MRI);
608 for (unsigned i = 0; i < RegPieces.size() - 1; ++i)
609 VRegs.push_back(RegPieces[i]);
610 LeftoverRegs.push_back(RegPieces[RegPieces.size() - 1]);
611 LeftoverTy = MRI.getType(LeftoverRegs[0]);
612 return true;
613 }
614
615 LeftoverTy = LLT::integer(LeftoverSize);
616 // For irregular sizes, extract the individual parts.
617 for (unsigned I = 0; I != NumParts; ++I) {
618 Register NewReg = MRI.createGenericVirtualRegister(MainTy);
619 VRegs.push_back(NewReg);
620 MIRBuilder.buildExtract(NewReg, Reg, MainSize * I);
621 }
622
623 for (unsigned Offset = MainSize * NumParts; Offset < RegSize;
624 Offset += LeftoverSize) {
625 Register NewReg = MRI.createGenericVirtualRegister(LeftoverTy);
626 LeftoverRegs.push_back(NewReg);
627 MIRBuilder.buildExtract(NewReg, Reg, Offset);
628 }
629
630 return true;
631}
632
633void llvm::extractVectorParts(Register Reg, unsigned NumElts,
635 MachineIRBuilder &MIRBuilder,
637 LLT RegTy = MRI.getType(Reg);
638 assert(RegTy.isVector() && "Expected a vector type");
639
640 LLT EltTy = RegTy.getElementType();
641 LLT NarrowTy = (NumElts == 1) ? EltTy : LLT::fixed_vector(NumElts, EltTy);
642 unsigned RegNumElts = RegTy.getNumElements();
643 unsigned LeftoverNumElts = RegNumElts % NumElts;
644 unsigned NumNarrowTyPieces = RegNumElts / NumElts;
645
646 // Perfect split without leftover
647 if (LeftoverNumElts == 0)
648 return extractParts(Reg, NarrowTy, NumNarrowTyPieces, VRegs, MIRBuilder,
649 MRI);
650
651 // Irregular split. Provide direct access to all elements for artifact
652 // combiner using unmerge to elements. Then build vectors with NumElts
653 // elements. Remaining element(s) will be (used to build vector) Leftover.
655 extractParts(Reg, EltTy, RegNumElts, Elts, MIRBuilder, MRI);
656
657 unsigned Offset = 0;
658 // Requested sub-vectors of NarrowTy.
659 for (unsigned i = 0; i < NumNarrowTyPieces; ++i, Offset += NumElts) {
660 ArrayRef<Register> Pieces(&Elts[Offset], NumElts);
661 VRegs.push_back(MIRBuilder.buildMergeLikeInstr(NarrowTy, Pieces).getReg(0));
662 }
663
664 // Leftover element(s).
665 if (LeftoverNumElts == 1) {
666 VRegs.push_back(Elts[Offset]);
667 } else {
668 LLT LeftoverTy = LLT::fixed_vector(LeftoverNumElts, EltTy);
669 ArrayRef<Register> Pieces(&Elts[Offset], LeftoverNumElts);
670 VRegs.push_back(
671 MIRBuilder.buildMergeLikeInstr(LeftoverTy, Pieces).getReg(0));
672 }
673}
674
676 const MachineRegisterInfo &MRI) {
678 return DefMI && DefMI->getOpcode() == Opcode ? DefMI : nullptr;
679}
680
681std::optional<APInt> llvm::ConstantFoldBinOp(unsigned Opcode,
682 const Register Op1,
683 const Register Op2,
684 const MachineRegisterInfo &MRI) {
685 auto MaybeOp2Cst = getAnyConstantVRegValWithLookThrough(Op2, MRI, false);
686 if (!MaybeOp2Cst)
687 return std::nullopt;
688
689 auto MaybeOp1Cst = getAnyConstantVRegValWithLookThrough(Op1, MRI, false);
690 if (!MaybeOp1Cst)
691 return std::nullopt;
692
693 const APInt &C1 = MaybeOp1Cst->Value;
694 const APInt &C2 = MaybeOp2Cst->Value;
695 switch (Opcode) {
696 default:
697 break;
698 case TargetOpcode::G_ADD:
699 return C1 + C2;
700 case TargetOpcode::G_PTR_ADD:
701 // Types can be of different width here.
702 // Result needs to be the same width as C1, so trunc or sext C2.
703 return C1 + C2.sextOrTrunc(C1.getBitWidth());
704 case TargetOpcode::G_AND:
705 return C1 & C2;
706 case TargetOpcode::G_ASHR:
707 return C1.ashr(C2);
708 case TargetOpcode::G_LSHR:
709 return C1.lshr(C2);
710 case TargetOpcode::G_MUL:
711 return C1 * C2;
712 case TargetOpcode::G_OR:
713 return C1 | C2;
714 case TargetOpcode::G_SHL:
715 return C1 << C2;
716 case TargetOpcode::G_SUB:
717 return C1 - C2;
718 case TargetOpcode::G_XOR:
719 return C1 ^ C2;
720 case TargetOpcode::G_UDIV:
721 if (!C2.getBoolValue())
722 break;
723 return C1.udiv(C2);
724 case TargetOpcode::G_SDIV:
725 if (!C2.getBoolValue())
726 break;
727 return C1.sdiv(C2);
728 case TargetOpcode::G_UREM:
729 if (!C2.getBoolValue())
730 break;
731 return C1.urem(C2);
732 case TargetOpcode::G_SREM:
733 if (!C2.getBoolValue())
734 break;
735 return C1.srem(C2);
736 case TargetOpcode::G_SMIN:
737 return APIntOps::smin(C1, C2);
738 case TargetOpcode::G_SMAX:
739 return APIntOps::smax(C1, C2);
740 case TargetOpcode::G_UMIN:
741 return APIntOps::umin(C1, C2);
742 case TargetOpcode::G_UMAX:
743 return APIntOps::umax(C1, C2);
744 }
745
746 return std::nullopt;
747}
748
749std::optional<APFloat>
750llvm::ConstantFoldFPBinOp(unsigned Opcode, const Register Op1,
751 const Register Op2, const MachineRegisterInfo &MRI) {
752 const ConstantFP *Op2Cst = getConstantFPVRegVal(Op2, MRI);
753 if (!Op2Cst)
754 return std::nullopt;
755
756 const ConstantFP *Op1Cst = getConstantFPVRegVal(Op1, MRI);
757 if (!Op1Cst)
758 return std::nullopt;
759
760 APFloat C1 = Op1Cst->getValueAPF();
761 const APFloat &C2 = Op2Cst->getValueAPF();
762 switch (Opcode) {
763 case TargetOpcode::G_FADD:
765 return C1;
766 case TargetOpcode::G_FSUB:
767 C1.subtract(C2, APFloat::rmNearestTiesToEven);
768 return C1;
769 case TargetOpcode::G_FMUL:
770 C1.multiply(C2, APFloat::rmNearestTiesToEven);
771 return C1;
772 case TargetOpcode::G_FDIV:
774 return C1;
775 case TargetOpcode::G_FREM:
776 C1.mod(C2);
777 return C1;
778 case TargetOpcode::G_FCOPYSIGN:
779 C1.copySign(C2);
780 return C1;
781 case TargetOpcode::G_FMINNUM:
782 return minnum(C1, C2);
783 case TargetOpcode::G_FMAXNUM:
784 return maxnum(C1, C2);
785 case TargetOpcode::G_FMINIMUM:
786 return minimum(C1, C2);
787 case TargetOpcode::G_FMAXIMUM:
788 return maximum(C1, C2);
789 case TargetOpcode::G_FMINIMUMNUM:
790 return minimumnum(C1, C2);
791 case TargetOpcode::G_FMAXIMUMNUM:
792 return maximumnum(C1, C2);
793 case TargetOpcode::G_FMINNUM_IEEE:
794 case TargetOpcode::G_FMAXNUM_IEEE:
795 // FIXME: These operations were unfortunately named. fminnum/fmaxnum do not
796 // follow the IEEE behavior for signaling nans and follow libm's fmin/fmax,
797 // and currently there isn't a nice wrapper in APFloat for the version with
798 // correct snan handling.
799 break;
800 default:
801 break;
802 }
803
804 return std::nullopt;
805}
806
808 const MachineRegisterInfo &MRI) {
809 if (auto *BV = getOpcodeDef<GBuildVector>(Reg, MRI))
810 return BV;
811
812 auto *Bitcast = getOpcodeDef(TargetOpcode::G_BITCAST, Reg, MRI);
813 if (!Bitcast)
814 return nullptr;
815
816 auto [Dst, DstTy, Src, SrcTy] = Bitcast->getFirst2RegLLTs();
817 if (!SrcTy.isVector() || !DstTy.isVector())
818 return nullptr;
819 if (SrcTy.getElementCount() != DstTy.getElementCount())
820 return nullptr;
821 if (SrcTy.getScalarSizeInBits() != DstTy.getScalarSizeInBits())
822 return nullptr;
823
824 return getOpcodeDef<GBuildVector>(Src, MRI);
825}
826
828llvm::ConstantFoldVectorBinop(unsigned Opcode, const Register Op1,
829 const Register Op2,
830 const MachineRegisterInfo &MRI) {
831 auto *SrcVec2 = getBuildVectorLikeDef(Op2, MRI);
832 if (!SrcVec2)
833 return SmallVector<APInt>();
834
835 auto *SrcVec1 = getBuildVectorLikeDef(Op1, MRI);
836 if (!SrcVec1)
837 return SmallVector<APInt>();
838
839 SmallVector<APInt> FoldedElements;
840 for (unsigned Idx = 0, E = SrcVec1->getNumSources(); Idx < E; ++Idx) {
841 auto MaybeCst = ConstantFoldBinOp(Opcode, SrcVec1->getSourceReg(Idx),
842 SrcVec2->getSourceReg(Idx), MRI);
843 if (!MaybeCst)
844 return SmallVector<APInt>();
845 FoldedElements.push_back(*MaybeCst);
846 }
847 return FoldedElements;
848}
849
851 const MachinePointerInfo &MPO) {
854 MachineFrameInfo &MFI = MF.getFrameInfo();
855 return commonAlignment(MFI.getObjectAlign(FSPV->getFrameIndex()),
856 MPO.Offset);
857 }
858
859 if (const Value *V = dyn_cast_if_present<const Value *>(MPO.V)) {
860 const Module *M = MF.getFunction().getParent();
861 return V->getPointerAlignment(M->getDataLayout());
862 }
863
864 return Align(1);
865}
866
868 const TargetInstrInfo &TII,
869 MCRegister PhysReg,
870 const TargetRegisterClass &RC,
871 const DebugLoc &DL, LLT RegTy) {
872 MachineBasicBlock &EntryMBB = MF.front();
874 Register LiveIn = MRI.getLiveInVirtReg(PhysReg);
875 if (LiveIn) {
876 MachineInstr *Def = MRI.getVRegDef(LiveIn);
877 if (Def) {
878 // FIXME: Should the verifier check this is in the entry block?
879 assert(Def->getParent() == &EntryMBB && "live-in copy not in entry block");
880 return LiveIn;
881 }
882
883 // It's possible the incoming argument register and copy was added during
884 // lowering, but later deleted due to being/becoming dead. If this happens,
885 // re-insert the copy.
886 } else {
887 // The live in register was not present, so add it.
888 LiveIn = MF.addLiveIn(PhysReg, &RC);
889 if (RegTy.isValid())
890 MRI.setType(LiveIn, RegTy);
891 }
892
893 BuildMI(EntryMBB, EntryMBB.begin(), DL, TII.get(TargetOpcode::COPY), LiveIn)
894 .addReg(PhysReg);
895 if (!EntryMBB.isLiveIn(PhysReg))
896 EntryMBB.addLiveIn(PhysReg);
897 return LiveIn;
898}
899
900std::optional<APInt> llvm::ConstantFoldExtOp(unsigned Opcode,
901 const Register Op1, uint64_t Imm,
902 const MachineRegisterInfo &MRI) {
903 auto MaybeOp1Cst = getIConstantVRegVal(Op1, MRI);
904 if (MaybeOp1Cst) {
905 switch (Opcode) {
906 default:
907 break;
908 case TargetOpcode::G_SEXT_INREG: {
909 LLT Ty = MRI.getType(Op1);
910 return MaybeOp1Cst->trunc(Imm).sext(Ty.getScalarSizeInBits());
911 }
912 }
913 }
914 return std::nullopt;
915}
916
917std::optional<APInt> llvm::ConstantFoldCastOp(unsigned Opcode, LLT DstTy,
918 const Register Op0,
919 const MachineRegisterInfo &MRI) {
920 std::optional<APInt> Val = getIConstantVRegVal(Op0, MRI);
921 if (!Val)
922 return Val;
923
924 const unsigned DstSize = DstTy.getScalarSizeInBits();
925
926 switch (Opcode) {
927 case TargetOpcode::G_SEXT:
928 return Val->sext(DstSize);
929 case TargetOpcode::G_ZEXT:
930 case TargetOpcode::G_ANYEXT:
931 // TODO: DAG considers target preference when constant folding any_extend.
932 return Val->zext(DstSize);
933 default:
934 break;
935 }
936
937 llvm_unreachable("unexpected cast opcode to constant fold");
938}
939
940std::optional<APFloat>
941llvm::ConstantFoldIntToFloat(unsigned Opcode, LLT DstTy, Register Src,
942 const MachineRegisterInfo &MRI) {
943 assert(Opcode == TargetOpcode::G_SITOFP || Opcode == TargetOpcode::G_UITOFP);
944 if (auto MaybeSrcVal = getIConstantVRegVal(Src, MRI)) {
945 APFloat DstVal(getFltSemanticForLLT(DstTy));
946 DstVal.convertFromAPInt(*MaybeSrcVal, Opcode == TargetOpcode::G_SITOFP,
948 return DstVal;
949 }
950 return std::nullopt;
951}
952
954llvm::ConstantFoldUnaryIntOp(unsigned Opcode, LLT DstTy, Register Src,
955 const MachineRegisterInfo &MRI) {
956 unsigned EltBits = DstTy.getScalarSizeInBits();
957 auto Fold = [Opcode, EltBits](const APInt &V) -> APInt {
958 switch (Opcode) {
959 case TargetOpcode::G_CTLZ:
960 case TargetOpcode::G_CTLZ_ZERO_POISON:
961 return APInt(EltBits, V.countl_zero());
962 case TargetOpcode::G_CTTZ:
963 case TargetOpcode::G_CTTZ_ZERO_POISON:
964 return APInt(EltBits, V.countr_zero());
965 case TargetOpcode::G_CTPOP:
966 return APInt(EltBits, V.popcount());
967 case TargetOpcode::G_ABS:
968 return V.abs();
969 case TargetOpcode::G_BSWAP:
970 return V.byteSwap();
971 case TargetOpcode::G_BITREVERSE:
972 return V.reverseBits();
973 }
974 llvm_unreachable("unexpected opcode in ConstantFoldUnaryIntOp");
975 };
976
977 auto tryFoldScalar = [&](Register R) -> std::optional<APInt> {
978 if (auto MaybeCst = getIConstantVRegVal(R, MRI))
979 return Fold(*MaybeCst);
980 return std::nullopt;
981 };
982 if (MRI.getType(Src).isVector()) {
983 auto *BV = getOpcodeDef<GBuildVector>(Src, MRI);
984 if (!BV)
985 return {};
987 for (unsigned SrcIdx = 0; SrcIdx < BV->getNumSources(); ++SrcIdx) {
988 if (auto MaybeFold = tryFoldScalar(BV->getSourceReg(SrcIdx))) {
989 Folded.emplace_back(std::move(*MaybeFold));
990 continue;
991 }
992 return {};
993 }
994 return Folded;
995 }
996 if (auto MaybeCst = tryFoldScalar(Src))
997 return {std::move(*MaybeCst)};
998 return {};
999}
1000
1001std::optional<SmallVector<APInt>>
1002llvm::ConstantFoldICmp(unsigned Pred, const Register Op1, const Register Op2,
1003 unsigned DstScalarSizeInBits, unsigned ExtOp,
1004 const MachineRegisterInfo &MRI) {
1005 assert(ExtOp == TargetOpcode::G_SEXT || ExtOp == TargetOpcode::G_ZEXT ||
1006 ExtOp == TargetOpcode::G_ANYEXT);
1007
1008 const LLT Ty = MRI.getType(Op1);
1009
1010 auto GetICmpResultCst = [&](bool IsTrue) {
1011 if (IsTrue)
1012 return ExtOp == TargetOpcode::G_SEXT
1013 ? APInt::getAllOnes(DstScalarSizeInBits)
1014 : APInt::getOneBitSet(DstScalarSizeInBits, 0);
1015 return APInt::getZero(DstScalarSizeInBits);
1016 };
1017
1018 auto TryFoldScalar = [&](Register LHS, Register RHS) -> std::optional<APInt> {
1019 auto RHSCst = getIConstantVRegVal(RHS, MRI);
1020 if (!RHSCst)
1021 return std::nullopt;
1022 auto LHSCst = getIConstantVRegVal(LHS, MRI);
1023 if (!LHSCst)
1024 return std::nullopt;
1025
1026 switch (Pred) {
1028 return GetICmpResultCst(LHSCst->eq(*RHSCst));
1030 return GetICmpResultCst(LHSCst->ne(*RHSCst));
1032 return GetICmpResultCst(LHSCst->ugt(*RHSCst));
1034 return GetICmpResultCst(LHSCst->uge(*RHSCst));
1036 return GetICmpResultCst(LHSCst->ult(*RHSCst));
1038 return GetICmpResultCst(LHSCst->ule(*RHSCst));
1040 return GetICmpResultCst(LHSCst->sgt(*RHSCst));
1042 return GetICmpResultCst(LHSCst->sge(*RHSCst));
1044 return GetICmpResultCst(LHSCst->slt(*RHSCst));
1046 return GetICmpResultCst(LHSCst->sle(*RHSCst));
1047 default:
1048 return std::nullopt;
1049 }
1050 };
1051
1052 SmallVector<APInt> FoldedICmps;
1053
1054 if (Ty.isVector()) {
1055 // Try to constant fold each element.
1056 auto *BV1 = getOpcodeDef<GBuildVector>(Op1, MRI);
1057 auto *BV2 = getOpcodeDef<GBuildVector>(Op2, MRI);
1058 if (!BV1 || !BV2)
1059 return std::nullopt;
1060 assert(BV1->getNumSources() == BV2->getNumSources() && "Invalid vectors");
1061 for (unsigned I = 0; I < BV1->getNumSources(); ++I) {
1062 if (auto MaybeFold =
1063 TryFoldScalar(BV1->getSourceReg(I), BV2->getSourceReg(I))) {
1064 FoldedICmps.emplace_back(*MaybeFold);
1065 continue;
1066 }
1067 return std::nullopt;
1068 }
1069 return FoldedICmps;
1070 }
1071
1072 if (auto MaybeCst = TryFoldScalar(Op1, Op2)) {
1073 FoldedICmps.emplace_back(*MaybeCst);
1074 return FoldedICmps;
1075 }
1076
1077 return std::nullopt;
1078}
1079
1081 GISelValueTracking *VT, bool OrNegative) {
1082 std::optional<DefinitionAndSourceRegister> DefSrcReg =
1084 if (!DefSrcReg)
1085 return false;
1086
1087 const MachineInstr &MI = *DefSrcReg->MI;
1088 const LLT Ty = MRI.getType(Reg);
1089
1090 auto IsPow2 = [OrNegative](const APInt &V) {
1091 return V.isPowerOf2() || (OrNegative && V.isNegatedPowerOf2());
1092 };
1093
1094 switch (MI.getOpcode()) {
1095 case TargetOpcode::G_CONSTANT: {
1096 unsigned BitWidth = Ty.getScalarSizeInBits();
1097 const ConstantInt *CI = MI.getOperand(1).getCImm();
1098 return IsPow2(CI->getValue().zextOrTrunc(BitWidth));
1099 }
1100 case TargetOpcode::G_SHL: {
1101 // A left-shift of a constant one will have exactly one bit set because
1102 // shifting the bit off the end is undefined.
1103
1104 // TODO: Constant splat
1105 if (auto ConstLHS = getIConstantVRegVal(MI.getOperand(1).getReg(), MRI)) {
1106 if (*ConstLHS == 1)
1107 return true;
1108 }
1109
1110 break;
1111 }
1112 case TargetOpcode::G_LSHR: {
1113 if (auto ConstLHS = getIConstantVRegVal(MI.getOperand(1).getReg(), MRI)) {
1114 if (ConstLHS->isSignMask())
1115 return true;
1116 }
1117
1118 break;
1119 }
1120 case TargetOpcode::G_BUILD_VECTOR: {
1121 // TODO: Probably should have a recursion depth guard since you could have
1122 // bitcasted vector elements.
1123 for (const MachineOperand &MO : llvm::drop_begin(MI.operands()))
1124 if (!isKnownToBeAPowerOfTwo(MO.getReg(), MRI, VT, OrNegative))
1125 return false;
1126
1127 return true;
1128 }
1129 case TargetOpcode::G_BUILD_VECTOR_TRUNC: {
1130 // Only handle constants since we would need to know if number of leading
1131 // zeros is greater than the truncation amount.
1132 const unsigned BitWidth = Ty.getScalarSizeInBits();
1133 for (const MachineOperand &MO : llvm::drop_begin(MI.operands())) {
1134 auto Const = getIConstantVRegVal(MO.getReg(), MRI);
1135 if (!Const || !IsPow2(Const->zextOrTrunc(BitWidth)))
1136 return false;
1137 }
1138
1139 return true;
1140 }
1141 default:
1142 break;
1143 }
1144
1145 if (!VT)
1146 return false;
1147
1148 // More could be done here, though the above checks are enough
1149 // to handle some common cases.
1150
1151 // Fall back to computeKnownBits to catch other known cases.
1152 KnownBits Known = VT->getKnownBits(Reg);
1153 return (Known.countMaxPopulation() == 1) && (Known.countMinPopulation() == 1);
1154}
1155
1159
1160LLT llvm::getLCMType(LLT OrigTy, LLT TargetTy) {
1161 if (OrigTy.getSizeInBits() == TargetTy.getSizeInBits())
1162 return OrigTy;
1163
1164 if (OrigTy.isVector() && TargetTy.isVector()) {
1165 LLT OrigElt = OrigTy.getElementType();
1166 LLT TargetElt = TargetTy.getElementType();
1167
1168 // TODO: The docstring for this function says the intention is to use this
1169 // function to build MERGE/UNMERGE instructions. It won't be the case that
1170 // we generate a MERGE/UNMERGE between fixed and scalable vector types. We
1171 // could implement getLCMType between the two in the future if there was a
1172 // need, but it is not worth it now as this function should not be used in
1173 // that way.
1174 assert(((OrigTy.isScalableVector() && !TargetTy.isFixedVector()) ||
1175 (OrigTy.isFixedVector() && !TargetTy.isScalableVector())) &&
1176 "getLCMType not implemented between fixed and scalable vectors.");
1177
1178 if (OrigElt.getSizeInBits() == TargetElt.getSizeInBits()) {
1179 int GCDMinElts = std::gcd(OrigTy.getElementCount().getKnownMinValue(),
1180 TargetTy.getElementCount().getKnownMinValue());
1181 // Prefer the original element type.
1182 ElementCount Mul = OrigTy.getElementCount() *
1183 TargetTy.getElementCount().getKnownMinValue();
1184 return LLT::vector(Mul.divideCoefficientBy(GCDMinElts),
1185 OrigTy.getElementType());
1186 }
1187 unsigned LCM = std::lcm(OrigTy.getSizeInBits().getKnownMinValue(),
1188 TargetTy.getSizeInBits().getKnownMinValue());
1189 return LLT::vector(
1190 ElementCount::get(LCM / OrigElt.getSizeInBits(), OrigTy.isScalable()),
1191 OrigElt);
1192 }
1193
1194 // One type is scalar, one type is vector
1195 if (OrigTy.isVector() || TargetTy.isVector()) {
1196 LLT VecTy = OrigTy.isVector() ? OrigTy : TargetTy;
1197 LLT ScalarTy = OrigTy.isVector() ? TargetTy : OrigTy;
1198 LLT EltTy = VecTy.getElementType();
1199 LLT OrigEltTy = OrigTy.isVector() ? OrigTy.getElementType() : OrigTy;
1200
1201 // Prefer scalar type from OrigTy.
1202 if (EltTy.getSizeInBits() == ScalarTy.getSizeInBits())
1203 return LLT::vector(VecTy.getElementCount(), OrigEltTy);
1204
1205 // Different size scalars. Create vector with the same total size.
1206 // LCM will take fixed/scalable from VecTy.
1207 unsigned LCM = std::lcm(EltTy.getSizeInBits().getFixedValue() *
1209 ScalarTy.getSizeInBits().getFixedValue());
1210 // Prefer type from OrigTy
1211 return LLT::vector(ElementCount::get(LCM / OrigEltTy.getSizeInBits(),
1212 VecTy.getElementCount().isScalable()),
1213 OrigEltTy);
1214 }
1215
1216 // At this point, both types are scalars of different size
1217 unsigned LCM = std::lcm(OrigTy.getSizeInBits().getFixedValue(),
1218 TargetTy.getSizeInBits().getFixedValue());
1219 // Preserve pointer types.
1220 if (LCM == OrigTy.getSizeInBits())
1221 return OrigTy;
1222 if (LCM == TargetTy.getSizeInBits())
1223 return TargetTy;
1224 return LLT::scalar(LCM);
1225}
1226
1227LLT llvm::getCoverTy(LLT OrigTy, LLT TargetTy) {
1228
1229 if ((OrigTy.isScalableVector() && TargetTy.isFixedVector()) ||
1230 (OrigTy.isFixedVector() && TargetTy.isScalableVector()))
1232 "getCoverTy not implemented between fixed and scalable vectors.");
1233
1234 if (!OrigTy.isVector() || !TargetTy.isVector() || OrigTy == TargetTy ||
1235 (OrigTy.getScalarSizeInBits() != TargetTy.getScalarSizeInBits()))
1236 return getLCMType(OrigTy, TargetTy);
1237
1238 unsigned OrigTyNumElts = OrigTy.getElementCount().getKnownMinValue();
1239 unsigned TargetTyNumElts = TargetTy.getElementCount().getKnownMinValue();
1240 if (OrigTyNumElts % TargetTyNumElts == 0)
1241 return OrigTy;
1242
1243 unsigned NumElts = alignTo(OrigTyNumElts, TargetTyNumElts);
1245 OrigTy.getElementType());
1246}
1247
1248LLT llvm::getGCDType(LLT OrigTy, LLT TargetTy) {
1249 if (OrigTy.getSizeInBits() == TargetTy.getSizeInBits())
1250 return OrigTy;
1251
1252 if (OrigTy.isVector() && TargetTy.isVector()) {
1253 LLT OrigElt = OrigTy.getElementType();
1254
1255 // TODO: The docstring for this function says the intention is to use this
1256 // function to build MERGE/UNMERGE instructions. It won't be the case that
1257 // we generate a MERGE/UNMERGE between fixed and scalable vector types. We
1258 // could implement getGCDType between the two in the future if there was a
1259 // need, but it is not worth it now as this function should not be used in
1260 // that way.
1261 assert(((OrigTy.isScalableVector() && !TargetTy.isFixedVector()) ||
1262 (OrigTy.isFixedVector() && !TargetTy.isScalableVector())) &&
1263 "getGCDType not implemented between fixed and scalable vectors.");
1264
1265 unsigned GCD = std::gcd(OrigTy.getSizeInBits().getKnownMinValue(),
1266 TargetTy.getSizeInBits().getKnownMinValue());
1267 if (GCD == OrigElt.getSizeInBits())
1269 OrigElt);
1270
1271 // Cannot produce original element type, but both have vscale in common.
1272 if (GCD < OrigElt.getSizeInBits())
1274 GCD);
1275
1276 return LLT::vector(
1278 OrigTy.isScalable()),
1279 OrigElt);
1280 }
1281
1282 // If one type is vector and the element size matches the scalar size, then
1283 // the gcd is the scalar type.
1284 if (OrigTy.isVector() &&
1285 OrigTy.getElementType().getSizeInBits() == TargetTy.getSizeInBits())
1286 return OrigTy.getElementType();
1287 if (TargetTy.isVector() &&
1288 TargetTy.getElementType().getSizeInBits() == OrigTy.getSizeInBits())
1289 return OrigTy;
1290
1291 // At this point, both types are either scalars of different type or one is a
1292 // vector and one is a scalar. If both types are scalars, the GCD type is the
1293 // GCD between the two scalar sizes. If one is vector and one is scalar, then
1294 // the GCD type is the GCD between the scalar and the vector element size.
1295 LLT OrigScalar = OrigTy.getScalarType();
1296 LLT TargetScalar = TargetTy.getScalarType();
1297 unsigned GCD = std::gcd(OrigScalar.getSizeInBits().getFixedValue(),
1298 TargetScalar.getSizeInBits().getFixedValue());
1299 return LLT::integer(GCD);
1300}
1301
1303 assert(MI.getOpcode() == TargetOpcode::G_SHUFFLE_VECTOR &&
1304 "Only G_SHUFFLE_VECTOR can have a splat index!");
1305 ArrayRef<int> Mask = MI.getOperand(3).getShuffleMask();
1306 auto FirstDefinedIdx = find_if(Mask, [](int Elt) { return Elt >= 0; });
1307
1308 // If all elements are undefined, this shuffle can be considered a splat.
1309 // Return 0 for better potential for callers to simplify.
1310 if (FirstDefinedIdx == Mask.end())
1311 return 0;
1312
1313 // Make sure all remaining elements are either undef or the same
1314 // as the first non-undef value.
1315 int SplatValue = *FirstDefinedIdx;
1316 if (any_of(make_range(std::next(FirstDefinedIdx), Mask.end()),
1317 [&SplatValue](int Elt) { return Elt >= 0 && Elt != SplatValue; }))
1318 return std::nullopt;
1319
1320 return SplatValue;
1321}
1322
1323static bool isBuildVectorOp(unsigned Opcode) {
1324 return Opcode == TargetOpcode::G_BUILD_VECTOR ||
1325 Opcode == TargetOpcode::G_BUILD_VECTOR_TRUNC;
1326}
1327
1328namespace {
1329
1330std::optional<ValueAndVReg> getAnyConstantSplat(Register VReg,
1331 const MachineRegisterInfo &MRI,
1332 bool AllowUndef) {
1334 if (!MI)
1335 return std::nullopt;
1336
1337 bool isConcatVectorsOp = MI->getOpcode() == TargetOpcode::G_CONCAT_VECTORS;
1338 if (!isBuildVectorOp(MI->getOpcode()) && !isConcatVectorsOp)
1339 return std::nullopt;
1340
1341 std::optional<ValueAndVReg> SplatValAndReg;
1342 for (MachineOperand &Op : MI->uses()) {
1343 Register Element = Op.getReg();
1344 // If we have a G_CONCAT_VECTOR, we recursively look into the
1345 // vectors that we're concatenating to see if they're splats.
1346 auto ElementValAndReg =
1347 isConcatVectorsOp
1348 ? getAnyConstantSplat(Element, MRI, AllowUndef)
1350
1351 // If AllowUndef, treat undef as value that will result in a constant splat.
1352 if (!ElementValAndReg) {
1353 if (AllowUndef && mi_match(Element, MRI, m_GImplicitDef()))
1354 continue;
1355 return std::nullopt;
1356 }
1357
1358 // Record splat value
1359 if (!SplatValAndReg)
1360 SplatValAndReg = ElementValAndReg;
1361
1362 // Different constant than the one already recorded, not a constant splat.
1363 if (SplatValAndReg->Value != ElementValAndReg->Value)
1364 return std::nullopt;
1365 }
1366
1367 return SplatValAndReg;
1368}
1369
1370} // end anonymous namespace
1371
1373 const MachineRegisterInfo &MRI,
1374 int64_t SplatValue, bool AllowUndef) {
1375 if (auto SplatValAndReg = getAnyConstantSplat(Reg, MRI, AllowUndef))
1376 return SplatValAndReg->Value.getSExtValue() == SplatValue;
1377
1378 return false;
1379}
1380
1382 const MachineRegisterInfo &MRI,
1383 const APInt &SplatValue,
1384 bool AllowUndef) {
1385 if (auto SplatValAndReg = getAnyConstantSplat(Reg, MRI, AllowUndef)) {
1386 if (SplatValAndReg->Value.getBitWidth() < SplatValue.getBitWidth())
1387 return APInt::isSameValue(
1388 SplatValAndReg->Value.sext(SplatValue.getBitWidth()), SplatValue);
1389 return APInt::isSameValue(
1390 SplatValAndReg->Value,
1391 SplatValue.sext(SplatValAndReg->Value.getBitWidth()));
1392 }
1393
1394 return false;
1395}
1396
1398 const MachineRegisterInfo &MRI,
1399 int64_t SplatValue, bool AllowUndef) {
1400 return isBuildVectorConstantSplat(MI.getOperand(0).getReg(), MRI, SplatValue,
1401 AllowUndef);
1402}
1403
1405 const MachineRegisterInfo &MRI,
1406 const APInt &SplatValue,
1407 bool AllowUndef) {
1408 return isBuildVectorConstantSplat(MI.getOperand(0).getReg(), MRI, SplatValue,
1409 AllowUndef);
1410}
1411
1412std::optional<APInt>
1414 if (auto SplatValAndReg =
1415 getAnyConstantSplat(Reg, MRI, /* AllowUndef */ false)) {
1416 if (std::optional<ValueAndVReg> ValAndVReg =
1417 getIConstantVRegValWithLookThrough(SplatValAndReg->VReg, MRI))
1418 return ValAndVReg->Value;
1419 }
1420
1421 return std::nullopt;
1422}
1423
1424std::optional<APInt>
1426 const MachineRegisterInfo &MRI) {
1427 return getIConstantSplatVal(MI.getOperand(0).getReg(), MRI);
1428}
1429
1430std::optional<int64_t>
1432 const MachineRegisterInfo &MRI) {
1433 if (auto SplatValAndReg =
1434 getAnyConstantSplat(Reg, MRI, /* AllowUndef */ false))
1435 return getIConstantVRegSExtVal(SplatValAndReg->VReg, MRI);
1436 return std::nullopt;
1437}
1438
1439std::optional<int64_t>
1441 const MachineRegisterInfo &MRI) {
1442 return getIConstantSplatSExtVal(MI.getOperand(0).getReg(), MRI);
1443}
1444
1445std::optional<FPValueAndVReg>
1447 bool AllowUndef) {
1448 if (auto SplatValAndReg = getAnyConstantSplat(VReg, MRI, AllowUndef))
1449 return getFConstantVRegValWithLookThrough(SplatValAndReg->VReg, MRI);
1450 return std::nullopt;
1451}
1452
1454 const MachineRegisterInfo &MRI,
1455 bool AllowUndef) {
1456 return isBuildVectorConstantSplat(MI, MRI, 0, AllowUndef);
1457}
1458
1460 const MachineRegisterInfo &MRI,
1461 bool AllowUndef) {
1462 return isBuildVectorConstantSplat(MI, MRI, -1, AllowUndef);
1463}
1464
1465std::optional<Register> llvm::getVectorSplat(const MachineInstr &MI,
1466 const MachineRegisterInfo &MRI) {
1467 unsigned Opc = MI.getOpcode();
1468 if (Opc == TargetOpcode::G_SPLAT_VECTOR)
1469 return MI.getOperand(1).getReg();
1470
1471 if (!isBuildVectorOp(Opc))
1472 return std::nullopt;
1473 auto Reg = MI.getOperand(1).getReg();
1474 if (any_of(drop_begin(MI.operands(), 2),
1475 [&Reg](const MachineOperand &Op) { return Op.getReg() != Reg; }))
1476 return std::nullopt;
1477 return Reg;
1478}
1479
1481 const MachineRegisterInfo &MRI,
1482 bool AllowFP = true,
1483 bool AllowOpaqueConstants = true) {
1484 switch (MI.getOpcode()) {
1485 case TargetOpcode::G_CONSTANT:
1486 case TargetOpcode::G_IMPLICIT_DEF:
1487 return true;
1488 case TargetOpcode::G_FCONSTANT:
1489 return AllowFP;
1490 case TargetOpcode::G_GLOBAL_VALUE:
1491 case TargetOpcode::G_FRAME_INDEX:
1492 case TargetOpcode::G_BLOCK_ADDR:
1493 case TargetOpcode::G_JUMP_TABLE:
1494 return AllowOpaqueConstants;
1495 default:
1496 return false;
1497 }
1498}
1499
1501 const MachineRegisterInfo &MRI) {
1502 Register Def = MI.getOperand(0).getReg();
1503 if (auto C = getIConstantVRegValWithLookThrough(Def, MRI))
1504 return true;
1506 if (!BV)
1507 return false;
1508 for (unsigned SrcIdx = 0; SrcIdx < BV->getNumSources(); ++SrcIdx) {
1511 continue;
1512 return false;
1513 }
1514 return true;
1515}
1516
1518 const MachineRegisterInfo &MRI,
1519 bool AllowFP, bool AllowOpaqueConstants) {
1520 if (isConstantScalar(MI, MRI, AllowFP, AllowOpaqueConstants))
1521 return true;
1522
1523 if (!isBuildVectorOp(MI.getOpcode()))
1524 return false;
1525
1526 const unsigned NumOps = MI.getNumOperands();
1527 for (unsigned I = 1; I != NumOps; ++I) {
1528 const MachineInstr *ElementDef = MRI.getVRegDef(MI.getOperand(I).getReg());
1529 if (!isConstantScalar(*ElementDef, MRI, AllowFP, AllowOpaqueConstants))
1530 return false;
1531 }
1532
1533 return true;
1534}
1535
1536std::optional<APInt>
1538 const MachineRegisterInfo &MRI) {
1539 if (auto C = getIConstantVRegValWithLookThrough(Def, MRI))
1540 return C->Value;
1541 auto MaybeCst = getIConstantSplatSExtVal(Def, MRI);
1542 if (!MaybeCst)
1543 return std::nullopt;
1544 const unsigned ScalarSize = MRI.getType(Def).getScalarSizeInBits();
1545 return APInt(ScalarSize, *MaybeCst, true);
1546}
1547
1548std::optional<APFloat>
1550 const MachineRegisterInfo &MRI) {
1551 if (auto FpConst = getFConstantVRegValWithLookThrough(Def, MRI))
1552 return FpConst->Value;
1553 auto MaybeCstFP = getFConstantSplat(Def, MRI, /*allowUndef=*/false);
1554 if (!MaybeCstFP)
1555 return std::nullopt;
1556 return MaybeCstFP->Value;
1557}
1558
1560 const MachineRegisterInfo &MRI, bool AllowUndefs) {
1561 switch (MI.getOpcode()) {
1562 case TargetOpcode::G_IMPLICIT_DEF:
1563 return AllowUndefs;
1564 case TargetOpcode::G_CONSTANT:
1565 return MI.getOperand(1).getCImm()->isNullValue();
1566 case TargetOpcode::G_FCONSTANT: {
1567 const ConstantFP *FPImm = MI.getOperand(1).getFPImm();
1568 return FPImm->isZero() && !FPImm->isNegative();
1569 }
1570 default:
1571 if (!AllowUndefs) // TODO: isBuildVectorAllZeros assumes undef is OK already
1572 return false;
1573 return isBuildVectorAllZeros(MI, MRI);
1574 }
1575}
1576
1578 const MachineRegisterInfo &MRI,
1579 bool AllowUndefs) {
1580 switch (MI.getOpcode()) {
1581 case TargetOpcode::G_IMPLICIT_DEF:
1582 return AllowUndefs;
1583 case TargetOpcode::G_CONSTANT:
1584 return MI.getOperand(1).getCImm()->isAllOnesValue();
1585 default:
1586 if (!AllowUndefs) // TODO: isBuildVectorAllOnes assumes undef is OK already
1587 return false;
1588 return isBuildVectorAllOnes(MI, MRI);
1589 }
1590}
1591
1593 const MachineRegisterInfo &MRI, Register Reg,
1594 llvm::function_ref<bool(const Constant *ConstVal)> Match,
1595 bool AllowUndefs) {
1596
1597 const MachineInstr *Def = getDefIgnoringCopies(Reg, MRI);
1598 if (AllowUndefs && Def->getOpcode() == TargetOpcode::G_IMPLICIT_DEF)
1599 return Match(nullptr);
1600
1601 // TODO: Also handle fconstant
1602 if (Def->getOpcode() == TargetOpcode::G_CONSTANT)
1603 return Match(Def->getOperand(1).getCImm());
1604
1605 if (Def->getOpcode() != TargetOpcode::G_BUILD_VECTOR)
1606 return false;
1607
1608 for (unsigned I = 1, E = Def->getNumOperands(); I != E; ++I) {
1609 Register SrcElt = Def->getOperand(I).getReg();
1610 const MachineInstr *SrcDef = getDefIgnoringCopies(SrcElt, MRI);
1611 if (AllowUndefs && SrcDef->getOpcode() == TargetOpcode::G_IMPLICIT_DEF) {
1612 if (!Match(nullptr))
1613 return false;
1614 continue;
1615 }
1616
1617 if (SrcDef->getOpcode() != TargetOpcode::G_CONSTANT ||
1618 !Match(SrcDef->getOperand(1).getCImm()))
1619 return false;
1620 }
1621
1622 return true;
1623}
1624
1625bool llvm::isConstTrueVal(const TargetLowering &TLI, int64_t Val, bool IsVector,
1626 bool IsFP) {
1627 switch (TLI.getBooleanContents(IsVector, IsFP)) {
1629 return Val & 0x1;
1631 return Val == 1;
1633 return Val == -1;
1634 }
1635 llvm_unreachable("Invalid boolean contents");
1636}
1637
1638bool llvm::isConstFalseVal(const TargetLowering &TLI, int64_t Val,
1639 bool IsVector, bool IsFP) {
1640 switch (TLI.getBooleanContents(IsVector, IsFP)) {
1642 return ~Val & 0x1;
1645 return Val == 0;
1646 }
1647 llvm_unreachable("Invalid boolean contents");
1648}
1649
1650int64_t llvm::getICmpTrueVal(const TargetLowering &TLI, bool IsVector,
1651 bool IsFP) {
1652 switch (TLI.getBooleanContents(IsVector, IsFP)) {
1655 return 1;
1657 return -1;
1658 }
1659 llvm_unreachable("Invalid boolean contents");
1660}
1661
1663 LostDebugLocObserver *LocObserver,
1664 SmallInstListTy &DeadInstChain) {
1665 for (MachineOperand &Op : MI.uses()) {
1666 if (Op.isReg() && Op.getReg().isVirtual())
1667 DeadInstChain.insert(MRI.getVRegDef(Op.getReg()));
1668 }
1669 LLVM_DEBUG(dbgs() << MI << "Is dead; erasing.\n");
1670 DeadInstChain.remove(&MI);
1672 MI.eraseFromParent();
1673 if (LocObserver)
1674 LocObserver->checkpoint(false);
1675}
1676
1679 LostDebugLocObserver *LocObserver) {
1680 SmallInstListTy DeadInstChain;
1681 for (MachineInstr *MI : DeadInstrs)
1682 saveUsesAndErase(*MI, MRI, LocObserver, DeadInstChain);
1683
1684 while (!DeadInstChain.empty()) {
1685 MachineInstr *Inst = DeadInstChain.pop_back_val();
1686 if (!isTriviallyDead(*Inst, MRI))
1687 continue;
1688 saveUsesAndErase(*Inst, MRI, LocObserver, DeadInstChain);
1689 }
1690}
1691
1693 LostDebugLocObserver *LocObserver) {
1694 return eraseInstrs({&MI}, MRI, LocObserver);
1695}
1696
1698 for (auto &Def : MI.defs()) {
1699 assert(Def.isReg() && "Must be a reg");
1700
1702 for (auto &MOUse : MRI.use_operands(Def.getReg())) {
1703 MachineInstr *DbgValue = MOUse.getParent();
1704 // Ignore partially formed DBG_VALUEs.
1705 if (DbgValue->isNonListDebugValue() && DbgValue->getNumOperands() == 4) {
1706 DbgUsers.push_back(&MOUse);
1707 }
1708 }
1709
1710 if (!DbgUsers.empty()) {
1712 }
1713
1714 // MI is about to go away, so whatever could not be salvaged would be left
1715 // referring to a register without a definition.
1716 MRI.markUsesInDebugValueAsUndef(Def.getReg());
1717 }
1718}
1719
1721 switch (Opc) {
1722 case TargetOpcode::G_FABS:
1723 case TargetOpcode::G_FADD:
1724 case TargetOpcode::G_FCANONICALIZE:
1725 case TargetOpcode::G_FCEIL:
1726 case TargetOpcode::G_FCONSTANT:
1727 case TargetOpcode::G_FCOPYSIGN:
1728 case TargetOpcode::G_FCOS:
1729 case TargetOpcode::G_FDIV:
1730 case TargetOpcode::G_FEXP2:
1731 case TargetOpcode::G_FEXP:
1732 case TargetOpcode::G_FFLOOR:
1733 case TargetOpcode::G_FLOG10:
1734 case TargetOpcode::G_FLOG2:
1735 case TargetOpcode::G_FLOG:
1736 case TargetOpcode::G_FMA:
1737 case TargetOpcode::G_FMAD:
1738 case TargetOpcode::G_FMAXIMUM:
1739 case TargetOpcode::G_FMAXIMUMNUM:
1740 case TargetOpcode::G_FMAXNUM:
1741 case TargetOpcode::G_FMAXNUM_IEEE:
1742 case TargetOpcode::G_FMINIMUM:
1743 case TargetOpcode::G_FMINIMUMNUM:
1744 case TargetOpcode::G_FMINNUM:
1745 case TargetOpcode::G_FMINNUM_IEEE:
1746 case TargetOpcode::G_FMUL:
1747 case TargetOpcode::G_FNEARBYINT:
1748 case TargetOpcode::G_FNEG:
1749 case TargetOpcode::G_FPEXT:
1750 case TargetOpcode::G_FPEXTLOAD:
1751 case TargetOpcode::G_FPOW:
1752 case TargetOpcode::G_FPTRUNC:
1753 case TargetOpcode::G_FPTRUNCSTORE:
1754 case TargetOpcode::G_FREM:
1755 case TargetOpcode::G_FRINT:
1756 case TargetOpcode::G_FSIN:
1757 case TargetOpcode::G_FTAN:
1758 case TargetOpcode::G_FACOS:
1759 case TargetOpcode::G_FASIN:
1760 case TargetOpcode::G_FATAN:
1761 case TargetOpcode::G_FATAN2:
1762 case TargetOpcode::G_FCOSH:
1763 case TargetOpcode::G_FSINH:
1764 case TargetOpcode::G_FTANH:
1765 case TargetOpcode::G_FSQRT:
1766 case TargetOpcode::G_FSUB:
1767 case TargetOpcode::G_INTRINSIC_ROUND:
1768 case TargetOpcode::G_INTRINSIC_ROUNDEVEN:
1769 case TargetOpcode::G_INTRINSIC_TRUNC:
1770 return true;
1771 default:
1772 return false;
1773 }
1774}
1775
1776/// Shifts return poison if shiftwidth is larger than the bitwidth.
1777static bool shiftAmountKnownInRange(Register ShiftAmount,
1778 const MachineRegisterInfo &MRI) {
1779 LLT Ty = MRI.getType(ShiftAmount);
1780
1781 if (Ty.isScalableVector())
1782 return false; // Can't tell, just return false to be safe
1783
1784 if (Ty.isScalar()) {
1785 std::optional<ValueAndVReg> Val =
1787 if (!Val)
1788 return false;
1789 return Val->Value.ult(Ty.getScalarSizeInBits());
1790 }
1791
1792 GBuildVector *BV = getOpcodeDef<GBuildVector>(ShiftAmount, MRI);
1793 if (!BV)
1794 return false;
1795
1796 unsigned Sources = BV->getNumSources();
1797 for (unsigned I = 0; I < Sources; ++I) {
1798 std::optional<ValueAndVReg> Val =
1800 if (!Val)
1801 return false;
1802 if (!Val->Value.ult(Ty.getScalarSizeInBits()))
1803 return false;
1804 }
1805
1806 return true;
1807}
1808
1810 bool ConsiderFlagsAndMetadata,
1811 UndefPoisonKind Kind) {
1812 MachineInstr *RegDef = MRI.getVRegDef(Reg);
1813
1814 if (ConsiderFlagsAndMetadata && includesPoison(Kind))
1815 if (auto *GMI = dyn_cast<GenericMachineInstr>(RegDef))
1816 if (GMI->hasPoisonGeneratingFlags())
1817 return true;
1818
1819 // Check whether opcode is a poison/undef-generating operation.
1820 switch (RegDef->getOpcode()) {
1821 case TargetOpcode::G_BUILD_VECTOR:
1822 case TargetOpcode::G_CONSTANT_FOLD_BARRIER:
1823 return false;
1824 case TargetOpcode::G_SHL:
1825 case TargetOpcode::G_ASHR:
1826 case TargetOpcode::G_LSHR:
1827 return includesPoison(Kind) &&
1829 case TargetOpcode::G_FPTOSI:
1830 case TargetOpcode::G_FPTOUI:
1831 // fptosi/ui yields poison if the resulting value does not fit in the
1832 // destination type.
1833 return true;
1834 case TargetOpcode::G_CTLZ:
1835 case TargetOpcode::G_CTTZ:
1836 case TargetOpcode::G_CTLS:
1837 case TargetOpcode::G_ABS:
1838 case TargetOpcode::G_CTPOP:
1839 case TargetOpcode::G_BSWAP:
1840 case TargetOpcode::G_BITREVERSE:
1841 case TargetOpcode::G_FSHL:
1842 case TargetOpcode::G_FSHR:
1843 case TargetOpcode::G_SMAX:
1844 case TargetOpcode::G_SMIN:
1845 case TargetOpcode::G_SCMP:
1846 case TargetOpcode::G_UMAX:
1847 case TargetOpcode::G_UMIN:
1848 case TargetOpcode::G_UCMP:
1849 case TargetOpcode::G_PTRMASK:
1850 case TargetOpcode::G_SADDO:
1851 case TargetOpcode::G_SSUBO:
1852 case TargetOpcode::G_UADDO:
1853 case TargetOpcode::G_USUBO:
1854 case TargetOpcode::G_SMULO:
1855 case TargetOpcode::G_UMULO:
1856 case TargetOpcode::G_SADDSAT:
1857 case TargetOpcode::G_UADDSAT:
1858 case TargetOpcode::G_SSUBSAT:
1859 case TargetOpcode::G_USUBSAT:
1860 case TargetOpcode::G_SBFX:
1861 case TargetOpcode::G_UBFX:
1862 return false;
1863 case TargetOpcode::G_SSHLSAT:
1864 case TargetOpcode::G_USHLSAT:
1865 return includesPoison(Kind) &&
1867 case TargetOpcode::G_INSERT_VECTOR_ELT: {
1869 if (includesPoison(Kind)) {
1870 std::optional<ValueAndVReg> Index =
1871 getIConstantVRegValWithLookThrough(Insert->getIndexReg(), MRI);
1872 if (!Index)
1873 return true;
1874 LLT VecTy = MRI.getType(Insert->getVectorReg());
1875 return Index->Value.uge(VecTy.getElementCount().getKnownMinValue());
1876 }
1877 return false;
1878 }
1879 case TargetOpcode::G_EXTRACT_VECTOR_ELT: {
1881 if (includesPoison(Kind)) {
1882 std::optional<ValueAndVReg> Index =
1884 if (!Index)
1885 return true;
1886 LLT VecTy = MRI.getType(Extract->getVectorReg());
1887 return Index->Value.uge(VecTy.getElementCount().getKnownMinValue());
1888 }
1889 return false;
1890 }
1891 case TargetOpcode::G_SHUFFLE_VECTOR: {
1892 GShuffleVector *Shuffle = cast<GShuffleVector>(RegDef);
1893 ArrayRef<int> Mask = Shuffle->getMask();
1894 return includesPoison(Kind) && is_contained(Mask, -1);
1895 }
1896 case TargetOpcode::G_FNEG:
1897 case TargetOpcode::G_PHI:
1898 case TargetOpcode::G_SELECT:
1899 case TargetOpcode::G_UREM:
1900 case TargetOpcode::G_SREM:
1901 case TargetOpcode::G_FREEZE:
1902 case TargetOpcode::G_ICMP:
1903 case TargetOpcode::G_FCMP:
1904 case TargetOpcode::G_FADD:
1905 case TargetOpcode::G_FSUB:
1906 case TargetOpcode::G_FMUL:
1907 case TargetOpcode::G_FDIV:
1908 case TargetOpcode::G_FREM:
1909 case TargetOpcode::G_PTR_ADD:
1910 return false;
1911 default:
1912 return !isa<GCastOp>(RegDef) && !isa<GBinOp>(RegDef);
1913 }
1914}
1915
1917 const MachineRegisterInfo &MRI,
1918 unsigned Depth,
1919 UndefPoisonKind Kind) {
1921 return false;
1922
1923 MachineInstr *RegDef = MRI.getVRegDef(Reg);
1924
1925 switch (RegDef->getOpcode()) {
1926 case TargetOpcode::G_FREEZE:
1927 return true;
1928 case TargetOpcode::G_IMPLICIT_DEF:
1929 return !includesUndef(Kind);
1930 case TargetOpcode::G_CONSTANT:
1931 case TargetOpcode::G_FCONSTANT:
1932 return true;
1933 case TargetOpcode::G_BUILD_VECTOR: {
1934 GBuildVector *BV = cast<GBuildVector>(RegDef);
1935 unsigned NumSources = BV->getNumSources();
1936 for (unsigned I = 0; I < NumSources; ++I)
1938 Depth + 1, Kind))
1939 return false;
1940 return true;
1941 }
1942 case TargetOpcode::G_PHI: {
1943 GPhi *Phi = cast<GPhi>(RegDef);
1944 unsigned NumIncoming = Phi->getNumIncomingValues();
1945 for (unsigned I = 0; I < NumIncoming; ++I)
1946 if (!::isGuaranteedNotToBeUndefOrPoison(Phi->getIncomingValue(I), MRI,
1947 Depth + 1, Kind))
1948 return false;
1949 return true;
1950 }
1951 default: {
1952 auto MOCheck = [&](const MachineOperand &MO) {
1953 if (!MO.isReg())
1954 return true;
1955 return ::isGuaranteedNotToBeUndefOrPoison(MO.getReg(), MRI, Depth + 1,
1956 Kind);
1957 };
1959 /*ConsiderFlagsAndMetadata=*/true, Kind) &&
1960 all_of(RegDef->uses(), MOCheck);
1961 }
1962 }
1963}
1964
1966 bool ConsiderFlagsAndMetadata) {
1967 return ::canCreateUndefOrPoison(Reg, MRI, ConsiderFlagsAndMetadata,
1969}
1970
1972 bool ConsiderFlagsAndMetadata = true) {
1973 return ::canCreateUndefOrPoison(Reg, MRI, ConsiderFlagsAndMetadata,
1975}
1976
1978 const MachineRegisterInfo &MRI,
1979 unsigned Depth) {
1980 return ::isGuaranteedNotToBeUndefOrPoison(Reg, MRI, Depth,
1982}
1983
1985 const MachineRegisterInfo &MRI,
1986 unsigned Depth) {
1987 return ::isGuaranteedNotToBeUndefOrPoison(Reg, MRI, Depth,
1989}
1990
1992 const MachineRegisterInfo &MRI,
1993 unsigned Depth) {
1994 return ::isGuaranteedNotToBeUndefOrPoison(Reg, MRI, Depth,
1996}
1997
1999 if (Ty.isVector())
2000 return VectorType::get(IntegerType::get(C, Ty.getScalarSizeInBits()),
2001 Ty.getElementCount());
2002 return IntegerType::get(C, Ty.getSizeInBits());
2003}
2004
2006 switch (MI.getOpcode()) {
2007 default:
2008 return false;
2009 case TargetOpcode::G_ASSERT_ALIGN:
2010 case TargetOpcode::G_ASSERT_SEXT:
2011 case TargetOpcode::G_ASSERT_ZEXT:
2012 return true;
2013 }
2014}
2015
2017 assert(Kind == GIConstantKind::Scalar && "Expected scalar constant");
2018
2019 return Value;
2020}
2021
2022std::optional<GIConstant>
2025
2027 std::optional<ValueAndVReg> MayBeConstant =
2029 if (!MayBeConstant)
2030 return std::nullopt;
2031 return GIConstant(MayBeConstant->Value, GIConstantKind::ScalableVector);
2032 }
2033
2035 SmallVector<APInt> Values;
2036 unsigned NumSources = Build->getNumSources();
2037 for (unsigned I = 0; I < NumSources; ++I) {
2038 Register SrcReg = Build->getSourceReg(I);
2039 std::optional<ValueAndVReg> MayBeConstant =
2041 if (!MayBeConstant)
2042 return std::nullopt;
2043 Values.push_back(MayBeConstant->Value);
2044 }
2045 return GIConstant(Values);
2046 }
2047
2048 std::optional<ValueAndVReg> MayBeConstant =
2050 if (!MayBeConstant)
2051 return std::nullopt;
2052
2053 return GIConstant(MayBeConstant->Value, GIConstantKind::Scalar);
2054}
2055
2057 assert(Kind == GFConstantKind::Scalar && "Expected scalar constant");
2058
2059 return Values[0];
2060}
2061
2062std::optional<GFConstant>
2065
2067 std::optional<FPValueAndVReg> MayBeConstant =
2069 if (!MayBeConstant)
2070 return std::nullopt;
2071 return GFConstant(MayBeConstant->Value, GFConstantKind::ScalableVector);
2072 }
2073
2075 SmallVector<APFloat> Values;
2076 unsigned NumSources = Build->getNumSources();
2077 for (unsigned I = 0; I < NumSources; ++I) {
2078 Register SrcReg = Build->getSourceReg(I);
2079 std::optional<FPValueAndVReg> MayBeConstant =
2081 if (!MayBeConstant)
2082 return std::nullopt;
2083 Values.push_back(MayBeConstant->Value);
2084 }
2085 return GFConstant(Values);
2086 }
2087
2088 std::optional<FPValueAndVReg> MayBeConstant =
2090 if (!MayBeConstant)
2091 return std::nullopt;
2092
2093 return GFConstant(MayBeConstant->Value, GFConstantKind::Scalar);
2094}
2095
2096// Returns a list of types to use for memory op lowering in MemOps. A partial
2097// port of findOptimalMemOpLowering in TargetLowering.
2098static bool findGISelOptimalMemOpLowering(std::vector<LLT> &MemOps,
2099 unsigned Limit, const MemOp &Op,
2100 unsigned DstAS, unsigned SrcAS,
2101 const AttributeList &FuncAttributes,
2102 const TargetLowering &TLI) {
2103 if (Op.isMemcpyOrMemmoveWithFixedDstAlign() &&
2104 Op.getSrcAlign() < Op.getDstAlign())
2105 return false;
2106
2107 LLT Ty = TLI.getOptimalMemOpLLT(Op, FuncAttributes);
2108
2109 if (Ty == LLT()) {
2110 // Use the largest scalar type whose alignment constraints are satisfied.
2111 // We only need to check DstAlign here as SrcAlign is always greater or
2112 // equal to DstAlign (or zero).
2113 Ty = LLT::integer(64);
2114 if (Op.isFixedDstAlign())
2115 while (Op.getDstAlign() < Ty.getSizeInBytes() &&
2116 !TLI.allowsMisalignedMemoryAccesses(Ty, DstAS, Op.getDstAlign()))
2117 Ty = LLT::integer(Ty.getSizeInBytes());
2118 assert(Ty.getSizeInBits() > 0 && "Could not find valid type");
2119 // FIXME: check for the largest legal type we can load/store to.
2120 }
2121
2122 unsigned NumMemOps = 0;
2123 uint64_t Size = Op.size();
2124 while (Size) {
2125 unsigned TySize = Ty.getSizeInBytes();
2126 while (TySize > Size) {
2127 // For now, only use non-vector load / store's for the left-over pieces.
2128 LLT NewTy = Ty;
2129 // FIXME: check for mem op safety and legality of the types. Not all of
2130 // SDAGisms map cleanly to GISel concepts.
2131 if (NewTy.isVector())
2132 NewTy =
2133 NewTy.getSizeInBits() > 64 ? LLT::integer(64) : LLT::integer(32);
2134 NewTy = LLT::integer(llvm::bit_floor(NewTy.getSizeInBits() - 1));
2135 unsigned NewTySize = NewTy.getSizeInBytes();
2136 assert(NewTySize > 0 && "Could not find appropriate type");
2137
2138 // If the new LLT cannot cover all of the remaining bits, then consider
2139 // issuing a (or a pair of) unaligned and overlapping load / store.
2140 unsigned Fast;
2141 // Need to get a VT equivalent for allowMisalignedMemoryAccesses().
2142 MVT VT = getMVTForLLT(Ty);
2143 if (NumMemOps && !Op.isVolatile() && NewTySize < Size &&
2145 VT, DstAS, Op.isFixedDstAlign() ? Op.getDstAlign() : Align(1),
2147 Fast)
2148 TySize = Size;
2149 else {
2150 Ty = NewTy;
2151 TySize = NewTySize;
2152 }
2153 }
2154
2155 if (++NumMemOps > Limit)
2156 return false;
2157
2158 MemOps.push_back(Ty);
2159 Size -= TySize;
2160 }
2161
2162 return true;
2163}
2164
2166 const MachineRegisterInfo &MRI, unsigned MaxLen,
2167 Register &Dst, Register &Src,
2168 uint64_t &KnownLen, Align &Alignment,
2169 bool &DstAlignCanChange,
2170 std::vector<LLT> &MemOps) {
2171 const unsigned Opc = MI.getOpcode();
2172 assert((Opc == TargetOpcode::G_MEMCPY ||
2173 Opc == TargetOpcode::G_MEMCPY_INLINE ||
2174 Opc == TargetOpcode::G_MEMMOVE || Opc == TargetOpcode::G_MEMSET ||
2175 Opc == TargetOpcode::G_MEMSET_INLINE) &&
2176 "Expected memcpy like instruction");
2177
2178 auto MMOIt = MI.memoperands_begin();
2179 const MachineMemOperand *MemOp = *MMOIt;
2180
2181 Align DstAlign = MemOp->getBaseAlign();
2182 Align SrcAlign;
2183 Alignment = DstAlign;
2184 Register Len;
2185 std::tie(Dst, Src, Len) = MI.getFirst3Regs();
2186
2187 if (Opc != TargetOpcode::G_MEMSET && Opc != TargetOpcode::G_MEMSET_INLINE) {
2188 assert(MMOIt != MI.memoperands_end() && "Expected a second MMO on MI");
2189 MemOp = *(++MMOIt);
2190 SrcAlign = MemOp->getBaseAlign();
2191 Alignment = std::min(DstAlign, SrcAlign);
2192 }
2193
2194 // See if this is a constant length copy.
2195 auto LenVRegAndVal = getIConstantVRegValWithLookThrough(Len, MRI);
2196 if (!LenVRegAndVal) {
2197 // FIXME: support dynamically sized G_MEMCPY_INLINE and G_MEMSET_INLINE
2198 assert(Opc != TargetOpcode::G_MEMCPY_INLINE &&
2199 Opc != TargetOpcode::G_MEMSET_INLINE &&
2200 "inline memcpy and memset with dynamic size are not yet supported");
2201 return false;
2202 }
2203
2204 KnownLen = LenVRegAndVal->Value.getZExtValue();
2205 DstAlignCanChange = false;
2206
2207 if (KnownLen == 0)
2208 return true;
2209
2210 if (Opc != TargetOpcode::G_MEMCPY_INLINE &&
2211 Opc != TargetOpcode::G_MEMSET_INLINE && MaxLen && KnownLen > MaxLen)
2212 return false;
2213
2214 bool IsVolatile = MemOp->isVolatile();
2215 const MachineFunction &MF = *MI.getParent()->getParent();
2216 const auto &TLI = *MF.getSubtarget().getTargetLowering();
2217 // On Darwin, -Os means optimize for size without hurting performance, so
2218 // only really optimize for size when -Oz (MinSize) is used.
2219 bool OptSize = MF.getTarget().getTargetTriple().isOSDarwin()
2220 ? MF.getFunction().hasMinSize()
2221 : MF.getFunction().hasOptSize();
2222
2223 const MachineFrameInfo &MFI = MF.getFrameInfo();
2224 MachineInstr *FIDef = getOpcodeDef(TargetOpcode::G_FRAME_INDEX, Dst, MRI);
2225 if (FIDef && !MFI.isFixedObjectIndex(FIDef->getOperand(1).getIndex()))
2226 DstAlignCanChange = true;
2227
2228 const auto &DstMMO = **MI.memoperands_begin();
2229 MachinePointerInfo DstPtrInfo = DstMMO.getPointerInfo();
2230
2231 switch (Opc) {
2232 case TargetOpcode::G_MEMCPY_INLINE:
2233 case TargetOpcode::G_MEMCPY: {
2234 const auto &SrcMMO = **std::next(MI.memoperands_begin());
2235 MachinePointerInfo SrcPtrInfo = SrcMMO.getPointerInfo();
2236 uint64_t Limit = Opc == TargetOpcode::G_MEMCPY_INLINE
2237 ? std::numeric_limits<uint64_t>::max()
2238 : TLI.getMaxStoresPerMemcpy(OptSize);
2240 MemOps, Limit,
2241 MemOp::Copy(KnownLen, DstAlignCanChange, std::min(DstAlign, SrcAlign),
2242 SrcAlign, IsVolatile),
2243 DstPtrInfo.getAddrSpace(), SrcPtrInfo.getAddrSpace(),
2244 MF.getFunction().getAttributes(), TLI);
2245 }
2246 case TargetOpcode::G_MEMMOVE: {
2247 const auto &SrcMMO = **std::next(MI.memoperands_begin());
2248 MachinePointerInfo SrcPtrInfo = SrcMMO.getPointerInfo();
2249 unsigned Limit = TLI.getMaxStoresPerMemmove(OptSize);
2251 MemOps, Limit,
2252 MemOp::Move(KnownLen, DstAlignCanChange, std::min(DstAlign, SrcAlign),
2253 SrcAlign, IsVolatile),
2254 DstPtrInfo.getAddrSpace(), SrcPtrInfo.getAddrSpace(),
2255 MF.getFunction().getAttributes(), TLI);
2256 }
2257 case TargetOpcode::G_MEMSET:
2258 case TargetOpcode::G_MEMSET_INLINE: {
2259 unsigned Limit = Opc == TargetOpcode::G_MEMSET_INLINE
2260 ? std::numeric_limits<unsigned>::max()
2261 : TLI.getMaxStoresPerMemset(OptSize);
2262 auto ValVRegAndVal = getIConstantVRegValWithLookThrough(Src, MRI);
2263 bool IsZeroVal = ValVRegAndVal && ValVRegAndVal->Value == 0;
2265 MemOps, Limit,
2266 MemOp::Set(KnownLen, DstAlignCanChange, DstAlign,
2267 /*IsZeroMemset=*/IsZeroVal,
2268 /*IsVolatile=*/IsVolatile),
2269 DstPtrInfo.getAddrSpace(), ~0u, MF.getFunction().getAttributes(), TLI);
2270 }
2271 default:
2272 llvm_unreachable("Unexpected memcpy-family opcode");
2273 }
2274}
MachineInstrBuilder MachineInstrBuilder & DefMI
unsigned RegSize
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
uint64_t uint64_t
uint64_t Imm
This file declares a class to represent arbitrary precision floating point values and provide a varie...
This file implements a class to represent arbitrary precision integral constant values and operations...
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static bool findGISelOptimalMemOpLowering(std::vector< LLT > &MemOps, unsigned Limit, const MemOp &Op, unsigned DstAS, unsigned SrcAS, const AttributeList &FuncAttributes, const TargetLowering &TLI)
Definition Utils.cpp:2098
static void reportGISelDiagnostic(DiagnosticSeverity Severity, MachineFunction &MF, MachineOptimizationRemarkEmitter &MORE, MachineOptimizationRemarkMissed &R)
Definition Utils.cpp:237
static bool shiftAmountKnownInRange(Register ShiftAmount, const MachineRegisterInfo &MRI)
Shifts return poison if shiftwidth is larger than the bitwidth.
Definition Utils.cpp:1777
static bool isBuildVectorOp(unsigned Opcode)
Definition Utils.cpp:1323
static bool isConstantScalar(const MachineInstr &MI, const MachineRegisterInfo &MRI, bool AllowFP=true, bool AllowOpaqueConstants=true)
Definition Utils.cpp:1480
static GBuildVector * getBuildVectorLikeDef(Register Reg, const MachineRegisterInfo &MRI)
Definition Utils.cpp:807
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This contains common code to allow clients to notify changes to machine instr.
Provides analysis for querying information about KnownBits during GISel passes.
Declares convenience wrapper classes for interpreting MachineInstr instances as specific generic oper...
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
Tracks DebugLocs between checkpoints and verifies that they are transferred.
Implement a low-level type suitable for MachineInstr level instruction selection.
#define I(x, y, z)
Definition MD5.cpp:57
Contains matchers for matching SSA Machine Instructions.
This file declares the MachineIRBuilder class.
===- MachineOptimizationRemarkEmitter.h - Opt Diagnostics -*- C++ -*-—===//
Register Reg
Register const TargetRegisterInfo * TRI
Promote Memory to Register
Definition Mem2Reg.cpp:110
uint64_t IntrinsicInst * II
MachineBasicBlock * Folded
int64_t C1
MachineRegisterInfo & MRI
const char * Msg
#define LLVM_DEBUG(...)
Definition Debug.h:119
This file describes how to lower LLVM code to machine code.
Target-Independent Code Generator Pass Configuration Options pass.
This file contains the UndefPoisonKind enum and helper functions.
static const char PassName[]
Class recording the (high level) value of a variable.
static LLVM_ABI unsigned getSizeInBits(const fltSemantics &Sem)
Returns the size of the floating point number (in bits) in the given semantics.
Definition APFloat.cpp:398
static constexpr roundingMode rmNearestTiesToEven
Definition APFloat.h:361
const fltSemantics & getSemantics() const
Definition APFloat.h:1591
opStatus convertFromAPInt(const APInt &Input, bool IsSigned, roundingMode RM)
Definition APFloat.h:1451
APInt bitcastToAPInt() const
Definition APFloat.h:1475
Class for arbitrary precision integers.
Definition APInt.h:78
static APInt getAllOnes(unsigned numBits)
Return an APInt of a specified width with all bits set.
Definition APInt.h:230
LLVM_ABI APInt zext(unsigned width) const
Zero extend to a new width.
Definition APInt.cpp:1057
LLVM_ABI APInt zextOrTrunc(unsigned width) const
Zero extend or truncate to width.
Definition APInt.cpp:1078
LLVM_ABI APInt trunc(unsigned width) const
Truncate to new width.
Definition APInt.cpp:970
unsigned getBitWidth() const
Return the number of bits in the APInt.
Definition APInt.h:1508
static bool isSameValue(const APInt &I1, const APInt &I2, bool SignedCompare=false)
Determine if two APInts have the same value, after zero-extending or sign-extending (if SignedCompare...
Definition APInt.h:550
LLVM_ABI APInt sext(unsigned width) const
Sign extend to a new width.
Definition APInt.cpp:1030
static APInt getZero(unsigned numBits)
Get the '0' value for the specified bit-width.
Definition APInt.h:196
static APInt getOneBitSet(unsigned numBits, unsigned BitNo)
Return an APInt with exactly one bit set in the result.
Definition APInt.h:235
Represent the analysis usage information of a pass.
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
@ ICMP_SLT
signed less than
Definition InstrTypes.h:769
@ ICMP_SLE
signed less or equal
Definition InstrTypes.h:770
@ ICMP_UGE
unsigned greater or equal
Definition InstrTypes.h:764
@ ICMP_UGT
unsigned greater than
Definition InstrTypes.h:763
@ ICMP_SGT
signed greater than
Definition InstrTypes.h:767
@ ICMP_ULT
unsigned less than
Definition InstrTypes.h:765
@ ICMP_NE
not equal
Definition InstrTypes.h:762
@ ICMP_SGE
signed greater or equal
Definition InstrTypes.h:768
@ ICMP_ULE
unsigned less or equal
Definition InstrTypes.h:766
ConstantFP - Floating Point Values [float, double].
Definition Constants.h:420
const APFloat & getValueAPF() const
Definition Constants.h:463
bool isNegative() const
Return true if the sign bit is set.
Definition Constants.h:476
bool isZero() const
Return true if the value is positive or negative zero.
Definition Constants.h:467
This is the shared class of boolean and integer constants.
Definition Constants.h:87
const APInt & getValue() const
Return the constant as an APInt value reference.
Definition Constants.h:159
This is an important base class in LLVM.
Definition Constant.h:44
A debug info location.
Definition DebugLoc.h:126
static constexpr ElementCount getFixed(ScalarTy MinVal)
Definition TypeSize.h:306
static constexpr ElementCount get(ScalarTy MinVal, bool Scalable)
Definition TypeSize.h:312
bool hasOptSize() const
Optimize this function for size (-Os) or minimum size (-Oz).
Definition Function.h:699
bool hasMinSize() const
Optimize this function for minimum size (-Oz).
Definition Function.h:696
AttributeList getAttributes() const
Return the attribute list for this Function.
Definition Function.h:329
Represents a G_BUILD_VECTOR.
Represents an extract vector element.
static LLVM_ABI std::optional< GFConstant > getConstant(Register Const, const MachineRegisterInfo &MRI)
Definition Utils.cpp:2063
GFConstant(ArrayRef< APFloat > Values)
Definition Utils.h:663
LLVM_ABI APFloat getScalarValue() const
Returns the value, if this constant is a scalar.
Definition Utils.cpp:2056
LLVM_ABI APInt getScalarValue() const
Returns the value, if this constant is a scalar.
Definition Utils.cpp:2016
static LLVM_ABI std::optional< GIConstant > getConstant(Register Const, const MachineRegisterInfo &MRI)
Definition Utils.cpp:2023
GIConstant(ArrayRef< APInt > Values)
Definition Utils.h:622
Abstract class that contains various methods for clients to notify about changes.
KnownBits getKnownBits(Register R)
void insert(MachineInstr *I)
Add the specified instruction to the worklist if it isn't already in it.
MachineInstr * pop_back_val()
void remove(const MachineInstr *I)
Remove I from the worklist if it exists.
Represents an insert vector element.
Register getSourceReg(unsigned I) const
Returns the I'th source register.
unsigned getNumSources() const
Returns the number of source registers.
Represents a G_PHI.
Represents a G_SHUFFLE_VECTOR.
ArrayRef< int > getMask() const
Represents a splat vector.
Module * getParent()
Get the module that this global value is contained inside of...
static LLVM_ABI IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
Definition Type.cpp:338
constexpr bool isScalableVector() const
Returns true if the LLT is a scalable vector.
constexpr unsigned getScalarSizeInBits() const
static constexpr LLT vector(ElementCount EC, unsigned ScalarSizeInBits)
Get a low-level vector of some number of elements and element width.
LLT getScalarType() const
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
constexpr bool isValid() const
constexpr uint16_t getNumElements() const
Returns the number of elements in a vector LLT.
constexpr bool isVector() const
constexpr bool isScalable() const
Returns true if the LLT is a scalable vector.
constexpr TypeSize getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
constexpr ElementCount getElementCount() const
static constexpr LLT fixed_vector(unsigned NumElements, unsigned ScalarSizeInBits)
Get a low-level fixed-width vector of some number of elements and element width.
constexpr bool isFixedVector() const
Returns true if the LLT is a fixed vector.
static LLT integer(unsigned SizeInBits)
constexpr TypeSize getSizeInBytes() const
Returns the total size of the type in bytes, i.e.
LLT getElementType() const
Returns the vector's element type. Only valid for vector types.
static constexpr LLT scalarOrVector(ElementCount EC, LLT ScalarTy)
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:76
void checkpoint(bool CheckDebugLocs=true)
Call this to indicate that it's a good point to assess whether locations have been lost.
Describe properties that are true of each instruction in the target description file.
Wrapper class representing physical registers. Should be passed by value.
Definition MCRegister.h:41
Machine Value Type.
void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
MachineInstrBundleIterator< MachineInstr > iterator
LLVM_ABI bool isLiveIn(MCRegister Reg, LaneBitmask LaneMask=LaneBitmask::getAll()) const
Return true if the specified register is in the live in set.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
Align getObjectAlign(int ObjectIdx) const
Return the alignment of the specified stack object.
bool isFixedObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a fixed stack object.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
GISelChangeObserver * getObserver() const
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
const MachineFunctionProperties & getProperties() const
Get the function properties.
const MachineBasicBlock & front() const
Register addLiveIn(MCRegister PReg, const TargetRegisterClass *RC)
addLiveIn - Add the specified physical register as a live-in value and create a corresponding virtual...
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
Helper class to build MachineInstr.
MachineInstrBuilder buildUnmerge(ArrayRef< LLT > Res, const SrcOp &Op)
Build and insert Res0, ... = G_UNMERGE_VALUES Op.
MachineInstrBuilder buildExtract(const DstOp &Res, const SrcOp &Src, uint64_t Index)
Build and insert Res0, ... = G_EXTRACT Src, Idx0.
MachineInstrBuilder buildMergeLikeInstr(const DstOp &Res, ArrayRef< Register > Ops)
Build and insert Res = G_MERGE_VALUES Op0, ... or Res = G_BUILD_VECTOR Op0, ... or Res = G_CONCAT_VEC...
Register getReg(unsigned Idx) const
Get the register for the operand index.
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineBasicBlock * getParent() const
mop_range uses()
Returns all operands which may be register uses.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
const MachineOperand & getOperand(unsigned i) const
A description of a memory reference used in the backend.
MachineOperand class - Representation of each machine instruction operand.
const ConstantInt * getCImm() const
bool isCImm() const
isCImm - Test if this is a MO_CImmediate operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
LLVM_ABI void setReg(Register Reg)
Change the register this operand corresponds to.
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
Register getReg() const
getReg - Returns the register number.
const ConstantFP * getFPImm() const
bool isFPImm() const
isFPImm - Tests if this is a MO_FPImmediate operand.
Diagnostic information for missed-optimization remarks.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:68
Holds all the information related to register banks.
static const TargetRegisterClass * constrainGenericRegister(Register Reg, const TargetRegisterClass &RC, MachineRegisterInfo &MRI)
Constrain the (possibly generic) virtual register Reg to RC.
Wrapper class representing virtual and physical registers.
Definition Register.h:20
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
Definition Register.h:83
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
TargetInstrInfo - Interface to description of machine instruction set.
virtual bool allowsMisalignedMemoryAccesses(EVT, unsigned AddrSpace=0, Align Alignment=Align(1), MachineMemOperand::Flags Flags=MachineMemOperand::MONone, unsigned *=nullptr) const
Determine if the target supports unaligned memory accesses.
virtual LLT getOptimalMemOpLLT(const MemOp &Op, const AttributeList &) const
LLT returning variant.
BooleanContent getBooleanContents(bool isVec, bool isFloat) const
For targets without i1 registers, this gives the nature of the high-bits of boolean values held in ty...
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
const Triple & getTargetTriple() const
TargetOptions Options
GlobalISelAbortMode GlobalISelAbort
EnableGlobalISelAbort - Control abort behaviour when global instruction selection fails to lower/sele...
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetLowering * getTargetLowering() const
bool isOSDarwin() const
Is this a "Darwin" OS (macOS, iOS, tvOS, watchOS, DriverKit, XROS, or bridgeOS).
Definition Triple.h:724
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
LLVM Value Representation.
Definition Value.h:75
static LLVM_ABI VectorType * get(Type *ElementType, ElementCount EC)
This static method is the primary way to construct an VectorType.
constexpr ScalarTy getFixedValue() const
Definition TypeSize.h:201
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
Definition TypeSize.h:169
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
Definition TypeSize.h:166
An efficient, type-erasing, non-owning reference to a callable.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
const APInt & smin(const APInt &A, const APInt &B)
Determine the smaller of two APInts considered to be signed.
Definition APInt.h:2274
const APInt & smax(const APInt &A, const APInt &B)
Determine the larger of two APInts considered to be signed.
Definition APInt.h:2279
const APInt & umin(const APInt &A, const APInt &B)
Determine the smaller of two APInts considered to be unsigned.
Definition APInt.h:2284
const APInt & umax(const APInt &A, const APInt &B)
Determine the larger of two APInts considered to be unsigned.
Definition APInt.h:2289
ImplicitDefMatch m_GImplicitDef()
bool mi_match(Reg R, const MachineRegisterInfo &MRI, Pattern &&P)
DiagnosticInfoMIROptimization::MachineArgument MNV
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI Register getFunctionLiveInPhysReg(MachineFunction &MF, const TargetInstrInfo &TII, MCRegister PhysReg, const TargetRegisterClass &RC, const DebugLoc &DL, LLT RegTy=LLT())
Return a virtual register corresponding to the incoming argument register PhysReg.
Definition Utils.cpp:867
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition STLExtras.h:316
LLVM_ABI std::optional< SmallVector< APInt > > ConstantFoldICmp(unsigned Pred, const Register Op1, const Register Op2, unsigned DstScalarSizeInBits, unsigned ExtOp, const MachineRegisterInfo &MRI)
Definition Utils.cpp:1002
LLVM_ABI std::optional< APInt > isConstantOrConstantSplatVector(Register Def, const MachineRegisterInfo &MRI)
Determines if Def defines a constant integer or a splat vector of constant integers.
Definition Utils.cpp:1537
@ Offset
Definition DWP.cpp:577
LLVM_ABI bool isBuildVectorAllZeros(const MachineInstr &MI, const MachineRegisterInfo &MRI, bool AllowUndef=false)
Return true if the specified instruction is a G_BUILD_VECTOR or G_BUILD_VECTOR_TRUNC where all of the...
Definition Utils.cpp:1453
LLVM_ABI Type * getTypeForLLT(LLT Ty, LLVMContext &C)
Get the type back from LLT.
Definition Utils.cpp:1998
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1755
LLVM_ABI Register constrainOperandRegClass(const MachineFunction &MF, const TargetRegisterInfo &TRI, MachineRegisterInfo &MRI, const TargetInstrInfo &TII, const RegisterBankInfo &RBI, MachineInstr &InsertPt, const TargetRegisterClass &RegClass, MachineOperand &RegMO)
Constrain the Register operand OpIdx, so that it is now constrained to the TargetRegisterClass passed...
Definition Utils.cpp:60
LLVM_ABI MachineInstr * getOpcodeDef(unsigned Opcode, Register Reg, const MachineRegisterInfo &MRI)
See if Reg is defined by an single def instruction that is Opcode.
Definition Utils.cpp:675
LLVM_ABI std::optional< APFloat > isConstantOrConstantSplatVectorFP(Register Def, const MachineRegisterInfo &MRI)
Determines if Def defines a float constant integer or a splat vector of float constant integers.
Definition Utils.cpp:1549
LLVM_ABI const ConstantFP * getConstantFPVRegVal(Register VReg, const MachineRegisterInfo &MRI)
Definition Utils.cpp:483
LLVM_ABI bool canCreatePoison(const Operator *Op, bool ConsiderFlagsAndMetadata=true)
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
LLVM_ABI std::optional< APInt > getIConstantVRegVal(Register VReg, const MachineRegisterInfo &MRI)
If VReg is defined by a G_CONSTANT, return the corresponding value.
Definition Utils.cpp:297
LLVM_ABI std::optional< APFloat > ConstantFoldIntToFloat(unsigned Opcode, LLT DstTy, Register Src, const MachineRegisterInfo &MRI)
Definition Utils.cpp:941
LLVM_ABI std::optional< APInt > getIConstantSplatVal(const Register Reg, const MachineRegisterInfo &MRI)
Definition Utils.cpp:1413
LLVM_ABI bool isAllOnesOrAllOnesSplat(const MachineInstr &MI, const MachineRegisterInfo &MRI, bool AllowUndefs=false)
Return true if the value is a constant -1 integer or a splatted vector of a constant -1 integer (with...
Definition Utils.cpp:1577
@ Known
Known to have no common set bits.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
LLVM_ABI const llvm::fltSemantics & getFltSemanticForLLT(LLT Ty)
Get the appropriate floating point arithmetic semantic based on the bit size of the given scalar LLT.
LLVM_ABI std::optional< APFloat > ConstantFoldFPBinOp(unsigned Opcode, const Register Op1, const Register Op2, const MachineRegisterInfo &MRI)
Definition Utils.cpp:750
LLVM_ABI void salvageDebugInfo(const MachineRegisterInfo &MRI, MachineInstr &MI)
Assuming the instruction MI is going to be deleted, attempt to salvage debug users of MI by writing t...
Definition Utils.cpp:1697
LLVM_ABI void constrainSelectedInstRegOperands(MachineInstr &I, const TargetInstrInfo &TII, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI)
Mutate the newly-selected instruction I to constrain its (possibly generic) virtual register operands...
Definition Utils.cpp:159
bool isPreISelGenericOpcode(unsigned Opcode)
Check whether the given Opcode is a generic opcode that is not supposed to appear after ISel.
LLVM_ABI bool matchUnaryPredicate(const MachineRegisterInfo &MRI, Register Reg, llvm::function_ref< bool(const Constant *ConstVal)> Match, bool AllowUndefs=false)
Attempt to match a unary predicate against a scalar/splat constant or every element of a constant G_B...
Definition Utils.cpp:1592
auto dyn_cast_if_present(const Y &Val)
dyn_cast_if_present<X> - Functionally identical to dyn_cast, except that a null (or none in the case ...
Definition Casting.h:732
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
LLVM_ABI std::optional< APInt > ConstantFoldExtOp(unsigned Opcode, const Register Op1, uint64_t Imm, const MachineRegisterInfo &MRI)
Definition Utils.cpp:900
LLVM_ABI MVT getMVTForLLT(LLT Ty)
Get a rough equivalent of an MVT for a given LLT.
LLVM_READONLY APFloat maximum(const APFloat &A, const APFloat &B)
Implements IEEE 754-2019 maximum semantics.
Definition APFloat.h:1801
GISelWorkList< 4 > SmallInstListTy
Definition Utils.h:542
LLVM_ABI bool isNullOrNullSplat(const MachineInstr &MI, const MachineRegisterInfo &MRI, bool AllowUndefs=false)
Return true if the value is a constant 0 integer or a splatted vector of a constant 0 integer (with n...
Definition Utils.cpp:1559
LLVM_ABI MachineInstr * getDefIgnoringCopies(Register Reg, const MachineRegisterInfo &MRI)
Find the def instruction for Reg, folding away any trivial copies.
Definition Utils.cpp:516
bool isPreISelGenericOptimizationHint(unsigned Opcode)
LLVM_ABI void reportGISelWarning(MachineFunction &MF, MachineOptimizationRemarkEmitter &MORE, MachineOptimizationRemarkMissed &R)
Report an ISel warning as a missed optimization remark to the LLVMContext's diagnostic stream.
Definition Utils.cpp:255
LLVM_ABI bool isGuaranteedNotToBeUndef(const Value *V, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
Returns true if V cannot be undef, but may be poison.
LLVM_ABI bool isConstTrueVal(const TargetLowering &TLI, int64_t Val, bool IsVector, bool IsFP)
Returns true if given the TargetLowering's boolean contents information, the value Val contains a tru...
Definition Utils.cpp:1625
LLVM_ABI LLVM_READNONE LLT getLCMType(LLT OrigTy, LLT TargetTy)
Return the least common multiple type of OrigTy and TargetTy, by changing the number of vector elemen...
Definition Utils.cpp:1160
LLVM_ABI bool isKnownToBeAPowerOfTwo(const Value *V, const DataLayout &DL, bool OrZero=false, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true, unsigned Depth=0)
Return true if the given value is known to have exactly one bit set when defined.
LLVM_ABI std::optional< int64_t > getIConstantVRegSExtVal(Register VReg, const MachineRegisterInfo &MRI)
If VReg is defined by a G_CONSTANT fits in int64_t returns it.
Definition Utils.cpp:317
LLVM_ABI std::optional< APInt > ConstantFoldBinOp(unsigned Opcode, const Register Op1, const Register Op2, const MachineRegisterInfo &MRI)
Definition Utils.cpp:681
auto dyn_cast_or_null(const Y &Val)
Definition Casting.h:753
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1762
LLVM_ABI const APInt & getIConstantFromReg(Register VReg, const MachineRegisterInfo &MRI)
VReg is defined by a G_CONSTANT, return the corresponding value.
Definition Utils.cpp:308
LLVM_READONLY APFloat maxnum(const APFloat &A, const APFloat &B)
Implements IEEE-754 2008 maxNum semantics.
Definition APFloat.h:1756
LLVM_ABI bool isConstantOrConstantVector(const MachineInstr &MI, const MachineRegisterInfo &MRI, bool AllowFP=true, bool AllowOpaqueConstants=true)
Return true if the specified instruction is known to be a constant, or a vector of constants.
Definition Utils.cpp:1517
constexpr unsigned MaxAnalysisRecursionDepth
auto reverse(ContainerTy &&C)
Definition STLExtras.h:408
LLVM_ABI bool canReplaceReg(Register DstReg, Register SrcReg, MachineRegisterInfo &MRI)
Check if DstReg can be replaced with SrcReg depending on the register constraints.
Definition Utils.cpp:203
LLVM_READONLY APFloat minimumnum(const APFloat &A, const APFloat &B)
Implements IEEE 754-2019 minimumNumber semantics.
Definition APFloat.h:1787
LLVM_ABI void saveUsesAndErase(MachineInstr &MI, MachineRegisterInfo &MRI, LostDebugLocObserver *LocObserver, SmallInstListTy &DeadInstChain)
Definition Utils.cpp:1662
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
LLVM_ABI void reportGISelFailure(MachineFunction &MF, MachineOptimizationRemarkEmitter &MORE, MachineOptimizationRemarkMissed &R)
Report an ISel error as a missed optimization remark to the LLVMContext's diagnostic stream.
Definition Utils.cpp:261
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition Alignment.h:149
LLVM_ABI std::optional< ValueAndVReg > getAnyConstantVRegValWithLookThrough(Register VReg, const MachineRegisterInfo &MRI, bool LookThroughInstrs=true, bool LookThroughAnyExt=false)
If VReg is defined by a statically evaluable chain of instructions rooted on a G_CONSTANT or G_FCONST...
Definition Utils.cpp:442
LLVM_ABI bool isBuildVectorAllOnes(const MachineInstr &MI, const MachineRegisterInfo &MRI, bool AllowUndef=false)
Return true if the specified instruction is a G_BUILD_VECTOR or G_BUILD_VECTOR_TRUNC where all of the...
Definition Utils.cpp:1459
LLVM_ABI bool canCreateUndefOrPoison(const Operator *Op, bool ConsiderFlagsAndMetadata=true)
canCreateUndefOrPoison returns true if Op can create undef or poison from non-undef & non-poison oper...
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
LLVM_ABI SmallVector< APInt > ConstantFoldVectorBinop(unsigned Opcode, const Register Op1, const Register Op2, const MachineRegisterInfo &MRI)
Tries to constant fold a vector binop with sources Op1 and Op2.
Definition Utils.cpp:828
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
LLVM_ABI std::optional< FPValueAndVReg > getFConstantSplat(Register VReg, const MachineRegisterInfo &MRI, bool AllowUndef=true)
Returns a floating point scalar constant of a build vector splat if it exists.
Definition Utils.cpp:1446
bool includesPoison(UndefPoisonKind Kind)
Returns true if Kind includes the Poison bit.
Definition UndefPoison.h:27
LLVM_ABI std::optional< APInt > ConstantFoldCastOp(unsigned Opcode, LLT DstTy, const Register Op0, const MachineRegisterInfo &MRI)
Definition Utils.cpp:917
LLVM_ABI void extractParts(Register Reg, LLT Ty, int NumParts, SmallVectorImpl< Register > &VRegs, MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI)
Helper function to split a wide generic register into bitwise blocks with the given Type (which impli...
Definition Utils.cpp:530
LLVM_ABI void getSelectionDAGFallbackAnalysisUsage(AnalysisUsage &AU)
Modify analysis usage so it preserves passes required for the SelectionDAG fallback.
Definition Utils.cpp:1156
LLVM_ABI bool canLowerMemCpyFamily(const MachineInstr &MI, const MachineRegisterInfo &MRI, unsigned MaxLen, Register &Dst, Register &Src, uint64_t &KnownLen, Align &Alignment, bool &DstAlignCanChange, std::vector< LLT > &MemOps)
Matcher for memcpy-like instructions.
Definition Utils.cpp:2165
LLVM_ABI LLVM_READNONE LLT getCoverTy(LLT OrigTy, LLT TargetTy)
Return smallest type that covers both OrigTy and TargetTy and is multiple of TargetTy.
Definition Utils.cpp:1227
bool includesUndef(UndefPoisonKind Kind)
Returns true if Kind includes the Undef bit.
Definition UndefPoison.h:33
LLVM_READONLY APFloat minnum(const APFloat &A, const APFloat &B)
Implements IEEE-754 2008 minNum semantics.
Definition APFloat.h:1737
LLVM_ABI unsigned getInverseGMinMaxOpcode(unsigned MinMaxOpc)
Returns the inverse opcode of MinMaxOpc, which is a generic min/max opcode like G_SMIN.
Definition Utils.cpp:282
@ Mul
Product of integers.
@ Fast
Assign the register banks as fast as possible (default).
bool isTargetSpecificOpcode(unsigned Opcode)
Check whether the given Opcode is a target-specific opcode.
DWARFExpression::Operation Op
LLVM_ABI bool isGuaranteedNotToBeUndefOrPoison(const Value *V, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
Return true if this function can prove that V does not have undef bits and is never poison.
LLVM_ABI std::optional< FPValueAndVReg > getFConstantVRegValWithLookThrough(Register VReg, const MachineRegisterInfo &MRI, bool LookThroughInstrs=true)
If VReg is defined by a statically evaluable chain of instructions rooted on a G_FCONSTANT returns it...
Definition Utils.cpp:450
LLVM_ABI bool isConstFalseVal(const TargetLowering &TLI, int64_t Val, bool IsVector, bool IsFP)
Definition Utils.cpp:1638
constexpr unsigned BitWidth
LLVM_ABI bool isBuildVectorConstantSplat(const Register Reg, const MachineRegisterInfo &MRI, int64_t SplatValue, bool AllowUndef)
Return true if the specified register is defined by G_BUILD_VECTOR or G_BUILD_VECTOR_TRUNC where all ...
Definition Utils.cpp:1372
LLVM_ABI void eraseInstr(MachineInstr &MI, MachineRegisterInfo &MRI, LostDebugLocObserver *LocObserver=nullptr)
Definition Utils.cpp:1692
DiagnosticSeverity
Defines the different supported severity of a diagnostic.
LLVM_ABI Register constrainRegToClass(MachineRegisterInfo &MRI, const TargetInstrInfo &TII, const RegisterBankInfo &RBI, Register Reg, const TargetRegisterClass &RegClass)
Try to constrain Reg to the specified register class.
Definition Utils.cpp:50
LLVM_ABI int64_t getICmpTrueVal(const TargetLowering &TLI, bool IsVector, bool IsFP)
Returns an integer representing true, as defined by the TargetBooleanContents.
Definition Utils.cpp:1650
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
LLVM_ABI std::optional< ValueAndVReg > getIConstantVRegValWithLookThrough(Register VReg, const MachineRegisterInfo &MRI, bool LookThroughInstrs=true)
If VReg is defined by a statically evaluable chain of instructions rooted on a G_CONSTANT returns its...
Definition Utils.cpp:436
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1788
UndefPoisonKind
Enumeration to track whether we are interested in Undef, Poison, or both.
Definition UndefPoison.h:20
LLVM_ABI bool isPreISelGenericFloatingPointOpcode(unsigned Opc)
Returns whether opcode Opc is a pre-isel generic floating-point opcode, having only floating-point op...
Definition Utils.cpp:1720
LLVM_ABI std::optional< DefinitionAndSourceRegister > getDefSrcRegIgnoringCopies(Register Reg, const MachineRegisterInfo &MRI)
Find the def instruction for Reg, and underlying value Register folding away any copies.
Definition Utils.cpp:491
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition STLExtras.h:1963
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
Definition Alignment.h:206
LLVM_ABI SmallVector< APInt > ConstantFoldUnaryIntOp(unsigned Opcode, LLT DstTy, Register Src, const MachineRegisterInfo &MRI)
Tries to constant fold a unary integer operation (G_CTLZ, G_CTTZ, G_CTPOP and their _ZERO_POISON vari...
Definition Utils.cpp:954
LLVM_ABI std::optional< Register > getVectorSplat(const MachineInstr &MI, const MachineRegisterInfo &MRI)
Definition Utils.cpp:1465
LLVM_ABI void eraseInstrs(ArrayRef< MachineInstr * > DeadInstrs, MachineRegisterInfo &MRI, LostDebugLocObserver *LocObserver=nullptr)
Definition Utils.cpp:1677
LLVM_ABI void salvageDebugInfoForDbgValue(const MachineRegisterInfo &MRI, MachineInstr &MI, ArrayRef< MachineOperand * > DbgUsers)
Assuming the instruction MI is going to be deleted, attempt to salvage debug users of MI by writing t...
LLVM_ABI Register getSrcRegIgnoringCopies(Register Reg, const MachineRegisterInfo &MRI)
Find the source register for Reg, folding away any trivial copies.
Definition Utils.cpp:523
LLVM_ABI LLVM_READNONE LLT getGCDType(LLT OrigTy, LLT TargetTy)
Return a type where the total size is the greatest common divisor of OrigTy and TargetTy.
Definition Utils.cpp:1248
LLVM_ABI bool isGuaranteedNotToBePoison(const Value *V, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
Returns true if V cannot be poison, but may be undef.
T bit_floor(T Value)
Returns the largest integral power of two no greater than Value if Value is nonzero.
Definition bit.h:347
LLVM_READONLY APFloat minimum(const APFloat &A, const APFloat &B)
Implements IEEE 754-2019 minimum semantics.
Definition APFloat.h:1774
LLVM_READONLY APFloat maximumnum(const APFloat &A, const APFloat &B)
Implements IEEE 754-2019 maximumNumber semantics.
Definition APFloat.h:1814
LLVM_ABI std::optional< int64_t > getIConstantSplatSExtVal(const Register Reg, const MachineRegisterInfo &MRI)
Definition Utils.cpp:1431
LLVM_ABI bool isAssertMI(const MachineInstr &MI)
Returns true if the instruction MI is one of the assert instructions.
Definition Utils.cpp:2005
LLVM_ABI void extractVectorParts(Register Reg, unsigned NumElts, SmallVectorImpl< Register > &VRegs, MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI)
Version which handles irregular sub-vector splits.
Definition Utils.cpp:633
LLVM_ABI int getSplatIndex(ArrayRef< int > Mask)
If all non-negative Mask elements are the same value, return that value.
LLVM_ABI bool isTriviallyDead(const MachineInstr &MI, const MachineRegisterInfo &MRI)
Check whether an instruction MI is dead: it only defines dead virtual registers, and doesn't have oth...
Definition Utils.cpp:224
MCRegisterClass TargetRegisterClass
Definition FastISel.h:58
LLVM_ABI Align inferAlignFromPtrInfo(MachineFunction &MF, const MachinePointerInfo &MPO)
Definition Utils.cpp:850
LLVM_ABI void reportFatalUsageError(Error Err)
Report a fatal error that does not indicate a bug in LLVM.
Definition Error.cpp:177
#define MORE()
Definition regcomp.c:247
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
Simple struct used to hold a Register value and the instruction which defines it.
Definition Utils.h:249
This class contains a discriminated union of information about pointers in memory operands,...
LLVM_ABI unsigned getAddrSpace() const
Return the LLVM IR address space number that this pointer points into.
int64_t Offset
Offset - This is an offset from the base Value*.
PointerUnion< const Value *, const PseudoSourceValue * > V
This is the IR pointer value for the access, or it is null if unknown.
static MemOp Set(uint64_t Size, bool DstAlignCanChange, Align DstAlign, bool IsZeroMemset, bool IsVolatile)
static MemOp Copy(uint64_t Size, bool DstAlignCanChange, Align DstAlign, Align SrcAlign, bool IsVolatile, bool MemcpyStrSrc=false)
static MemOp Move(uint64_t Size, bool DstAlignCanChange, Align DstAlign, Align SrcAlign, bool IsVolatile)
bool isVolatile() const
Simple struct used to hold a constant integer value and a virtual register.
Definition Utils.h:194