[llvm] [AMDGPU][FixIrreducible][UnifyLoopExits] Support callbr with inline-asm (PR #149308)

Michael Kruse via llvm-commits llvm-commits at lists.llvm.org
Wed Oct 29 06:57:32 PDT 2025


================
@@ -118,6 +122,34 @@ struct ControlFlowHub {
            std::optional<unsigned> MaxControlFlowBooleans = std::nullopt);
 
   SmallVector<BranchDescriptor> Branches;
+
+  /// \brief Create a new intermediate target block for a callbr edge.
+  ///
+  /// This function creates a new basic block (the "target block") that sits
+  /// between a callbr instruction and one of its successors. The callbr's
+  /// successor is rewired to this new block, and the new block unconditionally
+  /// branches to the original successor. This is useful for normalizing control
+  /// flow, e.g., when transforming irreducible loops.
+  ///
+  /// \param CallBr         The callbr instruction whose edge is to be split.
+  /// \param Succ           The original successor basic block to be reached.
+  /// \param SuccIdx        The index of the successor in the callbr
+  ///                       instruction.
+  /// \param CI             Optional CycleInfo for updating cycle membership.
+  /// \param DTU            Optional DomTreeUpdater for updating the dominator
+  ///                       tree.
+  /// \param LI             Optional LoopInfo for updating loop membership.
+  /// \param UpdatedLI      Optional output flag indicating if LoopInfo has been
+  ///                       updated.
+  ///
+  /// \returns The newly created intermediate target block.
+  ///
+  /// \note This function updates PHI nodes, dominator tree, loop info, and
+  /// cycle info as needed.
+  static BasicBlock *
+  createCallBrTarget(CallBrInst *CallBr, BasicBlock *Succ, unsigned SuccIdx,
+                     CycleInfo *CI = nullptr, DomTreeUpdater *DTU = nullptr,
+                     LoopInfo *LI = nullptr, bool *UpdatedLI = nullptr);
----------------
Meinersbur wrote:

I understand that the semantics may have some nuance. Splitting the predecessor moves the existing branch instruction (in this case `callbr`) behind the new block. Identifying the edge with the sources and destination BasicBlock can be ambiguous if there are multiple such edges.  So there may be a reason to introduce a new function, but it sounds to me as it should be an overload of `SplitEdge`.

`SplitEdge` only does not take a `CycleInfo` argument because `CycleInfo` is newer than `SplitEdge`. Preserving additional analyses can easily be added. `MemorySSAUpdater` was also added retroactively.

https://github.com/llvm/llvm-project/pull/149308


More information about the llvm-commits mailing list