[llvm] [FixIrreducible] Handle conditional branch with both successors as header (PR #206057)

via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 29 20:00:49 PDT 2026


https://github.com/lijinpei-amd updated https://github.com/llvm/llvm-project/pull/206057

>From 3826301999e6a3630d4e1859ae4433dfae96e15f Mon Sep 17 00:00:00 2001
From: Li Jinpei <jinpli at amd.com>
Date: Fri, 26 Jun 2026 21:05:29 +0800
Subject: [PATCH] [FixIrreducible] Handle conditional branch with both
 successors as header

A conditional branch redirecting edges to the cycle header may have both
successors equal to the header (e.g. `br i1 %c, label %h, label %h`),
which the previous `Succ1 = Succ0 ? nullptr : Header` logic mishandled by
dropping the second edge.

Check each successor independently against the header instead.

Fixes https://github.com/llvm/llvm-project/issues/191979.
---
 llvm/lib/Transforms/Utils/FixIrreducible.cpp  |  4 +-
 .../Transforms/FixIrreducible/pr191979.ll     | 40 +++++++++++++++++++
 2 files changed, 41 insertions(+), 3 deletions(-)
 create mode 100644 llvm/test/Transforms/FixIrreducible/pr191979.ll

diff --git a/llvm/lib/Transforms/Utils/FixIrreducible.cpp b/llvm/lib/Transforms/Utils/FixIrreducible.cpp
index ead39f5991081..b4f6262f7b309 100644
--- a/llvm/lib/Transforms/Utils/FixIrreducible.cpp
+++ b/llvm/lib/Transforms/Utils/FixIrreducible.cpp
@@ -298,10 +298,8 @@ static bool fixIrreducible(Cycle &C, CycleInfo &CI, DominatorTree &DT,
       LLVM_DEBUG(dbgs() << "Added internal branch: " << printBasicBlock(P)
                         << " -> " << printBasicBlock(Header) << '\n');
     } else if (CondBrInst *Branch = dyn_cast<CondBrInst>(P->getTerminator())) {
-      // Exactly one of the two successors is the header.
       BasicBlock *Succ0 = Branch->getSuccessor(0) == Header ? Header : nullptr;
-      BasicBlock *Succ1 = Succ0 ? nullptr : Header;
-      assert(Succ0 || Branch->getSuccessor(1) == Header);
+      BasicBlock *Succ1 = Branch->getSuccessor(1) == Header ? Header : nullptr;
       assert(Succ0 || Succ1);
       CHub.addBranch(P, Succ0, Succ1);
 
diff --git a/llvm/test/Transforms/FixIrreducible/pr191979.ll b/llvm/test/Transforms/FixIrreducible/pr191979.ll
new file mode 100644
index 0000000000000..e13dd852ec780
--- /dev/null
+++ b/llvm/test/Transforms/FixIrreducible/pr191979.ll
@@ -0,0 +1,40 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt -S -passes=fix-irreducible < %s | FileCheck %s
+
+; Regression test for https://github.com/llvm/llvm-project/issues/191979.
+define void @foo() {
+; CHECK-LABEL: define void @foo() {
+; CHECK-NEXT:  [[ENTRY:.*:]]
+; CHECK-NEXT:    br label %[[PAD0:.*]]
+; CHECK:       [[PAD0]]:
+; CHECK-NEXT:    br label %[[PAD1:.*]]
+; CHECK:       [[PAD1]]:
+; CHECK-NEXT:    br label %[[IRR_GUARD:.*]]
+; CHECK:       [[A:.*]]:
+; CHECK-NEXT:    br label %[[IRR_GUARD]]
+; CHECK:       [[B:.*]]:
+; CHECK-NEXT:    br i1 false, label %[[EXIT:.*]], label %[[A]]
+; CHECK:       [[EXIT]]:
+; CHECK-NEXT:    ret void
+; CHECK:       [[IRR_GUARD]]:
+; CHECK-NEXT:    [[GUARD_B:%.*]] = phi i1 [ true, %[[A]] ], [ true, %[[PAD1]] ]
+; CHECK-NEXT:    br i1 [[GUARD_B]], label %[[B]], label %[[A]]
+;
+entry:
+  br label %pad0
+
+pad0:
+  br label %pad1
+
+pad1:
+  br i1 false, label %a, label %b
+
+a:
+  br i1 false, label %b, label %b
+
+b:
+  br i1 false, label %exit, label %a
+
+exit:
+  ret void
+}



More information about the llvm-commits mailing list