[llvm] [GlobalIsel] Combine select to integer minmax. (PR #77213)
Matt Arsenault via llvm-commits
llvm-commits at lists.llvm.org
Mon Jan 8 22:52:26 PST 2024
================
@@ -6548,6 +6548,87 @@ bool CombinerHelper::tryFoldBoolSelectToLogic(GSelect *Select,
return false;
}
+bool CombinerHelper::tryFoldSelectToIntMinMax(GSelect *Select,
+ BuildFnTy &MatchInfo) {
+ Register DstReg = Select->getReg(0);
+ Register Cond = Select->getCondReg();
+ Register True = Select->getTrueReg();
+ Register False = Select->getFalseReg();
+ LLT DstTy = MRI.getType(DstReg);
+
+ // We need an G_ICMP on the condition register.
+ GICmp *Cmp = getOpcodeDef<GICmp>(Cond, MRI);
+ if (!Cmp)
+ return false;
+
+ CmpInst::Predicate Pred = Cmp->getCond();
+ // We need a larger or smaller predicate for
+ // canonicalization.
+ if (CmpInst::isEquality(Pred))
+ return false;
+
+ Register CmpLHS = Cmp->getLHSReg();
+ Register CmpRHS = Cmp->getRHSReg();
+
+ // We can swap CmpLHS and CmpRHS for higher hitrate.
+ if (True == CmpRHS && False == CmpLHS) {
+ std::swap(CmpLHS, CmpRHS);
+ Pred = CmpInst::getSwappedPredicate(Pred);
+ }
+
+ // (icmp X, Y) ? X : Y -> integer minmax.
+ // see matchSelectPattern in ValueTracking.
+ // Legality between G_SELECT and integer minmax can differ.
+ if (True == CmpLHS && False == CmpRHS) {
+ switch (Pred) {
+ case ICmpInst::ICMP_UGT:
+ case ICmpInst::ICMP_UGE: {
+ if (!isLegalOrBeforeLegalizer({TargetOpcode::G_UMAX, DstTy}))
----------------
arsenm wrote:
I think we need a smarter set of legality predicates. It also makes sense if we're going to legalize this type to a type where it's going to be legal. Doesn't really need to be part of this patch, it's an existing issue scattered around
https://github.com/llvm/llvm-project/pull/77213
More information about the llvm-commits
mailing list