diff options
Diffstat (limited to 'llvm/lib/CodeGen')
| -rw-r--r-- | llvm/lib/CodeGen/GlobalISel/CombinerHelperVectorOps.cpp | 25 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/GlobalISel/Utils.cpp | 83 |
2 files changed, 107 insertions, 1 deletions
diff --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelperVectorOps.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelperVectorOps.cpp index 123bf21f657c..fb33801a3a33 100644 --- a/llvm/lib/CodeGen/GlobalISel/CombinerHelperVectorOps.cpp +++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelperVectorOps.cpp @@ -77,7 +77,7 @@ bool CombinerHelper::matchExtractVectorElement(MachineInstr &MI, // Fold extractVectorElement(Vector, TOOLARGE) -> undef if (IndexC && VectorTy.isFixedVector() && - IndexC->getZExtValue() >= VectorTy.getNumElements() && + IndexC->uge(VectorTy.getNumElements()) && isLegalOrBeforeLegalizer({TargetOpcode::G_IMPLICIT_DEF, {DstTy}})) { // For fixed-length vectors, it's invalid to extract out-of-range elements. MatchInfo = [=](MachineIRBuilder &B) { B.buildUndef(Dst); }; @@ -324,3 +324,26 @@ bool CombinerHelper::matchExtractVectorElementWithBuildVectorTrunc( return true; } + +bool CombinerHelper::matchInsertVectorElementOOB(MachineInstr &MI, + BuildFnTy &MatchInfo) { + GInsertVectorElement *Insert = cast<GInsertVectorElement>(&MI); + + Register Dst = Insert->getReg(0); + LLT DstTy = MRI.getType(Dst); + Register Index = Insert->getIndexReg(); + + if (!DstTy.isFixedVector()) + return false; + + std::optional<ValueAndVReg> MaybeIndex = + getIConstantVRegValWithLookThrough(Index, MRI); + + if (MaybeIndex && MaybeIndex->Value.uge(DstTy.getNumElements()) && + isLegalOrBeforeLegalizer({TargetOpcode::G_IMPLICIT_DEF, {DstTy}})) { + MatchInfo = [=](MachineIRBuilder &B) { B.buildUndef(Dst); }; + return true; + } + + return false; +} diff --git a/llvm/lib/CodeGen/GlobalISel/Utils.cpp b/llvm/lib/CodeGen/GlobalISel/Utils.cpp index ae43e9ccf611..4e3781cb4e9d 100644 --- a/llvm/lib/CodeGen/GlobalISel/Utils.cpp +++ b/llvm/lib/CodeGen/GlobalISel/Utils.cpp @@ -12,6 +12,7 @@ #include "llvm/CodeGen/GlobalISel/Utils.h" #include "llvm/ADT/APFloat.h" #include "llvm/ADT/APInt.h" +#include "llvm/Analysis/ValueTracking.h" #include "llvm/CodeGen/CodeGenCommonISel.h" #include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h" #include "llvm/CodeGen/GlobalISel/GISelKnownBits.h" @@ -28,6 +29,7 @@ #include "llvm/CodeGen/StackProtector.h" #include "llvm/CodeGen/TargetInstrInfo.h" #include "llvm/CodeGen/TargetLowering.h" +#include "llvm/CodeGen/TargetOpcodes.h" #include "llvm/CodeGen/TargetPassConfig.h" #include "llvm/CodeGen/TargetRegisterInfo.h" #include "llvm/IR/Constants.h" @@ -1709,3 +1711,84 @@ bool llvm::isPreISelGenericFloatingPointOpcode(unsigned Opc) { return false; } } + +namespace { +enum class UndefPoisonKind { + PoisonOnly = (1 << 0), + UndefOnly = (1 << 1), + UndefOrPoison = PoisonOnly | UndefOnly, +}; +} + +[[maybe_unused]] static bool includesPoison(UndefPoisonKind Kind) { + return (unsigned(Kind) & unsigned(UndefPoisonKind::PoisonOnly)) != 0; +} + +[[maybe_unused]] static bool includesUndef(UndefPoisonKind Kind) { + return (unsigned(Kind) & unsigned(UndefPoisonKind::UndefOnly)) != 0; +} + +static bool canCreateUndefOrPoison(Register Reg, const MachineRegisterInfo &MRI, + bool ConsiderFlagsAndMetadata, + UndefPoisonKind Kind) { + MachineInstr *RegDef = MRI.getVRegDef(Reg); + + switch (RegDef->getOpcode()) { + case TargetOpcode::G_FREEZE: + return false; + default: + return true; + } +} + +static bool isGuaranteedNotToBeUndefOrPoison(Register Reg, + const MachineRegisterInfo &MRI, + unsigned Depth, + UndefPoisonKind Kind) { + if (Depth >= MaxAnalysisRecursionDepth) + return false; + + MachineInstr *RegDef = MRI.getVRegDef(Reg); + + switch (RegDef->getOpcode()) { + case TargetOpcode::G_FREEZE: + return true; + case TargetOpcode::G_IMPLICIT_DEF: + return !includesUndef(Kind); + default: + return false; + } +} + +bool llvm::canCreateUndefOrPoison(Register Reg, const MachineRegisterInfo &MRI, + bool ConsiderFlagsAndMetadata) { + return ::canCreateUndefOrPoison(Reg, MRI, ConsiderFlagsAndMetadata, + UndefPoisonKind::UndefOrPoison); +} + +bool canCreatePoison(Register Reg, const MachineRegisterInfo &MRI, + bool ConsiderFlagsAndMetadata = true) { + return ::canCreateUndefOrPoison(Reg, MRI, ConsiderFlagsAndMetadata, + UndefPoisonKind::PoisonOnly); +} + +bool llvm::isGuaranteedNotToBeUndefOrPoison(Register Reg, + const MachineRegisterInfo &MRI, + unsigned Depth) { + return ::isGuaranteedNotToBeUndefOrPoison(Reg, MRI, Depth, + UndefPoisonKind::UndefOrPoison); +} + +bool llvm::isGuaranteedNotToBePoison(Register Reg, + const MachineRegisterInfo &MRI, + unsigned Depth) { + return ::isGuaranteedNotToBeUndefOrPoison(Reg, MRI, Depth, + UndefPoisonKind::PoisonOnly); +} + +bool llvm::isGuaranteedNotToBeUndef(Register Reg, + const MachineRegisterInfo &MRI, + unsigned Depth) { + return ::isGuaranteedNotToBeUndefOrPoison(Reg, MRI, Depth, + UndefPoisonKind::UndefOnly); +} |
