[clang] [llvm] [LV] Support generating masks for switch terminators. (PR #99808)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Aug 1 13:29:51 PDT 2024
================
@@ -7842,6 +7853,61 @@ VPValue *VPRecipeBuilder::createEdgeMask(BasicBlock *Src, BasicBlock *Dst) {
VPValue *SrcMask = getBlockInMask(Src);
+ if (auto *SI = dyn_cast<SwitchInst>(Src->getTerminator())) {
+ assert(!OrigLoop->isLoopExiting(Src) &&
+ all_of(successors(Src),
+ [this](BasicBlock *Succ) {
+ return OrigLoop->getHeader() != Succ;
+ }) &&
+ "unsupported switch either exiting loop or continuing to header");
+ // Create masks where the terminator in Src is a switch. We create mask for
+ // all edges at the same time. This is more efficient, as we can create and
+ // collect compares for all cases once.
+ VPValue *Cond = getVPValueOrAddLiveIn(SI->getCondition(), Plan);
+ BasicBlock *DefaultDst = SI->getDefaultDest();
+ MapVector<BasicBlock *, SmallVector<VPValue *>> Map;
+ for (auto &C : SI->cases()) {
+ auto I = Map.insert({C.getCaseSuccessor(), {}});
+ VPValue *V = getVPValueOrAddLiveIn(C.getCaseValue(), Plan);
+ I.first->second.push_back(Builder.createICmp(CmpInst::ICMP_EQ, Cond, V));
+ }
+
+ // We need to handle 2 separate cases:
+ // 1. Dst is not the default destination. Dst is reached if any of the cases
+ // with destination == Dst are taken. Join the conditions for each case
+ // where destination == Dst using a logical OR.
+ for (const auto &[Dst, Conds] : Map) {
----------------
ayalz wrote:
`Dst` is also a parameter to the method. Better outline this part which computes masks for all edges of a switch to a separate `createSwitchEdgeMasks()` method?
https://github.com/llvm/llvm-project/pull/99808
More information about the cfe-commits
mailing list