[llvm] 750088f - [IR] Make BranchInst operand order consistent (#186609)

via llvm-commits llvm-commits at lists.llvm.org
Sat Mar 14 11:40:34 PDT 2026


Author: Alexis Engelke
Date: 2026-03-14T18:40:29Z
New Revision: 750088fa8abacc9263aa2e11b38e38be75d9aa8c

URL: https://github.com/llvm/llvm-project/commit/750088fa8abacc9263aa2e11b38e38be75d9aa8c
DIFF: https://github.com/llvm/llvm-project/commit/750088fa8abacc9263aa2e11b38e38be75d9aa8c.diff

LOG: [IR] Make BranchInst operand order consistent (#186609)

Ensure that successors are always reported in the same order in which
they are stored in the operand list.

Added: 
    

Modified: 
    llvm/docs/ReleaseNotes.md
    llvm/include/llvm/IR/Instructions.h
    llvm/lib/IR/Instructions.cpp
    llvm/tools/llvm-c-test/echo.cpp
    llvm/unittests/IR/InstructionsTest.cpp
    llvm/unittests/SandboxIR/SandboxIRTest.cpp
    llvm/unittests/SandboxIR/TrackerTest.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md
index 2053e087ba23e..b1196e9720451 100644
--- a/llvm/docs/ReleaseNotes.md
+++ b/llvm/docs/ReleaseNotes.md
@@ -86,6 +86,10 @@ Changes to LLVM infrastructure
 * The ``Br`` opcode was split into two opcodes separating unconditional
   (``UncondBr``) and conditional (``CondBr``) branches.
 
+* The operand order of ``CondBr`` instructions was adjusted to match the
+  successor order. This can cause subtle breakage when using ``getOperand`` or
+  ``setOperand`` to access successors.
+
 Changes to building LLVM
 ------------------------
 
@@ -190,6 +194,10 @@ Changes to the C API
 
 * Replaced opcode ``LLVMBr`` with ``LLVMUncondBr`` and ``LLVMCondBr``.
 
+* The operand order of ``CondBr`` instructions was adjusted to match the
+  successor order. This can cause subtle breakage when using ``LLVMGetOperand``
+  or ``LLVMSetOperand`` to access successors.
+
 Changes to the CodeGen infrastructure
 -------------------------------------
 

diff  --git a/llvm/include/llvm/IR/Instructions.h b/llvm/include/llvm/IR/Instructions.h
index ddd4420da2c7e..170b2899bcc4d 100644
--- a/llvm/include/llvm/IR/Instructions.h
+++ b/llvm/include/llvm/IR/Instructions.h
@@ -3226,12 +3226,12 @@ class CondBrInst : public BranchInst {
 
   BasicBlock *getSuccessor(unsigned i) const {
     assert(i < getNumSuccessors() && "Successor # out of range for Branch!");
-    return cast_or_null<BasicBlock>((&Op<-1>() - i)->get());
+    return cast_or_null<BasicBlock>((&Op<-2>() + i)->get());
   }
 
   void setSuccessor(unsigned idx, BasicBlock *NewSucc) {
     assert(idx < getNumSuccessors() && "Successor # out of range for Branch!");
-    *(&Op<-1>() - idx) = NewSucc;
+    *(&Op<-2>() + idx) = NewSucc;
   }
 
   /// Swap the successors of this branch instruction.

diff  --git a/llvm/lib/IR/Instructions.cpp b/llvm/lib/IR/Instructions.cpp
index 4c00ee29ac782..8423ff8a4c453 100644
--- a/llvm/lib/IR/Instructions.cpp
+++ b/llvm/lib/IR/Instructions.cpp
@@ -1218,8 +1218,8 @@ CondBrInst::CondBrInst(Value *Cond, BasicBlock *IfTrue, BasicBlock *IfFalse,
                  AllocMarker, InsertBefore) {
   // Assign in order of operand index to make use-list order predictable.
   Op<-3>() = Cond;
-  Op<-2>() = IfFalse;
-  Op<-1>() = IfTrue;
+  Op<-2>() = IfTrue;
+  Op<-1>() = IfFalse;
 #ifndef NDEBUG
   AssertOK();
 #endif

diff  --git a/llvm/tools/llvm-c-test/echo.cpp b/llvm/tools/llvm-c-test/echo.cpp
index 2f29933c8fe44..3df27998ec057 100644
--- a/llvm/tools/llvm-c-test/echo.cpp
+++ b/llvm/tools/llvm-c-test/echo.cpp
@@ -568,10 +568,10 @@ struct FunCloner {
       }
       case LLVMCondBr: {
         LLVMValueRef Cond = LLVMGetCondition(Src);
-        LLVMValueRef Else = LLVMGetOperand(Src, 1);
-        LLVMBasicBlockRef ElseBB = DeclareBB(LLVMValueAsBasicBlock(Else));
-        LLVMValueRef Then = LLVMGetOperand(Src, 2);
+        LLVMValueRef Then = LLVMGetOperand(Src, 1);
         LLVMBasicBlockRef ThenBB = DeclareBB(LLVMValueAsBasicBlock(Then));
+        LLVMValueRef Else = LLVMGetOperand(Src, 2);
+        LLVMBasicBlockRef ElseBB = DeclareBB(LLVMValueAsBasicBlock(Else));
         Dst = LLVMBuildCondBr(Builder, CloneValue(Cond), ThenBB, ElseBB);
         break;
       }

diff  --git a/llvm/unittests/IR/InstructionsTest.cpp b/llvm/unittests/IR/InstructionsTest.cpp
index ca596f7d7ba68..27f28dfe886a8 100644
--- a/llvm/unittests/IR/InstructionsTest.cpp
+++ b/llvm/unittests/IR/InstructionsTest.cpp
@@ -186,18 +186,18 @@ TEST(InstructionsTest, CondBrInst) {
   EXPECT_EQ(One, b1->getCondition());
   ++b;
 
-  // check ELSE
-  EXPECT_EQ(bb1, *b);
-  EXPECT_EQ(bb1, b1->getOperand(1));
-  EXPECT_EQ(bb1, b1->getSuccessor(1));
-  ++b;
-
   // check THEN
   EXPECT_EQ(bb0, *b);
-  EXPECT_EQ(bb0, b1->getOperand(2));
+  EXPECT_EQ(bb0, b1->getOperand(1));
   EXPECT_EQ(bb0, b1->getSuccessor(0));
   ++b;
 
+  // check ELSE
+  EXPECT_EQ(bb1, *b);
+  EXPECT_EQ(bb1, b1->getOperand(2));
+  EXPECT_EQ(bb1, b1->getSuccessor(1));
+  ++b;
+
   EXPECT_EQ(b1->op_end(), b);
 
   // clean up

diff  --git a/llvm/unittests/SandboxIR/SandboxIRTest.cpp b/llvm/unittests/SandboxIR/SandboxIRTest.cpp
index 271a06290cc1e..01f3a6b914b0f 100644
--- a/llvm/unittests/SandboxIR/SandboxIRTest.cpp
+++ b/llvm/unittests/SandboxIR/SandboxIRTest.cpp
@@ -3120,7 +3120,7 @@ define void @foo(i1 %cond0, i1 %cond2) {
   // Check successors().
   EXPECT_EQ(range_size(Br0->successors()), 2u);
   unsigned SuccIdx = 0;
-  SmallVector<sandboxir::BasicBlock *> ExpectedSuccs({BB1, BB2});
+  SmallVector<sandboxir::BasicBlock *> ExpectedSuccs({BB2, BB1});
   for (sandboxir::BasicBlock *Succ : Br0->successors())
     EXPECT_EQ(Succ, ExpectedSuccs[SuccIdx++]);
 
@@ -3159,7 +3159,7 @@ define void @foo(i1 %cond0, i1 %cond2) {
     EXPECT_TRUE(Br->isConditional());
     EXPECT_EQ(Br->getCondition(), Cond0);
     unsigned SuccIdx = 0;
-    SmallVector<sandboxir::BasicBlock *> ExpectedSuccs({BB2, BB1});
+    SmallVector<sandboxir::BasicBlock *> ExpectedSuccs({BB1, BB2});
     for (sandboxir::BasicBlock *Succ : Br->successors())
       EXPECT_EQ(Succ, ExpectedSuccs[SuccIdx++]);
     EXPECT_EQ(Br->getNextNode(), Ret1);
@@ -3171,7 +3171,7 @@ define void @foo(i1 %cond0, i1 %cond2) {
     EXPECT_TRUE(Br->isConditional());
     EXPECT_EQ(Br->getCondition(), Cond0);
     unsigned SuccIdx = 0;
-    SmallVector<sandboxir::BasicBlock *> ExpectedSuccs({BB2, BB1});
+    SmallVector<sandboxir::BasicBlock *> ExpectedSuccs({BB1, BB2});
     for (sandboxir::BasicBlock *Succ : Br->successors())
       EXPECT_EQ(Succ, ExpectedSuccs[SuccIdx++]);
     EXPECT_EQ(Br->getPrevNode(), Ret2);

diff  --git a/llvm/unittests/SandboxIR/TrackerTest.cpp b/llvm/unittests/SandboxIR/TrackerTest.cpp
index 9c18247b6b96d..7a69ef004ec98 100644
--- a/llvm/unittests/SandboxIR/TrackerTest.cpp
+++ b/llvm/unittests/SandboxIR/TrackerTest.cpp
@@ -131,7 +131,7 @@ define void @foo(i1 %cond) {
   auto *Br = cast<sandboxir::BranchInst>(&*It++);
 
   unsigned SuccIdx = 0;
-  SmallVector<sandboxir::BasicBlock *> ExpectedSuccs({BB2, BB1});
+  SmallVector<sandboxir::BasicBlock *> ExpectedSuccs({BB1, BB2});
   for (auto *Succ : Br->successors())
     EXPECT_EQ(Succ, ExpectedSuccs[SuccIdx++]);
 


        


More information about the llvm-commits mailing list