[llvm] [SimplifyCFG] Fold switch over ucmp/scmp to icmp and br (PR #105636)
Yingwei Zheng via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 22 03:21:53 PDT 2024
================
@@ -7131,6 +7131,59 @@ static bool simplifySwitchOfPowersOfTwo(SwitchInst *SI, IRBuilder<> &Builder,
return true;
}
+/// Fold switch over ucmp/scmp intrinsic to br if two of the switch arms have
+/// the same destination.
+static bool simplifySwitchOfCmpIntrinsic(SwitchInst *SI,
+ IRBuilderBase &Builder) {
+ auto *Cmp = dyn_cast<CmpIntrinsic>(SI->getCondition());
+ if (!Cmp || !Cmp->hasOneUse() || SI->getNumCases() != 2)
+ return false;
+
+ // Find which of 1, 0 or -1 is missing.
+ SmallSet<int64_t, 3> Missing;
+ Missing.insert(1);
+ Missing.insert(0);
+ Missing.insert(-1);
+ BasicBlock *Succ = nullptr;
+ for (auto &Case : SI->cases()) {
+ std::optional<int64_t> Val = Case.getCaseValue()->getValue().trySExtValue();
+ if (!Val)
+ return false;
+ if (!Missing.erase(*Val))
+ return false;
+ if (Succ && Succ != Case.getCaseSuccessor())
+ return false;
+ Succ = Case.getCaseSuccessor();
+ }
+
+ // Determine predicate for the missing case.
+ ICmpInst::Predicate Pred;
+ assert(Missing.size() == 1 && "Should have one case left");
+ switch (*Missing.begin()) {
+ case 1:
+ Pred = ICmpInst::ICMP_UGT;
+ break;
+ case 0:
+ Pred = ICmpInst::ICMP_EQ;
+ break;
+ case -1:
+ Pred = ICmpInst::ICMP_ULT;
+ break;
+ }
+ if (Cmp->isSigned())
+ Pred = ICmpInst::getSignedPredicate(Pred);
+
+ // The dominator tree does not change, because it treats multi-edges like
+ // a single edge anyway.
+ Builder.SetInsertPoint(SI->getIterator());
+ Value *ICmp = Builder.CreateICmp(Pred, Cmp->getLHS(), Cmp->getRHS());
+ Builder.CreateCondBr(ICmp, SI->getDefaultDest(), Succ);
----------------
dtcxzyw wrote:
Branch weights should be updated.
https://github.com/llvm/llvm-project/pull/105636
More information about the llvm-commits
mailing list