[llvm] Revert "[IR] Don't store switch case values as operands" (PR #170962)
Vitaly Buka via llvm-commits
llvm-commits at lists.llvm.org
Fri Dec 5 18:38:40 PST 2025
https://github.com/vitalybuka created https://github.com/llvm/llvm-project/pull/170962
Reverts llvm/llvm-project#166842
Breaks Mips LLVM tests, and LLD on bots.
See llvm/llvm-project#166842
>From 4294dc7f4b577d1c59efd7bf1b0ea70662c0790b Mon Sep 17 00:00:00 2001
From: Vitaly Buka <vitalybuka at gmail.com>
Date: Fri, 5 Dec 2025 18:37:56 -0800
Subject: [PATCH] Revert "[IR] Don't store switch case values as operands
(#166842)"
This reverts commit f26360f2150e7ff916f2aa5d5fe3ff32d1780c8c.
---
llvm/docs/ReleaseNotes.md | 2 --
llvm/include/llvm-c/Core.h | 24 -------------
llvm/include/llvm/IR/Instructions.h | 35 +++++++------------
llvm/include/llvm/IR/User.h | 8 ++---
llvm/lib/Bitcode/Writer/ValueEnumerator.cpp | 8 -----
llvm/lib/CodeGen/TypePromotion.cpp | 8 -----
llvm/lib/IR/Core.cpp | 13 -------
llvm/lib/IR/Instructions.cpp | 33 ++++++++---------
llvm/lib/IR/User.cpp | 20 +++++------
llvm/lib/IR/Verifier.cpp | 2 +-
llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp | 17 ++++-----
llvm/unittests/IR/InstructionsTest.cpp | 23 ------------
llvm/unittests/IR/VerifierTest.cpp | 3 ++
13 files changed, 55 insertions(+), 141 deletions(-)
diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md
index 5ffad71abaf35..dc0cec6122cdf 100644
--- a/llvm/docs/ReleaseNotes.md
+++ b/llvm/docs/ReleaseNotes.md
@@ -74,7 +74,6 @@ Changes to the LLVM IR
format string function implementations from statically-linked libc's based on
the requirements of each call. Currently only `float` is supported; this can
keep floating point support out of printf if it can be proven unused.
-* Case values are no longer operands of `SwitchInst`.
Changes to LLVM infrastructure
------------------------------
@@ -179,7 +178,6 @@ Changes to the C API
* Add `LLVMGetOrInsertFunction` to get or insert a function, replacing the combination of `LLVMGetNamedFunction` and `LLVMAddFunction`.
* Allow `LLVMGetVolatile` to work with any kind of Instruction.
* Add `LLVMConstFPFromBits` to get a constant floating-point value from an array of 64 bit values.
-* Add `LLVMGetSwitchCaseValue` and `LLVMSetSwitchCaseValue` to get and set switch case values; switch case values are no longer operands of the instruction.
Changes to the CodeGen infrastructure
-------------------------------------
diff --git a/llvm/include/llvm-c/Core.h b/llvm/include/llvm-c/Core.h
index 0074f1aad5a3c..fc41b5835d6eb 100644
--- a/llvm/include/llvm-c/Core.h
+++ b/llvm/include/llvm-c/Core.h
@@ -4213,30 +4213,6 @@ LLVM_C_ABI void LLVMSetCondition(LLVMValueRef Branch, LLVMValueRef Cond);
*/
LLVM_C_ABI LLVMBasicBlockRef LLVMGetSwitchDefaultDest(LLVMValueRef SwitchInstr);
-/**
- * Obtain the case value for a successor of a switch instruction. i corresponds
- * to the successor index. The first successor is the default destination, so i
- * must be greater than zero.
- *
- * This only works on llvm::SwitchInst instructions.
- *
- * @see llvm::SwitchInst::CaseHandle::getCaseValue()
- */
-LLVM_C_ABI LLVMValueRef LLVMGetSwitchCaseValue(LLVMValueRef SwitchInstr,
- unsigned i);
-
-/**
- * Set the case value for a successor of a switch instruction. i corresponds to
- * the successor index. The first successor is the default destination, so i
- * must be greater than zero.
- *
- * This only works on llvm::SwitchInst instructions.
- *
- * @see llvm::SwitchInst::CaseHandle::setValue()
- */
-LLVM_C_ABI void LLVMSetSwitchCaseValue(LLVMValueRef SwitchInstr, unsigned i,
- LLVMValueRef CaseValue);
-
/**
* @}
*/
diff --git a/llvm/include/llvm/IR/Instructions.h b/llvm/include/llvm/IR/Instructions.h
index 80e9cb5bd806b..8bd060ae8f485 100644
--- a/llvm/include/llvm/IR/Instructions.h
+++ b/llvm/include/llvm/IR/Instructions.h
@@ -2665,7 +2665,7 @@ class PHINode : public Instruction {
// User::allocHungoffUses, because we have to allocate Uses for the incoming
// values and pointers to the incoming blocks, all in one allocation.
void allocHungoffUses(unsigned N) {
- User::allocHungoffUses(N, /*WithExtraValues=*/true);
+ User::allocHungoffUses(N, /* IsPhi */ true);
}
public:
@@ -3198,10 +3198,10 @@ class SwitchInst : public Instruction {
unsigned ReservedSpace;
- // Operand[0] = Value to switch on
- // Operand[1] = Default basic block destination
- // Operand[n] = BasicBlock to go to on match
- // Values are stored after the Uses similar to PHINode's basic blocks.
+ // Operand[0] = Value to switch on
+ // Operand[1] = Default basic block destination
+ // Operand[2n ] = Value to match
+ // Operand[2n+1] = BasicBlock to go to on match
SwitchInst(const SwitchInst &SI);
/// Create a new switch instruction, specifying a value to switch on and a
@@ -3223,17 +3223,6 @@ class SwitchInst : public Instruction {
LLVM_ABI SwitchInst *cloneImpl() const;
- void allocHungoffUses(unsigned N) {
- User::allocHungoffUses(N, /*WithExtraValues=*/true);
- }
-
- ConstantInt *const *case_values() const {
- return reinterpret_cast<ConstantInt *const *>(op_begin() + ReservedSpace);
- }
- ConstantInt **case_values() {
- return reinterpret_cast<ConstantInt **>(op_begin() + ReservedSpace);
- }
-
public:
void operator delete(void *Ptr) { User::operator delete(Ptr); }
@@ -3268,7 +3257,7 @@ class SwitchInst : public Instruction {
ConstantIntT *getCaseValue() const {
assert((unsigned)Index < SI->getNumCases() &&
"Index out the number of cases.");
- return SI->case_values()[Index];
+ return reinterpret_cast<ConstantIntT *>(SI->getOperand(2 + Index * 2));
}
/// Resolves successor for current case.
@@ -3310,7 +3299,7 @@ class SwitchInst : public Instruction {
void setValue(ConstantInt *V) const {
assert((unsigned)Index < SI->getNumCases() &&
"Index out the number of cases.");
- SI->case_values()[Index] = V;
+ SI->setOperand(2 + Index*2, reinterpret_cast<Value*>(V));
}
/// Sets the new successor for current case.
@@ -3417,7 +3406,9 @@ class SwitchInst : public Instruction {
/// Return the number of 'cases' in this switch instruction, excluding the
/// default case.
- unsigned getNumCases() const { return getNumOperands() - 2; }
+ unsigned getNumCases() const {
+ return getNumOperands()/2 - 1;
+ }
/// Returns a read/write iterator that points to the first case in the
/// SwitchInst.
@@ -3519,14 +3510,14 @@ class SwitchInst : public Instruction {
/// case.
LLVM_ABI CaseIt removeCase(CaseIt I);
- unsigned getNumSuccessors() const { return getNumOperands() - 1; }
+ unsigned getNumSuccessors() const { return getNumOperands()/2; }
BasicBlock *getSuccessor(unsigned idx) const {
assert(idx < getNumSuccessors() &&"Successor idx out of range for switch!");
- return cast<BasicBlock>(getOperand(idx + 1));
+ return cast<BasicBlock>(getOperand(idx*2+1));
}
void setSuccessor(unsigned idx, BasicBlock *NewSucc) {
assert(idx < getNumSuccessors() && "Successor # out of range for switch!");
- setOperand(idx + 1, NewSucc);
+ setOperand(idx * 2 + 1, NewSucc);
}
// Methods for support type inquiry through isa, cast, and dyn_cast:
diff --git a/llvm/include/llvm/IR/User.h b/llvm/include/llvm/IR/User.h
index 394ea70d6637e..cbb4379b68c41 100644
--- a/llvm/include/llvm/IR/User.h
+++ b/llvm/include/llvm/IR/User.h
@@ -132,13 +132,13 @@ class User : public Value {
/// Allocate the array of Uses, followed by a pointer
/// (with bottom bit set) to the User.
- /// \param WithExtraValues identifies callers which need N Value* allocated
- /// along the N operands.
- LLVM_ABI void allocHungoffUses(unsigned N, bool WithExtraValues = false);
+ /// \param IsPhi identifies callers which are phi nodes and which need
+ /// N BasicBlock* allocated along with N
+ LLVM_ABI void allocHungoffUses(unsigned N, bool IsPhi = false);
/// Grow the number of hung off uses. Note that allocHungoffUses
/// should be called if there are no uses.
- LLVM_ABI void growHungoffUses(unsigned N, bool WithExtraValues = false);
+ LLVM_ABI void growHungoffUses(unsigned N, bool IsPhi = false);
protected:
~User() = default; // Use deleteValue() to delete a generic Instruction.
diff --git a/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp b/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp
index 4d5188cf7a0ce..36d0d35d024cc 100644
--- a/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp
+++ b/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp
@@ -164,10 +164,6 @@ static OrderMap orderModule(const Module &M) {
orderConstantValue(Op);
if (auto *SVI = dyn_cast<ShuffleVectorInst>(&I))
orderValue(SVI->getShuffleMaskForBitcode(), OM);
- if (auto *SI = dyn_cast<SwitchInst>(&I)) {
- for (const auto &Case : SI->cases())
- orderValue(Case.getCaseValue(), OM);
- }
orderValue(&I, OM);
}
}
@@ -1096,10 +1092,6 @@ void ValueEnumerator::incorporateFunction(const Function &F) {
}
if (auto *SVI = dyn_cast<ShuffleVectorInst>(&I))
EnumerateValue(SVI->getShuffleMaskForBitcode());
- if (auto *SI = dyn_cast<SwitchInst>(&I)) {
- for (const auto &Case : SI->cases())
- EnumerateValue(Case.getCaseValue());
- }
}
BasicBlocks.push_back(&BB);
ValueMap[&BB] = BasicBlocks.size();
diff --git a/llvm/lib/CodeGen/TypePromotion.cpp b/llvm/lib/CodeGen/TypePromotion.cpp
index 0865597dadcd6..e9fa78eabff7c 100644
--- a/llvm/lib/CodeGen/TypePromotion.cpp
+++ b/llvm/lib/CodeGen/TypePromotion.cpp
@@ -512,14 +512,6 @@ void IRPromoter::PromoteTree() {
I->setOperand(i, ConstantInt::get(ExtTy, 0));
}
- // For switch, also mutate case values, which are not operands.
- if (auto *SI = dyn_cast<SwitchInst>(I)) {
- for (auto Case : SI->cases()) {
- APInt NewConst = Case.getCaseValue()->getValue().zext(PromotedWidth);
- Case.setValue(ConstantInt::get(SI->getContext(), NewConst));
- }
- }
-
// Mutate the result type, unless this is an icmp or switch.
if (!isa<ICmpInst>(I) && !isa<SwitchInst>(I)) {
I->mutateType(ExtTy);
diff --git a/llvm/lib/IR/Core.cpp b/llvm/lib/IR/Core.cpp
index e0427e9c3d8b1..bea30649947c7 100644
--- a/llvm/lib/IR/Core.cpp
+++ b/llvm/lib/IR/Core.cpp
@@ -3257,19 +3257,6 @@ LLVMBasicBlockRef LLVMGetSwitchDefaultDest(LLVMValueRef Switch) {
return wrap(unwrap<SwitchInst>(Switch)->getDefaultDest());
}
-LLVMValueRef LLVMGetSwitchCaseValue(LLVMValueRef Switch, unsigned i) {
- assert(i > 0 && i <= unwrap<SwitchInst>(Switch)->getNumCases());
- auto It = unwrap<SwitchInst>(Switch)->case_begin() + (i - 1);
- return wrap(It->getCaseValue());
-}
-
-void LLVMSetSwitchCaseValue(LLVMValueRef Switch, unsigned i,
- LLVMValueRef CaseValue) {
- assert(i > 0 && i <= unwrap<SwitchInst>(Switch)->getNumCases());
- auto It = unwrap<SwitchInst>(Switch)->case_begin() + (i - 1);
- It->setValue(unwrap<ConstantInt>(CaseValue));
-}
-
/*--.. Operations on alloca instructions (only) ............................--*/
LLVMTypeRef LLVMGetAllocatedType(LLVMValueRef Alloca) {
diff --git a/llvm/lib/IR/Instructions.cpp b/llvm/lib/IR/Instructions.cpp
index db0d5af83655f..85d3690dd8306 100644
--- a/llvm/lib/IR/Instructions.cpp
+++ b/llvm/lib/IR/Instructions.cpp
@@ -202,7 +202,7 @@ void PHINode::growOperands() {
if (NumOps < 2) NumOps = 2; // 2 op PHI nodes are VERY common.
ReservedSpace = NumOps;
- growHungoffUses(ReservedSpace, /*WithExtraValues=*/true);
+ growHungoffUses(ReservedSpace, /* IsPhi */ true);
}
/// hasConstantValue - If the specified PHI node always merges together the same
@@ -4076,7 +4076,7 @@ SwitchInst::SwitchInst(Value *Value, BasicBlock *Default, unsigned NumCases,
InsertPosition InsertBefore)
: Instruction(Type::getVoidTy(Value->getContext()), Instruction::Switch,
AllocMarker, InsertBefore) {
- init(Value, Default, 2 + NumCases);
+ init(Value, Default, 2+NumCases*2);
}
SwitchInst::SwitchInst(const SwitchInst &SI)
@@ -4084,12 +4084,10 @@ SwitchInst::SwitchInst(const SwitchInst &SI)
init(SI.getCondition(), SI.getDefaultDest(), SI.getNumOperands());
setNumHungOffUseOperands(SI.getNumOperands());
Use *OL = getOperandList();
- ConstantInt **VL = case_values();
const Use *InOL = SI.getOperandList();
- ConstantInt *const *InVL = SI.case_values();
- for (unsigned i = 2, E = SI.getNumOperands(); i != E; ++i) {
+ for (unsigned i = 2, E = SI.getNumOperands(); i != E; i += 2) {
OL[i] = InOL[i];
- VL[i - 2] = InVL[i - 2];
+ OL[i+1] = InOL[i+1];
}
SubclassOptionalData = SI.SubclassOptionalData;
}
@@ -4099,11 +4097,11 @@ SwitchInst::SwitchInst(const SwitchInst &SI)
void SwitchInst::addCase(ConstantInt *OnVal, BasicBlock *Dest) {
unsigned NewCaseIdx = getNumCases();
unsigned OpNo = getNumOperands();
- if (OpNo + 1 > ReservedSpace)
+ if (OpNo+2 > ReservedSpace)
growOperands(); // Get more space!
// Initialize some new operands.
- assert(OpNo < ReservedSpace && "Growing didn't work!");
- setNumHungOffUseOperands(OpNo + 1);
+ assert(OpNo+1 < ReservedSpace && "Growing didn't work!");
+ setNumHungOffUseOperands(OpNo+2);
CaseHandle Case(this, NewCaseIdx);
Case.setValue(OnVal);
Case.setSuccessor(Dest);
@@ -4114,22 +4112,21 @@ void SwitchInst::addCase(ConstantInt *OnVal, BasicBlock *Dest) {
SwitchInst::CaseIt SwitchInst::removeCase(CaseIt I) {
unsigned idx = I->getCaseIndex();
- assert(2 + idx < getNumOperands() && "Case index out of range!!!");
+ assert(2 + idx*2 < getNumOperands() && "Case index out of range!!!");
unsigned NumOps = getNumOperands();
Use *OL = getOperandList();
- ConstantInt **VL = case_values();
// Overwrite this case with the end of the list.
- if (2 + idx + 1 != NumOps) {
- OL[2 + idx] = OL[NumOps - 1];
- VL[idx] = VL[NumOps - 2 - 1];
+ if (2 + (idx + 1) * 2 != NumOps) {
+ OL[2 + idx * 2] = OL[NumOps - 2];
+ OL[2 + idx * 2 + 1] = OL[NumOps - 1];
}
// Nuke the last value.
- OL[NumOps - 1].set(nullptr);
- VL[NumOps - 2 - 1] = nullptr;
- setNumHungOffUseOperands(NumOps - 1);
+ OL[NumOps-2].set(nullptr);
+ OL[NumOps-2+1].set(nullptr);
+ setNumHungOffUseOperands(NumOps-2);
return CaseIt(this, idx);
}
@@ -4142,7 +4139,7 @@ void SwitchInst::growOperands() {
unsigned NumOps = e*3;
ReservedSpace = NumOps;
- growHungoffUses(ReservedSpace, /*WithExtraValues=*/true);
+ growHungoffUses(ReservedSpace);
}
void SwitchInstProfUpdateWrapper::init() {
diff --git a/llvm/lib/IR/User.cpp b/llvm/lib/IR/User.cpp
index 1847c29d9ea4f..9bb7c1298593a 100644
--- a/llvm/lib/IR/User.cpp
+++ b/llvm/lib/IR/User.cpp
@@ -50,16 +50,16 @@ bool User::replaceUsesOfWith(Value *From, Value *To) {
// User allocHungoffUses Implementation
//===----------------------------------------------------------------------===//
-void User::allocHungoffUses(unsigned N, bool WithExtraValues) {
+void User::allocHungoffUses(unsigned N, bool IsPhi) {
assert(HasHungOffUses && "alloc must have hung off uses");
- static_assert(alignof(Use) >= alignof(Value *),
+ static_assert(alignof(Use) >= alignof(BasicBlock *),
"Alignment is insufficient for 'hung-off-uses' pieces");
// Allocate the array of Uses
size_t size = N * sizeof(Use);
- if (WithExtraValues)
- size += N * sizeof(Value *);
+ if (IsPhi)
+ size += N * sizeof(BasicBlock *);
Use *Begin = static_cast<Use*>(::operator new(size));
Use *End = Begin + N;
setOperandList(Begin);
@@ -67,7 +67,7 @@ void User::allocHungoffUses(unsigned N, bool WithExtraValues) {
new (Begin) Use(this);
}
-void User::growHungoffUses(unsigned NewNumUses, bool WithExtraValues) {
+void User::growHungoffUses(unsigned NewNumUses, bool IsPhi) {
assert(HasHungOffUses && "realloc must have hung off uses");
unsigned OldNumUses = getNumOperands();
@@ -77,22 +77,22 @@ void User::growHungoffUses(unsigned NewNumUses, bool WithExtraValues) {
assert(NewNumUses > OldNumUses && "realloc must grow num uses");
Use *OldOps = getOperandList();
- allocHungoffUses(NewNumUses, WithExtraValues);
+ allocHungoffUses(NewNumUses, IsPhi);
Use *NewOps = getOperandList();
// Now copy from the old operands list to the new one.
std::copy(OldOps, OldOps + OldNumUses, NewOps);
- // If the User has extra values (phi basic blocks, switch case values), then
- // we need to copy these, too.
- if (WithExtraValues) {
+ // If this is a Phi, then we need to copy the BB pointers too.
+ if (IsPhi) {
auto *OldPtr = reinterpret_cast<char *>(OldOps + OldNumUses);
auto *NewPtr = reinterpret_cast<char *>(NewOps + NewNumUses);
- std::copy(OldPtr, OldPtr + (OldNumUses * sizeof(Value *)), NewPtr);
+ std::copy(OldPtr, OldPtr + (OldNumUses * sizeof(BasicBlock *)), NewPtr);
}
Use::zap(OldOps, OldOps + OldNumUses, true);
}
+
// This is a private struct used by `User` to track the co-allocated descriptor
// section.
struct DescriptorInfo {
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 6aea9b0e7ecba..10e6c452680b0 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -3424,7 +3424,7 @@ void Verifier::visitSwitchInst(SwitchInst &SI) {
Type *SwitchTy = SI.getCondition()->getType();
SmallPtrSet<ConstantInt*, 32> Constants;
for (auto &Case : SI.cases()) {
- Check(isa<ConstantInt>(Case.getCaseValue()),
+ Check(isa<ConstantInt>(SI.getOperand(Case.getCaseIndex() * 2 + 2)),
"Case value is not a constant integer.", &SI);
Check(Case.getCaseValue()->getType() == SwitchTy,
"Switch constants must all be same type as switch value!", &SI);
diff --git a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
index 4081b6b526771..eea49bfdaf04b 100644
--- a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
@@ -1539,18 +1539,19 @@ void SPIRVEmitIntrinsics::useRoundingMode(ConstrainedFPIntrinsic *FPI,
Instruction *SPIRVEmitIntrinsics::visitSwitchInst(SwitchInst &I) {
BasicBlock *ParentBB = I.getParent();
- Function *F = ParentBB->getParent();
IRBuilder<> B(ParentBB);
B.SetInsertPoint(&I);
SmallVector<Value *, 4> Args;
SmallVector<BasicBlock *> BBCases;
- Args.push_back(I.getCondition());
- BBCases.push_back(I.getDefaultDest());
- Args.push_back(BlockAddress::get(F, I.getDefaultDest()));
- for (auto &Case : I.cases()) {
- Args.push_back(Case.getCaseValue());
- BBCases.push_back(Case.getCaseSuccessor());
- Args.push_back(BlockAddress::get(F, Case.getCaseSuccessor()));
+ for (auto &Op : I.operands()) {
+ if (Op.get()->getType()->isSized()) {
+ Args.push_back(Op);
+ } else if (BasicBlock *BB = dyn_cast<BasicBlock>(Op.get())) {
+ BBCases.push_back(BB);
+ Args.push_back(BlockAddress::get(BB->getParent(), BB));
+ } else {
+ report_fatal_error("Unexpected switch operand");
+ }
}
CallInst *NewI = B.CreateIntrinsic(Intrinsic::spv_switch,
{I.getOperand(0)->getType()}, {Args});
diff --git a/llvm/unittests/IR/InstructionsTest.cpp b/llvm/unittests/IR/InstructionsTest.cpp
index f7517a732e7f6..f4693bfb1a4d1 100644
--- a/llvm/unittests/IR/InstructionsTest.cpp
+++ b/llvm/unittests/IR/InstructionsTest.cpp
@@ -968,29 +968,6 @@ TEST(InstructionsTest, SwitchInst) {
const auto &Handle = *CCI;
EXPECT_EQ(1, Handle.getCaseValue()->getSExtValue());
EXPECT_EQ(BB1.get(), Handle.getCaseSuccessor());
-
- // C API tests.
- EXPECT_EQ(BB0.get(), unwrap(LLVMGetSwitchDefaultDest(wrap(SI))));
- EXPECT_EQ(BB0.get(), unwrap(LLVMGetSuccessor(wrap(SI), 0)));
- EXPECT_EQ(BB1.get(), unwrap(LLVMGetSuccessor(wrap(SI), 1)));
- EXPECT_EQ(
- 1,
- unwrap<ConstantInt>(LLVMGetSwitchCaseValue(wrap(SI), 1))->getSExtValue());
- EXPECT_EQ(BB2.get(), unwrap(LLVMGetSuccessor(wrap(SI), 2)));
- EXPECT_EQ(
- 2,
- unwrap<ConstantInt>(LLVMGetSwitchCaseValue(wrap(SI), 2))->getSExtValue());
- EXPECT_EQ(BB3.get(), unwrap(LLVMGetSuccessor(wrap(SI), 3)));
- EXPECT_EQ(
- 3,
- unwrap<ConstantInt>(LLVMGetSwitchCaseValue(wrap(SI), 3))->getSExtValue());
- // Test case value modification. The C API provides case value indices
- // matching the successor indices.
- LLVMSetSwitchCaseValue(wrap(SI), 2, wrap(ConstantInt::get(Int32Ty, 12)));
- EXPECT_EQ(12, (SI->case_begin() + 1)->getCaseValue()->getSExtValue());
- EXPECT_EQ(
- 12,
- unwrap<ConstantInt>(LLVMGetSwitchCaseValue(wrap(SI), 2))->getSExtValue());
}
TEST(InstructionsTest, SwitchInstProfUpdateWrapper) {
diff --git a/llvm/unittests/IR/VerifierTest.cpp b/llvm/unittests/IR/VerifierTest.cpp
index 49fad197d12d7..440db1216edc9 100644
--- a/llvm/unittests/IR/VerifierTest.cpp
+++ b/llvm/unittests/IR/VerifierTest.cpp
@@ -329,6 +329,9 @@ TEST(VerifierTest, SwitchInst) {
Switch->addCase(ConstantInt::get(Int32Ty, 2), OnTwo);
EXPECT_FALSE(verifyFunction(*F));
+ // set one case value to function argument.
+ Switch->setOperand(2, F->getArg(1));
+ EXPECT_TRUE(verifyFunction(*F));
}
TEST(VerifierTest, CrossFunctionRef) {
More information about the llvm-commits
mailing list