[llvm] [AMDGPU][FixIrreducible][UnifyLoopExits] Support callbr with inline-asm (PR #149308)
Sameer Sahasrabuddhe via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 14 01:17:46 PDT 2025
================
@@ -342,3 +345,76 @@ std::pair<BasicBlock *, bool> ControlFlowHub::finalize(
return {FirstGuardBlock, true};
}
+
+// Check if the given cycle is disjoint with the cycle of the given basic block.
+// If the basic block does not belong to any cycle, this is regarded as
+// disjoint, too.
+static bool disjointWithBlock(CycleInfo *CI, Cycle *C, BasicBlock *BB) {
+ Cycle *CC = CI->getCycle(BB);
+ if (!CC)
+ return true;
+ Cycle *CommonC = CI->getSmallestCommonCycle(C, CC);
+ return CommonC != C && CommonC != CC;
+}
+
+// Check if the given loop is disjoint with the loop of the given basic block.
+// If the basic block does not belong to any loop, this is regarded as
+// disjoint, too.
+static bool disjointWithBlock(LoopInfo *LI, Loop *L, BasicBlock *BB) {
+ Loop *LL = LI->getLoopFor(BB);
+ return LL && !L->contains(LL) && !LL->contains(L);
+}
+
+template <typename TI, typename T>
+static void updateCycleLoopInfo(TI *LCI, bool AttachToCallBr,
+ BasicBlock *CallBrBlock,
+ BasicBlock *CallBrTarget, BasicBlock *Succ) {
+ static_assert(std::is_same_v<TI, CycleInfo> || std::is_same_v<TI, LoopInfo>,
+ "type must be CycleInfo or LoopInfo");
+ if (!LCI)
+ return;
+
+ T *LC;
+ if constexpr (std::is_same_v<TI, CycleInfo>)
+ LC = LCI->getCycle(AttachToCallBr ? CallBrBlock : Succ);
+ else
+ LC = LCI->getLoopFor(AttachToCallBr ? CallBrBlock : Succ);
+ if (!LC)
+ return;
+
+ // Check if the cycles/loops are disjoint. In that case, we do not add the
+ // intermediate target to any cycle/loop.
+ if (AttachToCallBr && disjointWithBlock(LCI, LC, Succ))
----------------
ssahasra wrote:
If we return at the next line, then `CallBrTarget` is not added to any cycle, although there could be an outer cycle that contains both `LC` and `Succ`. Is there a test which demonstrate such a nesting?
Generalizing that, I am not sure we even need the complication of passing `AttachToCallBr` and checking `disjointWithBlock`. Isn't it sufficient to add `CallBrTarget` to the smallest common parent `CP` of `CallBrBlock` and `Succ`? If we added it to the parent of either block and that parent did not contain the other block, then that parent would no longer be strongly connected and `LCI` should fail validation.
https://github.com/llvm/llvm-project/pull/149308
More information about the llvm-commits
mailing list