[llvm] [GlobalIsel] Combine select to integer minmax. (PR #77213)
Thorsten Schütt via llvm-commits
llvm-commits at lists.llvm.org
Tue Jan 9 01:04:33 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}))
----------------
tschuett wrote:
It just reads strange: (a) the shape of the G_UMAX must be legal (AArch64 has limitations) and (b) the G_UMAX must fit into the DstReg.
https://github.com/llvm/llvm-project/pull/77213
More information about the llvm-commits
mailing list