Skip to content

[IR][NFC] Use SwitchInst::defaultDestUnreachable #134199

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Apr 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion llvm/include/llvm/IR/Instructions.h
Original file line number Diff line number Diff line change
Expand Up @@ -3366,7 +3366,7 @@ class SwitchInst : public Instruction {

/// Returns true if the default branch must result in immediate undefined
/// behavior, false otherwise.
bool defaultDestUndefined() const {
bool defaultDestUnreachable() const {
return isa<UnreachableInst>(getDefaultDest()->getFirstNonPHIOrDbg());
}

Expand Down
4 changes: 2 additions & 2 deletions llvm/include/llvm/SandboxIR/Instruction.h
Original file line number Diff line number Diff line change
Expand Up @@ -1865,8 +1865,8 @@ class SwitchInst : public SingleLLVMInstructionImpl<llvm::SwitchInst> {
Value *getCondition() const;
void setCondition(Value *V);
BasicBlock *getDefaultDest() const;
bool defaultDestUndefined() const {
return cast<llvm::SwitchInst>(Val)->defaultDestUndefined();
bool defaultDestUnreachable() const {
return cast<llvm::SwitchInst>(Val)->defaultDestUnreachable();
}
void setDefaultDest(BasicBlock *DefaultCase);
unsigned getNumCases() const {
Expand Down
16 changes: 8 additions & 8 deletions llvm/lib/Analysis/InlineCost.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ class CallAnalyzer : public InstVisitor<CallAnalyzer, bool> {
/// Called at the end of processing a switch instruction, with the given
/// number of case clusters.
virtual void onFinalizeSwitch(unsigned JumpTableSize, unsigned NumCaseCluster,
bool DefaultDestUndefined) {}
bool DefaultDestUnreachable) {}

/// Called to account for any other instruction not specifically accounted
/// for.
Expand Down Expand Up @@ -722,14 +722,14 @@ class InlineCostCallAnalyzer final : public CallAnalyzer {
}

void onFinalizeSwitch(unsigned JumpTableSize, unsigned NumCaseCluster,
bool DefaultDestUndefined) override {
bool DefaultDestUnreachable) override {
// If suitable for a jump table, consider the cost for the table size and
// branch to destination.
// Maximum valid cost increased in this function.
if (JumpTableSize) {
// Suppose a default branch includes one compare and one conditional
// branch if it's reachable.
if (!DefaultDestUndefined)
if (!DefaultDestUnreachable)
addCost(2 * InstrCost);
// Suppose a jump table requires one load and one jump instruction.
int64_t JTCost =
Expand All @@ -742,7 +742,7 @@ class InlineCostCallAnalyzer final : public CallAnalyzer {
// Suppose a comparison includes one compare and one conditional branch.
// We can reduce a set of instructions if the default branch is
// undefined.
addCost((NumCaseCluster - DefaultDestUndefined) * 2 * InstrCost);
addCost((NumCaseCluster - DefaultDestUnreachable) * 2 * InstrCost);
return;
}

Expand Down Expand Up @@ -1268,9 +1268,9 @@ class InlineCostFeaturesAnalyzer final : public CallAnalyzer {
}

void onFinalizeSwitch(unsigned JumpTableSize, unsigned NumCaseCluster,
bool DefaultDestUndefined) override {
bool DefaultDestUnreachable) override {
if (JumpTableSize) {
if (!DefaultDestUndefined)
if (!DefaultDestUnreachable)
increment(InlineCostFeatureIndex::switch_default_dest_penalty,
SwitchDefaultDestCostMultiplier * InstrCost);
int64_t JTCost = static_cast<int64_t>(JumpTableSize) * InstrCost +
Expand All @@ -1281,7 +1281,7 @@ class InlineCostFeaturesAnalyzer final : public CallAnalyzer {

if (NumCaseCluster <= 3) {
increment(InlineCostFeatureIndex::case_cluster_penalty,
(NumCaseCluster - DefaultDestUndefined) *
(NumCaseCluster - DefaultDestUnreachable) *
CaseClusterCostMultiplier * InstrCost);
return;
}
Expand Down Expand Up @@ -2508,7 +2508,7 @@ bool CallAnalyzer::visitSwitchInst(SwitchInst &SI) {
unsigned NumCaseCluster =
TTI.getEstimatedNumberOfCaseClusters(SI, JumpTableSize, PSI, BFI);

onFinalizeSwitch(JumpTableSize, NumCaseCluster, SI.defaultDestUndefined());
onFinalizeSwitch(JumpTableSize, NumCaseCluster, SI.defaultDestUnreachable());
return false;
}

Expand Down
5 changes: 2 additions & 3 deletions llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -410,9 +410,8 @@ static bool processSwitch(SwitchInst *I, LazyValueInfo *LVI,
++ReachableCaseCount;
}

BasicBlock *DefaultDest = SI->getDefaultDest();
if (ReachableCaseCount > 1 &&
!isa<UnreachableInst>(DefaultDest->getFirstNonPHIOrDbg())) {
if (ReachableCaseCount > 1 && !SI->defaultDestUnreachable()) {
BasicBlock *DefaultDest = SI->getDefaultDest();
ConstantRange CR = LVI->getConstantRangeAtUse(I->getOperandUse(0),
/*UndefAllowed*/ false);
// The default dest is unreachable if all cases are covered.
Expand Down
4 changes: 1 addition & 3 deletions llvm/lib/Transforms/Utils/Local.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -203,10 +203,8 @@ bool llvm::ConstantFoldTerminator(BasicBlock *BB, bool DeleteDeadConditions,
BasicBlock *TheOnlyDest = DefaultDest;

// If the default is unreachable, ignore it when searching for TheOnlyDest.
if (isa<UnreachableInst>(DefaultDest->getFirstNonPHIOrDbg()) &&
SI->getNumCases() > 0) {
if (SI->defaultDestUnreachable() && SI->getNumCases() > 0)
TheOnlyDest = SI->case_begin()->getCaseSuccessor();
}

bool Changed = false;

Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Transforms/Utils/LowerSwitch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,7 @@ void ProcessSwitchInst(SwitchInst *SI,
ConstantInt *UpperBound = nullptr;
bool DefaultIsUnreachableFromSwitch = false;

if (isa<UnreachableInst>(Default->getFirstNonPHIOrDbg())) {
if (SI->defaultDestUnreachable()) {
// Make the bounds tightly fitted around the case value range, because we
// know that the value passed to the switch must be exactly one of the case
// values.
Expand Down
17 changes: 6 additions & 11 deletions llvm/lib/Transforms/Utils/SimplifyCFG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5715,8 +5715,7 @@ bool SimplifyCFGOpt::turnSwitchRangeIntoICmp(SwitchInst *SI,
IRBuilder<> &Builder) {
assert(SI->getNumCases() > 1 && "Degenerate switch?");

bool HasDefault =
!isa<UnreachableInst>(SI->getDefaultDest()->getFirstNonPHIOrDbg());
bool HasDefault = !SI->defaultDestUnreachable();

auto *BB = SI->getParent();

Expand Down Expand Up @@ -5879,8 +5878,7 @@ static bool eliminateDeadSwitchCases(SwitchInst *SI, DomTreeUpdater *DTU,
// default destination becomes dead and we can remove it. If we know some
// of the bits in the value, we can use that to more precisely compute the
// number of possible unique case values.
bool HasDefault =
!isa<UnreachableInst>(SI->getDefaultDest()->getFirstNonPHIOrDbg());
bool HasDefault = !SI->defaultDestUnreachable();
const unsigned NumUnknownBits =
Known.getBitWidth() - (Known.Zero | Known.One).popcount();
assert(NumUnknownBits <= Known.getBitWidth());
Expand Down Expand Up @@ -6237,11 +6235,8 @@ static bool initializeUniqueCases(SwitchInst *SI, PHINode *&PHI,
// is unreachable.
DefaultResult =
DefaultResults.size() == 1 ? DefaultResults.begin()->second : nullptr;
if ((!DefaultResult &&
!isa<UnreachableInst>(DefaultDest->getFirstNonPHIOrDbg())))
return false;

return true;
return DefaultResult || SI->defaultDestUnreachable();
}

// Helper function that checks if it is possible to transform a switch with only
Expand Down Expand Up @@ -6948,7 +6943,7 @@ static bool switchToLookupTable(SwitchInst *SI, IRBuilder<> &Builder,
// If the default destination is unreachable, or if the lookup table covers
// all values of the conditional variable, branch directly to the lookup table
// BB. Otherwise, check that the condition is within the case range.
bool DefaultIsReachable = !SI->defaultDestUndefined();
bool DefaultIsReachable = !SI->defaultDestUnreachable();

bool TableHasHoles = (NumResults < TableSize);

Expand Down Expand Up @@ -7281,7 +7276,7 @@ static bool simplifySwitchOfPowersOfTwo(SwitchInst *SI, IRBuilder<> &Builder,
// We perform this optimization only for switches with
// unreachable default case.
// This assumtion will save us from checking if `Condition` is a power of two.
if (!isa<UnreachableInst>(SI->getDefaultDest()->getFirstNonPHIOrDbg()))
if (!SI->defaultDestUnreachable())
return false;

// Check that switch cases are powers of two.
Expand Down Expand Up @@ -7363,7 +7358,7 @@ static bool simplifySwitchOfCmpIntrinsic(SwitchInst *SI, IRBuilderBase &Builder,

assert(Missing.size() == 1 && "Should have one case left");
Res = *Missing.begin();
} else if (SI->getNumCases() == 3 && SI->defaultDestUndefined()) {
} else if (SI->getNumCases() == 3 && SI->defaultDestUnreachable()) {
// Normalize so that Succ is taken once and OtherSucc twice.
Unreachable = SI->getDefaultDest();
Succ = OtherSucc = nullptr;
Expand Down
5 changes: 3 additions & 2 deletions llvm/unittests/SandboxIR/SandboxIRTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4222,8 +4222,9 @@ define void @foo(i32 %cond0, i32 %cond1) {
EXPECT_EQ(Switch->getDefaultDest(),
Ctx.getValue(LLVMSwitch->getDefaultDest()));
EXPECT_EQ(Switch->getDefaultDest(), Default);
// Check defaultDestUndefined().
EXPECT_EQ(Switch->defaultDestUndefined(), LLVMSwitch->defaultDestUndefined());
// Check defaultDestUnreachable().
EXPECT_EQ(Switch->defaultDestUnreachable(),
LLVMSwitch->defaultDestUnreachable());
// Check setDefaultDest().
auto *OrigDefaultDest = Switch->getDefaultDest();
auto *NewDefaultDest = Entry;
Expand Down
Loading