LLVM 20.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"
35#include "llvm/IR/Constants.h"
38#include <numeric>
39#include <optional>
40
41#define DEBUG_TYPE "globalisel-utils"
42
43using namespace llvm;
44using namespace MIPatternMatch;
45
47 const TargetInstrInfo &TII,
48 const RegisterBankInfo &RBI, Register Reg,
49 const TargetRegisterClass &RegClass) {
50 if (!RBI.constrainGenericRegister(Reg, RegClass, MRI))
51 return MRI.createVirtualRegister(&RegClass);
52
53 return Reg;
54}
55
57 const MachineFunction &MF, const TargetRegisterInfo &TRI,
59 const RegisterBankInfo &RBI, MachineInstr &InsertPt,
60 const TargetRegisterClass &RegClass, MachineOperand &RegMO) {
61 Register Reg = RegMO.getReg();
62 // Assume physical registers are properly constrained.
63 assert(Reg.isVirtual() && "PhysReg not implemented");
64
65 // Save the old register class to check whether
66 // the change notifications will be required.
67 // TODO: A better approach would be to pass
68 // the observers to constrainRegToClass().
69 auto *OldRegClass = MRI.getRegClassOrNull(Reg);
70 Register ConstrainedReg = constrainRegToClass(MRI, TII, RBI, Reg, RegClass);
71 // If we created a new virtual register because the class is not compatible
72 // then create a copy between the new and the old register.
73 if (ConstrainedReg != Reg) {
74 MachineBasicBlock::iterator InsertIt(&InsertPt);
75 MachineBasicBlock &MBB = *InsertPt.getParent();
76 // FIXME: The copy needs to have the classes constrained for its operands.
77 // Use operand's regbank to get the class for old register (Reg).
78 if (RegMO.isUse()) {
79 BuildMI(MBB, InsertIt, InsertPt.getDebugLoc(),
80 TII.get(TargetOpcode::COPY), ConstrainedReg)
81 .addReg(Reg);
82 } else {
83 assert(RegMO.isDef() && "Must be a definition");
84 BuildMI(MBB, std::next(InsertIt), InsertPt.getDebugLoc(),
85 TII.get(TargetOpcode::COPY), Reg)
86 .addReg(ConstrainedReg);
87 }
88 if (GISelChangeObserver *Observer = MF.getObserver()) {
89 Observer->changingInstr(*RegMO.getParent());
90 }
91 RegMO.setReg(ConstrainedReg);
92 if (GISelChangeObserver *Observer = MF.getObserver()) {
93 Observer->changedInstr(*RegMO.getParent());
94 }
95 } else if (OldRegClass != MRI.getRegClassOrNull(Reg)) {
96 if (GISelChangeObserver *Observer = MF.getObserver()) {
97 if (!RegMO.isDef()) {
98 MachineInstr *RegDef = MRI.getVRegDef(Reg);
99 Observer->changedInstr(*RegDef);
100 }
101 Observer->changingAllUsesOfReg(MRI, Reg);
102 Observer->finishedChangingAllUsesOfReg();
103 }
104 }
105 return ConstrainedReg;
106}
107
109 const MachineFunction &MF, const TargetRegisterInfo &TRI,
111 const RegisterBankInfo &RBI, MachineInstr &InsertPt, const MCInstrDesc &II,
112 MachineOperand &RegMO, unsigned OpIdx) {
113 Register Reg = RegMO.getReg();
114 // Assume physical registers are properly constrained.
115 assert(Reg.isVirtual() && "PhysReg not implemented");
116
117 const TargetRegisterClass *OpRC = TII.getRegClass(II, OpIdx, &TRI, MF);
118 // Some of the target independent instructions, like COPY, may not impose any
119 // register class constraints on some of their operands: If it's a use, we can
120 // skip constraining as the instruction defining the register would constrain
121 // it.
122
123 if (OpRC) {
124 // Obtain the RC from incoming regbank if it is a proper sub-class. Operands
125 // can have multiple regbanks for a superclass that combine different
126 // register types (E.g., AMDGPU's VGPR and AGPR). The regbank ambiguity
127 // resolved by targets during regbankselect should not be overridden.
128 if (const auto *SubRC = TRI.getCommonSubClass(
129 OpRC, TRI.getConstrainedRegClassForOperand(RegMO, MRI)))
130 OpRC = SubRC;
131
132 OpRC = TRI.getAllocatableClass(OpRC);
133 }
134
135 if (!OpRC) {
136 assert((!isTargetSpecificOpcode(II.getOpcode()) || RegMO.isUse()) &&
137 "Register class constraint is required unless either the "
138 "instruction is target independent or the operand is a use");
139 // FIXME: Just bailing out like this here could be not enough, unless we
140 // expect the users of this function to do the right thing for PHIs and
141 // COPY:
142 // v1 = COPY v0
143 // v2 = COPY v1
144 // v1 here may end up not being constrained at all. Please notice that to
145 // reproduce the issue we likely need a destination pattern of a selection
146 // rule producing such extra copies, not just an input GMIR with them as
147 // every existing target using selectImpl handles copies before calling it
148 // and they never reach this function.
149 return Reg;
150 }
151 return constrainOperandRegClass(MF, TRI, MRI, TII, RBI, InsertPt, *OpRC,
152 RegMO);
153}
154
156 const TargetInstrInfo &TII,
157 const TargetRegisterInfo &TRI,
158 const RegisterBankInfo &RBI) {
159 assert(!isPreISelGenericOpcode(I.getOpcode()) &&
160 "A selected instruction is expected");
161 MachineBasicBlock &MBB = *I.getParent();
164
165 for (unsigned OpI = 0, OpE = I.getNumExplicitOperands(); OpI != OpE; ++OpI) {
166 MachineOperand &MO = I.getOperand(OpI);
167
168 // There's nothing to be done on non-register operands.
169 if (!MO.isReg())
170 continue;
171
172 LLVM_DEBUG(dbgs() << "Converting operand: " << MO << '\n');
173 assert(MO.isReg() && "Unsupported non-reg operand");
174
175 Register Reg = MO.getReg();
176 // Physical registers don't need to be constrained.
177 if (Reg.isPhysical())
178 continue;
179
180 // Register operands with a value of 0 (e.g. predicate operands) don't need
181 // to be constrained.
182 if (Reg == 0)
183 continue;
184
185 // If the operand is a vreg, we should constrain its regclass, and only
186 // insert COPYs if that's impossible.
187 // constrainOperandRegClass does that for us.
188 constrainOperandRegClass(MF, TRI, MRI, TII, RBI, I, I.getDesc(), MO, OpI);
189
190 // Tie uses to defs as indicated in MCInstrDesc if this hasn't already been
191 // done.
192 if (MO.isUse()) {
193 int DefIdx = I.getDesc().getOperandConstraint(OpI, MCOI::TIED_TO);
194 if (DefIdx != -1 && !I.isRegTiedToUseOperand(DefIdx))
195 I.tieOperands(DefIdx, OpI);
196 }
197 }
198 return true;
199}
200
203 // Give up if either DstReg or SrcReg is a physical register.
204 if (DstReg.isPhysical() || SrcReg.isPhysical())
205 return false;
206 // Give up if the types don't match.
207 if (MRI.getType(DstReg) != MRI.getType(SrcReg))
208 return false;
209 // Replace if either DstReg has no constraints or the register
210 // constraints match.
211 const auto &DstRBC = MRI.getRegClassOrRegBank(DstReg);
212 if (!DstRBC || DstRBC == MRI.getRegClassOrRegBank(SrcReg))
213 return true;
214
215 // Otherwise match if the Src is already a regclass that is covered by the Dst
216 // RegBank.
217 return isa<const RegisterBank *>(DstRBC) && MRI.getRegClassOrNull(SrcReg) &&
218 cast<const RegisterBank *>(DstRBC)->covers(
219 *MRI.getRegClassOrNull(SrcReg));
220}
221
223 const MachineRegisterInfo &MRI) {
224 // Instructions without side-effects are dead iff they only define dead regs.
225 // This function is hot and this loop returns early in the common case,
226 // so only perform additional checks before this if absolutely necessary.
227 for (const auto &MO : MI.all_defs()) {
228 Register Reg = MO.getReg();
229 if (Reg.isPhysical() || !MRI.use_nodbg_empty(Reg))
230 return false;
231 }
232 return MI.wouldBeTriviallyDead();
233}
234
236 MachineFunction &MF,
237 const TargetPassConfig &TPC,
240 bool IsFatal = Severity == DS_Error &&
242 // Print the function name explicitly if we don't have a debug location (which
243 // makes the diagnostic less useful) or if we're going to emit a raw error.
244 if (!R.getLocation().isValid() || IsFatal)
245 R << (" (in function: " + MF.getName() + ")").str();
246
247 if (IsFatal)
248 report_fatal_error(Twine(R.getMsg()));
249 else
250 MORE.emit(R);
251}
252
257}
258
262 MF.getProperties().set(MachineFunctionProperties::Property::FailedISel);
263 reportGISelDiagnostic(DS_Error, MF, TPC, MORE, R);
264}
265
268 const char *PassName, StringRef Msg,
269 const MachineInstr &MI) {
270 MachineOptimizationRemarkMissed R(PassName, "GISelFailure: ",
271 MI.getDebugLoc(), MI.getParent());
272 R << Msg;
273 // Printing MI is expensive; only do it if expensive remarks are enabled.
274 if (TPC.isGlobalISelAbortEnabled() || MORE.allowExtraAnalysis(PassName))
275 R << ": " << ore::MNV("Inst", MI);
276 reportGISelFailure(MF, TPC, MORE, R);
277}
278
279std::optional<APInt> llvm::getIConstantVRegVal(Register VReg,
280 const MachineRegisterInfo &MRI) {
281 std::optional<ValueAndVReg> ValAndVReg = getIConstantVRegValWithLookThrough(
282 VReg, MRI, /*LookThroughInstrs*/ false);
283 assert((!ValAndVReg || ValAndVReg->VReg == VReg) &&
284 "Value found while looking through instrs");
285 if (!ValAndVReg)
286 return std::nullopt;
287 return ValAndVReg->Value;
288}
289
291 const MachineRegisterInfo &MRI) {
292 MachineInstr *Const = MRI.getVRegDef(Reg);
293 assert((Const && Const->getOpcode() == TargetOpcode::G_CONSTANT) &&
294 "expected a G_CONSTANT on Reg");
295 return Const->getOperand(1).getCImm()->getValue();
296}
297
298std::optional<int64_t>
300 std::optional<APInt> Val = getIConstantVRegVal(VReg, MRI);
301 if (Val && Val->getBitWidth() <= 64)
302 return Val->getSExtValue();
303 return std::nullopt;
304}
305
306namespace {
307
308// This function is used in many places, and as such, it has some
309// micro-optimizations to try and make it as fast as it can be.
310//
311// - We use template arguments to avoid an indirect call caused by passing a
312// function_ref/std::function
313// - GetAPCstValue does not return std::optional<APInt> as that's expensive.
314// Instead it returns true/false and places the result in a pre-constructed
315// APInt.
316//
317// Please change this function carefully and benchmark your changes.
318template <bool (*IsConstantOpcode)(const MachineInstr *),
319 bool (*GetAPCstValue)(const MachineInstr *MI, APInt &)>
320std::optional<ValueAndVReg>
321getConstantVRegValWithLookThrough(Register VReg, const MachineRegisterInfo &MRI,
322 bool LookThroughInstrs = true,
323 bool LookThroughAnyExt = false) {
326
327 while ((MI = MRI.getVRegDef(VReg)) && !IsConstantOpcode(MI) &&
328 LookThroughInstrs) {
329 switch (MI->getOpcode()) {
330 case TargetOpcode::G_ANYEXT:
331 if (!LookThroughAnyExt)
332 return std::nullopt;
333 [[fallthrough]];
334 case TargetOpcode::G_TRUNC:
335 case TargetOpcode::G_SEXT:
336 case TargetOpcode::G_ZEXT:
337 SeenOpcodes.push_back(std::make_pair(
338 MI->getOpcode(),
339 MRI.getType(MI->getOperand(0).getReg()).getSizeInBits()));
340 VReg = MI->getOperand(1).getReg();
341 break;
342 case TargetOpcode::COPY:
343 VReg = MI->getOperand(1).getReg();
344 if (VReg.isPhysical())
345 return std::nullopt;
346 break;
347 case TargetOpcode::G_INTTOPTR:
348 VReg = MI->getOperand(1).getReg();
349 break;
350 default:
351 return std::nullopt;
352 }
353 }
354 if (!MI || !IsConstantOpcode(MI))
355 return std::nullopt;
356
357 APInt Val;
358 if (!GetAPCstValue(MI, Val))
359 return std::nullopt;
360 for (auto &Pair : reverse(SeenOpcodes)) {
361 switch (Pair.first) {
362 case TargetOpcode::G_TRUNC:
363 Val = Val.trunc(Pair.second);
364 break;
365 case TargetOpcode::G_ANYEXT:
366 case TargetOpcode::G_SEXT:
367 Val = Val.sext(Pair.second);
368 break;
369 case TargetOpcode::G_ZEXT:
370 Val = Val.zext(Pair.second);
371 break;
372 }
373 }
374
375 return ValueAndVReg{std::move(Val), VReg};
376}
377
378bool isIConstant(const MachineInstr *MI) {
379 if (!MI)
380 return false;
381 return MI->getOpcode() == TargetOpcode::G_CONSTANT;
382}
383
384bool isFConstant(const MachineInstr *MI) {
385 if (!MI)
386 return false;
387 return MI->getOpcode() == TargetOpcode::G_FCONSTANT;
388}
389
390bool isAnyConstant(const MachineInstr *MI) {
391 if (!MI)
392 return false;
393 unsigned Opc = MI->getOpcode();
394 return Opc == TargetOpcode::G_CONSTANT || Opc == TargetOpcode::G_FCONSTANT;
395}
396
397bool getCImmAsAPInt(const MachineInstr *MI, APInt &Result) {
398 const MachineOperand &CstVal = MI->getOperand(1);
399 if (!CstVal.isCImm())
400 return false;
401 Result = CstVal.getCImm()->getValue();
402 return true;
403}
404
405bool getCImmOrFPImmAsAPInt(const MachineInstr *MI, APInt &Result) {
406 const MachineOperand &CstVal = MI->getOperand(1);
407 if (CstVal.isCImm())
408 Result = CstVal.getCImm()->getValue();
409 else if (CstVal.isFPImm())
411 else
412 return false;
413 return true;
414}
415
416} // end anonymous namespace
417
419 Register VReg, const MachineRegisterInfo &MRI, bool LookThroughInstrs) {
420 return getConstantVRegValWithLookThrough<isIConstant, getCImmAsAPInt>(
421 VReg, MRI, LookThroughInstrs);
422}
423
425 Register VReg, const MachineRegisterInfo &MRI, bool LookThroughInstrs,
426 bool LookThroughAnyExt) {
427 return getConstantVRegValWithLookThrough<isAnyConstant,
428 getCImmOrFPImmAsAPInt>(
429 VReg, MRI, LookThroughInstrs, LookThroughAnyExt);
430}
431
432std::optional<FPValueAndVReg> llvm::getFConstantVRegValWithLookThrough(
433 Register VReg, const MachineRegisterInfo &MRI, bool LookThroughInstrs) {
434 auto Reg =
435 getConstantVRegValWithLookThrough<isFConstant, getCImmOrFPImmAsAPInt>(
436 VReg, MRI, LookThroughInstrs);
437 if (!Reg)
438 return std::nullopt;
440 Reg->VReg};
441}
442
443const ConstantFP *
445 MachineInstr *MI = MRI.getVRegDef(VReg);
446 if (TargetOpcode::G_FCONSTANT != MI->getOpcode())
447 return nullptr;
448 return MI->getOperand(1).getFPImm();
449}
450
451std::optional<DefinitionAndSourceRegister>
453 Register DefSrcReg = Reg;
454 auto *DefMI = MRI.getVRegDef(Reg);
455 auto DstTy = MRI.getType(DefMI->getOperand(0).getReg());
456 if (!DstTy.isValid())
457 return std::nullopt;
458 unsigned Opc = DefMI->getOpcode();
459 while (Opc == TargetOpcode::COPY || isPreISelGenericOptimizationHint(Opc)) {
460 Register SrcReg = DefMI->getOperand(1).getReg();
461 auto SrcTy = MRI.getType(SrcReg);
462 if (!SrcTy.isValid())
463 break;
464 DefMI = MRI.getVRegDef(SrcReg);
465 DefSrcReg = SrcReg;
466 Opc = DefMI->getOpcode();
467 }
468 return DefinitionAndSourceRegister{DefMI, DefSrcReg};
469}
470
472 const MachineRegisterInfo &MRI) {
473 std::optional<DefinitionAndSourceRegister> DefSrcReg =
475 return DefSrcReg ? DefSrcReg->MI : nullptr;
476}
477
479 const MachineRegisterInfo &MRI) {
480 std::optional<DefinitionAndSourceRegister> DefSrcReg =
482 return DefSrcReg ? DefSrcReg->Reg : Register();
483}
484
485void llvm::extractParts(Register Reg, LLT Ty, int NumParts,
487 MachineIRBuilder &MIRBuilder,
489 for (int i = 0; i < NumParts; ++i)
490 VRegs.push_back(MRI.createGenericVirtualRegister(Ty));
491 MIRBuilder.buildUnmerge(VRegs, Reg);
492}
493
494bool llvm::extractParts(Register Reg, LLT RegTy, LLT MainTy, LLT &LeftoverTy,
496 SmallVectorImpl<Register> &LeftoverRegs,
497 MachineIRBuilder &MIRBuilder,
499 assert(!LeftoverTy.isValid() && "this is an out argument");
500
501 unsigned RegSize = RegTy.getSizeInBits();
502 unsigned MainSize = MainTy.getSizeInBits();
503 unsigned NumParts = RegSize / MainSize;
504 unsigned LeftoverSize = RegSize - NumParts * MainSize;
505
506 // Use an unmerge when possible.
507 if (LeftoverSize == 0) {
508 for (unsigned I = 0; I < NumParts; ++I)
509 VRegs.push_back(MRI.createGenericVirtualRegister(MainTy));
510 MIRBuilder.buildUnmerge(VRegs, Reg);
511 return true;
512 }
513
514 // Try to use unmerge for irregular vector split where possible
515 // For example when splitting a <6 x i32> into <4 x i32> with <2 x i32>
516 // leftover, it becomes:
517 // <2 x i32> %2, <2 x i32>%3, <2 x i32> %4 = G_UNMERGE_VALUE <6 x i32> %1
518 // <4 x i32> %5 = G_CONCAT_VECTOR <2 x i32> %2, <2 x i32> %3
519 if (RegTy.isVector() && MainTy.isVector()) {
520 unsigned RegNumElts = RegTy.getNumElements();
521 unsigned MainNumElts = MainTy.getNumElements();
522 unsigned LeftoverNumElts = RegNumElts % MainNumElts;
523 // If can unmerge to LeftoverTy, do it
524 if (MainNumElts % LeftoverNumElts == 0 &&
525 RegNumElts % LeftoverNumElts == 0 &&
526 RegTy.getScalarSizeInBits() == MainTy.getScalarSizeInBits() &&
527 LeftoverNumElts > 1) {
528 LeftoverTy = LLT::fixed_vector(LeftoverNumElts, RegTy.getElementType());
529
530 // Unmerge the SrcReg to LeftoverTy vectors
531 SmallVector<Register, 4> UnmergeValues;
532 extractParts(Reg, LeftoverTy, RegNumElts / LeftoverNumElts, UnmergeValues,
533 MIRBuilder, MRI);
534
535 // Find how many LeftoverTy makes one MainTy
536 unsigned LeftoverPerMain = MainNumElts / LeftoverNumElts;
537 unsigned NumOfLeftoverVal =
538 ((RegNumElts % MainNumElts) / LeftoverNumElts);
539
540 // Create as many MainTy as possible using unmerged value
541 SmallVector<Register, 4> MergeValues;
542 for (unsigned I = 0; I < UnmergeValues.size() - NumOfLeftoverVal; I++) {
543 MergeValues.push_back(UnmergeValues[I]);
544 if (MergeValues.size() == LeftoverPerMain) {
545 VRegs.push_back(
546 MIRBuilder.buildMergeLikeInstr(MainTy, MergeValues).getReg(0));
547 MergeValues.clear();
548 }
549 }
550 // Populate LeftoverRegs with the leftovers
551 for (unsigned I = UnmergeValues.size() - NumOfLeftoverVal;
552 I < UnmergeValues.size(); I++) {
553 LeftoverRegs.push_back(UnmergeValues[I]);
554 }
555 return true;
556 }
557 }
558 // Perform irregular split. Leftover is last element of RegPieces.
559 if (MainTy.isVector()) {
560 SmallVector<Register, 8> RegPieces;
561 extractVectorParts(Reg, MainTy.getNumElements(), RegPieces, MIRBuilder,
562 MRI);
563 for (unsigned i = 0; i < RegPieces.size() - 1; ++i)
564 VRegs.push_back(RegPieces[i]);
565 LeftoverRegs.push_back(RegPieces[RegPieces.size() - 1]);
566 LeftoverTy = MRI.getType(LeftoverRegs[0]);
567 return true;
568 }
569
570 LeftoverTy = LLT::scalar(LeftoverSize);
571 // For irregular sizes, extract the individual parts.
572 for (unsigned I = 0; I != NumParts; ++I) {
573 Register NewReg = MRI.createGenericVirtualRegister(MainTy);
574 VRegs.push_back(NewReg);
575 MIRBuilder.buildExtract(NewReg, Reg, MainSize * I);
576 }
577
578 for (unsigned Offset = MainSize * NumParts; Offset < RegSize;
579 Offset += LeftoverSize) {
580 Register NewReg = MRI.createGenericVirtualRegister(LeftoverTy);
581 LeftoverRegs.push_back(NewReg);
582 MIRBuilder.buildExtract(NewReg, Reg, Offset);
583 }
584
585 return true;
586}
587
588void llvm::extractVectorParts(Register Reg, unsigned NumElts,
590 MachineIRBuilder &MIRBuilder,
592 LLT RegTy = MRI.getType(Reg);
593 assert(RegTy.isVector() && "Expected a vector type");
594
595 LLT EltTy = RegTy.getElementType();
596 LLT NarrowTy = (NumElts == 1) ? EltTy : LLT::fixed_vector(NumElts, EltTy);
597 unsigned RegNumElts = RegTy.getNumElements();
598 unsigned LeftoverNumElts = RegNumElts % NumElts;
599 unsigned NumNarrowTyPieces = RegNumElts / NumElts;
600
601 // Perfect split without leftover
602 if (LeftoverNumElts == 0)
603 return extractParts(Reg, NarrowTy, NumNarrowTyPieces, VRegs, MIRBuilder,
604 MRI);
605
606 // Irregular split. Provide direct access to all elements for artifact
607 // combiner using unmerge to elements. Then build vectors with NumElts
608 // elements. Remaining element(s) will be (used to build vector) Leftover.
610 extractParts(Reg, EltTy, RegNumElts, Elts, MIRBuilder, MRI);
611
612 unsigned Offset = 0;
613 // Requested sub-vectors of NarrowTy.
614 for (unsigned i = 0; i < NumNarrowTyPieces; ++i, Offset += NumElts) {
615 ArrayRef<Register> Pieces(&Elts[Offset], NumElts);
616 VRegs.push_back(MIRBuilder.buildMergeLikeInstr(NarrowTy, Pieces).getReg(0));
617 }
618
619 // Leftover element(s).
620 if (LeftoverNumElts == 1) {
621 VRegs.push_back(Elts[Offset]);
622 } else {
623 LLT LeftoverTy = LLT::fixed_vector(LeftoverNumElts, EltTy);
624 ArrayRef<Register> Pieces(&Elts[Offset], LeftoverNumElts);
625 VRegs.push_back(
626 MIRBuilder.buildMergeLikeInstr(LeftoverTy, Pieces).getReg(0));
627 }
628}
629
631 const MachineRegisterInfo &MRI) {
633 return DefMI && DefMI->getOpcode() == Opcode ? DefMI : nullptr;
634}
635
636APFloat llvm::getAPFloatFromSize(double Val, unsigned Size) {
637 if (Size == 32)
638 return APFloat(float(Val));
639 if (Size == 64)
640 return APFloat(Val);
641 if (Size != 16)
642 llvm_unreachable("Unsupported FPConstant size");
643 bool Ignored;
644 APFloat APF(Val);
645 APF.convert(APFloat::IEEEhalf(), APFloat::rmNearestTiesToEven, &Ignored);
646 return APF;
647}
648
649std::optional<APInt> llvm::ConstantFoldBinOp(unsigned Opcode,
650 const Register Op1,
651 const Register Op2,
652 const MachineRegisterInfo &MRI) {
653 auto MaybeOp2Cst = getAnyConstantVRegValWithLookThrough(Op2, MRI, false);
654 if (!MaybeOp2Cst)
655 return std::nullopt;
656
657 auto MaybeOp1Cst = getAnyConstantVRegValWithLookThrough(Op1, MRI, false);
658 if (!MaybeOp1Cst)
659 return std::nullopt;
660
661 const APInt &C1 = MaybeOp1Cst->Value;
662 const APInt &C2 = MaybeOp2Cst->Value;
663 switch (Opcode) {
664 default:
665 break;
666 case TargetOpcode::G_ADD:
667 return C1 + C2;
668 case TargetOpcode::G_PTR_ADD:
669 // Types can be of different width here.
670 // Result needs to be the same width as C1, so trunc or sext C2.
671 return C1 + C2.sextOrTrunc(C1.getBitWidth());
672 case TargetOpcode::G_AND:
673 return C1 & C2;
674 case TargetOpcode::G_ASHR:
675 return C1.ashr(C2);
676 case TargetOpcode::G_LSHR:
677 return C1.lshr(C2);
678 case TargetOpcode::G_MUL:
679 return C1 * C2;
680 case TargetOpcode::G_OR:
681 return C1 | C2;
682 case TargetOpcode::G_SHL:
683 return C1 << C2;
684 case TargetOpcode::G_SUB:
685 return C1 - C2;
686 case TargetOpcode::G_XOR:
687 return C1 ^ C2;
688 case TargetOpcode::G_UDIV:
689 if (!C2.getBoolValue())
690 break;
691 return C1.udiv(C2);
692 case TargetOpcode::G_SDIV:
693 if (!C2.getBoolValue())
694 break;
695 return C1.sdiv(C2);
696 case TargetOpcode::G_UREM:
697 if (!C2.getBoolValue())
698 break;
699 return C1.urem(C2);
700 case TargetOpcode::G_SREM:
701 if (!C2.getBoolValue())
702 break;
703 return C1.srem(C2);
704 case TargetOpcode::G_SMIN:
705 return APIntOps::smin(C1, C2);
706 case TargetOpcode::G_SMAX:
707 return APIntOps::smax(C1, C2);
708 case TargetOpcode::G_UMIN:
709 return APIntOps::umin(C1, C2);
710 case TargetOpcode::G_UMAX:
711 return APIntOps::umax(C1, C2);
712 }
713
714 return std::nullopt;
715}
716
717std::optional<APFloat>
718llvm::ConstantFoldFPBinOp(unsigned Opcode, const Register Op1,
719 const Register Op2, const MachineRegisterInfo &MRI) {
720 const ConstantFP *Op2Cst = getConstantFPVRegVal(Op2, MRI);
721 if (!Op2Cst)
722 return std::nullopt;
723
724 const ConstantFP *Op1Cst = getConstantFPVRegVal(Op1, MRI);
725 if (!Op1Cst)
726 return std::nullopt;
727
728 APFloat C1 = Op1Cst->getValueAPF();
729 const APFloat &C2 = Op2Cst->getValueAPF();
730 switch (Opcode) {
731 case TargetOpcode::G_FADD:
732 C1.add(C2, APFloat::rmNearestTiesToEven);
733 return C1;
734 case TargetOpcode::G_FSUB:
735 C1.subtract(C2, APFloat::rmNearestTiesToEven);
736 return C1;
737 case TargetOpcode::G_FMUL:
738 C1.multiply(C2, APFloat::rmNearestTiesToEven);
739 return C1;
740 case TargetOpcode::G_FDIV:
741 C1.divide(C2, APFloat::rmNearestTiesToEven);
742 return C1;
743 case TargetOpcode::G_FREM:
744 C1.mod(C2);
745 return C1;
746 case TargetOpcode::G_FCOPYSIGN:
747 C1.copySign(C2);
748 return C1;
749 case TargetOpcode::G_FMINNUM:
750 return minnum(C1, C2);
751 case TargetOpcode::G_FMAXNUM:
752 return maxnum(C1, C2);
753 case TargetOpcode::G_FMINIMUM:
754 return minimum(C1, C2);
755 case TargetOpcode::G_FMAXIMUM:
756 return maximum(C1, C2);
757 case TargetOpcode::G_FMINNUM_IEEE:
758 case TargetOpcode::G_FMAXNUM_IEEE:
759 // FIXME: These operations were unfortunately named. fminnum/fmaxnum do not
760 // follow the IEEE behavior for signaling nans and follow libm's fmin/fmax,
761 // and currently there isn't a nice wrapper in APFloat for the version with
762 // correct snan handling.
763 break;
764 default:
765 break;
766 }
767
768 return std::nullopt;
769}
770
772llvm::ConstantFoldVectorBinop(unsigned Opcode, const Register Op1,
773 const Register Op2,
774 const MachineRegisterInfo &MRI) {
775 auto *SrcVec2 = getOpcodeDef<GBuildVector>(Op2, MRI);
776 if (!SrcVec2)
777 return SmallVector<APInt>();
778
779 auto *SrcVec1 = getOpcodeDef<GBuildVector>(Op1, MRI);
780 if (!SrcVec1)
781 return SmallVector<APInt>();
782
783 SmallVector<APInt> FoldedElements;
784 for (unsigned Idx = 0, E = SrcVec1->getNumSources(); Idx < E; ++Idx) {
785 auto MaybeCst = ConstantFoldBinOp(Opcode, SrcVec1->getSourceReg(Idx),
786 SrcVec2->getSourceReg(Idx), MRI);
787 if (!MaybeCst)
788 return SmallVector<APInt>();
789 FoldedElements.push_back(*MaybeCst);
790 }
791 return FoldedElements;
792}
793
795 bool SNaN) {
796 const MachineInstr *DefMI = MRI.getVRegDef(Val);
797 if (!DefMI)
798 return false;
799
800 const TargetMachine& TM = DefMI->getMF()->getTarget();
801 if (DefMI->getFlag(MachineInstr::FmNoNans) || TM.Options.NoNaNsFPMath)
802 return true;
803
804 // If the value is a constant, we can obviously see if it is a NaN or not.
805 if (const ConstantFP *FPVal = getConstantFPVRegVal(Val, MRI)) {
806 return !FPVal->getValueAPF().isNaN() ||
807 (SNaN && !FPVal->getValueAPF().isSignaling());
808 }
809
810 if (DefMI->getOpcode() == TargetOpcode::G_BUILD_VECTOR) {
811 for (const auto &Op : DefMI->uses())
812 if (!isKnownNeverNaN(Op.getReg(), MRI, SNaN))
813 return false;
814 return true;
815 }
816
817 switch (DefMI->getOpcode()) {
818 default:
819 break;
820 case TargetOpcode::G_FADD:
821 case TargetOpcode::G_FSUB:
822 case TargetOpcode::G_FMUL:
823 case TargetOpcode::G_FDIV:
824 case TargetOpcode::G_FREM:
825 case TargetOpcode::G_FSIN:
826 case TargetOpcode::G_FCOS:
827 case TargetOpcode::G_FTAN:
828 case TargetOpcode::G_FACOS:
829 case TargetOpcode::G_FASIN:
830 case TargetOpcode::G_FATAN:
831 case TargetOpcode::G_FATAN2:
832 case TargetOpcode::G_FCOSH:
833 case TargetOpcode::G_FSINH:
834 case TargetOpcode::G_FTANH:
835 case TargetOpcode::G_FMA:
836 case TargetOpcode::G_FMAD:
837 if (SNaN)
838 return true;
839
840 // TODO: Need isKnownNeverInfinity
841 return false;
842 case TargetOpcode::G_FMINNUM_IEEE:
843 case TargetOpcode::G_FMAXNUM_IEEE: {
844 if (SNaN)
845 return true;
846 // This can return a NaN if either operand is an sNaN, or if both operands
847 // are NaN.
848 return (isKnownNeverNaN(DefMI->getOperand(1).getReg(), MRI) &&
852 }
853 case TargetOpcode::G_FMINNUM:
854 case TargetOpcode::G_FMAXNUM: {
855 // Only one needs to be known not-nan, since it will be returned if the
856 // other ends up being one.
857 return isKnownNeverNaN(DefMI->getOperand(1).getReg(), MRI, SNaN) ||
859 }
860 }
861
862 if (SNaN) {
863 // FP operations quiet. For now, just handle the ones inserted during
864 // legalization.
865 switch (DefMI->getOpcode()) {
866 case TargetOpcode::G_FPEXT:
867 case TargetOpcode::G_FPTRUNC:
868 case TargetOpcode::G_FCANONICALIZE:
869 return true;
870 default:
871 return false;
872 }
873 }
874
875 return false;
876}
877
879 const MachinePointerInfo &MPO) {
880 auto PSV = dyn_cast_if_present<const PseudoSourceValue *>(MPO.V);
881 if (auto FSPV = dyn_cast_or_null<FixedStackPseudoSourceValue>(PSV)) {
882 MachineFrameInfo &MFI = MF.getFrameInfo();
883 return commonAlignment(MFI.getObjectAlign(FSPV->getFrameIndex()),
884 MPO.Offset);
885 }
886
887 if (const Value *V = dyn_cast_if_present<const Value *>(MPO.V)) {
888 const Module *M = MF.getFunction().getParent();
889 return V->getPointerAlignment(M->getDataLayout());
890 }
891
892 return Align(1);
893}
894
896 const TargetInstrInfo &TII,
897 MCRegister PhysReg,
898 const TargetRegisterClass &RC,
899 const DebugLoc &DL, LLT RegTy) {
900 MachineBasicBlock &EntryMBB = MF.front();
902 Register LiveIn = MRI.getLiveInVirtReg(PhysReg);
903 if (LiveIn) {
904 MachineInstr *Def = MRI.getVRegDef(LiveIn);
905 if (Def) {
906 // FIXME: Should the verifier check this is in the entry block?
907 assert(Def->getParent() == &EntryMBB && "live-in copy not in entry block");
908 return LiveIn;
909 }
910
911 // It's possible the incoming argument register and copy was added during
912 // lowering, but later deleted due to being/becoming dead. If this happens,
913 // re-insert the copy.
914 } else {
915 // The live in register was not present, so add it.
916 LiveIn = MF.addLiveIn(PhysReg, &RC);
917 if (RegTy.isValid())
918 MRI.setType(LiveIn, RegTy);
919 }
920
921 BuildMI(EntryMBB, EntryMBB.begin(), DL, TII.get(TargetOpcode::COPY), LiveIn)
922 .addReg(PhysReg);
923 if (!EntryMBB.isLiveIn(PhysReg))
924 EntryMBB.addLiveIn(PhysReg);
925 return LiveIn;
926}
927
928std::optional<APInt> llvm::ConstantFoldExtOp(unsigned Opcode,
929 const Register Op1, uint64_t Imm,
930 const MachineRegisterInfo &MRI) {
931 auto MaybeOp1Cst = getIConstantVRegVal(Op1, MRI);
932 if (MaybeOp1Cst) {
933 switch (Opcode) {
934 default:
935 break;
936 case TargetOpcode::G_SEXT_INREG: {
937 LLT Ty = MRI.getType(Op1);
938 return MaybeOp1Cst->trunc(Imm).sext(Ty.getScalarSizeInBits());
939 }
940 }
941 }
942 return std::nullopt;
943}
944
945std::optional<APInt> llvm::ConstantFoldCastOp(unsigned Opcode, LLT DstTy,
946 const Register Op0,
947 const MachineRegisterInfo &MRI) {
948 std::optional<APInt> Val = getIConstantVRegVal(Op0, MRI);
949 if (!Val)
950 return Val;
951
952 const unsigned DstSize = DstTy.getScalarSizeInBits();
953
954 switch (Opcode) {
955 case TargetOpcode::G_SEXT:
956 return Val->sext(DstSize);
957 case TargetOpcode::G_ZEXT:
958 case TargetOpcode::G_ANYEXT:
959 // TODO: DAG considers target preference when constant folding any_extend.
960 return Val->zext(DstSize);
961 default:
962 break;
963 }
964
965 llvm_unreachable("unexpected cast opcode to constant fold");
966}
967
968std::optional<APFloat>
969llvm::ConstantFoldIntToFloat(unsigned Opcode, LLT DstTy, Register Src,
970 const MachineRegisterInfo &MRI) {
971 assert(Opcode == TargetOpcode::G_SITOFP || Opcode == TargetOpcode::G_UITOFP);
972 if (auto MaybeSrcVal = getIConstantVRegVal(Src, MRI)) {
973 APFloat DstVal(getFltSemanticForLLT(DstTy));
974 DstVal.convertFromAPInt(*MaybeSrcVal, Opcode == TargetOpcode::G_SITOFP,
975 APFloat::rmNearestTiesToEven);
976 return DstVal;
977 }
978 return std::nullopt;
979}
980
981std::optional<SmallVector<unsigned>>
983 std::function<unsigned(APInt)> CB) {
984 LLT Ty = MRI.getType(Src);
985 SmallVector<unsigned> FoldedCTLZs;
986 auto tryFoldScalar = [&](Register R) -> std::optional<unsigned> {
987 auto MaybeCst = getIConstantVRegVal(R, MRI);
988 if (!MaybeCst)
989 return std::nullopt;
990 return CB(*MaybeCst);
991 };
992 if (Ty.isVector()) {
993 // Try to constant fold each element.
994 auto *BV = getOpcodeDef<GBuildVector>(Src, MRI);
995 if (!BV)
996 return std::nullopt;
997 for (unsigned SrcIdx = 0; SrcIdx < BV->getNumSources(); ++SrcIdx) {
998 if (auto MaybeFold = tryFoldScalar(BV->getSourceReg(SrcIdx))) {
999 FoldedCTLZs.emplace_back(*MaybeFold);
1000 continue;
1001 }
1002 return std::nullopt;
1003 }
1004 return FoldedCTLZs;
1005 }
1006 if (auto MaybeCst = tryFoldScalar(Src)) {
1007 FoldedCTLZs.emplace_back(*MaybeCst);
1008 return FoldedCTLZs;
1009 }
1010 return std::nullopt;
1011}
1012
1013std::optional<SmallVector<APInt>>
1014llvm::ConstantFoldICmp(unsigned Pred, const Register Op1, const Register Op2,
1015 const MachineRegisterInfo &MRI) {
1016 LLT Ty = MRI.getType(Op1);
1017 if (Ty != MRI.getType(Op2))
1018 return std::nullopt;
1019
1020 auto TryFoldScalar = [&MRI, Pred](Register LHS,
1021 Register RHS) -> std::optional<APInt> {
1022 auto LHSCst = getIConstantVRegVal(LHS, MRI);
1023 auto RHSCst = getIConstantVRegVal(RHS, MRI);
1024 if (!LHSCst || !RHSCst)
1025 return std::nullopt;
1026
1027 switch (Pred) {
1028 case CmpInst::Predicate::ICMP_EQ:
1029 return APInt(/*numBits=*/1, LHSCst->eq(*RHSCst));
1030 case CmpInst::Predicate::ICMP_NE:
1031 return APInt(/*numBits=*/1, LHSCst->ne(*RHSCst));
1032 case CmpInst::Predicate::ICMP_UGT:
1033 return APInt(/*numBits=*/1, LHSCst->ugt(*RHSCst));
1034 case CmpInst::Predicate::ICMP_UGE:
1035 return APInt(/*numBits=*/1, LHSCst->uge(*RHSCst));
1036 case CmpInst::Predicate::ICMP_ULT:
1037 return APInt(/*numBits=*/1, LHSCst->ult(*RHSCst));
1038 case CmpInst::Predicate::ICMP_ULE:
1039 return APInt(/*numBits=*/1, LHSCst->ule(*RHSCst));
1040 case CmpInst::Predicate::ICMP_SGT:
1041 return APInt(/*numBits=*/1, LHSCst->sgt(*RHSCst));
1042 case CmpInst::Predicate::ICMP_SGE:
1043 return APInt(/*numBits=*/1, LHSCst->sge(*RHSCst));
1044 case CmpInst::Predicate::ICMP_SLT:
1045 return APInt(/*numBits=*/1, LHSCst->slt(*RHSCst));
1046 case CmpInst::Predicate::ICMP_SLE:
1047 return APInt(/*numBits=*/1, LHSCst->sle(*RHSCst));
1048 default:
1049 return std::nullopt;
1050 }
1051 };
1052
1053 SmallVector<APInt> FoldedICmps;
1054
1055 if (Ty.isVector()) {
1056 // Try to constant fold each element.
1057 auto *BV1 = getOpcodeDef<GBuildVector>(Op1, MRI);
1058 auto *BV2 = getOpcodeDef<GBuildVector>(Op2, MRI);
1059 if (!BV1 || !BV2)
1060 return std::nullopt;
1061 assert(BV1->getNumSources() == BV2->getNumSources() && "Invalid vectors");
1062 for (unsigned I = 0; I < BV1->getNumSources(); ++I) {
1063 if (auto MaybeFold =
1064 TryFoldScalar(BV1->getSourceReg(I), BV2->getSourceReg(I))) {
1065 FoldedICmps.emplace_back(*MaybeFold);
1066 continue;
1067 }
1068 return std::nullopt;
1069 }
1070 return FoldedICmps;
1071 }
1072
1073 if (auto MaybeCst = TryFoldScalar(Op1, Op2)) {
1074 FoldedICmps.emplace_back(*MaybeCst);
1075 return FoldedICmps;
1076 }
1077
1078 return std::nullopt;
1079}
1080
1082 GISelKnownBits *KB) {
1083 std::optional<DefinitionAndSourceRegister> DefSrcReg =
1085 if (!DefSrcReg)
1086 return false;
1087
1088 const MachineInstr &MI = *DefSrcReg->MI;
1089 const LLT Ty = MRI.getType(Reg);
1090
1091 switch (MI.getOpcode()) {
1092 case TargetOpcode::G_CONSTANT: {
1093 unsigned BitWidth = Ty.getScalarSizeInBits();
1094 const ConstantInt *CI = MI.getOperand(1).getCImm();
1095 return CI->getValue().zextOrTrunc(BitWidth).isPowerOf2();
1096 }
1097 case TargetOpcode::G_SHL: {
1098 // A left-shift of a constant one will have exactly one bit set because
1099 // shifting the bit off the end is undefined.
1100
1101 // TODO: Constant splat
1102 if (auto ConstLHS = getIConstantVRegVal(MI.getOperand(1).getReg(), MRI)) {
1103 if (*ConstLHS == 1)
1104 return true;
1105 }
1106
1107 break;
1108 }
1109 case TargetOpcode::G_LSHR: {
1110 if (auto ConstLHS = getIConstantVRegVal(MI.getOperand(1).getReg(), MRI)) {
1111 if (ConstLHS->isSignMask())
1112 return true;
1113 }
1114
1115 break;
1116 }
1117 case TargetOpcode::G_BUILD_VECTOR: {
1118 // TODO: Probably should have a recursion depth guard since you could have
1119 // bitcasted vector elements.
1120 for (const MachineOperand &MO : llvm::drop_begin(MI.operands()))
1121 if (!isKnownToBeAPowerOfTwo(MO.getReg(), MRI, KB))
1122 return false;
1123
1124 return true;
1125 }
1126 case TargetOpcode::G_BUILD_VECTOR_TRUNC: {
1127 // Only handle constants since we would need to know if number of leading
1128 // zeros is greater than the truncation amount.
1129 const unsigned BitWidth = Ty.getScalarSizeInBits();
1130 for (const MachineOperand &MO : llvm::drop_begin(MI.operands())) {
1131 auto Const = getIConstantVRegVal(MO.getReg(), MRI);
1132 if (!Const || !Const->zextOrTrunc(BitWidth).isPowerOf2())
1133 return false;
1134 }
1135
1136 return true;
1137 }
1138 default:
1139 break;
1140 }
1141
1142 if (!KB)
1143 return false;
1144
1145 // More could be done here, though the above checks are enough
1146 // to handle some common cases.
1147
1148 // Fall back to computeKnownBits to catch other known cases.
1149 KnownBits Known = KB->getKnownBits(Reg);
1150 return (Known.countMaxPopulation() == 1) && (Known.countMinPopulation() == 1);
1151}
1152
1155}
1156
1157LLT llvm::getLCMType(LLT OrigTy, LLT TargetTy) {
1158 if (OrigTy.getSizeInBits() == TargetTy.getSizeInBits())
1159 return OrigTy;
1160
1161 if (OrigTy.isVector() && TargetTy.isVector()) {
1162 LLT OrigElt = OrigTy.getElementType();
1163 LLT TargetElt = TargetTy.getElementType();
1164
1165 // TODO: The docstring for this function says the intention is to use this
1166 // function to build MERGE/UNMERGE instructions. It won't be the case that
1167 // we generate a MERGE/UNMERGE between fixed and scalable vector types. We
1168 // could implement getLCMType between the two in the future if there was a
1169 // need, but it is not worth it now as this function should not be used in
1170 // that way.
1171 assert(((OrigTy.isScalableVector() && !TargetTy.isFixedVector()) ||
1172 (OrigTy.isFixedVector() && !TargetTy.isScalableVector())) &&
1173 "getLCMType not implemented between fixed and scalable vectors.");
1174
1175 if (OrigElt.getSizeInBits() == TargetElt.getSizeInBits()) {
1176 int GCDMinElts = std::gcd(OrigTy.getElementCount().getKnownMinValue(),
1177 TargetTy.getElementCount().getKnownMinValue());
1178 // Prefer the original element type.
1180 TargetTy.getElementCount().getKnownMinValue());
1181 return LLT::vector(Mul.divideCoefficientBy(GCDMinElts),
1182 OrigTy.getElementType());
1183 }
1184 unsigned LCM = std::lcm(OrigTy.getSizeInBits().getKnownMinValue(),
1185 TargetTy.getSizeInBits().getKnownMinValue());
1186 return LLT::vector(
1187 ElementCount::get(LCM / OrigElt.getSizeInBits(), OrigTy.isScalable()),
1188 OrigElt);
1189 }
1190
1191 // One type is scalar, one type is vector
1192 if (OrigTy.isVector() || TargetTy.isVector()) {
1193 LLT VecTy = OrigTy.isVector() ? OrigTy : TargetTy;
1194 LLT ScalarTy = OrigTy.isVector() ? TargetTy : OrigTy;
1195 LLT EltTy = VecTy.getElementType();
1196 LLT OrigEltTy = OrigTy.isVector() ? OrigTy.getElementType() : OrigTy;
1197
1198 // Prefer scalar type from OrigTy.
1199 if (EltTy.getSizeInBits() == ScalarTy.getSizeInBits())
1200 return LLT::vector(VecTy.getElementCount(), OrigEltTy);
1201
1202 // Different size scalars. Create vector with the same total size.
1203 // LCM will take fixed/scalable from VecTy.
1204 unsigned LCM = std::lcm(EltTy.getSizeInBits().getFixedValue() *
1206 ScalarTy.getSizeInBits().getFixedValue());
1207 // Prefer type from OrigTy
1208 return LLT::vector(ElementCount::get(LCM / OrigEltTy.getSizeInBits(),
1209 VecTy.getElementCount().isScalable()),
1210 OrigEltTy);
1211 }
1212
1213 // At this point, both types are scalars of different size
1214 unsigned LCM = std::lcm(OrigTy.getSizeInBits().getFixedValue(),
1215 TargetTy.getSizeInBits().getFixedValue());
1216 // Preserve pointer types.
1217 if (LCM == OrigTy.getSizeInBits())
1218 return OrigTy;
1219 if (LCM == TargetTy.getSizeInBits())
1220 return TargetTy;
1221 return LLT::scalar(LCM);
1222}
1223
1224LLT llvm::getCoverTy(LLT OrigTy, LLT TargetTy) {
1225
1226 if ((OrigTy.isScalableVector() && TargetTy.isFixedVector()) ||
1227 (OrigTy.isFixedVector() && TargetTy.isScalableVector()))
1229 "getCoverTy not implemented between fixed and scalable vectors.");
1230
1231 if (!OrigTy.isVector() || !TargetTy.isVector() || OrigTy == TargetTy ||
1232 (OrigTy.getScalarSizeInBits() != TargetTy.getScalarSizeInBits()))
1233 return getLCMType(OrigTy, TargetTy);
1234
1235 unsigned OrigTyNumElts = OrigTy.getElementCount().getKnownMinValue();
1236 unsigned TargetTyNumElts = TargetTy.getElementCount().getKnownMinValue();
1237 if (OrigTyNumElts % TargetTyNumElts == 0)
1238 return OrigTy;
1239
1240 unsigned NumElts = alignTo(OrigTyNumElts, TargetTyNumElts);
1242 OrigTy.getElementType());
1243}
1244
1245LLT llvm::getGCDType(LLT OrigTy, LLT TargetTy) {
1246 if (OrigTy.getSizeInBits() == TargetTy.getSizeInBits())
1247 return OrigTy;
1248
1249 if (OrigTy.isVector() && TargetTy.isVector()) {
1250 LLT OrigElt = OrigTy.getElementType();
1251
1252 // TODO: The docstring for this function says the intention is to use this
1253 // function to build MERGE/UNMERGE instructions. It won't be the case that
1254 // we generate a MERGE/UNMERGE between fixed and scalable vector types. We
1255 // could implement getGCDType between the two in the future if there was a
1256 // need, but it is not worth it now as this function should not be used in
1257 // that way.
1258 assert(((OrigTy.isScalableVector() && !TargetTy.isFixedVector()) ||
1259 (OrigTy.isFixedVector() && !TargetTy.isScalableVector())) &&
1260 "getGCDType not implemented between fixed and scalable vectors.");
1261
1262 unsigned GCD = std::gcd(OrigTy.getSizeInBits().getKnownMinValue(),
1263 TargetTy.getSizeInBits().getKnownMinValue());
1264 if (GCD == OrigElt.getSizeInBits())
1266 OrigElt);
1267
1268 // Cannot produce original element type, but both have vscale in common.
1269 if (GCD < OrigElt.getSizeInBits())
1271 GCD);
1272
1273 return LLT::vector(
1275 OrigTy.isScalable()),
1276 OrigElt);
1277 }
1278
1279 // If one type is vector and the element size matches the scalar size, then
1280 // the gcd is the scalar type.
1281 if (OrigTy.isVector() &&
1282 OrigTy.getElementType().getSizeInBits() == TargetTy.getSizeInBits())
1283 return OrigTy.getElementType();
1284 if (TargetTy.isVector() &&
1285 TargetTy.getElementType().getSizeInBits() == OrigTy.getSizeInBits())
1286 return OrigTy;
1287
1288 // At this point, both types are either scalars of different type or one is a
1289 // vector and one is a scalar. If both types are scalars, the GCD type is the
1290 // GCD between the two scalar sizes. If one is vector and one is scalar, then
1291 // the GCD type is the GCD between the scalar and the vector element size.
1292 LLT OrigScalar = OrigTy.getScalarType();
1293 LLT TargetScalar = TargetTy.getScalarType();
1294 unsigned GCD = std::gcd(OrigScalar.getSizeInBits().getFixedValue(),
1295 TargetScalar.getSizeInBits().getFixedValue());
1296 return LLT::scalar(GCD);
1297}
1298
1300 assert(MI.getOpcode() == TargetOpcode::G_SHUFFLE_VECTOR &&
1301 "Only G_SHUFFLE_VECTOR can have a splat index!");
1302 ArrayRef<int> Mask = MI.getOperand(3).getShuffleMask();
1303 auto FirstDefinedIdx = find_if(Mask, [](int Elt) { return Elt >= 0; });
1304
1305 // If all elements are undefined, this shuffle can be considered a splat.
1306 // Return 0 for better potential for callers to simplify.
1307 if (FirstDefinedIdx == Mask.end())
1308 return 0;
1309
1310 // Make sure all remaining elements are either undef or the same
1311 // as the first non-undef value.
1312 int SplatValue = *FirstDefinedIdx;
1313 if (any_of(make_range(std::next(FirstDefinedIdx), Mask.end()),
1314 [&SplatValue](int Elt) { return Elt >= 0 && Elt != SplatValue; }))
1315 return std::nullopt;
1316
1317 return SplatValue;
1318}
1319
1320static bool isBuildVectorOp(unsigned Opcode) {
1321 return Opcode == TargetOpcode::G_BUILD_VECTOR ||
1322 Opcode == TargetOpcode::G_BUILD_VECTOR_TRUNC;
1323}
1324
1325namespace {
1326
1327std::optional<ValueAndVReg> getAnyConstantSplat(Register VReg,
1328 const MachineRegisterInfo &MRI,
1329 bool AllowUndef) {
1331 if (!MI)
1332 return std::nullopt;
1333
1334 bool isConcatVectorsOp = MI->getOpcode() == TargetOpcode::G_CONCAT_VECTORS;
1335 if (!isBuildVectorOp(MI->getOpcode()) && !isConcatVectorsOp)
1336 return std::nullopt;
1337
1338 std::optional<ValueAndVReg> SplatValAndReg;
1339 for (MachineOperand &Op : MI->uses()) {
1340 Register Element = Op.getReg();
1341 // If we have a G_CONCAT_VECTOR, we recursively look into the
1342 // vectors that we're concatenating to see if they're splats.
1343 auto ElementValAndReg =
1344 isConcatVectorsOp
1345 ? getAnyConstantSplat(Element, MRI, AllowUndef)
1347
1348 // If AllowUndef, treat undef as value that will result in a constant splat.
1349 if (!ElementValAndReg) {
1350 if (AllowUndef && isa<GImplicitDef>(MRI.getVRegDef(Element)))
1351 continue;
1352 return std::nullopt;
1353 }
1354
1355 // Record splat value
1356 if (!SplatValAndReg)
1357 SplatValAndReg = ElementValAndReg;
1358
1359 // Different constant than the one already recorded, not a constant splat.
1360 if (SplatValAndReg->Value != ElementValAndReg->Value)
1361 return std::nullopt;
1362 }
1363
1364 return SplatValAndReg;
1365}
1366
1367} // end anonymous namespace
1368
1370 const MachineRegisterInfo &MRI,
1371 int64_t SplatValue, bool AllowUndef) {
1372 if (auto SplatValAndReg = getAnyConstantSplat(Reg, MRI, AllowUndef))
1373 return mi_match(SplatValAndReg->VReg, MRI, m_SpecificICst(SplatValue));
1374 return false;
1375}
1376
1378 const MachineRegisterInfo &MRI,
1379 int64_t SplatValue, bool AllowUndef) {
1380 return isBuildVectorConstantSplat(MI.getOperand(0).getReg(), MRI, SplatValue,
1381 AllowUndef);
1382}
1383
1384std::optional<APInt>
1386 if (auto SplatValAndReg =
1387 getAnyConstantSplat(Reg, MRI, /* AllowUndef */ false)) {
1388 if (std::optional<ValueAndVReg> ValAndVReg =
1389 getIConstantVRegValWithLookThrough(SplatValAndReg->VReg, MRI))
1390 return ValAndVReg->Value;
1391 }
1392
1393 return std::nullopt;
1394}
1395
1396std::optional<APInt>
1398 const MachineRegisterInfo &MRI) {
1399 return getIConstantSplatVal(MI.getOperand(0).getReg(), MRI);
1400}
1401
1402std::optional<int64_t>
1404 const MachineRegisterInfo &MRI) {
1405 if (auto SplatValAndReg =
1406 getAnyConstantSplat(Reg, MRI, /* AllowUndef */ false))
1407 return getIConstantVRegSExtVal(SplatValAndReg->VReg, MRI);
1408 return std::nullopt;
1409}
1410
1411std::optional<int64_t>
1413 const MachineRegisterInfo &MRI) {
1414 return getIConstantSplatSExtVal(MI.getOperand(0).getReg(), MRI);
1415}
1416
1417std::optional<FPValueAndVReg>
1419 bool AllowUndef) {
1420 if (auto SplatValAndReg = getAnyConstantSplat(VReg, MRI, AllowUndef))
1421 return getFConstantVRegValWithLookThrough(SplatValAndReg->VReg, MRI);
1422 return std::nullopt;
1423}
1424
1426 const MachineRegisterInfo &MRI,
1427 bool AllowUndef) {
1428 return isBuildVectorConstantSplat(MI, MRI, 0, AllowUndef);
1429}
1430
1432 const MachineRegisterInfo &MRI,
1433 bool AllowUndef) {
1434 return isBuildVectorConstantSplat(MI, MRI, -1, AllowUndef);
1435}
1436
1437std::optional<RegOrConstant>
1439 unsigned Opc = MI.getOpcode();
1440 if (!isBuildVectorOp(Opc))
1441 return std::nullopt;
1442 if (auto Splat = getIConstantSplatSExtVal(MI, MRI))
1443 return RegOrConstant(*Splat);
1444 auto Reg = MI.getOperand(1).getReg();
1445 if (any_of(drop_begin(MI.operands(), 2),
1446 [&Reg](const MachineOperand &Op) { return Op.getReg() != Reg; }))
1447 return std::nullopt;
1448 return RegOrConstant(Reg);
1449}
1450
1452 const MachineRegisterInfo &MRI,
1453 bool AllowFP = true,
1454 bool AllowOpaqueConstants = true) {
1455 switch (MI.getOpcode()) {
1456 case TargetOpcode::G_CONSTANT:
1457 case TargetOpcode::G_IMPLICIT_DEF:
1458 return true;
1459 case TargetOpcode::G_FCONSTANT:
1460 return AllowFP;
1461 case TargetOpcode::G_GLOBAL_VALUE:
1462 case TargetOpcode::G_FRAME_INDEX:
1463 case TargetOpcode::G_BLOCK_ADDR:
1464 case TargetOpcode::G_JUMP_TABLE:
1465 return AllowOpaqueConstants;
1466 default:
1467 return false;
1468 }
1469}
1470
1472 const MachineRegisterInfo &MRI) {
1473 Register Def = MI.getOperand(0).getReg();
1474 if (auto C = getIConstantVRegValWithLookThrough(Def, MRI))
1475 return true;
1476 GBuildVector *BV = dyn_cast<GBuildVector>(&MI);
1477 if (!BV)
1478 return false;
1479 for (unsigned SrcIdx = 0; SrcIdx < BV->getNumSources(); ++SrcIdx) {
1481 getOpcodeDef<GImplicitDef>(BV->getSourceReg(SrcIdx), MRI))
1482 continue;
1483 return false;
1484 }
1485 return true;
1486}
1487
1489 const MachineRegisterInfo &MRI,
1490 bool AllowFP, bool AllowOpaqueConstants) {
1491 if (isConstantScalar(MI, MRI, AllowFP, AllowOpaqueConstants))
1492 return true;
1493
1494 if (!isBuildVectorOp(MI.getOpcode()))
1495 return false;
1496
1497 const unsigned NumOps = MI.getNumOperands();
1498 for (unsigned I = 1; I != NumOps; ++I) {
1499 const MachineInstr *ElementDef = MRI.getVRegDef(MI.getOperand(I).getReg());
1500 if (!isConstantScalar(*ElementDef, MRI, AllowFP, AllowOpaqueConstants))
1501 return false;
1502 }
1503
1504 return true;
1505}
1506
1507std::optional<APInt>
1509 const MachineRegisterInfo &MRI) {
1510 Register Def = MI.getOperand(0).getReg();
1511 if (auto C = getIConstantVRegValWithLookThrough(Def, MRI))
1512 return C->Value;
1513 auto MaybeCst = getIConstantSplatSExtVal(MI, MRI);
1514 if (!MaybeCst)
1515 return std::nullopt;
1516 const unsigned ScalarSize = MRI.getType(Def).getScalarSizeInBits();
1517 return APInt(ScalarSize, *MaybeCst, true);
1518}
1519
1521 const MachineRegisterInfo &MRI, bool AllowUndefs) {
1522 switch (MI.getOpcode()) {
1523 case TargetOpcode::G_IMPLICIT_DEF:
1524 return AllowUndefs;
1525 case TargetOpcode::G_CONSTANT:
1526 return MI.getOperand(1).getCImm()->isNullValue();
1527 case TargetOpcode::G_FCONSTANT: {
1528 const ConstantFP *FPImm = MI.getOperand(1).getFPImm();
1529 return FPImm->isZero() && !FPImm->isNegative();
1530 }
1531 default:
1532 if (!AllowUndefs) // TODO: isBuildVectorAllZeros assumes undef is OK already
1533 return false;
1534 return isBuildVectorAllZeros(MI, MRI);
1535 }
1536}
1537
1539 const MachineRegisterInfo &MRI,
1540 bool AllowUndefs) {
1541 switch (MI.getOpcode()) {
1542 case TargetOpcode::G_IMPLICIT_DEF:
1543 return AllowUndefs;
1544 case TargetOpcode::G_CONSTANT:
1545 return MI.getOperand(1).getCImm()->isAllOnesValue();
1546 default:
1547 if (!AllowUndefs) // TODO: isBuildVectorAllOnes assumes undef is OK already
1548 return false;
1549 return isBuildVectorAllOnes(MI, MRI);
1550 }
1551}
1552
1554 const MachineRegisterInfo &MRI, Register Reg,
1555 std::function<bool(const Constant *ConstVal)> Match, bool AllowUndefs) {
1556
1557 const MachineInstr *Def = getDefIgnoringCopies(Reg, MRI);
1558 if (AllowUndefs && Def->getOpcode() == TargetOpcode::G_IMPLICIT_DEF)
1559 return Match(nullptr);
1560
1561 // TODO: Also handle fconstant
1562 if (Def->getOpcode() == TargetOpcode::G_CONSTANT)
1563 return Match(Def->getOperand(1).getCImm());
1564
1565 if (Def->getOpcode() != TargetOpcode::G_BUILD_VECTOR)
1566 return false;
1567
1568 for (unsigned I = 1, E = Def->getNumOperands(); I != E; ++I) {
1569 Register SrcElt = Def->getOperand(I).getReg();
1570 const MachineInstr *SrcDef = getDefIgnoringCopies(SrcElt, MRI);
1571 if (AllowUndefs && SrcDef->getOpcode() == TargetOpcode::G_IMPLICIT_DEF) {
1572 if (!Match(nullptr))
1573 return false;
1574 continue;
1575 }
1576
1577 if (SrcDef->getOpcode() != TargetOpcode::G_CONSTANT ||
1578 !Match(SrcDef->getOperand(1).getCImm()))
1579 return false;
1580 }
1581
1582 return true;
1583}
1584
1585bool llvm::isConstTrueVal(const TargetLowering &TLI, int64_t Val, bool IsVector,
1586 bool IsFP) {
1587 switch (TLI.getBooleanContents(IsVector, IsFP)) {
1588 case TargetLowering::UndefinedBooleanContent:
1589 return Val & 0x1;
1590 case TargetLowering::ZeroOrOneBooleanContent:
1591 return Val == 1;
1592 case TargetLowering::ZeroOrNegativeOneBooleanContent:
1593 return Val == -1;
1594 }
1595 llvm_unreachable("Invalid boolean contents");
1596}
1597
1598bool llvm::isConstFalseVal(const TargetLowering &TLI, int64_t Val,
1599 bool IsVector, bool IsFP) {
1600 switch (TLI.getBooleanContents(IsVector, IsFP)) {
1601 case TargetLowering::UndefinedBooleanContent:
1602 return ~Val & 0x1;
1603 case TargetLowering::ZeroOrOneBooleanContent:
1604 case TargetLowering::ZeroOrNegativeOneBooleanContent:
1605 return Val == 0;
1606 }
1607 llvm_unreachable("Invalid boolean contents");
1608}
1609
1610int64_t llvm::getICmpTrueVal(const TargetLowering &TLI, bool IsVector,
1611 bool IsFP) {
1612 switch (TLI.getBooleanContents(IsVector, IsFP)) {
1613 case TargetLowering::UndefinedBooleanContent:
1614 case TargetLowering::ZeroOrOneBooleanContent:
1615 return 1;
1616 case TargetLowering::ZeroOrNegativeOneBooleanContent:
1617 return -1;
1618 }
1619 llvm_unreachable("Invalid boolean contents");
1620}
1621
1623 LostDebugLocObserver *LocObserver,
1624 SmallInstListTy &DeadInstChain) {
1625 for (MachineOperand &Op : MI.uses()) {
1626 if (Op.isReg() && Op.getReg().isVirtual())
1627 DeadInstChain.insert(MRI.getVRegDef(Op.getReg()));
1628 }
1629 LLVM_DEBUG(dbgs() << MI << "Is dead; erasing.\n");
1630 DeadInstChain.remove(&MI);
1631 MI.eraseFromParent();
1632 if (LocObserver)
1633 LocObserver->checkpoint(false);
1634}
1635
1638 LostDebugLocObserver *LocObserver) {
1639 SmallInstListTy DeadInstChain;
1640 for (MachineInstr *MI : DeadInstrs)
1641 saveUsesAndErase(*MI, MRI, LocObserver, DeadInstChain);
1642
1643 while (!DeadInstChain.empty()) {
1644 MachineInstr *Inst = DeadInstChain.pop_back_val();
1645 if (!isTriviallyDead(*Inst, MRI))
1646 continue;
1647 saveUsesAndErase(*Inst, MRI, LocObserver, DeadInstChain);
1648 }
1649}
1650
1652 LostDebugLocObserver *LocObserver) {
1653 return eraseInstrs({&MI}, MRI, LocObserver);
1654}
1655
1657 for (auto &Def : MI.defs()) {
1658 assert(Def.isReg() && "Must be a reg");
1659
1661 for (auto &MOUse : MRI.use_operands(Def.getReg())) {
1662 MachineInstr *DbgValue = MOUse.getParent();
1663 // Ignore partially formed DBG_VALUEs.
1664 if (DbgValue->isNonListDebugValue() && DbgValue->getNumOperands() == 4) {
1665 DbgUsers.push_back(&MOUse);
1666 }
1667 }
1668
1669 if (!DbgUsers.empty()) {
1671 }
1672 }
1673}
1674
1676 switch (Opc) {
1677 case TargetOpcode::G_FABS:
1678 case TargetOpcode::G_FADD:
1679 case TargetOpcode::G_FCANONICALIZE:
1680 case TargetOpcode::G_FCEIL:
1681 case TargetOpcode::G_FCONSTANT:
1682 case TargetOpcode::G_FCOPYSIGN:
1683 case TargetOpcode::G_FCOS:
1684 case TargetOpcode::G_FDIV:
1685 case TargetOpcode::G_FEXP2:
1686 case TargetOpcode::G_FEXP:
1687 case TargetOpcode::G_FFLOOR:
1688 case TargetOpcode::G_FLOG10:
1689 case TargetOpcode::G_FLOG2:
1690 case TargetOpcode::G_FLOG:
1691 case TargetOpcode::G_FMA:
1692 case TargetOpcode::G_FMAD:
1693 case TargetOpcode::G_FMAXIMUM:
1694 case TargetOpcode::G_FMAXNUM:
1695 case TargetOpcode::G_FMAXNUM_IEEE:
1696 case TargetOpcode::G_FMINIMUM:
1697 case TargetOpcode::G_FMINNUM:
1698 case TargetOpcode::G_FMINNUM_IEEE:
1699 case TargetOpcode::G_FMUL:
1700 case TargetOpcode::G_FNEARBYINT:
1701 case TargetOpcode::G_FNEG:
1702 case TargetOpcode::G_FPEXT:
1703 case TargetOpcode::G_FPOW:
1704 case TargetOpcode::G_FPTRUNC:
1705 case TargetOpcode::G_FREM:
1706 case TargetOpcode::G_FRINT:
1707 case TargetOpcode::G_FSIN:
1708 case TargetOpcode::G_FTAN:
1709 case TargetOpcode::G_FACOS:
1710 case TargetOpcode::G_FASIN:
1711 case TargetOpcode::G_FATAN:
1712 case TargetOpcode::G_FATAN2:
1713 case TargetOpcode::G_FCOSH:
1714 case TargetOpcode::G_FSINH:
1715 case TargetOpcode::G_FTANH:
1716 case TargetOpcode::G_FSQRT:
1717 case TargetOpcode::G_FSUB:
1718 case TargetOpcode::G_INTRINSIC_ROUND:
1719 case TargetOpcode::G_INTRINSIC_ROUNDEVEN:
1720 case TargetOpcode::G_INTRINSIC_TRUNC:
1721 return true;
1722 default:
1723 return false;
1724 }
1725}
1726
1727/// Shifts return poison if shiftwidth is larger than the bitwidth.
1728static bool shiftAmountKnownInRange(Register ShiftAmount,
1729 const MachineRegisterInfo &MRI) {
1730 LLT Ty = MRI.getType(ShiftAmount);
1731
1732 if (Ty.isScalableVector())
1733 return false; // Can't tell, just return false to be safe
1734
1735 if (Ty.isScalar()) {
1736 std::optional<ValueAndVReg> Val =
1738 if (!Val)
1739 return false;
1740 return Val->Value.ult(Ty.getScalarSizeInBits());
1741 }
1742
1743 GBuildVector *BV = getOpcodeDef<GBuildVector>(ShiftAmount, MRI);
1744 if (!BV)
1745 return false;
1746
1747 unsigned Sources = BV->getNumSources();
1748 for (unsigned I = 0; I < Sources; ++I) {
1749 std::optional<ValueAndVReg> Val =
1751 if (!Val)
1752 return false;
1753 if (!Val->Value.ult(Ty.getScalarSizeInBits()))
1754 return false;
1755 }
1756
1757 return true;
1758}
1759
1760namespace {
1761enum class UndefPoisonKind {
1762 PoisonOnly = (1 << 0),
1763 UndefOnly = (1 << 1),
1765};
1766}
1767
1769 return (unsigned(Kind) & unsigned(UndefPoisonKind::PoisonOnly)) != 0;
1770}
1771
1773 return (unsigned(Kind) & unsigned(UndefPoisonKind::UndefOnly)) != 0;
1774}
1775
1777 bool ConsiderFlagsAndMetadata,
1778 UndefPoisonKind Kind) {
1779 MachineInstr *RegDef = MRI.getVRegDef(Reg);
1780
1781 if (ConsiderFlagsAndMetadata && includesPoison(Kind))
1782 if (auto *GMI = dyn_cast<GenericMachineInstr>(RegDef))
1783 if (GMI->hasPoisonGeneratingFlags())
1784 return true;
1785
1786 // Check whether opcode is a poison/undef-generating operation.
1787 switch (RegDef->getOpcode()) {
1788 case TargetOpcode::G_BUILD_VECTOR:
1789 case TargetOpcode::G_CONSTANT_FOLD_BARRIER:
1790 return false;
1791 case TargetOpcode::G_SHL:
1792 case TargetOpcode::G_ASHR:
1793 case TargetOpcode::G_LSHR:
1794 return includesPoison(Kind) &&
1796 case TargetOpcode::G_FPTOSI:
1797 case TargetOpcode::G_FPTOUI:
1798 // fptosi/ui yields poison if the resulting value does not fit in the
1799 // destination type.
1800 return true;
1801 case TargetOpcode::G_CTLZ:
1802 case TargetOpcode::G_CTTZ:
1803 case TargetOpcode::G_ABS:
1804 case TargetOpcode::G_CTPOP:
1805 case TargetOpcode::G_BSWAP:
1806 case TargetOpcode::G_BITREVERSE:
1807 case TargetOpcode::G_FSHL:
1808 case TargetOpcode::G_FSHR:
1809 case TargetOpcode::G_SMAX:
1810 case TargetOpcode::G_SMIN:
1811 case TargetOpcode::G_UMAX:
1812 case TargetOpcode::G_UMIN:
1813 case TargetOpcode::G_PTRMASK:
1814 case TargetOpcode::G_SADDO:
1815 case TargetOpcode::G_SSUBO:
1816 case TargetOpcode::G_UADDO:
1817 case TargetOpcode::G_USUBO:
1818 case TargetOpcode::G_SMULO:
1819 case TargetOpcode::G_UMULO:
1820 case TargetOpcode::G_SADDSAT:
1821 case TargetOpcode::G_UADDSAT:
1822 case TargetOpcode::G_SSUBSAT:
1823 case TargetOpcode::G_USUBSAT:
1824 return false;
1825 case TargetOpcode::G_SSHLSAT:
1826 case TargetOpcode::G_USHLSAT:
1827 return includesPoison(Kind) &&
1829 case TargetOpcode::G_INSERT_VECTOR_ELT: {
1830 GInsertVectorElement *Insert = cast<GInsertVectorElement>(RegDef);
1831 if (includesPoison(Kind)) {
1832 std::optional<ValueAndVReg> Index =
1833 getIConstantVRegValWithLookThrough(Insert->getIndexReg(), MRI);
1834 if (!Index)
1835 return true;
1836 LLT VecTy = MRI.getType(Insert->getVectorReg());
1837 return Index->Value.uge(VecTy.getElementCount().getKnownMinValue());
1838 }
1839 return false;
1840 }
1841 case TargetOpcode::G_EXTRACT_VECTOR_ELT: {
1842 GExtractVectorElement *Extract = cast<GExtractVectorElement>(RegDef);
1843 if (includesPoison(Kind)) {
1844 std::optional<ValueAndVReg> Index =
1846 if (!Index)
1847 return true;
1848 LLT VecTy = MRI.getType(Extract->getVectorReg());
1849 return Index->Value.uge(VecTy.getElementCount().getKnownMinValue());
1850 }
1851 return false;
1852 }
1853 case TargetOpcode::G_SHUFFLE_VECTOR: {
1854 GShuffleVector *Shuffle = cast<GShuffleVector>(RegDef);
1855 ArrayRef<int> Mask = Shuffle->getMask();
1856 return includesPoison(Kind) && is_contained(Mask, -1);
1857 }
1858 case TargetOpcode::G_FNEG:
1859 case TargetOpcode::G_PHI:
1860 case TargetOpcode::G_SELECT:
1861 case TargetOpcode::G_UREM:
1862 case TargetOpcode::G_SREM:
1863 case TargetOpcode::G_FREEZE:
1864 case TargetOpcode::G_ICMP:
1865 case TargetOpcode::G_FCMP:
1866 case TargetOpcode::G_FADD:
1867 case TargetOpcode::G_FSUB:
1868 case TargetOpcode::G_FMUL:
1869 case TargetOpcode::G_FDIV:
1870 case TargetOpcode::G_FREM:
1871 case TargetOpcode::G_PTR_ADD:
1872 return false;
1873 default:
1874 return !isa<GCastOp>(RegDef) && !isa<GBinOp>(RegDef);
1875 }
1876}
1877
1879 const MachineRegisterInfo &MRI,
1880 unsigned Depth,
1881 UndefPoisonKind Kind) {
1883 return false;
1884
1885 MachineInstr *RegDef = MRI.getVRegDef(Reg);
1886
1887 switch (RegDef->getOpcode()) {
1888 case TargetOpcode::G_FREEZE:
1889 return true;
1890 case TargetOpcode::G_IMPLICIT_DEF:
1891 return !includesUndef(Kind);
1892 case TargetOpcode::G_CONSTANT:
1893 case TargetOpcode::G_FCONSTANT:
1894 return true;
1895 case TargetOpcode::G_BUILD_VECTOR: {
1896 GBuildVector *BV = cast<GBuildVector>(RegDef);
1897 unsigned NumSources = BV->getNumSources();
1898 for (unsigned I = 0; I < NumSources; ++I)
1900 Depth + 1, Kind))
1901 return false;
1902 return true;
1903 }
1904 case TargetOpcode::G_PHI: {
1905 GPhi *Phi = cast<GPhi>(RegDef);
1906 unsigned NumIncoming = Phi->getNumIncomingValues();
1907 for (unsigned I = 0; I < NumIncoming; ++I)
1908 if (!::isGuaranteedNotToBeUndefOrPoison(Phi->getIncomingValue(I), MRI,
1909 Depth + 1, Kind))
1910 return false;
1911 return true;
1912 }
1913 default: {
1914 auto MOCheck = [&](const MachineOperand &MO) {
1915 if (!MO.isReg())
1916 return true;
1917 return ::isGuaranteedNotToBeUndefOrPoison(MO.getReg(), MRI, Depth + 1,
1918 Kind);
1919 };
1920 return !::canCreateUndefOrPoison(Reg, MRI,
1921 /*ConsiderFlagsAndMetadata=*/true, Kind) &&
1922 all_of(RegDef->uses(), MOCheck);
1923 }
1924 }
1925}
1926
1928 bool ConsiderFlagsAndMetadata) {
1929 return ::canCreateUndefOrPoison(Reg, MRI, ConsiderFlagsAndMetadata,
1931}
1932
1934 bool ConsiderFlagsAndMetadata = true) {
1935 return ::canCreateUndefOrPoison(Reg, MRI, ConsiderFlagsAndMetadata,
1937}
1938
1940 const MachineRegisterInfo &MRI,
1941 unsigned Depth) {
1942 return ::isGuaranteedNotToBeUndefOrPoison(Reg, MRI, Depth,
1944}
1945
1947 const MachineRegisterInfo &MRI,
1948 unsigned Depth) {
1949 return ::isGuaranteedNotToBeUndefOrPoison(Reg, MRI, Depth,
1951}
1952
1954 const MachineRegisterInfo &MRI,
1955 unsigned Depth) {
1956 return ::isGuaranteedNotToBeUndefOrPoison(Reg, MRI, Depth,
1958}
1959
1961 if (Ty.isVector())
1962 return VectorType::get(IntegerType::get(C, Ty.getScalarSizeInBits()),
1963 Ty.getElementCount());
1964 return IntegerType::get(C, Ty.getSizeInBits());
1965}
1966
1968 assert(Kind == GIConstantKind::Scalar && "Expected scalar constant");
1969
1970 return Value;
1971}
1972
1973std::optional<GIConstant>
1976
1977 if (GSplatVector *Splat = dyn_cast<GSplatVector>(Constant)) {
1978 std::optional<ValueAndVReg> MayBeConstant =
1980 if (!MayBeConstant)
1981 return std::nullopt;
1982 return GIConstant(MayBeConstant->Value, GIConstantKind::ScalableVector);
1983 }
1984
1985 if (GBuildVector *Build = dyn_cast<GBuildVector>(Constant)) {
1986 SmallVector<APInt> Values;
1987 unsigned NumSources = Build->getNumSources();
1988 for (unsigned I = 0; I < NumSources; ++I) {
1989 Register SrcReg = Build->getSourceReg(I);
1990 std::optional<ValueAndVReg> MayBeConstant =
1992 if (!MayBeConstant)
1993 return std::nullopt;
1994 Values.push_back(MayBeConstant->Value);
1995 }
1996 return GIConstant(Values);
1997 }
1998
1999 std::optional<ValueAndVReg> MayBeConstant =
2001 if (!MayBeConstant)
2002 return std::nullopt;
2003
2004 return GIConstant(MayBeConstant->Value, GIConstantKind::Scalar);
2005}
2006
2008 assert(Kind == GFConstantKind::Scalar && "Expected scalar constant");
2009
2010 return Values[0];
2011}
2012
2013std::optional<GFConstant>
2016
2017 if (GSplatVector *Splat = dyn_cast<GSplatVector>(Constant)) {
2018 std::optional<FPValueAndVReg> MayBeConstant =
2020 if (!MayBeConstant)
2021 return std::nullopt;
2022 return GFConstant(MayBeConstant->Value, GFConstantKind::ScalableVector);
2023 }
2024
2025 if (GBuildVector *Build = dyn_cast<GBuildVector>(Constant)) {
2026 SmallVector<APFloat> Values;
2027 unsigned NumSources = Build->getNumSources();
2028 for (unsigned I = 0; I < NumSources; ++I) {
2029 Register SrcReg = Build->getSourceReg(I);
2030 std::optional<FPValueAndVReg> MayBeConstant =
2032 if (!MayBeConstant)
2033 return std::nullopt;
2034 Values.push_back(MayBeConstant->Value);
2035 }
2036 return GFConstant(Values);
2037 }
2038
2039 std::optional<FPValueAndVReg> MayBeConstant =
2041 if (!MayBeConstant)
2042 return std::nullopt;
2043
2044 return GFConstant(MayBeConstant->Value, GFConstantKind::Scalar);
2045}
unsigned const MachineRegisterInfo * MRI
MachineInstrBuilder MachineInstrBuilder & DefMI
unsigned RegSize
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
basic Basic Alias true
static bool canCreateUndefOrPoison(Register Reg, const MachineRegisterInfo &MRI, bool ConsiderFlagsAndMetadata, UndefPoisonKind Kind)
Definition: Utils.cpp:1776
static bool isGuaranteedNotToBeUndefOrPoison(Register Reg, const MachineRegisterInfo &MRI, unsigned Depth, UndefPoisonKind Kind)
Definition: Utils.cpp:1878
static bool includesPoison(UndefPoisonKind Kind)
Definition: Utils.cpp:1768
static bool includesUndef(UndefPoisonKind Kind)
Definition: Utils.cpp:1772
static void reportGISelDiagnostic(DiagnosticSeverity Severity, MachineFunction &MF, const TargetPassConfig &TPC, MachineOptimizationRemarkEmitter &MORE, MachineOptimizationRemarkMissed &R)
Definition: Utils.cpp:235
static bool shiftAmountKnownInRange(Register ShiftAmount, const MachineRegisterInfo &MRI)
Shifts return poison if shiftwidth is larger than the bitwidth.
Definition: Utils.cpp:1728
bool canCreatePoison(Register Reg, const MachineRegisterInfo &MRI, bool ConsiderFlagsAndMetadata=true)
Definition: Utils.cpp:1933
static bool isBuildVectorOp(unsigned Opcode)
Definition: Utils.cpp:1320
static bool isConstantScalar(const MachineInstr &MI, const MachineRegisterInfo &MRI, bool AllowFP=true, bool AllowOpaqueConstants=true)
Definition: Utils.cpp:1451
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
#define LLVM_DEBUG(...)
Definition: Debug.h:106
uint64_t Size
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
Tracks DebugLocs between checkpoints and verifies that they are transferred.
#define I(x, y, z)
Definition: MD5.cpp:58
Contains matchers for matching SSA Machine Instructions.
This file declares the MachineIRBuilder class.
===- MachineOptimizationRemarkEmitter.h - Opt Diagnostics -*- C++ -*-—===//
unsigned const TargetRegisterInfo * TRI
uint64_t IntrinsicInst * II
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file describes how to lower LLVM code to machine code.
Target-Independent Code Generator Pass Configuration Options pass.
UndefPoisonKind
static const char PassName[]
Value * RHS
Value * LHS
BinaryOperator * Mul
Class recording the (high level) value of a variable.
opStatus divide(const APFloat &RHS, roundingMode RM)
Definition: APFloat.h:1205
void copySign(const APFloat &RHS)
Definition: APFloat.h:1299
opStatus convert(const fltSemantics &ToSemantics, roundingMode RM, bool *losesInfo)
Definition: APFloat.cpp:5465
opStatus subtract(const APFloat &RHS, roundingMode RM)
Definition: APFloat.h:1187
opStatus add(const APFloat &RHS, roundingMode RM)
Definition: APFloat.h:1178
opStatus convertFromAPInt(const APInt &Input, bool IsSigned, roundingMode RM)
Definition: APFloat.h:1329
opStatus multiply(const APFloat &RHS, roundingMode RM)
Definition: APFloat.h:1196
APInt bitcastToAPInt() const
Definition: APFloat.h:1346
opStatus mod(const APFloat &RHS)
Definition: APFloat.h:1223
Class for arbitrary precision integers.
Definition: APInt.h:78
APInt udiv(const APInt &RHS) const
Unsigned division operation.
Definition: APInt.cpp:1547
APInt zext(unsigned width) const
Zero extend to a new width.
Definition: APInt.cpp:986
APInt zextOrTrunc(unsigned width) const
Zero extend or truncate to width.
Definition: APInt.cpp:1007
APInt trunc(unsigned width) const
Truncate to new width.
Definition: APInt.cpp:910
APInt urem(const APInt &RHS) const
Unsigned remainder operation.
Definition: APInt.cpp:1640
unsigned getBitWidth() const
Return the number of bits in the APInt.
Definition: APInt.h:1468
APInt sdiv(const APInt &RHS) const
Signed division function for APInt.
Definition: APInt.cpp:1618
APInt sextOrTrunc(unsigned width) const
Sign extend or truncate to width.
Definition: APInt.cpp:1015
APInt ashr(unsigned ShiftAmt) const
Arithmetic right-shift function.
Definition: APInt.h:827
APInt srem(const APInt &RHS) const
Function for signed remainder operation.
Definition: APInt.cpp:1710
APInt sext(unsigned width) const
Sign extend to a new width.
Definition: APInt.cpp:959
bool isPowerOf2() const
Check if this APInt's value is a power of two greater than zero.
Definition: APInt.h:440
APInt lshr(unsigned shiftAmt) const
Logical right-shift function.
Definition: APInt.h:851
Represent the analysis usage information of a pass.
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
ConstantFP - Floating Point Values [float, double].
Definition: Constants.h:271
const APFloat & getValueAPF() const
Definition: Constants.h:314
bool isNegative() const
Return true if the sign bit is set.
Definition: Constants.h:321
bool isZero() const
Return true if the value is positive or negative zero.
Definition: Constants.h:318
This is the shared class of boolean and integer constants.
Definition: Constants.h:83
const APInt & getValue() const
Return the constant as an APInt value reference.
Definition: Constants.h:148
This is an important base class in LLVM.
Definition: Constant.h:42
This class represents an Operation in the Expression.
A debug info location.
Definition: DebugLoc.h:33
static constexpr ElementCount getFixed(ScalarTy MinVal)
Definition: TypeSize.h:311
static constexpr ElementCount get(ScalarTy MinVal, bool Scalable)
Definition: TypeSize.h:317
Represents a G_BUILD_VECTOR.
Represents an extract vector element.
An floating-point-like constant.
Definition: Utils.h:645
static std::optional< GFConstant > getConstant(Register Const, const MachineRegisterInfo &MRI)
Definition: Utils.cpp:2014
APFloat getScalarValue() const
Returns the value, if this constant is a scalar.
Definition: Utils.cpp:2007
An integer-like constant.
Definition: Utils.h:606
APInt getScalarValue() const
Returns the value, if this constant is a scalar.
Definition: Utils.cpp:1967
static std::optional< GIConstant > getConstant(Register Const, const MachineRegisterInfo &MRI)
Definition: Utils.cpp:1974
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.
Definition: GISelWorkList.h:74
MachineInstr * pop_back_val()
bool empty() const
Definition: GISelWorkList.h:38
void remove(const MachineInstr *I)
Remove I from the worklist if it exists.
Definition: GISelWorkList.h:83
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...
Definition: GlobalValue.h:656
static IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
Definition: Type.cpp:311
constexpr bool isScalableVector() const
Returns true if the LLT is a scalable vector.
Definition: LowLevelType.h:181
constexpr unsigned getScalarSizeInBits() const
Definition: LowLevelType.h:264
constexpr bool isScalar() const
Definition: LowLevelType.h:146
static constexpr LLT vector(ElementCount EC, unsigned ScalarSizeInBits)
Get a low-level vector of some number of elements and element width.
Definition: LowLevelType.h:64
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
Definition: LowLevelType.h:42
constexpr bool isValid() const
Definition: LowLevelType.h:145
constexpr uint16_t getNumElements() const
Returns the number of elements in a vector LLT.
Definition: LowLevelType.h:159
constexpr bool isVector() const
Definition: LowLevelType.h:148
constexpr bool isScalable() const
Returns true if the LLT is a scalable vector.
Definition: LowLevelType.h:170
constexpr TypeSize getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
Definition: LowLevelType.h:190
constexpr LLT getElementType() const
Returns the vector's element type. Only valid for vector types.
Definition: LowLevelType.h:277
constexpr ElementCount getElementCount() const
Definition: LowLevelType.h:183
static constexpr LLT fixed_vector(unsigned NumElements, unsigned ScalarSizeInBits)
Get a low-level fixed-width vector of some number of elements and element width.
Definition: LowLevelType.h:100
constexpr bool isFixedVector() const
Returns true if the LLT is a fixed vector.
Definition: LowLevelType.h:177
constexpr LLT getScalarType() const
Definition: LowLevelType.h:205
static constexpr LLT scalarOrVector(ElementCount EC, LLT ScalarTy)
Definition: LowLevelType.h:124
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:67
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.
Definition: MCInstrDesc.h:198
Wrapper class representing physical registers. Should be passed by value.
Definition: MCRegister.h:33
void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
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.
MachineFunctionProperties & set(Property P)
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, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
Representation of each machine instruction.
Definition: MachineInstr.h:69
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:575
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:347
bool getFlag(MIFlag Flag) const
Return whether an MI flag is set.
Definition: MachineInstr.h:397
iterator_range< mop_iterator > uses()
Returns a range that includes all operands which may be register uses.
Definition: MachineInstr.h:739
const MachineFunction * getMF() const
Return the function that contains the basic block that this instruction belongs to.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
Definition: MachineInstr.h:499
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:585
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.
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:65
Represents a value which can be a Register or a constant.
Definition: Utils.h:395
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:19
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
Definition: Register.h:95
bool empty() const
Definition: SmallVector.h:81
size_t size() const
Definition: SmallVector.h:78
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:573
reference emplace_back(ArgTypes &&... Args)
Definition: SmallVector.h:937
void push_back(const T &Elt)
Definition: SmallVector.h:413
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1196
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:51
TargetInstrInfo - Interface to description of machine instruction set.
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...
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:77
Target-Independent Code Generator Pass Configuration Options.
bool isGlobalISelAbortEnabled() const
Check whether or not GlobalISel should abort on error.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
LLVM Value Representation.
Definition: Value.h:74
constexpr ScalarTy getFixedValue() const
Definition: TypeSize.h:202
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
Definition: TypeSize.h:171
constexpr LeafTy multiplyCoefficientBy(ScalarTy RHS) const
Definition: TypeSize.h:258
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
Definition: TypeSize.h:168
#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:2217
const APInt & smax(const APInt &A, const APInt &B)
Determine the larger of two APInts considered to be signed.
Definition: APInt.h:2222
const APInt & umin(const APInt &A, const APInt &B)
Determine the smaller of two APInts considered to be unsigned.
Definition: APInt.h:2227
const APInt & umax(const APInt &A, const APInt &B)
Determine the larger of two APInts considered to be unsigned.
Definition: APInt.h:2232
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
SpecificConstantMatch m_SpecificICst(int64_t RequestedValue)
Matches a constant equal to RequestedValue.
bool mi_match(Reg R, const MachineRegisterInfo &MRI, Pattern &&P)
DiagnosticInfoMIROptimization::MachineArgument MNV
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
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:895
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition: STLExtras.h:329
@ Offset
Definition: DWP.cpp:480
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:1425
Type * getTypeForLLT(LLT Ty, LLVMContext &C)
Get the type back from LLT.
Definition: Utils.cpp:1960
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:1739
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:56
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:630
const ConstantFP * getConstantFPVRegVal(Register VReg, const MachineRegisterInfo &MRI)
Definition: Utils.cpp:444
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
std::optional< APInt > getIConstantVRegVal(Register VReg, const MachineRegisterInfo &MRI)
If VReg is defined by a G_CONSTANT, return the corresponding value.
Definition: Utils.cpp:279
std::optional< APFloat > ConstantFoldIntToFloat(unsigned Opcode, LLT DstTy, Register Src, const MachineRegisterInfo &MRI)
Definition: Utils.cpp:969
std::optional< APInt > getIConstantSplatVal(const Register Reg, const MachineRegisterInfo &MRI)
Definition: Utils.cpp:1385
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:1538
const llvm::fltSemantics & getFltSemanticForLLT(LLT Ty)
Get the appropriate floating point arithmetic semantic based on the bit size of the given scalar LLT.
std::optional< APFloat > ConstantFoldFPBinOp(unsigned Opcode, const Register Op1, const Register Op2, const MachineRegisterInfo &MRI)
Definition: Utils.cpp:718
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:1656
bool 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:155
bool isPreISelGenericOpcode(unsigned Opcode)
Check whether the given Opcode is a generic opcode that is not supposed to appear after ISel.
Definition: TargetOpcodes.h:30
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
std::optional< SmallVector< unsigned > > ConstantFoldCountZeros(Register Src, const MachineRegisterInfo &MRI, std::function< unsigned(APInt)> CB)
Tries to constant fold a counting-zero operation (G_CTLZ or G_CTTZ) on Src.
Definition: Utils.cpp:982
std::optional< APInt > ConstantFoldExtOp(unsigned Opcode, const Register Op1, uint64_t Imm, const MachineRegisterInfo &MRI)
Definition: Utils.cpp:928
std::optional< RegOrConstant > getVectorSplat(const MachineInstr &MI, const MachineRegisterInfo &MRI)
Definition: Utils.cpp:1438
LLVM_READONLY APFloat maximum(const APFloat &A, const APFloat &B)
Implements IEEE 754-2019 maximum semantics.
Definition: APFloat.h:1599
bool isKnownToBeAPowerOfTwo(const Value *V, const DataLayout &DL, bool OrZero=false, unsigned Depth=0, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true)
Return true if the given value is known to have exactly one bit set when defined.
std::optional< APInt > isConstantOrConstantSplatVector(MachineInstr &MI, const MachineRegisterInfo &MRI)
Determines if MI defines a constant integer or a splat vector of constant integers.
Definition: Utils.cpp:1508
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:1520
MachineInstr * getDefIgnoringCopies(Register Reg, const MachineRegisterInfo &MRI)
Find the def instruction for Reg, folding away any trivial copies.
Definition: Utils.cpp:471
bool matchUnaryPredicate(const MachineRegisterInfo &MRI, Register Reg, std::function< 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:1553
bool isPreISelGenericOptimizationHint(unsigned Opcode)
Definition: TargetOpcodes.h:42
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.
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:1585
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:1157
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:299
std::optional< APInt > ConstantFoldBinOp(unsigned Opcode, const Register Op1, const Register Op2, const MachineRegisterInfo &MRI)
Definition: Utils.cpp:649
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:1746
const APInt & getIConstantFromReg(Register VReg, const MachineRegisterInfo &MRI)
VReg is defined by a G_CONSTANT, return the corresponding value.
Definition: Utils.cpp:290
LLVM_READONLY APFloat maxnum(const APFloat &A, const APFloat &B)
Implements IEEE-754 2019 maximumNumber semantics.
Definition: APFloat.h:1558
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:1488
constexpr unsigned MaxAnalysisRecursionDepth
Definition: ValueTracking.h:44
auto reverse(ContainerTy &&C)
Definition: STLExtras.h:420
bool canReplaceReg(Register DstReg, Register SrcReg, MachineRegisterInfo &MRI)
Check if DstReg can be replaced with SrcReg depending on the register constraints.
Definition: Utils.cpp:201
void saveUsesAndErase(MachineInstr &MI, MachineRegisterInfo &MRI, LostDebugLocObserver *LocObserver, SmallInstListTy &DeadInstChain)
Definition: Utils.cpp:1622
void reportGISelFailure(MachineFunction &MF, const TargetPassConfig &TPC, MachineOptimizationRemarkEmitter &MORE, MachineOptimizationRemarkMissed &R)
Report an ISel error as a missed optimization remark to the LLVMContext's diagnostic stream.
Definition: Utils.cpp:259
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:167
std::optional< SmallVector< APInt > > ConstantFoldICmp(unsigned Pred, const Register Op1, const Register Op2, const MachineRegisterInfo &MRI)
Definition: Utils.cpp:1014
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:424
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:1431
bool canCreateUndefOrPoison(const Operator *Op, bool ConsiderFlagsAndMetadata=true)
canCreateUndefOrPoison returns true if Op can create undef or poison from non-undef & non-poison oper...
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:772
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:1418
std::optional< APInt > ConstantFoldCastOp(unsigned Opcode, LLT DstTy, const Register Op0, const MachineRegisterInfo &MRI)
Definition: Utils.cpp:945
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:485
void getSelectionDAGFallbackAnalysisUsage(AnalysisUsage &AU)
Modify analysis usage so it preserves passes required for the SelectionDAG fallback.
Definition: Utils.cpp:1153
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:1224
LLVM_READONLY APFloat minnum(const APFloat &A, const APFloat &B)
Implements IEEE-754 2019 minimumNumber semantics.
Definition: APFloat.h:1544
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition: Alignment.h:155
bool isTargetSpecificOpcode(unsigned Opcode)
Check whether the given Opcode is a target-specific opcode.
Definition: TargetOpcodes.h:36
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.
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:432
bool isConstFalseVal(const TargetLowering &TLI, int64_t Val, bool IsVector, bool IsFP)
Definition: Utils.cpp:1598
constexpr unsigned BitWidth
Definition: BitmaskEnum.h:217
APFloat getAPFloatFromSize(double Val, unsigned Size)
Returns an APFloat from Val converted to the appropriate size.
Definition: Utils.cpp:636
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:1369
void eraseInstr(MachineInstr &MI, MachineRegisterInfo &MRI, LostDebugLocObserver *LocObserver=nullptr)
Definition: Utils.cpp:1651
DiagnosticSeverity
Defines the different supported severity of a diagnostic.
@ DS_Warning
@ DS_Error
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:46
int64_t getICmpTrueVal(const TargetLowering &TLI, bool IsVector, bool IsFP)
Returns an integer representing true, as defined by the TargetBooleanContents.
Definition: Utils.cpp:1610
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:418
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:1766
bool isPreISelGenericFloatingPointOpcode(unsigned Opc)
Returns whether opcode Opc is a pre-isel generic floating-point opcode, having only floating-point op...
Definition: Utils.cpp:1675
bool isKnownNeverSNaN(Register Val, const MachineRegisterInfo &MRI)
Returns true if Val can be assumed to never be a signaling NaN.
Definition: Utils.h:338
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:452
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition: STLExtras.h:1903
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
Definition: Alignment.h:212
void eraseInstrs(ArrayRef< MachineInstr * > DeadInstrs, MachineRegisterInfo &MRI, LostDebugLocObserver *LocObserver=nullptr)
Definition: Utils.cpp:1636
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...
bool isKnownNeverNaN(const Value *V, unsigned Depth, const SimplifyQuery &SQ)
Return true if the floating-point scalar value is not a NaN or if the floating-point vector value has...
Register getSrcRegIgnoringCopies(Register Reg, const MachineRegisterInfo &MRI)
Find the source register for Reg, folding away any trivial copies.
Definition: Utils.cpp:478
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:1245
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.
LLVM_READONLY APFloat minimum(const APFloat &A, const APFloat &B)
Implements IEEE 754-2019 minimum semantics.
Definition: APFloat.h:1572
std::optional< int64_t > getIConstantSplatSExtVal(const Register Reg, const MachineRegisterInfo &MRI)
Definition: Utils.cpp:1403
void extractVectorParts(Register Reg, unsigned NumElts, SmallVectorImpl< Register > &VRegs, MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI)
Version which handles irregular sub-vector splits.
Definition: Utils.cpp:588
int getSplatIndex(ArrayRef< int > Mask)
If all non-negative Mask elements are the same value, return that value.
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:222
Align inferAlignFromPtrInfo(MachineFunction &MF, const MachinePointerInfo &MPO)
Definition: Utils.cpp:878
void reportGISelWarning(MachineFunction &MF, const TargetPassConfig &TPC, MachineOptimizationRemarkEmitter &MORE, MachineOptimizationRemarkMissed &R)
Report an ISel warning as a missed optimization remark to the LLVMContext's diagnostic stream.
Definition: Utils.cpp:253
#define MORE()
Definition: regcomp.c:252
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:228
unsigned countMaxPopulation() const
Returns the maximum number of bits that could be one.
Definition: KnownBits.h:281
unsigned countMinPopulation() const
Returns the number of bits known to be one.
Definition: KnownBits.h:278
This class contains a discriminated union of information about pointers in memory operands,...
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.
Simple struct used to hold a constant integer value and a virtual register.
Definition: Utils.h:187