aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r--llvm/lib/CodeGen/GlobalISel/CombinerHelperVectorOps.cpp25
-rw-r--r--llvm/lib/CodeGen/GlobalISel/Utils.cpp83
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);
+}