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
12 #include "llvm/CodeGen/GlobalISel/Utils.h"
13 #include "llvm/ADT/APFloat.h"
14 #include "llvm/ADT/APInt.h"
15 #include "llvm/Analysis/ValueTracking.h"
16 #include "llvm/CodeGen/CodeGenCommonISel.h"
17 #include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h"
18 #include "llvm/CodeGen/GlobalISel/GISelValueTracking.h"
19 #include "llvm/CodeGen/GlobalISel/GenericMachineInstrs.h"
20 #include "llvm/CodeGen/GlobalISel/LostDebugLocObserver.h"
21 #include "llvm/CodeGen/GlobalISel/MIPatternMatch.h"
22 #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
23 #include "llvm/CodeGen/MachineInstr.h"
24 #include "llvm/CodeGen/MachineInstrBuilder.h"
25 #include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"
26 #include "llvm/CodeGen/MachineRegisterInfo.h"
27 #include "llvm/CodeGen/MachineSizeOpts.h"
28 #include "llvm/CodeGen/RegisterBankInfo.h"
29 #include "llvm/CodeGen/StackProtector.h"
30 #include "llvm/CodeGen/TargetInstrInfo.h"
31 #include "llvm/CodeGen/TargetLowering.h"
32 #include "llvm/CodeGen/TargetOpcodes.h"
33 #include "llvm/CodeGen/TargetPassConfig.h"
34 #include "llvm/CodeGen/TargetRegisterInfo.h"
35 #include "llvm/IR/Constants.h"
36 #include "llvm/Target/TargetMachine.h"
37 #include "llvm/Transforms/Utils/SizeOpts.h"
38 #include <numeric>
39 #include <optional>
40
41 #define DEBUG_TYPE "globalisel-utils"
42
43 using namespace llvm;
44 using namespace MIPatternMatch;
45
constrainRegToClass(MachineRegisterInfo & MRI,const TargetInstrInfo & TII,const RegisterBankInfo & RBI,Register Reg,const TargetRegisterClass & RegClass)46 Register llvm::constrainRegToClass(MachineRegisterInfo &MRI,
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
constrainOperandRegClass(const MachineFunction & MF,const TargetRegisterInfo & TRI,MachineRegisterInfo & MRI,const TargetInstrInfo & TII,const RegisterBankInfo & RBI,MachineInstr & InsertPt,const TargetRegisterClass & RegClass,MachineOperand & RegMO)56 Register llvm::constrainOperandRegClass(
57 const MachineFunction &MF, const TargetRegisterInfo &TRI,
58 MachineRegisterInfo &MRI, const TargetInstrInfo &TII,
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
constrainOperandRegClass(const MachineFunction & MF,const TargetRegisterInfo & TRI,MachineRegisterInfo & MRI,const TargetInstrInfo & TII,const RegisterBankInfo & RBI,MachineInstr & InsertPt,const MCInstrDesc & II,MachineOperand & RegMO,unsigned OpIdx)108 Register llvm::constrainOperandRegClass(
109 const MachineFunction &MF, const TargetRegisterInfo &TRI,
110 MachineRegisterInfo &MRI, const TargetInstrInfo &TII,
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
constrainSelectedInstRegOperands(MachineInstr & I,const TargetInstrInfo & TII,const TargetRegisterInfo & TRI,const RegisterBankInfo & RBI)155 bool llvm::constrainSelectedInstRegOperands(MachineInstr &I,
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();
162 MachineFunction &MF = *MBB.getParent();
163 MachineRegisterInfo &MRI = MF.getRegInfo();
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
canReplaceReg(Register DstReg,Register SrcReg,MachineRegisterInfo & MRI)201 bool llvm::canReplaceReg(Register DstReg, Register SrcReg,
202 MachineRegisterInfo &MRI) {
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
isTriviallyDead(const MachineInstr & MI,const MachineRegisterInfo & MRI)222 bool llvm::isTriviallyDead(const MachineInstr &MI,
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
reportGISelDiagnostic(DiagnosticSeverity Severity,MachineFunction & MF,const TargetPassConfig & TPC,MachineOptimizationRemarkEmitter & MORE,MachineOptimizationRemarkMissed & R)235 static void reportGISelDiagnostic(DiagnosticSeverity Severity,
236 MachineFunction &MF,
237 const TargetPassConfig &TPC,
238 MachineOptimizationRemarkEmitter &MORE,
239 MachineOptimizationRemarkMissed &R) {
240 bool IsFatal = Severity == DS_Error &&
241 TPC.isGlobalISelAbortEnabled();
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 reportFatalUsageError(Twine(R.getMsg()));
249 else
250 MORE.emit(R);
251 }
252
reportGISelWarning(MachineFunction & MF,const TargetPassConfig & TPC,MachineOptimizationRemarkEmitter & MORE,MachineOptimizationRemarkMissed & R)253 void llvm::reportGISelWarning(MachineFunction &MF, const TargetPassConfig &TPC,
254 MachineOptimizationRemarkEmitter &MORE,
255 MachineOptimizationRemarkMissed &R) {
256 reportGISelDiagnostic(DS_Warning, MF, TPC, MORE, R);
257 }
258
reportGISelFailure(MachineFunction & MF,const TargetPassConfig & TPC,MachineOptimizationRemarkEmitter & MORE,MachineOptimizationRemarkMissed & R)259 void llvm::reportGISelFailure(MachineFunction &MF, const TargetPassConfig &TPC,
260 MachineOptimizationRemarkEmitter &MORE,
261 MachineOptimizationRemarkMissed &R) {
262 MF.getProperties().setFailedISel();
263 reportGISelDiagnostic(DS_Error, MF, TPC, MORE, R);
264 }
265
reportGISelFailure(MachineFunction & MF,const TargetPassConfig & TPC,MachineOptimizationRemarkEmitter & MORE,const char * PassName,StringRef Msg,const MachineInstr & MI)266 void llvm::reportGISelFailure(MachineFunction &MF, const TargetPassConfig &TPC,
267 MachineOptimizationRemarkEmitter &MORE,
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
getInverseGMinMaxOpcode(unsigned MinMaxOpc)279 unsigned llvm::getInverseGMinMaxOpcode(unsigned MinMaxOpc) {
280 switch (MinMaxOpc) {
281 case TargetOpcode::G_SMIN:
282 return TargetOpcode::G_SMAX;
283 case TargetOpcode::G_SMAX:
284 return TargetOpcode::G_SMIN;
285 case TargetOpcode::G_UMIN:
286 return TargetOpcode::G_UMAX;
287 case TargetOpcode::G_UMAX:
288 return TargetOpcode::G_UMIN;
289 default:
290 llvm_unreachable("unrecognized opcode");
291 }
292 }
293
getIConstantVRegVal(Register VReg,const MachineRegisterInfo & MRI)294 std::optional<APInt> llvm::getIConstantVRegVal(Register VReg,
295 const MachineRegisterInfo &MRI) {
296 std::optional<ValueAndVReg> ValAndVReg = getIConstantVRegValWithLookThrough(
297 VReg, MRI, /*LookThroughInstrs*/ false);
298 assert((!ValAndVReg || ValAndVReg->VReg == VReg) &&
299 "Value found while looking through instrs");
300 if (!ValAndVReg)
301 return std::nullopt;
302 return ValAndVReg->Value;
303 }
304
getIConstantFromReg(Register Reg,const MachineRegisterInfo & MRI)305 const APInt &llvm::getIConstantFromReg(Register Reg,
306 const MachineRegisterInfo &MRI) {
307 MachineInstr *Const = MRI.getVRegDef(Reg);
308 assert((Const && Const->getOpcode() == TargetOpcode::G_CONSTANT) &&
309 "expected a G_CONSTANT on Reg");
310 return Const->getOperand(1).getCImm()->getValue();
311 }
312
313 std::optional<int64_t>
getIConstantVRegSExtVal(Register VReg,const MachineRegisterInfo & MRI)314 llvm::getIConstantVRegSExtVal(Register VReg, const MachineRegisterInfo &MRI) {
315 std::optional<APInt> Val = getIConstantVRegVal(VReg, MRI);
316 if (Val && Val->getBitWidth() <= 64)
317 return Val->getSExtValue();
318 return std::nullopt;
319 }
320
321 namespace {
322
323 // This function is used in many places, and as such, it has some
324 // micro-optimizations to try and make it as fast as it can be.
325 //
326 // - We use template arguments to avoid an indirect call caused by passing a
327 // function_ref/std::function
328 // - GetAPCstValue does not return std::optional<APInt> as that's expensive.
329 // Instead it returns true/false and places the result in a pre-constructed
330 // APInt.
331 //
332 // Please change this function carefully and benchmark your changes.
333 template <bool (*IsConstantOpcode)(const MachineInstr *),
334 bool (*GetAPCstValue)(const MachineInstr *MI, APInt &)>
335 std::optional<ValueAndVReg>
getConstantVRegValWithLookThrough(Register VReg,const MachineRegisterInfo & MRI,bool LookThroughInstrs=true,bool LookThroughAnyExt=false)336 getConstantVRegValWithLookThrough(Register VReg, const MachineRegisterInfo &MRI,
337 bool LookThroughInstrs = true,
338 bool LookThroughAnyExt = false) {
339 SmallVector<std::pair<unsigned, unsigned>, 4> SeenOpcodes;
340 MachineInstr *MI;
341
342 while ((MI = MRI.getVRegDef(VReg)) && !IsConstantOpcode(MI) &&
343 LookThroughInstrs) {
344 switch (MI->getOpcode()) {
345 case TargetOpcode::G_ANYEXT:
346 if (!LookThroughAnyExt)
347 return std::nullopt;
348 [[fallthrough]];
349 case TargetOpcode::G_TRUNC:
350 case TargetOpcode::G_SEXT:
351 case TargetOpcode::G_ZEXT:
352 SeenOpcodes.push_back(std::make_pair(
353 MI->getOpcode(),
354 MRI.getType(MI->getOperand(0).getReg()).getSizeInBits()));
355 VReg = MI->getOperand(1).getReg();
356 break;
357 case TargetOpcode::COPY:
358 VReg = MI->getOperand(1).getReg();
359 if (VReg.isPhysical())
360 return std::nullopt;
361 break;
362 case TargetOpcode::G_INTTOPTR:
363 VReg = MI->getOperand(1).getReg();
364 break;
365 default:
366 return std::nullopt;
367 }
368 }
369 if (!MI || !IsConstantOpcode(MI))
370 return std::nullopt;
371
372 APInt Val;
373 if (!GetAPCstValue(MI, Val))
374 return std::nullopt;
375 for (auto &Pair : reverse(SeenOpcodes)) {
376 switch (Pair.first) {
377 case TargetOpcode::G_TRUNC:
378 Val = Val.trunc(Pair.second);
379 break;
380 case TargetOpcode::G_ANYEXT:
381 case TargetOpcode::G_SEXT:
382 Val = Val.sext(Pair.second);
383 break;
384 case TargetOpcode::G_ZEXT:
385 Val = Val.zext(Pair.second);
386 break;
387 }
388 }
389
390 return ValueAndVReg{std::move(Val), VReg};
391 }
392
isIConstant(const MachineInstr * MI)393 bool isIConstant(const MachineInstr *MI) {
394 if (!MI)
395 return false;
396 return MI->getOpcode() == TargetOpcode::G_CONSTANT;
397 }
398
isFConstant(const MachineInstr * MI)399 bool isFConstant(const MachineInstr *MI) {
400 if (!MI)
401 return false;
402 return MI->getOpcode() == TargetOpcode::G_FCONSTANT;
403 }
404
isAnyConstant(const MachineInstr * MI)405 bool isAnyConstant(const MachineInstr *MI) {
406 if (!MI)
407 return false;
408 unsigned Opc = MI->getOpcode();
409 return Opc == TargetOpcode::G_CONSTANT || Opc == TargetOpcode::G_FCONSTANT;
410 }
411
getCImmAsAPInt(const MachineInstr * MI,APInt & Result)412 bool getCImmAsAPInt(const MachineInstr *MI, APInt &Result) {
413 const MachineOperand &CstVal = MI->getOperand(1);
414 if (!CstVal.isCImm())
415 return false;
416 Result = CstVal.getCImm()->getValue();
417 return true;
418 }
419
getCImmOrFPImmAsAPInt(const MachineInstr * MI,APInt & Result)420 bool getCImmOrFPImmAsAPInt(const MachineInstr *MI, APInt &Result) {
421 const MachineOperand &CstVal = MI->getOperand(1);
422 if (CstVal.isCImm())
423 Result = CstVal.getCImm()->getValue();
424 else if (CstVal.isFPImm())
425 Result = CstVal.getFPImm()->getValueAPF().bitcastToAPInt();
426 else
427 return false;
428 return true;
429 }
430
431 } // end anonymous namespace
432
getIConstantVRegValWithLookThrough(Register VReg,const MachineRegisterInfo & MRI,bool LookThroughInstrs)433 std::optional<ValueAndVReg> llvm::getIConstantVRegValWithLookThrough(
434 Register VReg, const MachineRegisterInfo &MRI, bool LookThroughInstrs) {
435 return getConstantVRegValWithLookThrough<isIConstant, getCImmAsAPInt>(
436 VReg, MRI, LookThroughInstrs);
437 }
438
getAnyConstantVRegValWithLookThrough(Register VReg,const MachineRegisterInfo & MRI,bool LookThroughInstrs,bool LookThroughAnyExt)439 std::optional<ValueAndVReg> llvm::getAnyConstantVRegValWithLookThrough(
440 Register VReg, const MachineRegisterInfo &MRI, bool LookThroughInstrs,
441 bool LookThroughAnyExt) {
442 return getConstantVRegValWithLookThrough<isAnyConstant,
443 getCImmOrFPImmAsAPInt>(
444 VReg, MRI, LookThroughInstrs, LookThroughAnyExt);
445 }
446
getFConstantVRegValWithLookThrough(Register VReg,const MachineRegisterInfo & MRI,bool LookThroughInstrs)447 std::optional<FPValueAndVReg> llvm::getFConstantVRegValWithLookThrough(
448 Register VReg, const MachineRegisterInfo &MRI, bool LookThroughInstrs) {
449 auto Reg =
450 getConstantVRegValWithLookThrough<isFConstant, getCImmOrFPImmAsAPInt>(
451 VReg, MRI, LookThroughInstrs);
452 if (!Reg)
453 return std::nullopt;
454 return FPValueAndVReg{getConstantFPVRegVal(Reg->VReg, MRI)->getValueAPF(),
455 Reg->VReg};
456 }
457
458 const ConstantFP *
getConstantFPVRegVal(Register VReg,const MachineRegisterInfo & MRI)459 llvm::getConstantFPVRegVal(Register VReg, const MachineRegisterInfo &MRI) {
460 MachineInstr *MI = MRI.getVRegDef(VReg);
461 if (TargetOpcode::G_FCONSTANT != MI->getOpcode())
462 return nullptr;
463 return MI->getOperand(1).getFPImm();
464 }
465
466 std::optional<DefinitionAndSourceRegister>
getDefSrcRegIgnoringCopies(Register Reg,const MachineRegisterInfo & MRI)467 llvm::getDefSrcRegIgnoringCopies(Register Reg, const MachineRegisterInfo &MRI) {
468 Register DefSrcReg = Reg;
469 auto *DefMI = MRI.getVRegDef(Reg);
470 auto DstTy = MRI.getType(DefMI->getOperand(0).getReg());
471 if (!DstTy.isValid())
472 return std::nullopt;
473 unsigned Opc = DefMI->getOpcode();
474 while (Opc == TargetOpcode::COPY || isPreISelGenericOptimizationHint(Opc)) {
475 Register SrcReg = DefMI->getOperand(1).getReg();
476 auto SrcTy = MRI.getType(SrcReg);
477 if (!SrcTy.isValid())
478 break;
479 DefMI = MRI.getVRegDef(SrcReg);
480 DefSrcReg = SrcReg;
481 Opc = DefMI->getOpcode();
482 }
483 return DefinitionAndSourceRegister{DefMI, DefSrcReg};
484 }
485
getDefIgnoringCopies(Register Reg,const MachineRegisterInfo & MRI)486 MachineInstr *llvm::getDefIgnoringCopies(Register Reg,
487 const MachineRegisterInfo &MRI) {
488 std::optional<DefinitionAndSourceRegister> DefSrcReg =
489 getDefSrcRegIgnoringCopies(Reg, MRI);
490 return DefSrcReg ? DefSrcReg->MI : nullptr;
491 }
492
getSrcRegIgnoringCopies(Register Reg,const MachineRegisterInfo & MRI)493 Register llvm::getSrcRegIgnoringCopies(Register Reg,
494 const MachineRegisterInfo &MRI) {
495 std::optional<DefinitionAndSourceRegister> DefSrcReg =
496 getDefSrcRegIgnoringCopies(Reg, MRI);
497 return DefSrcReg ? DefSrcReg->Reg : Register();
498 }
499
extractParts(Register Reg,LLT Ty,int NumParts,SmallVectorImpl<Register> & VRegs,MachineIRBuilder & MIRBuilder,MachineRegisterInfo & MRI)500 void llvm::extractParts(Register Reg, LLT Ty, int NumParts,
501 SmallVectorImpl<Register> &VRegs,
502 MachineIRBuilder &MIRBuilder,
503 MachineRegisterInfo &MRI) {
504 for (int i = 0; i < NumParts; ++i)
505 VRegs.push_back(MRI.createGenericVirtualRegister(Ty));
506 MIRBuilder.buildUnmerge(VRegs, Reg);
507 }
508
extractParts(Register Reg,LLT RegTy,LLT MainTy,LLT & LeftoverTy,SmallVectorImpl<Register> & VRegs,SmallVectorImpl<Register> & LeftoverRegs,MachineIRBuilder & MIRBuilder,MachineRegisterInfo & MRI)509 bool llvm::extractParts(Register Reg, LLT RegTy, LLT MainTy, LLT &LeftoverTy,
510 SmallVectorImpl<Register> &VRegs,
511 SmallVectorImpl<Register> &LeftoverRegs,
512 MachineIRBuilder &MIRBuilder,
513 MachineRegisterInfo &MRI) {
514 assert(!LeftoverTy.isValid() && "this is an out argument");
515
516 unsigned RegSize = RegTy.getSizeInBits();
517 unsigned MainSize = MainTy.getSizeInBits();
518 unsigned NumParts = RegSize / MainSize;
519 unsigned LeftoverSize = RegSize - NumParts * MainSize;
520
521 // Use an unmerge when possible.
522 if (LeftoverSize == 0) {
523 for (unsigned I = 0; I < NumParts; ++I)
524 VRegs.push_back(MRI.createGenericVirtualRegister(MainTy));
525 MIRBuilder.buildUnmerge(VRegs, Reg);
526 return true;
527 }
528
529 // Try to use unmerge for irregular vector split where possible
530 // For example when splitting a <6 x i32> into <4 x i32> with <2 x i32>
531 // leftover, it becomes:
532 // <2 x i32> %2, <2 x i32>%3, <2 x i32> %4 = G_UNMERGE_VALUE <6 x i32> %1
533 // <4 x i32> %5 = G_CONCAT_VECTOR <2 x i32> %2, <2 x i32> %3
534 if (RegTy.isVector() && MainTy.isVector()) {
535 unsigned RegNumElts = RegTy.getNumElements();
536 unsigned MainNumElts = MainTy.getNumElements();
537 unsigned LeftoverNumElts = RegNumElts % MainNumElts;
538 // If can unmerge to LeftoverTy, do it
539 if (MainNumElts % LeftoverNumElts == 0 &&
540 RegNumElts % LeftoverNumElts == 0 &&
541 RegTy.getScalarSizeInBits() == MainTy.getScalarSizeInBits() &&
542 LeftoverNumElts > 1) {
543 LeftoverTy = LLT::fixed_vector(LeftoverNumElts, RegTy.getElementType());
544
545 // Unmerge the SrcReg to LeftoverTy vectors
546 SmallVector<Register, 4> UnmergeValues;
547 extractParts(Reg, LeftoverTy, RegNumElts / LeftoverNumElts, UnmergeValues,
548 MIRBuilder, MRI);
549
550 // Find how many LeftoverTy makes one MainTy
551 unsigned LeftoverPerMain = MainNumElts / LeftoverNumElts;
552 unsigned NumOfLeftoverVal =
553 ((RegNumElts % MainNumElts) / LeftoverNumElts);
554
555 // Create as many MainTy as possible using unmerged value
556 SmallVector<Register, 4> MergeValues;
557 for (unsigned I = 0; I < UnmergeValues.size() - NumOfLeftoverVal; I++) {
558 MergeValues.push_back(UnmergeValues[I]);
559 if (MergeValues.size() == LeftoverPerMain) {
560 VRegs.push_back(
561 MIRBuilder.buildMergeLikeInstr(MainTy, MergeValues).getReg(0));
562 MergeValues.clear();
563 }
564 }
565 // Populate LeftoverRegs with the leftovers
566 for (unsigned I = UnmergeValues.size() - NumOfLeftoverVal;
567 I < UnmergeValues.size(); I++) {
568 LeftoverRegs.push_back(UnmergeValues[I]);
569 }
570 return true;
571 }
572 }
573 // Perform irregular split. Leftover is last element of RegPieces.
574 if (MainTy.isVector()) {
575 SmallVector<Register, 8> RegPieces;
576 extractVectorParts(Reg, MainTy.getNumElements(), RegPieces, MIRBuilder,
577 MRI);
578 for (unsigned i = 0; i < RegPieces.size() - 1; ++i)
579 VRegs.push_back(RegPieces[i]);
580 LeftoverRegs.push_back(RegPieces[RegPieces.size() - 1]);
581 LeftoverTy = MRI.getType(LeftoverRegs[0]);
582 return true;
583 }
584
585 LeftoverTy = LLT::scalar(LeftoverSize);
586 // For irregular sizes, extract the individual parts.
587 for (unsigned I = 0; I != NumParts; ++I) {
588 Register NewReg = MRI.createGenericVirtualRegister(MainTy);
589 VRegs.push_back(NewReg);
590 MIRBuilder.buildExtract(NewReg, Reg, MainSize * I);
591 }
592
593 for (unsigned Offset = MainSize * NumParts; Offset < RegSize;
594 Offset += LeftoverSize) {
595 Register NewReg = MRI.createGenericVirtualRegister(LeftoverTy);
596 LeftoverRegs.push_back(NewReg);
597 MIRBuilder.buildExtract(NewReg, Reg, Offset);
598 }
599
600 return true;
601 }
602
extractVectorParts(Register Reg,unsigned NumElts,SmallVectorImpl<Register> & VRegs,MachineIRBuilder & MIRBuilder,MachineRegisterInfo & MRI)603 void llvm::extractVectorParts(Register Reg, unsigned NumElts,
604 SmallVectorImpl<Register> &VRegs,
605 MachineIRBuilder &MIRBuilder,
606 MachineRegisterInfo &MRI) {
607 LLT RegTy = MRI.getType(Reg);
608 assert(RegTy.isVector() && "Expected a vector type");
609
610 LLT EltTy = RegTy.getElementType();
611 LLT NarrowTy = (NumElts == 1) ? EltTy : LLT::fixed_vector(NumElts, EltTy);
612 unsigned RegNumElts = RegTy.getNumElements();
613 unsigned LeftoverNumElts = RegNumElts % NumElts;
614 unsigned NumNarrowTyPieces = RegNumElts / NumElts;
615
616 // Perfect split without leftover
617 if (LeftoverNumElts == 0)
618 return extractParts(Reg, NarrowTy, NumNarrowTyPieces, VRegs, MIRBuilder,
619 MRI);
620
621 // Irregular split. Provide direct access to all elements for artifact
622 // combiner using unmerge to elements. Then build vectors with NumElts
623 // elements. Remaining element(s) will be (used to build vector) Leftover.
624 SmallVector<Register, 8> Elts;
625 extractParts(Reg, EltTy, RegNumElts, Elts, MIRBuilder, MRI);
626
627 unsigned Offset = 0;
628 // Requested sub-vectors of NarrowTy.
629 for (unsigned i = 0; i < NumNarrowTyPieces; ++i, Offset += NumElts) {
630 ArrayRef<Register> Pieces(&Elts[Offset], NumElts);
631 VRegs.push_back(MIRBuilder.buildMergeLikeInstr(NarrowTy, Pieces).getReg(0));
632 }
633
634 // Leftover element(s).
635 if (LeftoverNumElts == 1) {
636 VRegs.push_back(Elts[Offset]);
637 } else {
638 LLT LeftoverTy = LLT::fixed_vector(LeftoverNumElts, EltTy);
639 ArrayRef<Register> Pieces(&Elts[Offset], LeftoverNumElts);
640 VRegs.push_back(
641 MIRBuilder.buildMergeLikeInstr(LeftoverTy, Pieces).getReg(0));
642 }
643 }
644
getOpcodeDef(unsigned Opcode,Register Reg,const MachineRegisterInfo & MRI)645 MachineInstr *llvm::getOpcodeDef(unsigned Opcode, Register Reg,
646 const MachineRegisterInfo &MRI) {
647 MachineInstr *DefMI = getDefIgnoringCopies(Reg, MRI);
648 return DefMI && DefMI->getOpcode() == Opcode ? DefMI : nullptr;
649 }
650
getAPFloatFromSize(double Val,unsigned Size)651 APFloat llvm::getAPFloatFromSize(double Val, unsigned Size) {
652 if (Size == 32)
653 return APFloat(float(Val));
654 if (Size == 64)
655 return APFloat(Val);
656 if (Size != 16)
657 llvm_unreachable("Unsupported FPConstant size");
658 bool Ignored;
659 APFloat APF(Val);
660 APF.convert(APFloat::IEEEhalf(), APFloat::rmNearestTiesToEven, &Ignored);
661 return APF;
662 }
663
ConstantFoldBinOp(unsigned Opcode,const Register Op1,const Register Op2,const MachineRegisterInfo & MRI)664 std::optional<APInt> llvm::ConstantFoldBinOp(unsigned Opcode,
665 const Register Op1,
666 const Register Op2,
667 const MachineRegisterInfo &MRI) {
668 auto MaybeOp2Cst = getAnyConstantVRegValWithLookThrough(Op2, MRI, false);
669 if (!MaybeOp2Cst)
670 return std::nullopt;
671
672 auto MaybeOp1Cst = getAnyConstantVRegValWithLookThrough(Op1, MRI, false);
673 if (!MaybeOp1Cst)
674 return std::nullopt;
675
676 const APInt &C1 = MaybeOp1Cst->Value;
677 const APInt &C2 = MaybeOp2Cst->Value;
678 switch (Opcode) {
679 default:
680 break;
681 case TargetOpcode::G_ADD:
682 return C1 + C2;
683 case TargetOpcode::G_PTR_ADD:
684 // Types can be of different width here.
685 // Result needs to be the same width as C1, so trunc or sext C2.
686 return C1 + C2.sextOrTrunc(C1.getBitWidth());
687 case TargetOpcode::G_AND:
688 return C1 & C2;
689 case TargetOpcode::G_ASHR:
690 return C1.ashr(C2);
691 case TargetOpcode::G_LSHR:
692 return C1.lshr(C2);
693 case TargetOpcode::G_MUL:
694 return C1 * C2;
695 case TargetOpcode::G_OR:
696 return C1 | C2;
697 case TargetOpcode::G_SHL:
698 return C1 << C2;
699 case TargetOpcode::G_SUB:
700 return C1 - C2;
701 case TargetOpcode::G_XOR:
702 return C1 ^ C2;
703 case TargetOpcode::G_UDIV:
704 if (!C2.getBoolValue())
705 break;
706 return C1.udiv(C2);
707 case TargetOpcode::G_SDIV:
708 if (!C2.getBoolValue())
709 break;
710 return C1.sdiv(C2);
711 case TargetOpcode::G_UREM:
712 if (!C2.getBoolValue())
713 break;
714 return C1.urem(C2);
715 case TargetOpcode::G_SREM:
716 if (!C2.getBoolValue())
717 break;
718 return C1.srem(C2);
719 case TargetOpcode::G_SMIN:
720 return APIntOps::smin(C1, C2);
721 case TargetOpcode::G_SMAX:
722 return APIntOps::smax(C1, C2);
723 case TargetOpcode::G_UMIN:
724 return APIntOps::umin(C1, C2);
725 case TargetOpcode::G_UMAX:
726 return APIntOps::umax(C1, C2);
727 }
728
729 return std::nullopt;
730 }
731
732 std::optional<APFloat>
ConstantFoldFPBinOp(unsigned Opcode,const Register Op1,const Register Op2,const MachineRegisterInfo & MRI)733 llvm::ConstantFoldFPBinOp(unsigned Opcode, const Register Op1,
734 const Register Op2, const MachineRegisterInfo &MRI) {
735 const ConstantFP *Op2Cst = getConstantFPVRegVal(Op2, MRI);
736 if (!Op2Cst)
737 return std::nullopt;
738
739 const ConstantFP *Op1Cst = getConstantFPVRegVal(Op1, MRI);
740 if (!Op1Cst)
741 return std::nullopt;
742
743 APFloat C1 = Op1Cst->getValueAPF();
744 const APFloat &C2 = Op2Cst->getValueAPF();
745 switch (Opcode) {
746 case TargetOpcode::G_FADD:
747 C1.add(C2, APFloat::rmNearestTiesToEven);
748 return C1;
749 case TargetOpcode::G_FSUB:
750 C1.subtract(C2, APFloat::rmNearestTiesToEven);
751 return C1;
752 case TargetOpcode::G_FMUL:
753 C1.multiply(C2, APFloat::rmNearestTiesToEven);
754 return C1;
755 case TargetOpcode::G_FDIV:
756 C1.divide(C2, APFloat::rmNearestTiesToEven);
757 return C1;
758 case TargetOpcode::G_FREM:
759 C1.mod(C2);
760 return C1;
761 case TargetOpcode::G_FCOPYSIGN:
762 C1.copySign(C2);
763 return C1;
764 case TargetOpcode::G_FMINNUM:
765 return minnum(C1, C2);
766 case TargetOpcode::G_FMAXNUM:
767 return maxnum(C1, C2);
768 case TargetOpcode::G_FMINIMUM:
769 return minimum(C1, C2);
770 case TargetOpcode::G_FMAXIMUM:
771 return maximum(C1, C2);
772 case TargetOpcode::G_FMINNUM_IEEE:
773 case TargetOpcode::G_FMAXNUM_IEEE:
774 // FIXME: These operations were unfortunately named. fminnum/fmaxnum do not
775 // follow the IEEE behavior for signaling nans and follow libm's fmin/fmax,
776 // and currently there isn't a nice wrapper in APFloat for the version with
777 // correct snan handling.
778 break;
779 default:
780 break;
781 }
782
783 return std::nullopt;
784 }
785
786 SmallVector<APInt>
ConstantFoldVectorBinop(unsigned Opcode,const Register Op1,const Register Op2,const MachineRegisterInfo & MRI)787 llvm::ConstantFoldVectorBinop(unsigned Opcode, const Register Op1,
788 const Register Op2,
789 const MachineRegisterInfo &MRI) {
790 auto *SrcVec2 = getOpcodeDef<GBuildVector>(Op2, MRI);
791 if (!SrcVec2)
792 return SmallVector<APInt>();
793
794 auto *SrcVec1 = getOpcodeDef<GBuildVector>(Op1, MRI);
795 if (!SrcVec1)
796 return SmallVector<APInt>();
797
798 SmallVector<APInt> FoldedElements;
799 for (unsigned Idx = 0, E = SrcVec1->getNumSources(); Idx < E; ++Idx) {
800 auto MaybeCst = ConstantFoldBinOp(Opcode, SrcVec1->getSourceReg(Idx),
801 SrcVec2->getSourceReg(Idx), MRI);
802 if (!MaybeCst)
803 return SmallVector<APInt>();
804 FoldedElements.push_back(*MaybeCst);
805 }
806 return FoldedElements;
807 }
808
isKnownNeverNaN(Register Val,const MachineRegisterInfo & MRI,bool SNaN)809 bool llvm::isKnownNeverNaN(Register Val, const MachineRegisterInfo &MRI,
810 bool SNaN) {
811 const MachineInstr *DefMI = MRI.getVRegDef(Val);
812 if (!DefMI)
813 return false;
814
815 const TargetMachine& TM = DefMI->getMF()->getTarget();
816 if (DefMI->getFlag(MachineInstr::FmNoNans) || TM.Options.NoNaNsFPMath)
817 return true;
818
819 // If the value is a constant, we can obviously see if it is a NaN or not.
820 if (const ConstantFP *FPVal = getConstantFPVRegVal(Val, MRI)) {
821 return !FPVal->getValueAPF().isNaN() ||
822 (SNaN && !FPVal->getValueAPF().isSignaling());
823 }
824
825 if (DefMI->getOpcode() == TargetOpcode::G_BUILD_VECTOR) {
826 for (const auto &Op : DefMI->uses())
827 if (!isKnownNeverNaN(Op.getReg(), MRI, SNaN))
828 return false;
829 return true;
830 }
831
832 switch (DefMI->getOpcode()) {
833 default:
834 break;
835 case TargetOpcode::G_FADD:
836 case TargetOpcode::G_FSUB:
837 case TargetOpcode::G_FMUL:
838 case TargetOpcode::G_FDIV:
839 case TargetOpcode::G_FREM:
840 case TargetOpcode::G_FSIN:
841 case TargetOpcode::G_FCOS:
842 case TargetOpcode::G_FTAN:
843 case TargetOpcode::G_FACOS:
844 case TargetOpcode::G_FASIN:
845 case TargetOpcode::G_FATAN:
846 case TargetOpcode::G_FATAN2:
847 case TargetOpcode::G_FCOSH:
848 case TargetOpcode::G_FSINH:
849 case TargetOpcode::G_FTANH:
850 case TargetOpcode::G_FMA:
851 case TargetOpcode::G_FMAD:
852 if (SNaN)
853 return true;
854
855 // TODO: Need isKnownNeverInfinity
856 return false;
857 case TargetOpcode::G_FMINNUM_IEEE:
858 case TargetOpcode::G_FMAXNUM_IEEE: {
859 if (SNaN)
860 return true;
861 // This can return a NaN if either operand is an sNaN, or if both operands
862 // are NaN.
863 return (isKnownNeverNaN(DefMI->getOperand(1).getReg(), MRI) &&
864 isKnownNeverSNaN(DefMI->getOperand(2).getReg(), MRI)) ||
865 (isKnownNeverSNaN(DefMI->getOperand(1).getReg(), MRI) &&
866 isKnownNeverNaN(DefMI->getOperand(2).getReg(), MRI));
867 }
868 case TargetOpcode::G_FMINNUM:
869 case TargetOpcode::G_FMAXNUM: {
870 // Only one needs to be known not-nan, since it will be returned if the
871 // other ends up being one.
872 return isKnownNeverNaN(DefMI->getOperand(1).getReg(), MRI, SNaN) ||
873 isKnownNeverNaN(DefMI->getOperand(2).getReg(), MRI, SNaN);
874 }
875 }
876
877 if (SNaN) {
878 // FP operations quiet. For now, just handle the ones inserted during
879 // legalization.
880 switch (DefMI->getOpcode()) {
881 case TargetOpcode::G_FPEXT:
882 case TargetOpcode::G_FPTRUNC:
883 case TargetOpcode::G_FCANONICALIZE:
884 return true;
885 default:
886 return false;
887 }
888 }
889
890 return false;
891 }
892
inferAlignFromPtrInfo(MachineFunction & MF,const MachinePointerInfo & MPO)893 Align llvm::inferAlignFromPtrInfo(MachineFunction &MF,
894 const MachinePointerInfo &MPO) {
895 auto PSV = dyn_cast_if_present<const PseudoSourceValue *>(MPO.V);
896 if (auto FSPV = dyn_cast_or_null<FixedStackPseudoSourceValue>(PSV)) {
897 MachineFrameInfo &MFI = MF.getFrameInfo();
898 return commonAlignment(MFI.getObjectAlign(FSPV->getFrameIndex()),
899 MPO.Offset);
900 }
901
902 if (const Value *V = dyn_cast_if_present<const Value *>(MPO.V)) {
903 const Module *M = MF.getFunction().getParent();
904 return V->getPointerAlignment(M->getDataLayout());
905 }
906
907 return Align(1);
908 }
909
getFunctionLiveInPhysReg(MachineFunction & MF,const TargetInstrInfo & TII,MCRegister PhysReg,const TargetRegisterClass & RC,const DebugLoc & DL,LLT RegTy)910 Register llvm::getFunctionLiveInPhysReg(MachineFunction &MF,
911 const TargetInstrInfo &TII,
912 MCRegister PhysReg,
913 const TargetRegisterClass &RC,
914 const DebugLoc &DL, LLT RegTy) {
915 MachineBasicBlock &EntryMBB = MF.front();
916 MachineRegisterInfo &MRI = MF.getRegInfo();
917 Register LiveIn = MRI.getLiveInVirtReg(PhysReg);
918 if (LiveIn) {
919 MachineInstr *Def = MRI.getVRegDef(LiveIn);
920 if (Def) {
921 // FIXME: Should the verifier check this is in the entry block?
922 assert(Def->getParent() == &EntryMBB && "live-in copy not in entry block");
923 return LiveIn;
924 }
925
926 // It's possible the incoming argument register and copy was added during
927 // lowering, but later deleted due to being/becoming dead. If this happens,
928 // re-insert the copy.
929 } else {
930 // The live in register was not present, so add it.
931 LiveIn = MF.addLiveIn(PhysReg, &RC);
932 if (RegTy.isValid())
933 MRI.setType(LiveIn, RegTy);
934 }
935
936 BuildMI(EntryMBB, EntryMBB.begin(), DL, TII.get(TargetOpcode::COPY), LiveIn)
937 .addReg(PhysReg);
938 if (!EntryMBB.isLiveIn(PhysReg))
939 EntryMBB.addLiveIn(PhysReg);
940 return LiveIn;
941 }
942
ConstantFoldExtOp(unsigned Opcode,const Register Op1,uint64_t Imm,const MachineRegisterInfo & MRI)943 std::optional<APInt> llvm::ConstantFoldExtOp(unsigned Opcode,
944 const Register Op1, uint64_t Imm,
945 const MachineRegisterInfo &MRI) {
946 auto MaybeOp1Cst = getIConstantVRegVal(Op1, MRI);
947 if (MaybeOp1Cst) {
948 switch (Opcode) {
949 default:
950 break;
951 case TargetOpcode::G_SEXT_INREG: {
952 LLT Ty = MRI.getType(Op1);
953 return MaybeOp1Cst->trunc(Imm).sext(Ty.getScalarSizeInBits());
954 }
955 }
956 }
957 return std::nullopt;
958 }
959
ConstantFoldCastOp(unsigned Opcode,LLT DstTy,const Register Op0,const MachineRegisterInfo & MRI)960 std::optional<APInt> llvm::ConstantFoldCastOp(unsigned Opcode, LLT DstTy,
961 const Register Op0,
962 const MachineRegisterInfo &MRI) {
963 std::optional<APInt> Val = getIConstantVRegVal(Op0, MRI);
964 if (!Val)
965 return Val;
966
967 const unsigned DstSize = DstTy.getScalarSizeInBits();
968
969 switch (Opcode) {
970 case TargetOpcode::G_SEXT:
971 return Val->sext(DstSize);
972 case TargetOpcode::G_ZEXT:
973 case TargetOpcode::G_ANYEXT:
974 // TODO: DAG considers target preference when constant folding any_extend.
975 return Val->zext(DstSize);
976 default:
977 break;
978 }
979
980 llvm_unreachable("unexpected cast opcode to constant fold");
981 }
982
983 std::optional<APFloat>
ConstantFoldIntToFloat(unsigned Opcode,LLT DstTy,Register Src,const MachineRegisterInfo & MRI)984 llvm::ConstantFoldIntToFloat(unsigned Opcode, LLT DstTy, Register Src,
985 const MachineRegisterInfo &MRI) {
986 assert(Opcode == TargetOpcode::G_SITOFP || Opcode == TargetOpcode::G_UITOFP);
987 if (auto MaybeSrcVal = getIConstantVRegVal(Src, MRI)) {
988 APFloat DstVal(getFltSemanticForLLT(DstTy));
989 DstVal.convertFromAPInt(*MaybeSrcVal, Opcode == TargetOpcode::G_SITOFP,
990 APFloat::rmNearestTiesToEven);
991 return DstVal;
992 }
993 return std::nullopt;
994 }
995
996 std::optional<SmallVector<unsigned>>
ConstantFoldCountZeros(Register Src,const MachineRegisterInfo & MRI,std::function<unsigned (APInt)> CB)997 llvm::ConstantFoldCountZeros(Register Src, const MachineRegisterInfo &MRI,
998 std::function<unsigned(APInt)> CB) {
999 LLT Ty = MRI.getType(Src);
1000 SmallVector<unsigned> FoldedCTLZs;
1001 auto tryFoldScalar = [&](Register R) -> std::optional<unsigned> {
1002 auto MaybeCst = getIConstantVRegVal(R, MRI);
1003 if (!MaybeCst)
1004 return std::nullopt;
1005 return CB(*MaybeCst);
1006 };
1007 if (Ty.isVector()) {
1008 // Try to constant fold each element.
1009 auto *BV = getOpcodeDef<GBuildVector>(Src, MRI);
1010 if (!BV)
1011 return std::nullopt;
1012 for (unsigned SrcIdx = 0; SrcIdx < BV->getNumSources(); ++SrcIdx) {
1013 if (auto MaybeFold = tryFoldScalar(BV->getSourceReg(SrcIdx))) {
1014 FoldedCTLZs.emplace_back(*MaybeFold);
1015 continue;
1016 }
1017 return std::nullopt;
1018 }
1019 return FoldedCTLZs;
1020 }
1021 if (auto MaybeCst = tryFoldScalar(Src)) {
1022 FoldedCTLZs.emplace_back(*MaybeCst);
1023 return FoldedCTLZs;
1024 }
1025 return std::nullopt;
1026 }
1027
1028 std::optional<SmallVector<APInt>>
ConstantFoldICmp(unsigned Pred,const Register Op1,const Register Op2,unsigned DstScalarSizeInBits,unsigned ExtOp,const MachineRegisterInfo & MRI)1029 llvm::ConstantFoldICmp(unsigned Pred, const Register Op1, const Register Op2,
1030 unsigned DstScalarSizeInBits, unsigned ExtOp,
1031 const MachineRegisterInfo &MRI) {
1032 assert(ExtOp == TargetOpcode::G_SEXT || ExtOp == TargetOpcode::G_ZEXT ||
1033 ExtOp == TargetOpcode::G_ANYEXT);
1034
1035 const LLT Ty = MRI.getType(Op1);
1036
1037 auto GetICmpResultCst = [&](bool IsTrue) {
1038 if (IsTrue)
1039 return ExtOp == TargetOpcode::G_SEXT
1040 ? APInt::getAllOnes(DstScalarSizeInBits)
1041 : APInt::getOneBitSet(DstScalarSizeInBits, 0);
1042 return APInt::getZero(DstScalarSizeInBits);
1043 };
1044
1045 auto TryFoldScalar = [&](Register LHS, Register RHS) -> std::optional<APInt> {
1046 auto RHSCst = getIConstantVRegVal(RHS, MRI);
1047 if (!RHSCst)
1048 return std::nullopt;
1049 auto LHSCst = getIConstantVRegVal(LHS, MRI);
1050 if (!LHSCst)
1051 return std::nullopt;
1052
1053 switch (Pred) {
1054 case CmpInst::Predicate::ICMP_EQ:
1055 return GetICmpResultCst(LHSCst->eq(*RHSCst));
1056 case CmpInst::Predicate::ICMP_NE:
1057 return GetICmpResultCst(LHSCst->ne(*RHSCst));
1058 case CmpInst::Predicate::ICMP_UGT:
1059 return GetICmpResultCst(LHSCst->ugt(*RHSCst));
1060 case CmpInst::Predicate::ICMP_UGE:
1061 return GetICmpResultCst(LHSCst->uge(*RHSCst));
1062 case CmpInst::Predicate::ICMP_ULT:
1063 return GetICmpResultCst(LHSCst->ult(*RHSCst));
1064 case CmpInst::Predicate::ICMP_ULE:
1065 return GetICmpResultCst(LHSCst->ule(*RHSCst));
1066 case CmpInst::Predicate::ICMP_SGT:
1067 return GetICmpResultCst(LHSCst->sgt(*RHSCst));
1068 case CmpInst::Predicate::ICMP_SGE:
1069 return GetICmpResultCst(LHSCst->sge(*RHSCst));
1070 case CmpInst::Predicate::ICMP_SLT:
1071 return GetICmpResultCst(LHSCst->slt(*RHSCst));
1072 case CmpInst::Predicate::ICMP_SLE:
1073 return GetICmpResultCst(LHSCst->sle(*RHSCst));
1074 default:
1075 return std::nullopt;
1076 }
1077 };
1078
1079 SmallVector<APInt> FoldedICmps;
1080
1081 if (Ty.isVector()) {
1082 // Try to constant fold each element.
1083 auto *BV1 = getOpcodeDef<GBuildVector>(Op1, MRI);
1084 auto *BV2 = getOpcodeDef<GBuildVector>(Op2, MRI);
1085 if (!BV1 || !BV2)
1086 return std::nullopt;
1087 assert(BV1->getNumSources() == BV2->getNumSources() && "Invalid vectors");
1088 for (unsigned I = 0; I < BV1->getNumSources(); ++I) {
1089 if (auto MaybeFold =
1090 TryFoldScalar(BV1->getSourceReg(I), BV2->getSourceReg(I))) {
1091 FoldedICmps.emplace_back(*MaybeFold);
1092 continue;
1093 }
1094 return std::nullopt;
1095 }
1096 return FoldedICmps;
1097 }
1098
1099 if (auto MaybeCst = TryFoldScalar(Op1, Op2)) {
1100 FoldedICmps.emplace_back(*MaybeCst);
1101 return FoldedICmps;
1102 }
1103
1104 return std::nullopt;
1105 }
1106
isKnownToBeAPowerOfTwo(Register Reg,const MachineRegisterInfo & MRI,GISelValueTracking * VT)1107 bool llvm::isKnownToBeAPowerOfTwo(Register Reg, const MachineRegisterInfo &MRI,
1108 GISelValueTracking *VT) {
1109 std::optional<DefinitionAndSourceRegister> DefSrcReg =
1110 getDefSrcRegIgnoringCopies(Reg, MRI);
1111 if (!DefSrcReg)
1112 return false;
1113
1114 const MachineInstr &MI = *DefSrcReg->MI;
1115 const LLT Ty = MRI.getType(Reg);
1116
1117 switch (MI.getOpcode()) {
1118 case TargetOpcode::G_CONSTANT: {
1119 unsigned BitWidth = Ty.getScalarSizeInBits();
1120 const ConstantInt *CI = MI.getOperand(1).getCImm();
1121 return CI->getValue().zextOrTrunc(BitWidth).isPowerOf2();
1122 }
1123 case TargetOpcode::G_SHL: {
1124 // A left-shift of a constant one will have exactly one bit set because
1125 // shifting the bit off the end is undefined.
1126
1127 // TODO: Constant splat
1128 if (auto ConstLHS = getIConstantVRegVal(MI.getOperand(1).getReg(), MRI)) {
1129 if (*ConstLHS == 1)
1130 return true;
1131 }
1132
1133 break;
1134 }
1135 case TargetOpcode::G_LSHR: {
1136 if (auto ConstLHS = getIConstantVRegVal(MI.getOperand(1).getReg(), MRI)) {
1137 if (ConstLHS->isSignMask())
1138 return true;
1139 }
1140
1141 break;
1142 }
1143 case TargetOpcode::G_BUILD_VECTOR: {
1144 // TODO: Probably should have a recursion depth guard since you could have
1145 // bitcasted vector elements.
1146 for (const MachineOperand &MO : llvm::drop_begin(MI.operands()))
1147 if (!isKnownToBeAPowerOfTwo(MO.getReg(), MRI, VT))
1148 return false;
1149
1150 return true;
1151 }
1152 case TargetOpcode::G_BUILD_VECTOR_TRUNC: {
1153 // Only handle constants since we would need to know if number of leading
1154 // zeros is greater than the truncation amount.
1155 const unsigned BitWidth = Ty.getScalarSizeInBits();
1156 for (const MachineOperand &MO : llvm::drop_begin(MI.operands())) {
1157 auto Const = getIConstantVRegVal(MO.getReg(), MRI);
1158 if (!Const || !Const->zextOrTrunc(BitWidth).isPowerOf2())
1159 return false;
1160 }
1161
1162 return true;
1163 }
1164 default:
1165 break;
1166 }
1167
1168 if (!VT)
1169 return false;
1170
1171 // More could be done here, though the above checks are enough
1172 // to handle some common cases.
1173
1174 // Fall back to computeKnownBits to catch other known cases.
1175 KnownBits Known = VT->getKnownBits(Reg);
1176 return (Known.countMaxPopulation() == 1) && (Known.countMinPopulation() == 1);
1177 }
1178
getSelectionDAGFallbackAnalysisUsage(AnalysisUsage & AU)1179 void llvm::getSelectionDAGFallbackAnalysisUsage(AnalysisUsage &AU) {
1180 AU.addPreserved<StackProtector>();
1181 }
1182
getLCMType(LLT OrigTy,LLT TargetTy)1183 LLT llvm::getLCMType(LLT OrigTy, LLT TargetTy) {
1184 if (OrigTy.getSizeInBits() == TargetTy.getSizeInBits())
1185 return OrigTy;
1186
1187 if (OrigTy.isVector() && TargetTy.isVector()) {
1188 LLT OrigElt = OrigTy.getElementType();
1189 LLT TargetElt = TargetTy.getElementType();
1190
1191 // TODO: The docstring for this function says the intention is to use this
1192 // function to build MERGE/UNMERGE instructions. It won't be the case that
1193 // we generate a MERGE/UNMERGE between fixed and scalable vector types. We
1194 // could implement getLCMType between the two in the future if there was a
1195 // need, but it is not worth it now as this function should not be used in
1196 // that way.
1197 assert(((OrigTy.isScalableVector() && !TargetTy.isFixedVector()) ||
1198 (OrigTy.isFixedVector() && !TargetTy.isScalableVector())) &&
1199 "getLCMType not implemented between fixed and scalable vectors.");
1200
1201 if (OrigElt.getSizeInBits() == TargetElt.getSizeInBits()) {
1202 int GCDMinElts = std::gcd(OrigTy.getElementCount().getKnownMinValue(),
1203 TargetTy.getElementCount().getKnownMinValue());
1204 // Prefer the original element type.
1205 ElementCount Mul = OrigTy.getElementCount().multiplyCoefficientBy(
1206 TargetTy.getElementCount().getKnownMinValue());
1207 return LLT::vector(Mul.divideCoefficientBy(GCDMinElts),
1208 OrigTy.getElementType());
1209 }
1210 unsigned LCM = std::lcm(OrigTy.getSizeInBits().getKnownMinValue(),
1211 TargetTy.getSizeInBits().getKnownMinValue());
1212 return LLT::vector(
1213 ElementCount::get(LCM / OrigElt.getSizeInBits(), OrigTy.isScalable()),
1214 OrigElt);
1215 }
1216
1217 // One type is scalar, one type is vector
1218 if (OrigTy.isVector() || TargetTy.isVector()) {
1219 LLT VecTy = OrigTy.isVector() ? OrigTy : TargetTy;
1220 LLT ScalarTy = OrigTy.isVector() ? TargetTy : OrigTy;
1221 LLT EltTy = VecTy.getElementType();
1222 LLT OrigEltTy = OrigTy.isVector() ? OrigTy.getElementType() : OrigTy;
1223
1224 // Prefer scalar type from OrigTy.
1225 if (EltTy.getSizeInBits() == ScalarTy.getSizeInBits())
1226 return LLT::vector(VecTy.getElementCount(), OrigEltTy);
1227
1228 // Different size scalars. Create vector with the same total size.
1229 // LCM will take fixed/scalable from VecTy.
1230 unsigned LCM = std::lcm(EltTy.getSizeInBits().getFixedValue() *
1231 VecTy.getElementCount().getKnownMinValue(),
1232 ScalarTy.getSizeInBits().getFixedValue());
1233 // Prefer type from OrigTy
1234 return LLT::vector(ElementCount::get(LCM / OrigEltTy.getSizeInBits(),
1235 VecTy.getElementCount().isScalable()),
1236 OrigEltTy);
1237 }
1238
1239 // At this point, both types are scalars of different size
1240 unsigned LCM = std::lcm(OrigTy.getSizeInBits().getFixedValue(),
1241 TargetTy.getSizeInBits().getFixedValue());
1242 // Preserve pointer types.
1243 if (LCM == OrigTy.getSizeInBits())
1244 return OrigTy;
1245 if (LCM == TargetTy.getSizeInBits())
1246 return TargetTy;
1247 return LLT::scalar(LCM);
1248 }
1249
getCoverTy(LLT OrigTy,LLT TargetTy)1250 LLT llvm::getCoverTy(LLT OrigTy, LLT TargetTy) {
1251
1252 if ((OrigTy.isScalableVector() && TargetTy.isFixedVector()) ||
1253 (OrigTy.isFixedVector() && TargetTy.isScalableVector()))
1254 llvm_unreachable(
1255 "getCoverTy not implemented between fixed and scalable vectors.");
1256
1257 if (!OrigTy.isVector() || !TargetTy.isVector() || OrigTy == TargetTy ||
1258 (OrigTy.getScalarSizeInBits() != TargetTy.getScalarSizeInBits()))
1259 return getLCMType(OrigTy, TargetTy);
1260
1261 unsigned OrigTyNumElts = OrigTy.getElementCount().getKnownMinValue();
1262 unsigned TargetTyNumElts = TargetTy.getElementCount().getKnownMinValue();
1263 if (OrigTyNumElts % TargetTyNumElts == 0)
1264 return OrigTy;
1265
1266 unsigned NumElts = alignTo(OrigTyNumElts, TargetTyNumElts);
1267 return LLT::scalarOrVector(ElementCount::getFixed(NumElts),
1268 OrigTy.getElementType());
1269 }
1270
getGCDType(LLT OrigTy,LLT TargetTy)1271 LLT llvm::getGCDType(LLT OrigTy, LLT TargetTy) {
1272 if (OrigTy.getSizeInBits() == TargetTy.getSizeInBits())
1273 return OrigTy;
1274
1275 if (OrigTy.isVector() && TargetTy.isVector()) {
1276 LLT OrigElt = OrigTy.getElementType();
1277
1278 // TODO: The docstring for this function says the intention is to use this
1279 // function to build MERGE/UNMERGE instructions. It won't be the case that
1280 // we generate a MERGE/UNMERGE between fixed and scalable vector types. We
1281 // could implement getGCDType between the two in the future if there was a
1282 // need, but it is not worth it now as this function should not be used in
1283 // that way.
1284 assert(((OrigTy.isScalableVector() && !TargetTy.isFixedVector()) ||
1285 (OrigTy.isFixedVector() && !TargetTy.isScalableVector())) &&
1286 "getGCDType not implemented between fixed and scalable vectors.");
1287
1288 unsigned GCD = std::gcd(OrigTy.getSizeInBits().getKnownMinValue(),
1289 TargetTy.getSizeInBits().getKnownMinValue());
1290 if (GCD == OrigElt.getSizeInBits())
1291 return LLT::scalarOrVector(ElementCount::get(1, OrigTy.isScalable()),
1292 OrigElt);
1293
1294 // Cannot produce original element type, but both have vscale in common.
1295 if (GCD < OrigElt.getSizeInBits())
1296 return LLT::scalarOrVector(ElementCount::get(1, OrigTy.isScalable()),
1297 GCD);
1298
1299 return LLT::vector(
1300 ElementCount::get(GCD / OrigElt.getSizeInBits().getFixedValue(),
1301 OrigTy.isScalable()),
1302 OrigElt);
1303 }
1304
1305 // If one type is vector and the element size matches the scalar size, then
1306 // the gcd is the scalar type.
1307 if (OrigTy.isVector() &&
1308 OrigTy.getElementType().getSizeInBits() == TargetTy.getSizeInBits())
1309 return OrigTy.getElementType();
1310 if (TargetTy.isVector() &&
1311 TargetTy.getElementType().getSizeInBits() == OrigTy.getSizeInBits())
1312 return OrigTy;
1313
1314 // At this point, both types are either scalars of different type or one is a
1315 // vector and one is a scalar. If both types are scalars, the GCD type is the
1316 // GCD between the two scalar sizes. If one is vector and one is scalar, then
1317 // the GCD type is the GCD between the scalar and the vector element size.
1318 LLT OrigScalar = OrigTy.getScalarType();
1319 LLT TargetScalar = TargetTy.getScalarType();
1320 unsigned GCD = std::gcd(OrigScalar.getSizeInBits().getFixedValue(),
1321 TargetScalar.getSizeInBits().getFixedValue());
1322 return LLT::scalar(GCD);
1323 }
1324
getSplatIndex(MachineInstr & MI)1325 std::optional<int> llvm::getSplatIndex(MachineInstr &MI) {
1326 assert(MI.getOpcode() == TargetOpcode::G_SHUFFLE_VECTOR &&
1327 "Only G_SHUFFLE_VECTOR can have a splat index!");
1328 ArrayRef<int> Mask = MI.getOperand(3).getShuffleMask();
1329 auto FirstDefinedIdx = find_if(Mask, [](int Elt) { return Elt >= 0; });
1330
1331 // If all elements are undefined, this shuffle can be considered a splat.
1332 // Return 0 for better potential for callers to simplify.
1333 if (FirstDefinedIdx == Mask.end())
1334 return 0;
1335
1336 // Make sure all remaining elements are either undef or the same
1337 // as the first non-undef value.
1338 int SplatValue = *FirstDefinedIdx;
1339 if (any_of(make_range(std::next(FirstDefinedIdx), Mask.end()),
1340 [&SplatValue](int Elt) { return Elt >= 0 && Elt != SplatValue; }))
1341 return std::nullopt;
1342
1343 return SplatValue;
1344 }
1345
isBuildVectorOp(unsigned Opcode)1346 static bool isBuildVectorOp(unsigned Opcode) {
1347 return Opcode == TargetOpcode::G_BUILD_VECTOR ||
1348 Opcode == TargetOpcode::G_BUILD_VECTOR_TRUNC;
1349 }
1350
1351 namespace {
1352
getAnyConstantSplat(Register VReg,const MachineRegisterInfo & MRI,bool AllowUndef)1353 std::optional<ValueAndVReg> getAnyConstantSplat(Register VReg,
1354 const MachineRegisterInfo &MRI,
1355 bool AllowUndef) {
1356 MachineInstr *MI = getDefIgnoringCopies(VReg, MRI);
1357 if (!MI)
1358 return std::nullopt;
1359
1360 bool isConcatVectorsOp = MI->getOpcode() == TargetOpcode::G_CONCAT_VECTORS;
1361 if (!isBuildVectorOp(MI->getOpcode()) && !isConcatVectorsOp)
1362 return std::nullopt;
1363
1364 std::optional<ValueAndVReg> SplatValAndReg;
1365 for (MachineOperand &Op : MI->uses()) {
1366 Register Element = Op.getReg();
1367 // If we have a G_CONCAT_VECTOR, we recursively look into the
1368 // vectors that we're concatenating to see if they're splats.
1369 auto ElementValAndReg =
1370 isConcatVectorsOp
1371 ? getAnyConstantSplat(Element, MRI, AllowUndef)
1372 : getAnyConstantVRegValWithLookThrough(Element, MRI, true, true);
1373
1374 // If AllowUndef, treat undef as value that will result in a constant splat.
1375 if (!ElementValAndReg) {
1376 if (AllowUndef && isa<GImplicitDef>(MRI.getVRegDef(Element)))
1377 continue;
1378 return std::nullopt;
1379 }
1380
1381 // Record splat value
1382 if (!SplatValAndReg)
1383 SplatValAndReg = ElementValAndReg;
1384
1385 // Different constant than the one already recorded, not a constant splat.
1386 if (SplatValAndReg->Value != ElementValAndReg->Value)
1387 return std::nullopt;
1388 }
1389
1390 return SplatValAndReg;
1391 }
1392
1393 } // end anonymous namespace
1394
isBuildVectorConstantSplat(const Register Reg,const MachineRegisterInfo & MRI,int64_t SplatValue,bool AllowUndef)1395 bool llvm::isBuildVectorConstantSplat(const Register Reg,
1396 const MachineRegisterInfo &MRI,
1397 int64_t SplatValue, bool AllowUndef) {
1398 if (auto SplatValAndReg = getAnyConstantSplat(Reg, MRI, AllowUndef))
1399 return SplatValAndReg->Value.getSExtValue() == SplatValue;
1400
1401 return false;
1402 }
1403
isBuildVectorConstantSplat(const MachineInstr & MI,const MachineRegisterInfo & MRI,int64_t SplatValue,bool AllowUndef)1404 bool llvm::isBuildVectorConstantSplat(const MachineInstr &MI,
1405 const MachineRegisterInfo &MRI,
1406 int64_t SplatValue, bool AllowUndef) {
1407 return isBuildVectorConstantSplat(MI.getOperand(0).getReg(), MRI, SplatValue,
1408 AllowUndef);
1409 }
1410
1411 std::optional<APInt>
getIConstantSplatVal(const Register Reg,const MachineRegisterInfo & MRI)1412 llvm::getIConstantSplatVal(const Register Reg, const MachineRegisterInfo &MRI) {
1413 if (auto SplatValAndReg =
1414 getAnyConstantSplat(Reg, MRI, /* AllowUndef */ false)) {
1415 if (std::optional<ValueAndVReg> ValAndVReg =
1416 getIConstantVRegValWithLookThrough(SplatValAndReg->VReg, MRI))
1417 return ValAndVReg->Value;
1418 }
1419
1420 return std::nullopt;
1421 }
1422
1423 std::optional<APInt>
getIConstantSplatVal(const MachineInstr & MI,const MachineRegisterInfo & MRI)1424 llvm::getIConstantSplatVal(const MachineInstr &MI,
1425 const MachineRegisterInfo &MRI) {
1426 return getIConstantSplatVal(MI.getOperand(0).getReg(), MRI);
1427 }
1428
1429 std::optional<int64_t>
getIConstantSplatSExtVal(const Register Reg,const MachineRegisterInfo & MRI)1430 llvm::getIConstantSplatSExtVal(const Register Reg,
1431 const MachineRegisterInfo &MRI) {
1432 if (auto SplatValAndReg =
1433 getAnyConstantSplat(Reg, MRI, /* AllowUndef */ false))
1434 return getIConstantVRegSExtVal(SplatValAndReg->VReg, MRI);
1435 return std::nullopt;
1436 }
1437
1438 std::optional<int64_t>
getIConstantSplatSExtVal(const MachineInstr & MI,const MachineRegisterInfo & MRI)1439 llvm::getIConstantSplatSExtVal(const MachineInstr &MI,
1440 const MachineRegisterInfo &MRI) {
1441 return getIConstantSplatSExtVal(MI.getOperand(0).getReg(), MRI);
1442 }
1443
1444 std::optional<FPValueAndVReg>
getFConstantSplat(Register VReg,const MachineRegisterInfo & MRI,bool AllowUndef)1445 llvm::getFConstantSplat(Register VReg, const MachineRegisterInfo &MRI,
1446 bool AllowUndef) {
1447 if (auto SplatValAndReg = getAnyConstantSplat(VReg, MRI, AllowUndef))
1448 return getFConstantVRegValWithLookThrough(SplatValAndReg->VReg, MRI);
1449 return std::nullopt;
1450 }
1451
isBuildVectorAllZeros(const MachineInstr & MI,const MachineRegisterInfo & MRI,bool AllowUndef)1452 bool llvm::isBuildVectorAllZeros(const MachineInstr &MI,
1453 const MachineRegisterInfo &MRI,
1454 bool AllowUndef) {
1455 return isBuildVectorConstantSplat(MI, MRI, 0, AllowUndef);
1456 }
1457
isBuildVectorAllOnes(const MachineInstr & MI,const MachineRegisterInfo & MRI,bool AllowUndef)1458 bool llvm::isBuildVectorAllOnes(const MachineInstr &MI,
1459 const MachineRegisterInfo &MRI,
1460 bool AllowUndef) {
1461 return isBuildVectorConstantSplat(MI, MRI, -1, AllowUndef);
1462 }
1463
1464 std::optional<RegOrConstant>
getVectorSplat(const MachineInstr & MI,const MachineRegisterInfo & MRI)1465 llvm::getVectorSplat(const MachineInstr &MI, const MachineRegisterInfo &MRI) {
1466 unsigned Opc = MI.getOpcode();
1467 if (!isBuildVectorOp(Opc))
1468 return std::nullopt;
1469 if (auto Splat = getIConstantSplatSExtVal(MI, MRI))
1470 return RegOrConstant(*Splat);
1471 auto Reg = MI.getOperand(1).getReg();
1472 if (any_of(drop_begin(MI.operands(), 2),
1473 [&Reg](const MachineOperand &Op) { return Op.getReg() != Reg; }))
1474 return std::nullopt;
1475 return RegOrConstant(Reg);
1476 }
1477
isConstantScalar(const MachineInstr & MI,const MachineRegisterInfo & MRI,bool AllowFP=true,bool AllowOpaqueConstants=true)1478 static bool isConstantScalar(const MachineInstr &MI,
1479 const MachineRegisterInfo &MRI,
1480 bool AllowFP = true,
1481 bool AllowOpaqueConstants = true) {
1482 switch (MI.getOpcode()) {
1483 case TargetOpcode::G_CONSTANT:
1484 case TargetOpcode::G_IMPLICIT_DEF:
1485 return true;
1486 case TargetOpcode::G_FCONSTANT:
1487 return AllowFP;
1488 case TargetOpcode::G_GLOBAL_VALUE:
1489 case TargetOpcode::G_FRAME_INDEX:
1490 case TargetOpcode::G_BLOCK_ADDR:
1491 case TargetOpcode::G_JUMP_TABLE:
1492 return AllowOpaqueConstants;
1493 default:
1494 return false;
1495 }
1496 }
1497
isConstantOrConstantVector(MachineInstr & MI,const MachineRegisterInfo & MRI)1498 bool llvm::isConstantOrConstantVector(MachineInstr &MI,
1499 const MachineRegisterInfo &MRI) {
1500 Register Def = MI.getOperand(0).getReg();
1501 if (auto C = getIConstantVRegValWithLookThrough(Def, MRI))
1502 return true;
1503 GBuildVector *BV = dyn_cast<GBuildVector>(&MI);
1504 if (!BV)
1505 return false;
1506 for (unsigned SrcIdx = 0; SrcIdx < BV->getNumSources(); ++SrcIdx) {
1507 if (getIConstantVRegValWithLookThrough(BV->getSourceReg(SrcIdx), MRI) ||
1508 getOpcodeDef<GImplicitDef>(BV->getSourceReg(SrcIdx), MRI))
1509 continue;
1510 return false;
1511 }
1512 return true;
1513 }
1514
isConstantOrConstantVector(const MachineInstr & MI,const MachineRegisterInfo & MRI,bool AllowFP,bool AllowOpaqueConstants)1515 bool llvm::isConstantOrConstantVector(const MachineInstr &MI,
1516 const MachineRegisterInfo &MRI,
1517 bool AllowFP, bool AllowOpaqueConstants) {
1518 if (isConstantScalar(MI, MRI, AllowFP, AllowOpaqueConstants))
1519 return true;
1520
1521 if (!isBuildVectorOp(MI.getOpcode()))
1522 return false;
1523
1524 const unsigned NumOps = MI.getNumOperands();
1525 for (unsigned I = 1; I != NumOps; ++I) {
1526 const MachineInstr *ElementDef = MRI.getVRegDef(MI.getOperand(I).getReg());
1527 if (!isConstantScalar(*ElementDef, MRI, AllowFP, AllowOpaqueConstants))
1528 return false;
1529 }
1530
1531 return true;
1532 }
1533
1534 std::optional<APInt>
isConstantOrConstantSplatVector(MachineInstr & MI,const MachineRegisterInfo & MRI)1535 llvm::isConstantOrConstantSplatVector(MachineInstr &MI,
1536 const MachineRegisterInfo &MRI) {
1537 Register Def = MI.getOperand(0).getReg();
1538 if (auto C = getIConstantVRegValWithLookThrough(Def, MRI))
1539 return C->Value;
1540 auto MaybeCst = getIConstantSplatSExtVal(MI, MRI);
1541 if (!MaybeCst)
1542 return std::nullopt;
1543 const unsigned ScalarSize = MRI.getType(Def).getScalarSizeInBits();
1544 return APInt(ScalarSize, *MaybeCst, true);
1545 }
1546
1547 std::optional<APFloat>
isConstantOrConstantSplatVectorFP(MachineInstr & MI,const MachineRegisterInfo & MRI)1548 llvm::isConstantOrConstantSplatVectorFP(MachineInstr &MI,
1549 const MachineRegisterInfo &MRI) {
1550 Register Def = MI.getOperand(0).getReg();
1551 if (auto FpConst = getFConstantVRegValWithLookThrough(Def, MRI))
1552 return FpConst->Value;
1553 auto MaybeCstFP = getFConstantSplat(Def, MRI, /*allowUndef=*/false);
1554 if (!MaybeCstFP)
1555 return std::nullopt;
1556 return MaybeCstFP->Value;
1557 }
1558
isNullOrNullSplat(const MachineInstr & MI,const MachineRegisterInfo & MRI,bool AllowUndefs)1559 bool llvm::isNullOrNullSplat(const MachineInstr &MI,
1560 const MachineRegisterInfo &MRI, bool AllowUndefs) {
1561 switch (MI.getOpcode()) {
1562 case TargetOpcode::G_IMPLICIT_DEF:
1563 return AllowUndefs;
1564 case TargetOpcode::G_CONSTANT:
1565 return MI.getOperand(1).getCImm()->isNullValue();
1566 case TargetOpcode::G_FCONSTANT: {
1567 const ConstantFP *FPImm = MI.getOperand(1).getFPImm();
1568 return FPImm->isZero() && !FPImm->isNegative();
1569 }
1570 default:
1571 if (!AllowUndefs) // TODO: isBuildVectorAllZeros assumes undef is OK already
1572 return false;
1573 return isBuildVectorAllZeros(MI, MRI);
1574 }
1575 }
1576
isAllOnesOrAllOnesSplat(const MachineInstr & MI,const MachineRegisterInfo & MRI,bool AllowUndefs)1577 bool llvm::isAllOnesOrAllOnesSplat(const MachineInstr &MI,
1578 const MachineRegisterInfo &MRI,
1579 bool AllowUndefs) {
1580 switch (MI.getOpcode()) {
1581 case TargetOpcode::G_IMPLICIT_DEF:
1582 return AllowUndefs;
1583 case TargetOpcode::G_CONSTANT:
1584 return MI.getOperand(1).getCImm()->isAllOnesValue();
1585 default:
1586 if (!AllowUndefs) // TODO: isBuildVectorAllOnes assumes undef is OK already
1587 return false;
1588 return isBuildVectorAllOnes(MI, MRI);
1589 }
1590 }
1591
matchUnaryPredicate(const MachineRegisterInfo & MRI,Register Reg,std::function<bool (const Constant * ConstVal)> Match,bool AllowUndefs)1592 bool llvm::matchUnaryPredicate(
1593 const MachineRegisterInfo &MRI, Register Reg,
1594 std::function<bool(const Constant *ConstVal)> Match, bool AllowUndefs) {
1595
1596 const MachineInstr *Def = getDefIgnoringCopies(Reg, MRI);
1597 if (AllowUndefs && Def->getOpcode() == TargetOpcode::G_IMPLICIT_DEF)
1598 return Match(nullptr);
1599
1600 // TODO: Also handle fconstant
1601 if (Def->getOpcode() == TargetOpcode::G_CONSTANT)
1602 return Match(Def->getOperand(1).getCImm());
1603
1604 if (Def->getOpcode() != TargetOpcode::G_BUILD_VECTOR)
1605 return false;
1606
1607 for (unsigned I = 1, E = Def->getNumOperands(); I != E; ++I) {
1608 Register SrcElt = Def->getOperand(I).getReg();
1609 const MachineInstr *SrcDef = getDefIgnoringCopies(SrcElt, MRI);
1610 if (AllowUndefs && SrcDef->getOpcode() == TargetOpcode::G_IMPLICIT_DEF) {
1611 if (!Match(nullptr))
1612 return false;
1613 continue;
1614 }
1615
1616 if (SrcDef->getOpcode() != TargetOpcode::G_CONSTANT ||
1617 !Match(SrcDef->getOperand(1).getCImm()))
1618 return false;
1619 }
1620
1621 return true;
1622 }
1623
isConstTrueVal(const TargetLowering & TLI,int64_t Val,bool IsVector,bool IsFP)1624 bool llvm::isConstTrueVal(const TargetLowering &TLI, int64_t Val, bool IsVector,
1625 bool IsFP) {
1626 switch (TLI.getBooleanContents(IsVector, IsFP)) {
1627 case TargetLowering::UndefinedBooleanContent:
1628 return Val & 0x1;
1629 case TargetLowering::ZeroOrOneBooleanContent:
1630 return Val == 1;
1631 case TargetLowering::ZeroOrNegativeOneBooleanContent:
1632 return Val == -1;
1633 }
1634 llvm_unreachable("Invalid boolean contents");
1635 }
1636
isConstFalseVal(const TargetLowering & TLI,int64_t Val,bool IsVector,bool IsFP)1637 bool llvm::isConstFalseVal(const TargetLowering &TLI, int64_t Val,
1638 bool IsVector, bool IsFP) {
1639 switch (TLI.getBooleanContents(IsVector, IsFP)) {
1640 case TargetLowering::UndefinedBooleanContent:
1641 return ~Val & 0x1;
1642 case TargetLowering::ZeroOrOneBooleanContent:
1643 case TargetLowering::ZeroOrNegativeOneBooleanContent:
1644 return Val == 0;
1645 }
1646 llvm_unreachable("Invalid boolean contents");
1647 }
1648
getICmpTrueVal(const TargetLowering & TLI,bool IsVector,bool IsFP)1649 int64_t llvm::getICmpTrueVal(const TargetLowering &TLI, bool IsVector,
1650 bool IsFP) {
1651 switch (TLI.getBooleanContents(IsVector, IsFP)) {
1652 case TargetLowering::UndefinedBooleanContent:
1653 case TargetLowering::ZeroOrOneBooleanContent:
1654 return 1;
1655 case TargetLowering::ZeroOrNegativeOneBooleanContent:
1656 return -1;
1657 }
1658 llvm_unreachable("Invalid boolean contents");
1659 }
1660
saveUsesAndErase(MachineInstr & MI,MachineRegisterInfo & MRI,LostDebugLocObserver * LocObserver,SmallInstListTy & DeadInstChain)1661 void llvm::saveUsesAndErase(MachineInstr &MI, MachineRegisterInfo &MRI,
1662 LostDebugLocObserver *LocObserver,
1663 SmallInstListTy &DeadInstChain) {
1664 for (MachineOperand &Op : MI.uses()) {
1665 if (Op.isReg() && Op.getReg().isVirtual())
1666 DeadInstChain.insert(MRI.getVRegDef(Op.getReg()));
1667 }
1668 LLVM_DEBUG(dbgs() << MI << "Is dead; erasing.\n");
1669 DeadInstChain.remove(&MI);
1670 MI.eraseFromParent();
1671 if (LocObserver)
1672 LocObserver->checkpoint(false);
1673 }
1674
eraseInstrs(ArrayRef<MachineInstr * > DeadInstrs,MachineRegisterInfo & MRI,LostDebugLocObserver * LocObserver)1675 void llvm::eraseInstrs(ArrayRef<MachineInstr *> DeadInstrs,
1676 MachineRegisterInfo &MRI,
1677 LostDebugLocObserver *LocObserver) {
1678 SmallInstListTy DeadInstChain;
1679 for (MachineInstr *MI : DeadInstrs)
1680 saveUsesAndErase(*MI, MRI, LocObserver, DeadInstChain);
1681
1682 while (!DeadInstChain.empty()) {
1683 MachineInstr *Inst = DeadInstChain.pop_back_val();
1684 if (!isTriviallyDead(*Inst, MRI))
1685 continue;
1686 saveUsesAndErase(*Inst, MRI, LocObserver, DeadInstChain);
1687 }
1688 }
1689
eraseInstr(MachineInstr & MI,MachineRegisterInfo & MRI,LostDebugLocObserver * LocObserver)1690 void llvm::eraseInstr(MachineInstr &MI, MachineRegisterInfo &MRI,
1691 LostDebugLocObserver *LocObserver) {
1692 return eraseInstrs({&MI}, MRI, LocObserver);
1693 }
1694
salvageDebugInfo(const MachineRegisterInfo & MRI,MachineInstr & MI)1695 void llvm::salvageDebugInfo(const MachineRegisterInfo &MRI, MachineInstr &MI) {
1696 for (auto &Def : MI.defs()) {
1697 assert(Def.isReg() && "Must be a reg");
1698
1699 SmallVector<MachineOperand *, 16> DbgUsers;
1700 for (auto &MOUse : MRI.use_operands(Def.getReg())) {
1701 MachineInstr *DbgValue = MOUse.getParent();
1702 // Ignore partially formed DBG_VALUEs.
1703 if (DbgValue->isNonListDebugValue() && DbgValue->getNumOperands() == 4) {
1704 DbgUsers.push_back(&MOUse);
1705 }
1706 }
1707
1708 if (!DbgUsers.empty()) {
1709 salvageDebugInfoForDbgValue(MRI, MI, DbgUsers);
1710 }
1711 }
1712 }
1713
isPreISelGenericFloatingPointOpcode(unsigned Opc)1714 bool llvm::isPreISelGenericFloatingPointOpcode(unsigned Opc) {
1715 switch (Opc) {
1716 case TargetOpcode::G_FABS:
1717 case TargetOpcode::G_FADD:
1718 case TargetOpcode::G_FCANONICALIZE:
1719 case TargetOpcode::G_FCEIL:
1720 case TargetOpcode::G_FCONSTANT:
1721 case TargetOpcode::G_FCOPYSIGN:
1722 case TargetOpcode::G_FCOS:
1723 case TargetOpcode::G_FDIV:
1724 case TargetOpcode::G_FEXP2:
1725 case TargetOpcode::G_FEXP:
1726 case TargetOpcode::G_FFLOOR:
1727 case TargetOpcode::G_FLOG10:
1728 case TargetOpcode::G_FLOG2:
1729 case TargetOpcode::G_FLOG:
1730 case TargetOpcode::G_FMA:
1731 case TargetOpcode::G_FMAD:
1732 case TargetOpcode::G_FMAXIMUM:
1733 case TargetOpcode::G_FMAXNUM:
1734 case TargetOpcode::G_FMAXNUM_IEEE:
1735 case TargetOpcode::G_FMINIMUM:
1736 case TargetOpcode::G_FMINNUM:
1737 case TargetOpcode::G_FMINNUM_IEEE:
1738 case TargetOpcode::G_FMUL:
1739 case TargetOpcode::G_FNEARBYINT:
1740 case TargetOpcode::G_FNEG:
1741 case TargetOpcode::G_FPEXT:
1742 case TargetOpcode::G_FPOW:
1743 case TargetOpcode::G_FPTRUNC:
1744 case TargetOpcode::G_FREM:
1745 case TargetOpcode::G_FRINT:
1746 case TargetOpcode::G_FSIN:
1747 case TargetOpcode::G_FTAN:
1748 case TargetOpcode::G_FACOS:
1749 case TargetOpcode::G_FASIN:
1750 case TargetOpcode::G_FATAN:
1751 case TargetOpcode::G_FATAN2:
1752 case TargetOpcode::G_FCOSH:
1753 case TargetOpcode::G_FSINH:
1754 case TargetOpcode::G_FTANH:
1755 case TargetOpcode::G_FSQRT:
1756 case TargetOpcode::G_FSUB:
1757 case TargetOpcode::G_INTRINSIC_ROUND:
1758 case TargetOpcode::G_INTRINSIC_ROUNDEVEN:
1759 case TargetOpcode::G_INTRINSIC_TRUNC:
1760 return true;
1761 default:
1762 return false;
1763 }
1764 }
1765
1766 /// Shifts return poison if shiftwidth is larger than the bitwidth.
shiftAmountKnownInRange(Register ShiftAmount,const MachineRegisterInfo & MRI)1767 static bool shiftAmountKnownInRange(Register ShiftAmount,
1768 const MachineRegisterInfo &MRI) {
1769 LLT Ty = MRI.getType(ShiftAmount);
1770
1771 if (Ty.isScalableVector())
1772 return false; // Can't tell, just return false to be safe
1773
1774 if (Ty.isScalar()) {
1775 std::optional<ValueAndVReg> Val =
1776 getIConstantVRegValWithLookThrough(ShiftAmount, MRI);
1777 if (!Val)
1778 return false;
1779 return Val->Value.ult(Ty.getScalarSizeInBits());
1780 }
1781
1782 GBuildVector *BV = getOpcodeDef<GBuildVector>(ShiftAmount, MRI);
1783 if (!BV)
1784 return false;
1785
1786 unsigned Sources = BV->getNumSources();
1787 for (unsigned I = 0; I < Sources; ++I) {
1788 std::optional<ValueAndVReg> Val =
1789 getIConstantVRegValWithLookThrough(BV->getSourceReg(I), MRI);
1790 if (!Val)
1791 return false;
1792 if (!Val->Value.ult(Ty.getScalarSizeInBits()))
1793 return false;
1794 }
1795
1796 return true;
1797 }
1798
1799 namespace {
1800 enum class UndefPoisonKind {
1801 PoisonOnly = (1 << 0),
1802 UndefOnly = (1 << 1),
1803 UndefOrPoison = PoisonOnly | UndefOnly,
1804 };
1805 }
1806
includesPoison(UndefPoisonKind Kind)1807 static bool includesPoison(UndefPoisonKind Kind) {
1808 return (unsigned(Kind) & unsigned(UndefPoisonKind::PoisonOnly)) != 0;
1809 }
1810
includesUndef(UndefPoisonKind Kind)1811 static bool includesUndef(UndefPoisonKind Kind) {
1812 return (unsigned(Kind) & unsigned(UndefPoisonKind::UndefOnly)) != 0;
1813 }
1814
canCreateUndefOrPoison(Register Reg,const MachineRegisterInfo & MRI,bool ConsiderFlagsAndMetadata,UndefPoisonKind Kind)1815 static bool canCreateUndefOrPoison(Register Reg, const MachineRegisterInfo &MRI,
1816 bool ConsiderFlagsAndMetadata,
1817 UndefPoisonKind Kind) {
1818 MachineInstr *RegDef = MRI.getVRegDef(Reg);
1819
1820 if (ConsiderFlagsAndMetadata && includesPoison(Kind))
1821 if (auto *GMI = dyn_cast<GenericMachineInstr>(RegDef))
1822 if (GMI->hasPoisonGeneratingFlags())
1823 return true;
1824
1825 // Check whether opcode is a poison/undef-generating operation.
1826 switch (RegDef->getOpcode()) {
1827 case TargetOpcode::G_BUILD_VECTOR:
1828 case TargetOpcode::G_CONSTANT_FOLD_BARRIER:
1829 return false;
1830 case TargetOpcode::G_SHL:
1831 case TargetOpcode::G_ASHR:
1832 case TargetOpcode::G_LSHR:
1833 return includesPoison(Kind) &&
1834 !shiftAmountKnownInRange(RegDef->getOperand(2).getReg(), MRI);
1835 case TargetOpcode::G_FPTOSI:
1836 case TargetOpcode::G_FPTOUI:
1837 // fptosi/ui yields poison if the resulting value does not fit in the
1838 // destination type.
1839 return true;
1840 case TargetOpcode::G_CTLZ:
1841 case TargetOpcode::G_CTTZ:
1842 case TargetOpcode::G_ABS:
1843 case TargetOpcode::G_CTPOP:
1844 case TargetOpcode::G_BSWAP:
1845 case TargetOpcode::G_BITREVERSE:
1846 case TargetOpcode::G_FSHL:
1847 case TargetOpcode::G_FSHR:
1848 case TargetOpcode::G_SMAX:
1849 case TargetOpcode::G_SMIN:
1850 case TargetOpcode::G_UMAX:
1851 case TargetOpcode::G_UMIN:
1852 case TargetOpcode::G_PTRMASK:
1853 case TargetOpcode::G_SADDO:
1854 case TargetOpcode::G_SSUBO:
1855 case TargetOpcode::G_UADDO:
1856 case TargetOpcode::G_USUBO:
1857 case TargetOpcode::G_SMULO:
1858 case TargetOpcode::G_UMULO:
1859 case TargetOpcode::G_SADDSAT:
1860 case TargetOpcode::G_UADDSAT:
1861 case TargetOpcode::G_SSUBSAT:
1862 case TargetOpcode::G_USUBSAT:
1863 return false;
1864 case TargetOpcode::G_SSHLSAT:
1865 case TargetOpcode::G_USHLSAT:
1866 return includesPoison(Kind) &&
1867 !shiftAmountKnownInRange(RegDef->getOperand(2).getReg(), MRI);
1868 case TargetOpcode::G_INSERT_VECTOR_ELT: {
1869 GInsertVectorElement *Insert = cast<GInsertVectorElement>(RegDef);
1870 if (includesPoison(Kind)) {
1871 std::optional<ValueAndVReg> Index =
1872 getIConstantVRegValWithLookThrough(Insert->getIndexReg(), MRI);
1873 if (!Index)
1874 return true;
1875 LLT VecTy = MRI.getType(Insert->getVectorReg());
1876 return Index->Value.uge(VecTy.getElementCount().getKnownMinValue());
1877 }
1878 return false;
1879 }
1880 case TargetOpcode::G_EXTRACT_VECTOR_ELT: {
1881 GExtractVectorElement *Extract = cast<GExtractVectorElement>(RegDef);
1882 if (includesPoison(Kind)) {
1883 std::optional<ValueAndVReg> Index =
1884 getIConstantVRegValWithLookThrough(Extract->getIndexReg(), MRI);
1885 if (!Index)
1886 return true;
1887 LLT VecTy = MRI.getType(Extract->getVectorReg());
1888 return Index->Value.uge(VecTy.getElementCount().getKnownMinValue());
1889 }
1890 return false;
1891 }
1892 case TargetOpcode::G_SHUFFLE_VECTOR: {
1893 GShuffleVector *Shuffle = cast<GShuffleVector>(RegDef);
1894 ArrayRef<int> Mask = Shuffle->getMask();
1895 return includesPoison(Kind) && is_contained(Mask, -1);
1896 }
1897 case TargetOpcode::G_FNEG:
1898 case TargetOpcode::G_PHI:
1899 case TargetOpcode::G_SELECT:
1900 case TargetOpcode::G_UREM:
1901 case TargetOpcode::G_SREM:
1902 case TargetOpcode::G_FREEZE:
1903 case TargetOpcode::G_ICMP:
1904 case TargetOpcode::G_FCMP:
1905 case TargetOpcode::G_FADD:
1906 case TargetOpcode::G_FSUB:
1907 case TargetOpcode::G_FMUL:
1908 case TargetOpcode::G_FDIV:
1909 case TargetOpcode::G_FREM:
1910 case TargetOpcode::G_PTR_ADD:
1911 return false;
1912 default:
1913 return !isa<GCastOp>(RegDef) && !isa<GBinOp>(RegDef);
1914 }
1915 }
1916
isGuaranteedNotToBeUndefOrPoison(Register Reg,const MachineRegisterInfo & MRI,unsigned Depth,UndefPoisonKind Kind)1917 static bool isGuaranteedNotToBeUndefOrPoison(Register Reg,
1918 const MachineRegisterInfo &MRI,
1919 unsigned Depth,
1920 UndefPoisonKind Kind) {
1921 if (Depth >= MaxAnalysisRecursionDepth)
1922 return false;
1923
1924 MachineInstr *RegDef = MRI.getVRegDef(Reg);
1925
1926 switch (RegDef->getOpcode()) {
1927 case TargetOpcode::G_FREEZE:
1928 return true;
1929 case TargetOpcode::G_IMPLICIT_DEF:
1930 return !includesUndef(Kind);
1931 case TargetOpcode::G_CONSTANT:
1932 case TargetOpcode::G_FCONSTANT:
1933 return true;
1934 case TargetOpcode::G_BUILD_VECTOR: {
1935 GBuildVector *BV = cast<GBuildVector>(RegDef);
1936 unsigned NumSources = BV->getNumSources();
1937 for (unsigned I = 0; I < NumSources; ++I)
1938 if (!::isGuaranteedNotToBeUndefOrPoison(BV->getSourceReg(I), MRI,
1939 Depth + 1, Kind))
1940 return false;
1941 return true;
1942 }
1943 case TargetOpcode::G_PHI: {
1944 GPhi *Phi = cast<GPhi>(RegDef);
1945 unsigned NumIncoming = Phi->getNumIncomingValues();
1946 for (unsigned I = 0; I < NumIncoming; ++I)
1947 if (!::isGuaranteedNotToBeUndefOrPoison(Phi->getIncomingValue(I), MRI,
1948 Depth + 1, Kind))
1949 return false;
1950 return true;
1951 }
1952 default: {
1953 auto MOCheck = [&](const MachineOperand &MO) {
1954 if (!MO.isReg())
1955 return true;
1956 return ::isGuaranteedNotToBeUndefOrPoison(MO.getReg(), MRI, Depth + 1,
1957 Kind);
1958 };
1959 return !::canCreateUndefOrPoison(Reg, MRI,
1960 /*ConsiderFlagsAndMetadata=*/true, Kind) &&
1961 all_of(RegDef->uses(), MOCheck);
1962 }
1963 }
1964 }
1965
canCreateUndefOrPoison(Register Reg,const MachineRegisterInfo & MRI,bool ConsiderFlagsAndMetadata)1966 bool llvm::canCreateUndefOrPoison(Register Reg, const MachineRegisterInfo &MRI,
1967 bool ConsiderFlagsAndMetadata) {
1968 return ::canCreateUndefOrPoison(Reg, MRI, ConsiderFlagsAndMetadata,
1969 UndefPoisonKind::UndefOrPoison);
1970 }
1971
canCreatePoison(Register Reg,const MachineRegisterInfo & MRI,bool ConsiderFlagsAndMetadata=true)1972 bool canCreatePoison(Register Reg, const MachineRegisterInfo &MRI,
1973 bool ConsiderFlagsAndMetadata = true) {
1974 return ::canCreateUndefOrPoison(Reg, MRI, ConsiderFlagsAndMetadata,
1975 UndefPoisonKind::PoisonOnly);
1976 }
1977
isGuaranteedNotToBeUndefOrPoison(Register Reg,const MachineRegisterInfo & MRI,unsigned Depth)1978 bool llvm::isGuaranteedNotToBeUndefOrPoison(Register Reg,
1979 const MachineRegisterInfo &MRI,
1980 unsigned Depth) {
1981 return ::isGuaranteedNotToBeUndefOrPoison(Reg, MRI, Depth,
1982 UndefPoisonKind::UndefOrPoison);
1983 }
1984
isGuaranteedNotToBePoison(Register Reg,const MachineRegisterInfo & MRI,unsigned Depth)1985 bool llvm::isGuaranteedNotToBePoison(Register Reg,
1986 const MachineRegisterInfo &MRI,
1987 unsigned Depth) {
1988 return ::isGuaranteedNotToBeUndefOrPoison(Reg, MRI, Depth,
1989 UndefPoisonKind::PoisonOnly);
1990 }
1991
isGuaranteedNotToBeUndef(Register Reg,const MachineRegisterInfo & MRI,unsigned Depth)1992 bool llvm::isGuaranteedNotToBeUndef(Register Reg,
1993 const MachineRegisterInfo &MRI,
1994 unsigned Depth) {
1995 return ::isGuaranteedNotToBeUndefOrPoison(Reg, MRI, Depth,
1996 UndefPoisonKind::UndefOnly);
1997 }
1998
getTypeForLLT(LLT Ty,LLVMContext & C)1999 Type *llvm::getTypeForLLT(LLT Ty, LLVMContext &C) {
2000 if (Ty.isVector())
2001 return VectorType::get(IntegerType::get(C, Ty.getScalarSizeInBits()),
2002 Ty.getElementCount());
2003 return IntegerType::get(C, Ty.getSizeInBits());
2004 }
2005
isAssertMI(const MachineInstr & MI)2006 bool llvm::isAssertMI(const MachineInstr &MI) {
2007 switch (MI.getOpcode()) {
2008 default:
2009 return false;
2010 case TargetOpcode::G_ASSERT_ALIGN:
2011 case TargetOpcode::G_ASSERT_SEXT:
2012 case TargetOpcode::G_ASSERT_ZEXT:
2013 return true;
2014 }
2015 }
2016
getScalarValue() const2017 APInt llvm::GIConstant::getScalarValue() const {
2018 assert(Kind == GIConstantKind::Scalar && "Expected scalar constant");
2019
2020 return Value;
2021 }
2022
2023 std::optional<GIConstant>
getConstant(Register Const,const MachineRegisterInfo & MRI)2024 llvm::GIConstant::getConstant(Register Const, const MachineRegisterInfo &MRI) {
2025 MachineInstr *Constant = getDefIgnoringCopies(Const, MRI);
2026
2027 if (GSplatVector *Splat = dyn_cast<GSplatVector>(Constant)) {
2028 std::optional<ValueAndVReg> MayBeConstant =
2029 getIConstantVRegValWithLookThrough(Splat->getScalarReg(), MRI);
2030 if (!MayBeConstant)
2031 return std::nullopt;
2032 return GIConstant(MayBeConstant->Value, GIConstantKind::ScalableVector);
2033 }
2034
2035 if (GBuildVector *Build = dyn_cast<GBuildVector>(Constant)) {
2036 SmallVector<APInt> Values;
2037 unsigned NumSources = Build->getNumSources();
2038 for (unsigned I = 0; I < NumSources; ++I) {
2039 Register SrcReg = Build->getSourceReg(I);
2040 std::optional<ValueAndVReg> MayBeConstant =
2041 getIConstantVRegValWithLookThrough(SrcReg, MRI);
2042 if (!MayBeConstant)
2043 return std::nullopt;
2044 Values.push_back(MayBeConstant->Value);
2045 }
2046 return GIConstant(Values);
2047 }
2048
2049 std::optional<ValueAndVReg> MayBeConstant =
2050 getIConstantVRegValWithLookThrough(Const, MRI);
2051 if (!MayBeConstant)
2052 return std::nullopt;
2053
2054 return GIConstant(MayBeConstant->Value, GIConstantKind::Scalar);
2055 }
2056
getScalarValue() const2057 APFloat llvm::GFConstant::getScalarValue() const {
2058 assert(Kind == GFConstantKind::Scalar && "Expected scalar constant");
2059
2060 return Values[0];
2061 }
2062
2063 std::optional<GFConstant>
getConstant(Register Const,const MachineRegisterInfo & MRI)2064 llvm::GFConstant::getConstant(Register Const, const MachineRegisterInfo &MRI) {
2065 MachineInstr *Constant = getDefIgnoringCopies(Const, MRI);
2066
2067 if (GSplatVector *Splat = dyn_cast<GSplatVector>(Constant)) {
2068 std::optional<FPValueAndVReg> MayBeConstant =
2069 getFConstantVRegValWithLookThrough(Splat->getScalarReg(), MRI);
2070 if (!MayBeConstant)
2071 return std::nullopt;
2072 return GFConstant(MayBeConstant->Value, GFConstantKind::ScalableVector);
2073 }
2074
2075 if (GBuildVector *Build = dyn_cast<GBuildVector>(Constant)) {
2076 SmallVector<APFloat> Values;
2077 unsigned NumSources = Build->getNumSources();
2078 for (unsigned I = 0; I < NumSources; ++I) {
2079 Register SrcReg = Build->getSourceReg(I);
2080 std::optional<FPValueAndVReg> MayBeConstant =
2081 getFConstantVRegValWithLookThrough(SrcReg, MRI);
2082 if (!MayBeConstant)
2083 return std::nullopt;
2084 Values.push_back(MayBeConstant->Value);
2085 }
2086 return GFConstant(Values);
2087 }
2088
2089 std::optional<FPValueAndVReg> MayBeConstant =
2090 getFConstantVRegValWithLookThrough(Const, MRI);
2091 if (!MayBeConstant)
2092 return std::nullopt;
2093
2094 return GFConstant(MayBeConstant->Value, GFConstantKind::Scalar);
2095 }
2096