[llvm] [GlobalIsel] Visit ICmp (PR #105991)
Dhruv Chawla via llvm-commits
llvm-commits at lists.llvm.org
Sun Aug 25 21:16:54 PDT 2024
Thorsten =?utf-8?q?Schütt?= <schuett at gmail.com>,
Thorsten =?utf-8?q?Schütt?= <schuett at gmail.com>
Message-ID:
In-Reply-To: <llvm.org/llvm/llvm-project/pull/105991 at github.com>
================
@@ -1984,3 +1984,323 @@ Type *llvm::getTypeForLLT(LLT Ty, LLVMContext &C) {
Ty.getElementCount());
return IntegerType::get(C, Ty.getSizeInBits());
}
+
+APInt llvm::GIConstant::getScalarValue() const {
+ assert(Kind == GIConstantKind::Scalar && "Expected scalar constant");
+
+ return Value;
+}
+
+std::optional<GIConstant>
+llvm::GIConstant::getConstant(Register Const, const MachineRegisterInfo &MRI) {
+ MachineInstr *Constant = getDefIgnoringCopies(Const, MRI);
+
+ if (GSplatVector *Splat = dyn_cast<GSplatVector>(Constant)) {
+ std::optional<ValueAndVReg> MayBeConstant =
+ getIConstantVRegValWithLookThrough(Splat->getValueReg(), MRI);
+ if (!MayBeConstant)
+ return std::nullopt;
+ return GIConstant(MayBeConstant->Value, GIConstantKind::ScalableVector);
+ }
+
+ if (GBuildVector *Build = dyn_cast<GBuildVector>(Constant)) {
+ SmallVector<APInt> Values;
+ unsigned NumSources = Build->getNumSources();
+ for (unsigned I = 0; I < NumSources; ++I) {
+ Register SrcReg = Build->getSourceReg(I);
+ std::optional<ValueAndVReg> MayBeConstant =
+ getIConstantVRegValWithLookThrough(SrcReg, MRI);
+ if (!MayBeConstant)
+ return std::nullopt;
+ Values.push_back(MayBeConstant->Value);
+ }
+ return GIConstant(Values);
+ }
+
+ std::optional<ValueAndVReg> MayBeConstant =
+ getIConstantVRegValWithLookThrough(Const, MRI);
+ if (!MayBeConstant)
+ return std::nullopt;
+
+ return GIConstant(MayBeConstant->Value, GIConstantKind::Scalar);
+}
+
+static bool isKnownNonZero(Register Reg, const MachineRegisterInfo &MRI,
+ GISelKnownBits *KB, unsigned Depth);
+
+bool llvm::isKnownNonZero(Register Reg, const MachineRegisterInfo &MRI,
+ GISelKnownBits *KB, unsigned Depth) {
+ if (!Reg.isVirtual())
+ return false;
+
+ LLT Ty = MRI.getType(Reg);
+ if (!Ty.isValid())
+ return false;
+
+ if (Ty.isPointer())
+ return false;
+
+ assert(Ty.isScalar() && "Expected a scalar value");
+ return ::isKnownNonZero(Reg, MRI, KB, Depth);
+}
+
+static bool matchOpWithOpEqZero(Register Op0, Register Op1,
+ const MachineRegisterInfo &MRI) {
+ MachineInstr *MI = MRI.getVRegDef(Op0);
+
+ bool Result = false;
+
+ if (GZextOrSextOp *ZS = dyn_cast<GZextOrSextOp>(MI)) {
+ MachineInstr *SrcMI = MRI.getVRegDef(ZS->getSrcReg());
+ if (GICmp *Cmp = dyn_cast<GICmp>(SrcMI)) {
+ std::optional<ValueAndVReg> MayBeConstant =
+ getIConstantVRegValWithLookThrough(Cmp->getRHSReg(), MRI);
+ if (MayBeConstant)
+ Result |= (MayBeConstant->Value == 0) && (Cmp->getLHSReg() == Op1) &&
+ (Cmp->getCond() == ICmpInst::ICMP_EQ);
+ }
+ }
+
+ MI = MRI.getVRegDef(Op1);
+ if (GZextOrSextOp *ZS = dyn_cast<GZextOrSextOp>(MI)) {
+ MachineInstr *SrcMI = MRI.getVRegDef(ZS->getSrcReg());
+ if (GICmp *Cmp = dyn_cast<GICmp>(SrcMI)) {
+ std::optional<ValueAndVReg> MayBeConstant =
+ getIConstantVRegValWithLookThrough(Cmp->getRHSReg(), MRI);
+ if (MayBeConstant)
+ Result |= (MayBeConstant->Value == 0) && (Cmp->getLHSReg() == Op0) &&
+ (Cmp->getCond() == ICmpInst::ICMP_EQ);
+ }
+ }
----------------
dc03-work wrote:
The duplication works in InstCombine because of the matching framework, which makes the code much shorter. GlobalISel does not have this, so the code looks much worse. Please deduplicate the code.
https://github.com/llvm/llvm-project/pull/105991
More information about the llvm-commits
mailing list