Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:43:26

0001 //==-- llvm/CodeGen/GlobalISel/Utils.h ---------------------------*- C++ -*-==//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 /// \file This file declares the API of helper functions used throughout the
0010 /// GlobalISel pipeline.
0011 //
0012 //===----------------------------------------------------------------------===//
0013 
0014 #ifndef LLVM_CODEGEN_GLOBALISEL_UTILS_H
0015 #define LLVM_CODEGEN_GLOBALISEL_UTILS_H
0016 
0017 #include "GISelWorkList.h"
0018 #include "llvm/ADT/APFloat.h"
0019 #include "llvm/ADT/StringRef.h"
0020 #include "llvm/CodeGen/Register.h"
0021 #include "llvm/CodeGenTypes/LowLevelType.h"
0022 #include "llvm/IR/DebugLoc.h"
0023 #include "llvm/Support/Alignment.h"
0024 #include "llvm/Support/Casting.h"
0025 
0026 #include <cstdint>
0027 
0028 namespace llvm {
0029 
0030 class AnalysisUsage;
0031 class LostDebugLocObserver;
0032 class MachineBasicBlock;
0033 class BlockFrequencyInfo;
0034 class GISelKnownBits;
0035 class MachineFunction;
0036 class MachineInstr;
0037 class MachineIRBuilder;
0038 class MachineOperand;
0039 class MachineOptimizationRemarkEmitter;
0040 class MachineOptimizationRemarkMissed;
0041 struct MachinePointerInfo;
0042 class MachineRegisterInfo;
0043 class MCInstrDesc;
0044 class ProfileSummaryInfo;
0045 class RegisterBankInfo;
0046 class TargetInstrInfo;
0047 class TargetLowering;
0048 class TargetPassConfig;
0049 class TargetRegisterInfo;
0050 class TargetRegisterClass;
0051 class ConstantFP;
0052 class APFloat;
0053 
0054 // Convenience macros for dealing with vector reduction opcodes.
0055 #define GISEL_VECREDUCE_CASES_ALL                                              \
0056   case TargetOpcode::G_VECREDUCE_SEQ_FADD:                                     \
0057   case TargetOpcode::G_VECREDUCE_SEQ_FMUL:                                     \
0058   case TargetOpcode::G_VECREDUCE_FADD:                                         \
0059   case TargetOpcode::G_VECREDUCE_FMUL:                                         \
0060   case TargetOpcode::G_VECREDUCE_FMAX:                                         \
0061   case TargetOpcode::G_VECREDUCE_FMIN:                                         \
0062   case TargetOpcode::G_VECREDUCE_FMAXIMUM:                                     \
0063   case TargetOpcode::G_VECREDUCE_FMINIMUM:                                     \
0064   case TargetOpcode::G_VECREDUCE_ADD:                                          \
0065   case TargetOpcode::G_VECREDUCE_MUL:                                          \
0066   case TargetOpcode::G_VECREDUCE_AND:                                          \
0067   case TargetOpcode::G_VECREDUCE_OR:                                           \
0068   case TargetOpcode::G_VECREDUCE_XOR:                                          \
0069   case TargetOpcode::G_VECREDUCE_SMAX:                                         \
0070   case TargetOpcode::G_VECREDUCE_SMIN:                                         \
0071   case TargetOpcode::G_VECREDUCE_UMAX:                                         \
0072   case TargetOpcode::G_VECREDUCE_UMIN:
0073 
0074 #define GISEL_VECREDUCE_CASES_NONSEQ                                           \
0075   case TargetOpcode::G_VECREDUCE_FADD:                                         \
0076   case TargetOpcode::G_VECREDUCE_FMUL:                                         \
0077   case TargetOpcode::G_VECREDUCE_FMAX:                                         \
0078   case TargetOpcode::G_VECREDUCE_FMIN:                                         \
0079   case TargetOpcode::G_VECREDUCE_FMAXIMUM:                                     \
0080   case TargetOpcode::G_VECREDUCE_FMINIMUM:                                     \
0081   case TargetOpcode::G_VECREDUCE_ADD:                                          \
0082   case TargetOpcode::G_VECREDUCE_MUL:                                          \
0083   case TargetOpcode::G_VECREDUCE_AND:                                          \
0084   case TargetOpcode::G_VECREDUCE_OR:                                           \
0085   case TargetOpcode::G_VECREDUCE_XOR:                                          \
0086   case TargetOpcode::G_VECREDUCE_SMAX:                                         \
0087   case TargetOpcode::G_VECREDUCE_SMIN:                                         \
0088   case TargetOpcode::G_VECREDUCE_UMAX:                                         \
0089   case TargetOpcode::G_VECREDUCE_UMIN:
0090 
0091 /// Try to constrain Reg to the specified register class. If this fails,
0092 /// create a new virtual register in the correct class.
0093 ///
0094 /// \return The virtual register constrained to the right register class.
0095 Register constrainRegToClass(MachineRegisterInfo &MRI,
0096                              const TargetInstrInfo &TII,
0097                              const RegisterBankInfo &RBI, Register Reg,
0098                              const TargetRegisterClass &RegClass);
0099 
0100 /// Constrain the Register operand OpIdx, so that it is now constrained to the
0101 /// TargetRegisterClass passed as an argument (RegClass).
0102 /// If this fails, create a new virtual register in the correct class and insert
0103 /// a COPY before \p InsertPt if it is a use or after if it is a definition.
0104 /// In both cases, the function also updates the register of RegMo. The debug
0105 /// location of \p InsertPt is used for the new copy.
0106 ///
0107 /// \return The virtual register constrained to the right register class.
0108 Register constrainOperandRegClass(const MachineFunction &MF,
0109                                   const TargetRegisterInfo &TRI,
0110                                   MachineRegisterInfo &MRI,
0111                                   const TargetInstrInfo &TII,
0112                                   const RegisterBankInfo &RBI,
0113                                   MachineInstr &InsertPt,
0114                                   const TargetRegisterClass &RegClass,
0115                                   MachineOperand &RegMO);
0116 
0117 /// Try to constrain Reg so that it is usable by argument OpIdx of the provided
0118 /// MCInstrDesc \p II. If this fails, create a new virtual register in the
0119 /// correct class and insert a COPY before \p InsertPt if it is a use or after
0120 /// if it is a definition. In both cases, the function also updates the register
0121 /// of RegMo.
0122 /// This is equivalent to constrainOperandRegClass(..., RegClass, ...)
0123 /// with RegClass obtained from the MCInstrDesc. The debug location of \p
0124 /// InsertPt is used for the new copy.
0125 ///
0126 /// \return The virtual register constrained to the right register class.
0127 Register constrainOperandRegClass(const MachineFunction &MF,
0128                                   const TargetRegisterInfo &TRI,
0129                                   MachineRegisterInfo &MRI,
0130                                   const TargetInstrInfo &TII,
0131                                   const RegisterBankInfo &RBI,
0132                                   MachineInstr &InsertPt, const MCInstrDesc &II,
0133                                   MachineOperand &RegMO, unsigned OpIdx);
0134 
0135 /// Mutate the newly-selected instruction \p I to constrain its (possibly
0136 /// generic) virtual register operands to the instruction's register class.
0137 /// This could involve inserting COPYs before (for uses) or after (for defs).
0138 /// This requires the number of operands to match the instruction description.
0139 /// \returns whether operand regclass constraining succeeded.
0140 ///
0141 // FIXME: Not all instructions have the same number of operands. We should
0142 // probably expose a constrain helper per operand and let the target selector
0143 // constrain individual registers, like fast-isel.
0144 bool constrainSelectedInstRegOperands(MachineInstr &I,
0145                                       const TargetInstrInfo &TII,
0146                                       const TargetRegisterInfo &TRI,
0147                                       const RegisterBankInfo &RBI);
0148 
0149 /// Check if DstReg can be replaced with SrcReg depending on the register
0150 /// constraints.
0151 bool canReplaceReg(Register DstReg, Register SrcReg, MachineRegisterInfo &MRI);
0152 
0153 /// Check whether an instruction \p MI is dead: it only defines dead virtual
0154 /// registers, and doesn't have other side effects.
0155 bool isTriviallyDead(const MachineInstr &MI, const MachineRegisterInfo &MRI);
0156 
0157 /// Report an ISel error as a missed optimization remark to the LLVMContext's
0158 /// diagnostic stream.  Set the FailedISel MachineFunction property.
0159 void reportGISelFailure(MachineFunction &MF, const TargetPassConfig &TPC,
0160                         MachineOptimizationRemarkEmitter &MORE,
0161                         MachineOptimizationRemarkMissed &R);
0162 
0163 void reportGISelFailure(MachineFunction &MF, const TargetPassConfig &TPC,
0164                         MachineOptimizationRemarkEmitter &MORE,
0165                         const char *PassName, StringRef Msg,
0166                         const MachineInstr &MI);
0167 
0168 /// Report an ISel warning as a missed optimization remark to the LLVMContext's
0169 /// diagnostic stream.
0170 void reportGISelWarning(MachineFunction &MF, const TargetPassConfig &TPC,
0171                         MachineOptimizationRemarkEmitter &MORE,
0172                         MachineOptimizationRemarkMissed &R);
0173 
0174 /// Returns the inverse opcode of \p MinMaxOpc, which is a generic min/max
0175 /// opcode like G_SMIN.
0176 unsigned getInverseGMinMaxOpcode(unsigned MinMaxOpc);
0177 
0178 /// If \p VReg is defined by a G_CONSTANT, return the corresponding value.
0179 std::optional<APInt> getIConstantVRegVal(Register VReg,
0180                                          const MachineRegisterInfo &MRI);
0181 
0182 /// If \p VReg is defined by a G_CONSTANT fits in int64_t returns it.
0183 std::optional<int64_t> getIConstantVRegSExtVal(Register VReg,
0184                                                const MachineRegisterInfo &MRI);
0185 
0186 /// \p VReg is defined by a G_CONSTANT, return the corresponding value.
0187 const APInt &getIConstantFromReg(Register VReg, const MachineRegisterInfo &MRI);
0188 
0189 /// Simple struct used to hold a constant integer value and a virtual
0190 /// register.
0191 struct ValueAndVReg {
0192   APInt Value;
0193   Register VReg;
0194 };
0195 
0196 /// If \p VReg is defined by a statically evaluable chain of instructions rooted
0197 /// on a G_CONSTANT returns its APInt value and def register.
0198 std::optional<ValueAndVReg>
0199 getIConstantVRegValWithLookThrough(Register VReg,
0200                                    const MachineRegisterInfo &MRI,
0201                                    bool LookThroughInstrs = true);
0202 
0203 /// If \p VReg is defined by a statically evaluable chain of instructions rooted
0204 /// on a G_CONSTANT or G_FCONSTANT returns its value as APInt and def register.
0205 std::optional<ValueAndVReg> getAnyConstantVRegValWithLookThrough(
0206     Register VReg, const MachineRegisterInfo &MRI,
0207     bool LookThroughInstrs = true, bool LookThroughAnyExt = false);
0208 
0209 struct FPValueAndVReg {
0210   APFloat Value;
0211   Register VReg;
0212 };
0213 
0214 /// If \p VReg is defined by a statically evaluable chain of instructions rooted
0215 /// on a G_FCONSTANT returns its APFloat value and def register.
0216 std::optional<FPValueAndVReg>
0217 getFConstantVRegValWithLookThrough(Register VReg,
0218                                    const MachineRegisterInfo &MRI,
0219                                    bool LookThroughInstrs = true);
0220 
0221 const ConstantFP* getConstantFPVRegVal(Register VReg,
0222                                        const MachineRegisterInfo &MRI);
0223 
0224 /// See if Reg is defined by an single def instruction that is
0225 /// Opcode. Also try to do trivial folding if it's a COPY with
0226 /// same types. Returns null otherwise.
0227 MachineInstr *getOpcodeDef(unsigned Opcode, Register Reg,
0228                            const MachineRegisterInfo &MRI);
0229 
0230 /// Simple struct used to hold a Register value and the instruction which
0231 /// defines it.
0232 struct DefinitionAndSourceRegister {
0233   MachineInstr *MI;
0234   Register Reg;
0235 };
0236 
0237 /// Find the def instruction for \p Reg, and underlying value Register folding
0238 /// away any copies.
0239 ///
0240 /// Also walks through hints such as G_ASSERT_ZEXT.
0241 std::optional<DefinitionAndSourceRegister>
0242 getDefSrcRegIgnoringCopies(Register Reg, const MachineRegisterInfo &MRI);
0243 
0244 /// Find the def instruction for \p Reg, folding away any trivial copies. May
0245 /// return nullptr if \p Reg is not a generic virtual register.
0246 ///
0247 /// Also walks through hints such as G_ASSERT_ZEXT.
0248 MachineInstr *getDefIgnoringCopies(Register Reg,
0249                                    const MachineRegisterInfo &MRI);
0250 
0251 /// Find the source register for \p Reg, folding away any trivial copies. It
0252 /// will be an output register of the instruction that getDefIgnoringCopies
0253 /// returns. May return an invalid register if \p Reg is not a generic virtual
0254 /// register.
0255 ///
0256 /// Also walks through hints such as G_ASSERT_ZEXT.
0257 Register getSrcRegIgnoringCopies(Register Reg, const MachineRegisterInfo &MRI);
0258 
0259 /// Helper function to split a wide generic register into bitwise blocks with
0260 /// the given Type (which implies the number of blocks needed). The generic
0261 /// registers created are appended to Ops, starting at bit 0 of Reg.
0262 void extractParts(Register Reg, LLT Ty, int NumParts,
0263                   SmallVectorImpl<Register> &VRegs,
0264                   MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI);
0265 
0266 /// Version which handles irregular splits.
0267 bool extractParts(Register Reg, LLT RegTy, LLT MainTy, LLT &LeftoverTy,
0268                   SmallVectorImpl<Register> &VRegs,
0269                   SmallVectorImpl<Register> &LeftoverVRegs,
0270                   MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI);
0271 
0272 /// Version which handles irregular sub-vector splits.
0273 void extractVectorParts(Register Reg, unsigned NumElts,
0274                         SmallVectorImpl<Register> &VRegs,
0275                         MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI);
0276 
0277 // Templated variant of getOpcodeDef returning a MachineInstr derived T.
0278 /// See if Reg is defined by an single def instruction of type T
0279 /// Also try to do trivial folding if it's a COPY with
0280 /// same types. Returns null otherwise.
0281 template <class T>
0282 T *getOpcodeDef(Register Reg, const MachineRegisterInfo &MRI) {
0283   MachineInstr *DefMI = getDefIgnoringCopies(Reg, MRI);
0284   return dyn_cast_or_null<T>(DefMI);
0285 }
0286 
0287 /// Returns an APFloat from Val converted to the appropriate size.
0288 APFloat getAPFloatFromSize(double Val, unsigned Size);
0289 
0290 /// Modify analysis usage so it preserves passes required for the SelectionDAG
0291 /// fallback.
0292 void getSelectionDAGFallbackAnalysisUsage(AnalysisUsage &AU);
0293 
0294 std::optional<APInt> ConstantFoldBinOp(unsigned Opcode, const Register Op1,
0295                                        const Register Op2,
0296                                        const MachineRegisterInfo &MRI);
0297 std::optional<APFloat> ConstantFoldFPBinOp(unsigned Opcode, const Register Op1,
0298                                            const Register Op2,
0299                                            const MachineRegisterInfo &MRI);
0300 
0301 /// Tries to constant fold a vector binop with sources \p Op1 and \p Op2.
0302 /// Returns an empty vector on failure.
0303 SmallVector<APInt> ConstantFoldVectorBinop(unsigned Opcode, const Register Op1,
0304                                            const Register Op2,
0305                                            const MachineRegisterInfo &MRI);
0306 
0307 std::optional<APInt> ConstantFoldCastOp(unsigned Opcode, LLT DstTy,
0308                                         const Register Op0,
0309                                         const MachineRegisterInfo &MRI);
0310 
0311 std::optional<APInt> ConstantFoldExtOp(unsigned Opcode, const Register Op1,
0312                                        uint64_t Imm,
0313                                        const MachineRegisterInfo &MRI);
0314 
0315 std::optional<APFloat> ConstantFoldIntToFloat(unsigned Opcode, LLT DstTy,
0316                                               Register Src,
0317                                               const MachineRegisterInfo &MRI);
0318 
0319 /// Tries to constant fold a counting-zero operation (G_CTLZ or G_CTTZ) on \p
0320 /// Src. If \p Src is a vector then it tries to do an element-wise constant
0321 /// fold.
0322 std::optional<SmallVector<unsigned>>
0323 ConstantFoldCountZeros(Register Src, const MachineRegisterInfo &MRI,
0324                        std::function<unsigned(APInt)> CB);
0325 
0326 std::optional<SmallVector<APInt>>
0327 ConstantFoldICmp(unsigned Pred, const Register Op1, const Register Op2,
0328                  const MachineRegisterInfo &MRI);
0329 
0330 /// Test if the given value is known to have exactly one bit set. This differs
0331 /// from computeKnownBits in that it doesn't necessarily determine which bit is
0332 /// set.
0333 bool isKnownToBeAPowerOfTwo(Register Val, const MachineRegisterInfo &MRI,
0334                             GISelKnownBits *KnownBits = nullptr);
0335 
0336 /// Returns true if \p Val can be assumed to never be a NaN. If \p SNaN is true,
0337 /// this returns if \p Val can be assumed to never be a signaling NaN.
0338 bool isKnownNeverNaN(Register Val, const MachineRegisterInfo &MRI,
0339                      bool SNaN = false);
0340 
0341 /// Returns true if \p Val can be assumed to never be a signaling NaN.
0342 inline bool isKnownNeverSNaN(Register Val, const MachineRegisterInfo &MRI) {
0343   return isKnownNeverNaN(Val, MRI, true);
0344 }
0345 
0346 Align inferAlignFromPtrInfo(MachineFunction &MF, const MachinePointerInfo &MPO);
0347 
0348 /// Return a virtual register corresponding to the incoming argument register \p
0349 /// PhysReg. This register is expected to have class \p RC, and optional type \p
0350 /// RegTy. This assumes all references to the register will use the same type.
0351 ///
0352 /// If there is an existing live-in argument register, it will be returned.
0353 /// This will also ensure there is a valid copy
0354 Register getFunctionLiveInPhysReg(MachineFunction &MF,
0355                                   const TargetInstrInfo &TII,
0356                                   MCRegister PhysReg,
0357                                   const TargetRegisterClass &RC,
0358                                   const DebugLoc &DL, LLT RegTy = LLT());
0359 
0360 /// Return the least common multiple type of \p OrigTy and \p TargetTy, by
0361 /// changing the number of vector elements or scalar bitwidth. The intent is a
0362 /// G_MERGE_VALUES, G_BUILD_VECTOR, or G_CONCAT_VECTORS can be constructed from
0363 /// \p OrigTy elements, and unmerged into \p TargetTy. It is an error to call
0364 /// this function where one argument is a fixed vector and the other is a
0365 /// scalable vector, since it is illegal to build a G_{MERGE|UNMERGE}_VALUES
0366 /// between fixed and scalable vectors.
0367 LLVM_READNONE
0368 LLT getLCMType(LLT OrigTy, LLT TargetTy);
0369 
0370 LLVM_READNONE
0371 /// Return smallest type that covers both \p OrigTy and \p TargetTy and is
0372 /// multiple of TargetTy.
0373 LLT getCoverTy(LLT OrigTy, LLT TargetTy);
0374 
0375 /// Return a type where the total size is the greatest common divisor of \p
0376 /// OrigTy and \p TargetTy. This will try to either change the number of vector
0377 /// elements, or bitwidth of scalars. The intent is the result type can be used
0378 /// as the result of a G_UNMERGE_VALUES from \p OrigTy, and then some
0379 /// combination of G_MERGE_VALUES, G_BUILD_VECTOR and G_CONCAT_VECTORS (possibly
0380 /// with intermediate casts) can re-form \p TargetTy.
0381 ///
0382 /// If these are vectors with different element types, this will try to produce
0383 /// a vector with a compatible total size, but the element type of \p OrigTy. If
0384 /// this can't be satisfied, this will produce a scalar smaller than the
0385 /// original vector elements. It is an error to call this function where
0386 /// one argument is a fixed vector and the other is a scalable vector, since it
0387 /// is illegal to build a G_{MERGE|UNMERGE}_VALUES between fixed and scalable
0388 /// vectors.
0389 ///
0390 /// In the worst case, this returns LLT::scalar(1)
0391 LLVM_READNONE
0392 LLT getGCDType(LLT OrigTy, LLT TargetTy);
0393 
0394 /// Represents a value which can be a Register or a constant.
0395 ///
0396 /// This is useful in situations where an instruction may have an interesting
0397 /// register operand or interesting constant operand. For a concrete example,
0398 /// \see getVectorSplat.
0399 class RegOrConstant {
0400   int64_t Cst;
0401   Register Reg;
0402   bool IsReg;
0403 
0404 public:
0405   explicit RegOrConstant(Register Reg) : Reg(Reg), IsReg(true) {}
0406   explicit RegOrConstant(int64_t Cst) : Cst(Cst), IsReg(false) {}
0407   bool isReg() const { return IsReg; }
0408   bool isCst() const { return !IsReg; }
0409   Register getReg() const {
0410     assert(isReg() && "Expected a register!");
0411     return Reg;
0412   }
0413   int64_t getCst() const {
0414     assert(isCst() && "Expected a constant!");
0415     return Cst;
0416   }
0417 };
0418 
0419 /// \returns The splat index of a G_SHUFFLE_VECTOR \p MI when \p MI is a splat.
0420 /// If \p MI is not a splat, returns std::nullopt.
0421 std::optional<int> getSplatIndex(MachineInstr &MI);
0422 
0423 /// \returns the scalar integral splat value of \p Reg if possible.
0424 std::optional<APInt> getIConstantSplatVal(const Register Reg,
0425                                           const MachineRegisterInfo &MRI);
0426 
0427 /// \returns the scalar integral splat value defined by \p MI if possible.
0428 std::optional<APInt> getIConstantSplatVal(const MachineInstr &MI,
0429                                           const MachineRegisterInfo &MRI);
0430 
0431 /// \returns the scalar sign extended integral splat value of \p Reg if
0432 /// possible.
0433 std::optional<int64_t> getIConstantSplatSExtVal(const Register Reg,
0434                                                 const MachineRegisterInfo &MRI);
0435 
0436 /// \returns the scalar sign extended integral splat value defined by \p MI if
0437 /// possible.
0438 std::optional<int64_t> getIConstantSplatSExtVal(const MachineInstr &MI,
0439                                                 const MachineRegisterInfo &MRI);
0440 
0441 /// Returns a floating point scalar constant of a build vector splat if it
0442 /// exists. When \p AllowUndef == true some elements can be undef but not all.
0443 std::optional<FPValueAndVReg> getFConstantSplat(Register VReg,
0444                                                 const MachineRegisterInfo &MRI,
0445                                                 bool AllowUndef = true);
0446 
0447 /// Return true if the specified register is defined by G_BUILD_VECTOR or
0448 /// G_BUILD_VECTOR_TRUNC where all of the elements are \p SplatValue or undef.
0449 bool isBuildVectorConstantSplat(const Register Reg,
0450                                 const MachineRegisterInfo &MRI,
0451                                 int64_t SplatValue, bool AllowUndef);
0452 
0453 /// Return true if the specified instruction is a G_BUILD_VECTOR or
0454 /// G_BUILD_VECTOR_TRUNC where all of the elements are \p SplatValue or undef.
0455 bool isBuildVectorConstantSplat(const MachineInstr &MI,
0456                                 const MachineRegisterInfo &MRI,
0457                                 int64_t SplatValue, bool AllowUndef);
0458 
0459 /// Return true if the specified instruction is a G_BUILD_VECTOR or
0460 /// G_BUILD_VECTOR_TRUNC where all of the elements are 0 or undef.
0461 bool isBuildVectorAllZeros(const MachineInstr &MI,
0462                            const MachineRegisterInfo &MRI,
0463                            bool AllowUndef = false);
0464 
0465 /// Return true if the specified instruction is a G_BUILD_VECTOR or
0466 /// G_BUILD_VECTOR_TRUNC where all of the elements are ~0 or undef.
0467 bool isBuildVectorAllOnes(const MachineInstr &MI,
0468                           const MachineRegisterInfo &MRI,
0469                           bool AllowUndef = false);
0470 
0471 /// Return true if the specified instruction is known to be a constant, or a
0472 /// vector of constants.
0473 ///
0474 /// If \p AllowFP is true, this will consider G_FCONSTANT in addition to
0475 /// G_CONSTANT. If \p AllowOpaqueConstants is true, constant-like instructions
0476 /// such as G_GLOBAL_VALUE will also be considered.
0477 bool isConstantOrConstantVector(const MachineInstr &MI,
0478                                 const MachineRegisterInfo &MRI,
0479                                 bool AllowFP = true,
0480                                 bool AllowOpaqueConstants = true);
0481 
0482 /// Return true if the value is a constant 0 integer or a splatted vector of a
0483 /// constant 0 integer (with no undefs if \p AllowUndefs is false). This will
0484 /// handle G_BUILD_VECTOR and G_BUILD_VECTOR_TRUNC as truncation is not an issue
0485 /// for null values.
0486 bool isNullOrNullSplat(const MachineInstr &MI, const MachineRegisterInfo &MRI,
0487                        bool AllowUndefs = false);
0488 
0489 /// Return true if the value is a constant -1 integer or a splatted vector of a
0490 /// constant -1 integer (with no undefs if \p AllowUndefs is false).
0491 bool isAllOnesOrAllOnesSplat(const MachineInstr &MI,
0492                              const MachineRegisterInfo &MRI,
0493                              bool AllowUndefs = false);
0494 
0495 /// \returns a value when \p MI is a vector splat. The splat can be either a
0496 /// Register or a constant.
0497 ///
0498 /// Examples:
0499 ///
0500 /// \code
0501 ///   %reg = COPY $physreg
0502 ///   %reg_splat = G_BUILD_VECTOR %reg, %reg, ..., %reg
0503 /// \endcode
0504 ///
0505 /// If called on the G_BUILD_VECTOR above, this will return a RegOrConstant
0506 /// containing %reg.
0507 ///
0508 /// \code
0509 ///   %cst = G_CONSTANT iN 4
0510 ///   %constant_splat = G_BUILD_VECTOR %cst, %cst, ..., %cst
0511 /// \endcode
0512 ///
0513 /// In the above case, this will return a RegOrConstant containing 4.
0514 std::optional<RegOrConstant> getVectorSplat(const MachineInstr &MI,
0515                                             const MachineRegisterInfo &MRI);
0516 
0517 /// Determines if \p MI defines a constant integer or a build vector of
0518 /// constant integers. Treats undef values as constants.
0519 bool isConstantOrConstantVector(MachineInstr &MI,
0520                                 const MachineRegisterInfo &MRI);
0521 
0522 /// Determines if \p MI defines a constant integer or a splat vector of
0523 /// constant integers.
0524 /// \returns the scalar constant or std::nullopt.
0525 std::optional<APInt>
0526 isConstantOrConstantSplatVector(MachineInstr &MI,
0527                                 const MachineRegisterInfo &MRI);
0528 
0529 /// Determines if \p MI defines a float constant integer or a splat vector of
0530 /// float constant integers.
0531 /// \returns the float constant or std::nullopt.
0532 std::optional<APFloat>
0533 isConstantOrConstantSplatVectorFP(MachineInstr &MI,
0534                                   const MachineRegisterInfo &MRI);
0535 
0536 /// Attempt to match a unary predicate against a scalar/splat constant or every
0537 /// element of a constant G_BUILD_VECTOR. If \p ConstVal is null, the source
0538 /// value was undef.
0539 bool matchUnaryPredicate(const MachineRegisterInfo &MRI, Register Reg,
0540                          std::function<bool(const Constant *ConstVal)> Match,
0541                          bool AllowUndefs = false);
0542 
0543 /// Returns true if given the TargetLowering's boolean contents information,
0544 /// the value \p Val contains a true value.
0545 bool isConstTrueVal(const TargetLowering &TLI, int64_t Val, bool IsVector,
0546                     bool IsFP);
0547 /// \returns true if given the TargetLowering's boolean contents information,
0548 /// the value \p Val contains a false value.
0549 bool isConstFalseVal(const TargetLowering &TLI, int64_t Val, bool IsVector,
0550                     bool IsFP);
0551 
0552 /// Returns an integer representing true, as defined by the
0553 /// TargetBooleanContents.
0554 int64_t getICmpTrueVal(const TargetLowering &TLI, bool IsVector, bool IsFP);
0555 
0556 using SmallInstListTy = GISelWorkList<4>;
0557 void saveUsesAndErase(MachineInstr &MI, MachineRegisterInfo &MRI,
0558                       LostDebugLocObserver *LocObserver,
0559                       SmallInstListTy &DeadInstChain);
0560 void eraseInstrs(ArrayRef<MachineInstr *> DeadInstrs, MachineRegisterInfo &MRI,
0561                  LostDebugLocObserver *LocObserver = nullptr);
0562 void eraseInstr(MachineInstr &MI, MachineRegisterInfo &MRI,
0563                 LostDebugLocObserver *LocObserver = nullptr);
0564 
0565 /// Assuming the instruction \p MI is going to be deleted, attempt to salvage
0566 /// debug users of \p MI by writing the effect of \p MI in a DIExpression.
0567 void salvageDebugInfo(const MachineRegisterInfo &MRI, MachineInstr &MI);
0568 
0569 /// Returns whether opcode \p Opc is a pre-isel generic floating-point opcode,
0570 /// having only floating-point operands.
0571 bool isPreISelGenericFloatingPointOpcode(unsigned Opc);
0572 
0573 /// Returns true if \p Reg can create undef or poison from non-undef &
0574 /// non-poison operands. \p ConsiderFlagsAndMetadata controls whether poison
0575 /// producing flags and metadata on the instruction are considered. This can be
0576 /// used to see if the instruction could still introduce undef or poison even
0577 /// without poison generating flags and metadata which might be on the
0578 /// instruction.
0579 bool canCreateUndefOrPoison(Register Reg, const MachineRegisterInfo &MRI,
0580                             bool ConsiderFlagsAndMetadata = true);
0581 
0582 /// Returns true if \p Reg can create poison from non-poison operands.
0583 bool canCreatePoison(Register Reg, const MachineRegisterInfo &MRI,
0584                      bool ConsiderFlagsAndMetadata = true);
0585 
0586 /// Returns true if \p Reg cannot be poison and undef.
0587 bool isGuaranteedNotToBeUndefOrPoison(Register Reg,
0588                                       const MachineRegisterInfo &MRI,
0589                                       unsigned Depth = 0);
0590 
0591 /// Returns true if \p Reg cannot be poison, but may be undef.
0592 bool isGuaranteedNotToBePoison(Register Reg, const MachineRegisterInfo &MRI,
0593                                unsigned Depth = 0);
0594 
0595 /// Returns true if \p Reg cannot be undef, but may be poison.
0596 bool isGuaranteedNotToBeUndef(Register Reg, const MachineRegisterInfo &MRI,
0597                               unsigned Depth = 0);
0598 
0599 /// Get the type back from LLT. It won't be 100 percent accurate but returns an
0600 /// estimate of the type.
0601 Type *getTypeForLLT(LLT Ty, LLVMContext &C);
0602 
0603 /// An integer-like constant.
0604 ///
0605 /// It abstracts over scalar, fixed-length vectors, and scalable vectors.
0606 /// In the common case, it provides a common API and feels like an APInt,
0607 /// while still providing low-level access.
0608 /// It can be used for constant-folding.
0609 ///
0610 /// bool isZero()
0611 /// abstracts over the kind.
0612 ///
0613 /// switch(const.getKind())
0614 /// {
0615 /// }
0616 /// provides low-level access.
0617 class GIConstant {
0618 public:
0619   enum class GIConstantKind { Scalar, FixedVector, ScalableVector };
0620 
0621 private:
0622   GIConstantKind Kind;
0623   SmallVector<APInt> Values;
0624   APInt Value;
0625 
0626 public:
0627   GIConstant(ArrayRef<APInt> Values)
0628       : Kind(GIConstantKind::FixedVector), Values(Values) {};
0629   GIConstant(const APInt &Value, GIConstantKind Kind)
0630       : Kind(Kind), Value(Value) {};
0631 
0632   /// Returns the kind of of this constant, e.g, Scalar.
0633   GIConstantKind getKind() const { return Kind; }
0634 
0635   /// Returns the value, if this constant is a scalar.
0636   APInt getScalarValue() const;
0637 
0638   static std::optional<GIConstant> getConstant(Register Const,
0639                                                const MachineRegisterInfo &MRI);
0640 };
0641 
0642 /// An floating-point-like constant.
0643 ///
0644 /// It abstracts over scalar, fixed-length vectors, and scalable vectors.
0645 /// In the common case, it provides a common API and feels like an APFloat,
0646 /// while still providing low-level access.
0647 /// It can be used for constant-folding.
0648 ///
0649 /// bool isZero()
0650 /// abstracts over the kind.
0651 ///
0652 /// switch(const.getKind())
0653 /// {
0654 /// }
0655 /// provides low-level access.
0656 class GFConstant {
0657 public:
0658   enum class GFConstantKind { Scalar, FixedVector, ScalableVector };
0659 
0660 private:
0661   GFConstantKind Kind;
0662   SmallVector<APFloat> Values;
0663 
0664 public:
0665   GFConstant(ArrayRef<APFloat> Values)
0666       : Kind(GFConstantKind::FixedVector), Values(Values) {};
0667   GFConstant(const APFloat &Value, GFConstantKind Kind) : Kind(Kind) {
0668     Values.push_back(Value);
0669   }
0670 
0671   /// Returns the kind of of this constant, e.g, Scalar.
0672   GFConstantKind getKind() const { return Kind; }
0673 
0674   /// Returns the value, if this constant is a scalar.
0675   APFloat getScalarValue() const;
0676 
0677   static std::optional<GFConstant> getConstant(Register Const,
0678                                                const MachineRegisterInfo &MRI);
0679 };
0680 
0681 } // End namespace llvm.
0682 #endif