[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