[SandboxIR] Implement UncondBrInst and CondBrInst (#187196)

This patch implements the unconditional and conditional branch
instructions mirroring the newly added LLVM IR instructions.

So now we have two new classes UncondBrInst and CondBrInst inheriting
from BranchInst.

The original Br opcode has been removed in favor of UncondBr and CondBr.
This commit is contained in:
vporpo 2026-03-19 10:28:32 -07:00 committed by GitHub
parent 7925ef6df8
commit 467cf7caed
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 226 additions and 129 deletions

View File

@ -178,8 +178,10 @@ protected:
friend ExtractValueInst; // For createExtractValueInst()
LLVM_ABI InsertValueInst *createInsertValueInst(llvm::InsertValueInst *IVI);
friend InsertValueInst; // For createInsertValueInst()
LLVM_ABI BranchInst *createBranchInst(llvm::BranchInst *I);
friend BranchInst; // For createBranchInst()
LLVM_ABI UncondBrInst *createUncondBrInst(llvm::UncondBrInst *UBI);
friend UncondBrInst; // For createUncondBrInst()
LLVM_ABI CondBrInst *createCondBrInst(llvm::CondBrInst *CBI);
friend CondBrInst; // For createCondBrInst()
LLVM_ABI LoadInst *createLoadInst(llvm::LoadInst *LI);
friend LoadInst; // For createLoadInst()
LLVM_ABI StoreInst *createStoreInst(llvm::StoreInst *SI);

View File

@ -68,7 +68,6 @@ protected:
friend class ShuffleVectorInst; // For getTopmostLLVMInstruction().
friend class ExtractValueInst; // For getTopmostLLVMInstruction().
friend class InsertValueInst; // For getTopmostLLVMInstruction().
friend class BranchInst; // For getTopmostLLVMInstruction().
friend class LoadInst; // For getTopmostLLVMInstruction().
friend class StoreInst; // For getTopmostLLVMInstruction().
friend class ReturnInst; // For getTopmostLLVMInstruction().
@ -1019,33 +1018,9 @@ public:
}
};
class BranchInst : public SingleLLVMInstructionImpl<llvm::BranchInst> {
/// Use Context::createBranchInst(). Don't call the constructor directly.
BranchInst(llvm::BranchInst *BI, Context &Ctx)
: SingleLLVMInstructionImpl(ClassID::Br, Opcode::Br, BI, Ctx) {}
friend Context; // for BranchInst()
public:
LLVM_ABI static BranchInst *create(BasicBlock *IfTrue, InsertPosition Pos,
Context &Ctx);
LLVM_ABI static BranchInst *create(BasicBlock *IfTrue, BasicBlock *IfFalse,
Value *Cond, InsertPosition Pos,
Context &Ctx);
/// For isa/dyn_cast.
LLVM_ABI static bool classof(const Value *From);
bool isUnconditional() const {
return cast<llvm::BranchInst>(Val)->isUnconditional();
}
bool isConditional() const {
return cast<llvm::BranchInst>(Val)->isConditional();
}
LLVM_ABI Value *getCondition() const;
void setCondition(Value *V) { setOperand(0, V); }
unsigned getNumSuccessors() const { return 1 + isConditional(); }
LLVM_ABI BasicBlock *getSuccessor(unsigned SuccIdx) const;
LLVM_ABI void setSuccessor(unsigned Idx, BasicBlock *NewSucc);
void swapSuccessors() { swapOperandsInternal(1, 2); }
/// Both UncondBrInst and CondBrInst inherit from this to avoid duplication of
/// the successor iterators and successors(). Does not hold any state.
class BrInstCommon {
private:
struct LLVMBBToSBBB {
Context &Ctx;
@ -1059,33 +1034,99 @@ private:
LLVM_ABI const BasicBlock *operator()(const llvm::BasicBlock *BB) const;
};
public:
protected:
template <typename LLVMBrTy>
using sb_succ_op_iterator =
mapped_iterator<llvm::BranchInst::succ_iterator, LLVMBBToSBBB>;
iterator_range<sb_succ_op_iterator> successors() {
iterator_range<llvm::BranchInst::succ_iterator> LLVMRange =
cast<llvm::BranchInst>(Val)->successors();
mapped_iterator<typename LLVMBrTy::succ_iterator, LLVMBBToSBBB>;
template <typename LLVMBrTy>
iterator_range<sb_succ_op_iterator<LLVMBrTy>> successors(llvm::Value *Val,
Context &Ctx) {
iterator_range<typename LLVMBrTy::succ_iterator> LLVMRange =
cast<LLVMBrTy>(Val)->successors();
LLVMBBToSBBB BBMap(Ctx);
sb_succ_op_iterator MappedBegin = map_iterator(LLVMRange.begin(), BBMap);
sb_succ_op_iterator MappedEnd = map_iterator(LLVMRange.end(), BBMap);
sb_succ_op_iterator<LLVMBrTy> MappedBegin =
map_iterator(LLVMRange.begin(), BBMap);
sb_succ_op_iterator<LLVMBrTy> MappedEnd =
map_iterator(LLVMRange.end(), BBMap);
return make_range(MappedBegin, MappedEnd);
}
template <typename LLVMBrTy>
using const_sb_succ_op_iterator =
mapped_iterator<llvm::BranchInst::const_succ_iterator, ConstLLVMBBToSBBB>;
iterator_range<const_sb_succ_op_iterator> successors() const {
iterator_range<llvm::BranchInst::const_succ_iterator> ConstLLVMRange =
static_cast<const llvm::BranchInst *>(cast<llvm::BranchInst>(Val))
->successors();
mapped_iterator<typename LLVMBrTy::const_succ_iterator,
ConstLLVMBBToSBBB>;
template <typename LLVMBrTy>
iterator_range<const_sb_succ_op_iterator<LLVMBrTy>>
successors(llvm::Value *Val, Context &Ctx) const {
llvm::iterator_range<typename LLVMBrTy::const_succ_iterator>
ConstLLVMRange =
static_cast<const LLVMBrTy *>(cast<LLVMBrTy>(Val))->successors();
ConstLLVMBBToSBBB ConstBBMap(Ctx);
const_sb_succ_op_iterator ConstMappedBegin =
const_sb_succ_op_iterator<LLVMBrTy> ConstMappedBegin =
map_iterator(ConstLLVMRange.begin(), ConstBBMap);
const_sb_succ_op_iterator ConstMappedEnd =
const_sb_succ_op_iterator<LLVMBrTy> ConstMappedEnd =
map_iterator(ConstLLVMRange.end(), ConstBBMap);
return make_range(ConstMappedBegin, ConstMappedEnd);
}
};
class UncondBrInst : public SingleLLVMInstructionImpl<llvm::UncondBrInst>,
public BrInstCommon {
/// Use Context::createUncondBrInst(). Don't call the constructor directly.
UncondBrInst(llvm::UncondBrInst *UBI, Context &Ctx)
: SingleLLVMInstructionImpl(ClassID::UncondBr, Opcode::UncondBr, UBI,
Ctx) {}
friend Context; // for UncondBrInst()
public:
static UncondBrInst *create(BasicBlock *Target, InsertPosition InsertBefore,
Context &Ctx);
LLVM_ABI BasicBlock *getSuccessor() const;
LLVM_ABI void setSuccessor(BasicBlock *NewSucc);
unsigned getNumSuccessors() const { return 1; }
using succ_op_iterator = sb_succ_op_iterator<llvm::UncondBrInst>;
using const_succ_op_iterator = const_sb_succ_op_iterator<llvm::UncondBrInst>;
iterator_range<succ_op_iterator> successors() {
return BrInstCommon::successors<llvm::UncondBrInst>(Val, Ctx);
}
iterator_range<const_succ_op_iterator> successors() const {
return BrInstCommon::successors<llvm::UncondBrInst>(Val, Ctx);
}
/// For isa/dyn_cast.
LLVM_ABI static bool classof(const Value *From);
};
class CondBrInst : public SingleLLVMInstructionImpl<llvm::CondBrInst>,
public BrInstCommon {
/// Use Context::createUncondBrInst(). Don't call the constructor directly.
CondBrInst(llvm::CondBrInst *CBI, Context &Ctx)
: SingleLLVMInstructionImpl(ClassID::CondBr, Opcode::CondBr, CBI, Ctx) {}
friend Context; // for UcnondBrInst()
public:
static CondBrInst *create(Value *Cond, BasicBlock *IfTrue,
BasicBlock *IfFalse, InsertPosition InsertBefore,
Context &Ctx);
LLVM_ABI Value *getCondition() const;
void setCondition(Value *V);
LLVM_ABI BasicBlock *getSuccessor(unsigned SuccIdx) const;
LLVM_ABI void setSuccessor(unsigned Idx, BasicBlock *NewSucc);
unsigned getNumSuccessors() const { return 2; }
void swapSuccessors() { swapOperandsInternal(1, 2); }
using succ_op_iterator = sb_succ_op_iterator<llvm::CondBrInst>;
using const_succ_op_iterator = const_sb_succ_op_iterator<llvm::CondBrInst>;
iterator_range<succ_op_iterator> successors() {
return BrInstCommon::successors<llvm::CondBrInst>(Val, Ctx);
}
iterator_range<const_succ_op_iterator> successors() const {
return BrInstCommon::successors<llvm::CondBrInst>(Val, Ctx);
}
/// For isa/dyn_cast.
LLVM_ABI static bool classof(const Value *From);
};
/// An abstract class, parent of unary instructions.
class UnaryInstruction
: public SingleLLVMInstructionImpl<llvm::UnaryInstruction> {

View File

@ -34,6 +34,8 @@ class Operator;
class OverflowingBinaryOperator;
class FPMathOperator;
class Region;
class UncondBrInst;
class CondBrInst;
/// Iterator for the `Use` edges of a Value's users.
/// \Returns a `Use` when dereferenced.
@ -117,7 +119,8 @@ protected:
friend class ShuffleVectorInst; // For getting `Val`.
friend class ExtractValueInst; // For getting `Val`.
friend class InsertValueInst; // For getting `Val`.
friend class BranchInst; // For getting `Val`.
friend class UncondBrInst; // For getting `Val`.
friend class CondBrInst; // For getting `Val`.
friend class LoadInst; // For getting `Val`.
friend class StoreInst; // For getting `Val`.
friend class ReturnInst; // For getting `Val`.

View File

@ -70,7 +70,8 @@ DEF_INSTR(ShuffleVector, OP(ShuffleVector), ShuffleVectorInst)
DEF_INSTR(ExtractValue, OP(ExtractValue), ExtractValueInst)
DEF_INSTR(InsertValue, OP(InsertValue), InsertValueInst)
DEF_INSTR(Select, OP(Select), SelectInst)
DEF_INSTR(Br, OP(Br), BranchInst)
DEF_INSTR(UncondBr, OP(UncondBr), UncondBrInst)
DEF_INSTR(CondBr, OP(CondBr), CondBrInst)
DEF_INSTR(Load, OP(Load), LoadInst)
DEF_INSTR(Store, OP(Store), StoreInst)
DEF_INSTR(Ret, OP(Ret), ReturnInst)

View File

@ -113,10 +113,15 @@ Value *Context::getOrCreateValueInternal(llvm::Value *LLVMV, llvm::User *U) {
std::unique_ptr<InsertValueInst>(new InsertValueInst(LLVMIns, *this));
return It->second.get();
}
case llvm::Instruction::UncondBr:
case llvm::Instruction::UncondBr: {
auto *LLVMBr = cast<llvm::UncondBrInst>(LLVMV);
It->second =
std::unique_ptr<UncondBrInst>(new UncondBrInst(LLVMBr, *this));
return It->second.get();
}
case llvm::Instruction::CondBr: {
auto *LLVMBr = cast<llvm::BranchInst>(LLVMV);
It->second = std::unique_ptr<BranchInst>(new BranchInst(LLVMBr, *this));
auto *LLVMBr = cast<llvm::CondBrInst>(LLVMV);
It->second = std::unique_ptr<CondBrInst>(new CondBrInst(LLVMBr, *this));
return It->second.get();
}
case llvm::Instruction::Load: {
@ -509,9 +514,14 @@ InsertValueInst *Context::createInsertValueInst(llvm::InsertValueInst *IVI) {
return cast<InsertValueInst>(registerValue(std::move(NewPtr)));
}
BranchInst *Context::createBranchInst(llvm::BranchInst *BI) {
auto NewPtr = std::unique_ptr<BranchInst>(new BranchInst(BI, *this));
return cast<BranchInst>(registerValue(std::move(NewPtr)));
UncondBrInst *Context::createUncondBrInst(llvm::UncondBrInst *UBI) {
auto NewPtr = std::unique_ptr<UncondBrInst>(new UncondBrInst(UBI, *this));
return cast<UncondBrInst>(registerValue(std::move(NewPtr)));
}
CondBrInst *Context::createCondBrInst(llvm::CondBrInst *CBI) {
auto NewPtr = std::unique_ptr<CondBrInst>(new CondBrInst(CBI, *this));
return cast<CondBrInst>(registerValue(std::move(NewPtr)));
}
LoadInst *Context::createLoadInst(llvm::LoadInst *LI) {

View File

@ -347,52 +347,84 @@ bool SelectInst::classof(const Value *From) {
return From->getSubclassID() == ClassID::Select;
}
BranchInst *BranchInst::create(BasicBlock *IfTrue, InsertPosition Pos,
Context &Ctx) {
auto &Builder = setInsertPos(Pos);
llvm::BranchInst *NewBr =
Builder.CreateBr(cast<llvm::BasicBlock>(IfTrue->Val));
return Ctx.createBranchInst(NewBr);
}
BranchInst *BranchInst::create(BasicBlock *IfTrue, BasicBlock *IfFalse,
Value *Cond, InsertPosition Pos, Context &Ctx) {
auto &Builder = setInsertPos(Pos);
llvm::BranchInst *NewBr =
Builder.CreateCondBr(Cond->Val, cast<llvm::BasicBlock>(IfTrue->Val),
cast<llvm::BasicBlock>(IfFalse->Val));
return Ctx.createBranchInst(NewBr);
}
bool BranchInst::classof(const Value *From) {
return From->getSubclassID() == ClassID::Br;
}
Value *BranchInst::getCondition() const {
assert(isConditional() && "Cannot get condition of an uncond branch!");
return Ctx.getValue(cast<llvm::BranchInst>(Val)->getCondition());
}
BasicBlock *BranchInst::getSuccessor(unsigned SuccIdx) const {
assert(SuccIdx < getNumSuccessors() &&
"Successor # out of range for Branch!");
return cast_or_null<BasicBlock>(
Ctx.getValue(cast<llvm::BranchInst>(Val)->getSuccessor(SuccIdx)));
}
void BranchInst::setSuccessor(unsigned Idx, BasicBlock *NewSucc) {
assert((Idx == 0 || Idx == 1) && "Out of bounds!");
setOperand(2u - Idx, NewSucc);
}
BasicBlock *BranchInst::LLVMBBToSBBB::operator()(llvm::BasicBlock *BB) const {
BasicBlock *BrInstCommon::LLVMBBToSBBB::operator()(llvm::BasicBlock *BB) const {
return cast<BasicBlock>(Ctx.getValue(BB));
}
const BasicBlock *
BranchInst::ConstLLVMBBToSBBB::operator()(const llvm::BasicBlock *BB) const {
BrInstCommon::ConstLLVMBBToSBBB::operator()(const llvm::BasicBlock *BB) const {
return cast<BasicBlock>(Ctx.getValue(BB));
}
UncondBrInst *UncondBrInst::create(BasicBlock *Target,
InsertPosition InsertBefore, Context &Ctx) {
auto &Builder = setInsertPos(InsertBefore);
llvm::UncondBrInst *NewUBr =
Builder.CreateBr(cast<llvm::BasicBlock>(Target->Val));
return Ctx.createUncondBrInst(NewUBr);
}
BasicBlock *UncondBrInst::getSuccessor() const {
return cast_or_null<BasicBlock>(
Ctx.getValue(cast<llvm::UncondBrInst>(Val)->getSuccessor()));
}
void UncondBrInst::setSuccessor(BasicBlock *NewSucc) {
Ctx.getTracker()
.emplaceIfTracking<GenericSetter<&UncondBrInst::getSuccessor,
&UncondBrInst::setSuccessor>>(this);
cast<llvm::UncondBrInst>(Val)->setSuccessor(
0, cast<llvm::BasicBlock>(NewSucc->Val));
}
bool UncondBrInst::classof(const Value *From) {
return From->getSubclassID() == ClassID::UncondBr;
}
CondBrInst *CondBrInst::create(Value *Cond, BasicBlock *IfTrue,
BasicBlock *IfFalse, InsertPosition InsertBefore,
Context &Ctx) {
auto &Builder = setInsertPos(InsertBefore);
llvm::CondBrInst *NewCBr = Builder.CreateCondBr(
cast<llvm::Value>(Cond->Val), cast<llvm::BasicBlock>(IfTrue->Val),
cast<llvm::BasicBlock>(IfFalse->Val));
return Ctx.createCondBrInst(NewCBr);
}
Value *CondBrInst::getCondition() const {
assert(isa<llvm::CondBrInst>(Val) &&
"Cannot get condition of an uncond branch!");
return Ctx.getValue(cast<llvm::CondBrInst>(Val)->getCondition());
}
void CondBrInst::setCondition(Value *V) {
Ctx.getTracker()
.emplaceIfTracking<
GenericSetter<&CondBrInst::getCondition, &CondBrInst::setCondition>>(
this);
llvm::Value *LLVMV = V->Val;
cast<llvm::CondBrInst>(Val)->setCondition(LLVMV);
}
BasicBlock *CondBrInst::getSuccessor(unsigned SuccIdx) const {
assert(SuccIdx < getNumSuccessors() &&
"Successor # out of range for Branch!");
return cast_or_null<BasicBlock>(
Ctx.getValue(cast<llvm::CondBrInst>(Val)->getSuccessor(SuccIdx)));
}
void CondBrInst::setSuccessor(unsigned Idx, BasicBlock *NewSucc) {
assert(Idx < getNumSuccessors() && "Out of bounds!");
Ctx.getTracker()
.emplaceIfTracking<GenericSetterWithIdx<&CondBrInst::getSuccessor,
&CondBrInst::setSuccessor>>(this,
Idx);
cast<llvm::CondBrInst>(Val)->setSuccessor(
Idx, cast<llvm::BasicBlock>(NewSucc->Val));
}
bool CondBrInst::classof(const Value *From) {
return From->getSubclassID() == ClassID::CondBr;
}
void LoadInst::setVolatile(bool V) {
Ctx.getTracker()
.emplaceIfTracking<

View File

@ -159,7 +159,8 @@ LegalityAnalysis::notVectorizableBasedOnOpcodesAndTypes(
return ResultReason::Unimplemented;
case Instruction::Opcode::Opaque:
return ResultReason::Unimplemented;
case Instruction::Opcode::Br:
case Instruction::Opcode::UncondBr:
case Instruction::Opcode::CondBr:
case Instruction::Opcode::Ret:
case Instruction::Opcode::AddrSpaceCast:
case Instruction::Opcode::InsertElement:

View File

@ -153,7 +153,8 @@ Value *BottomUpVec::createVectorInstr(ArrayRef<Value *> Bndl,
Value *Ptr = Operands[1];
return StoreInst::create(Val, Ptr, Align, WhereIt, Ctx);
}
case Instruction::Opcode::Br:
case Instruction::Opcode::UncondBr:
case Instruction::Opcode::CondBr:
case Instruction::Opcode::Ret:
case Instruction::Opcode::PHI:
case Instruction::Opcode::AddrSpaceCast:

View File

@ -1842,7 +1842,7 @@ define void @foo1() {
EXPECT_EQ(Buff, R"IR(
void @foo0(i32 %arg0, i32 %arg1) {
bb0:
br label %bb1 ; SB4. (Br)
br label %bb1 ; SB4. (UncondBr)
bb1:
ret void ; SB6. (Ret)
@ -1983,7 +1983,7 @@ bb1:
BB0.dumpOS(BS);
EXPECT_EQ(Buff, R"IR(
bb0:
br label %bb1 ; SB3. (Br)
br label %bb1 ; SB3. (UncondBr)
)IR");
}
#endif // NDEBUG
@ -3098,11 +3098,7 @@ define void @foo(i1 %cond0, i1 %cond2) {
Ctx.getValue(getBasicBlockByName(*LLVMF, "bb2")));
auto *Ret2 = BB2->getTerminator();
auto It = BB0->begin();
auto *Br0 = cast<sandboxir::BranchInst>(&*It++);
// Check isUnconditional().
EXPECT_FALSE(Br0->isUnconditional());
// Check isConditional().
EXPECT_TRUE(Br0->isConditional());
auto *Br0 = cast<sandboxir::CondBrInst>(&*It++);
// Check getCondition().
EXPECT_EQ(Br0->getCondition(), Cond0);
// Check setCondition().
@ -3111,12 +3107,12 @@ define void @foo(i1 %cond0, i1 %cond2) {
// Check getNumSuccessors().
EXPECT_EQ(Br0->getNumSuccessors(), 2u);
// Check getSuccessor().
EXPECT_EQ(Br0->getSuccessor(0), BB1);
EXPECT_EQ(Br0->getSuccessor(1), BB2);
EXPECT_EQ(cast<sandboxir::CondBrInst>(Br0)->getSuccessor(0), BB1);
EXPECT_EQ(cast<sandboxir::CondBrInst>(Br0)->getSuccessor(1), BB2);
// Check swapSuccessors().
Br0->swapSuccessors();
EXPECT_EQ(Br0->getSuccessor(0), BB2);
EXPECT_EQ(Br0->getSuccessor(1), BB1);
EXPECT_EQ(cast<sandboxir::CondBrInst>(Br0)->getSuccessor(0), BB2);
EXPECT_EQ(cast<sandboxir::CondBrInst>(Br0)->getSuccessor(1), BB1);
// Check successors().
EXPECT_EQ(range_size(Br0->successors()), 2u);
unsigned SuccIdx = 0;
@ -3125,13 +3121,15 @@ define void @foo(i1 %cond0, i1 %cond2) {
EXPECT_EQ(Succ, ExpectedSuccs[SuccIdx++]);
{
// Check unconditional BranchInst::create() InsertBefore.
auto *Br = sandboxir::BranchInst::create(BB1, Ret1->getIterator(), Ctx);
EXPECT_FALSE(Br->isConditional());
EXPECT_TRUE(Br->isUnconditional());
#ifndef NDEBUG
EXPECT_DEATH(Br->getCondition(), ".*condition.*");
#endif // NDEBUG
// Check UncondBrInst::create() InsertBefore.
auto *Br = sandboxir::UncondBrInst::create(BB1, Ret1->getIterator(), Ctx);
EXPECT_EQ(Br->getSuccessor(), BB1);
// Check UncondBrInst::setSuccessor().
EXPECT_EQ(Br->getSuccessor(), BB1);
Br->setSuccessor(BB2);
EXPECT_EQ(Br->getSuccessor(), BB2);
Br->setSuccessor(BB1);
unsigned SuccIdx = 0;
SmallVector<sandboxir::BasicBlock *> ExpectedSuccs({BB1});
for (sandboxir::BasicBlock *Succ : Br->successors())
@ -3139,13 +3137,8 @@ define void @foo(i1 %cond0, i1 %cond2) {
EXPECT_EQ(Br->getNextNode(), Ret1);
}
{
// Check unconditional BranchInst::create() InsertAtEnd.
auto *Br = sandboxir::BranchInst::create(BB1, /*InsertAtEnd=*/BB1, Ctx);
EXPECT_FALSE(Br->isConditional());
EXPECT_TRUE(Br->isUnconditional());
#ifndef NDEBUG
EXPECT_DEATH(Br->getCondition(), ".*condition.*");
#endif // NDEBUG
// Check UncondBrInst::create() InsertAtEnd.
auto *Br = sandboxir::UncondBrInst::create(BB1, /*InsertAtEnd=*/BB1, Ctx);
unsigned SuccIdx = 0;
SmallVector<sandboxir::BasicBlock *> ExpectedSuccs({BB1});
for (sandboxir::BasicBlock *Succ : Br->successors())
@ -3153,11 +3146,25 @@ define void @foo(i1 %cond0, i1 %cond2) {
EXPECT_EQ(Br->getPrevNode(), Ret1);
}
{
// Check conditional BranchInst::create() InsertBefore.
auto *Br = sandboxir::BranchInst::create(BB1, BB2, Cond0,
// Check CondBrInst::create() InsertBefore.
auto *Br = sandboxir::CondBrInst::create(Cond0, BB1, BB2,
Ret1->getIterator(), Ctx);
EXPECT_TRUE(Br->isConditional());
EXPECT_EQ(Br->getCondition(), Cond0);
// Check CondBrInst::setSuccessor().
EXPECT_EQ(Br->getSuccessor(0), BB1);
EXPECT_EQ(Br->getSuccessor(1), BB2);
Br->setSuccessor(0, BB2);
EXPECT_EQ(Br->getSuccessor(0), BB2);
EXPECT_EQ(Br->getSuccessor(1), BB2);
Br->setSuccessor(1, BB1);
EXPECT_EQ(Br->getSuccessor(0), BB2);
EXPECT_EQ(Br->getSuccessor(1), BB1);
Br->setSuccessor(0, BB1);
Br->setSuccessor(1, BB2);
EXPECT_EQ(Br->getSuccessor(0), BB1);
EXPECT_EQ(Br->getSuccessor(1), BB2);
unsigned SuccIdx = 0;
SmallVector<sandboxir::BasicBlock *> ExpectedSuccs({BB1, BB2});
for (sandboxir::BasicBlock *Succ : Br->successors())
@ -3165,10 +3172,9 @@ define void @foo(i1 %cond0, i1 %cond2) {
EXPECT_EQ(Br->getNextNode(), Ret1);
}
{
// Check conditional BranchInst::create() InsertAtEnd.
auto *Br = sandboxir::BranchInst::create(BB1, BB2, Cond0,
// Check CondBrInst::create() InsertAtEnd.
auto *Br = sandboxir::CondBrInst::create(Cond0, BB1, BB2,
/*InsertAtEnd=*/BB2, Ctx);
EXPECT_TRUE(Br->isConditional());
EXPECT_EQ(Br->getCondition(), Cond0);
unsigned SuccIdx = 0;
SmallVector<sandboxir::BasicBlock *> ExpectedSuccs({BB1, BB2});
@ -5875,7 +5881,7 @@ bb5:
auto It = BB2->begin();
// Check classof().
auto *PHI = cast<sandboxir::PHINode>(&*It++);
auto *Br = cast<sandboxir::BranchInst>(&*It++);
auto *Br = cast<sandboxir::UncondBrInst>(&*It++);
// Check blocks().
EXPECT_EQ(range_size(PHI->blocks()), range_size(LLVMPHI->blocks()));
auto BlockIt = PHI->block_begin();

View File

@ -128,7 +128,7 @@ define void @foo(i1 %cond) {
auto &Tracker = Ctx.getTracker();
Tracker.save();
auto It = BB0->begin();
auto *Br = cast<sandboxir::BranchInst>(&*It++);
auto *Br = cast<sandboxir::CondBrInst>(&*It++);
unsigned SuccIdx = 0;
SmallVector<sandboxir::BasicBlock *> ExpectedSuccs({BB1, BB2});

View File

@ -442,7 +442,7 @@ bb1:
auto &F = *Ctx.createFunction(&LLVMF);
auto &BB0 = getBasicBlockByName(F, "bb0");
auto It = BB0.begin();
auto *BB0I = cast<sandboxir::BranchInst>(&*It++);
auto *BB0I = cast<sandboxir::UncondBrInst>(&*It++);
auto &BB = getBasicBlockByName(F, "bb1");
It = BB.begin();
@ -518,7 +518,7 @@ bb2:
auto It = BB.begin();
auto *PHI1 = cast<sandboxir::PHINode>(&*It++);
auto *PHI2 = cast<sandboxir::PHINode>(&*It++);
auto *Br = cast<sandboxir::BranchInst>(&*It++);
auto *Br = cast<sandboxir::UncondBrInst>(&*It++);
EXPECT_EQ(sandboxir::VecUtils::getLastPHIOrSelf(PHI1), PHI2);
EXPECT_EQ(sandboxir::VecUtils::getLastPHIOrSelf(PHI2), PHI2);
EXPECT_EQ(sandboxir::VecUtils::getLastPHIOrSelf(Br), Br);