aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm/Instructions.h3
-rw-r--r--lib/VMCore/Instructions.cpp12
2 files changed, 6 insertions, 9 deletions
diff --git a/include/llvm/Instructions.h b/include/llvm/Instructions.h
index c79fda0deb..17ff763c52 100644
--- a/include/llvm/Instructions.h
+++ b/include/llvm/Instructions.h
@@ -2247,7 +2247,8 @@ public:
/// removeCase - This method removes the specified successor from the switch
/// instruction. Note that this cannot be used to remove the default
- /// destination (successor #0).
+ /// destination (successor #0). Also note that this operation may reorder the
+ /// remaining cases at index idx and above.
///
void removeCase(unsigned idx);
diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp
index db38a1568f..6b561f34af 100644
--- a/lib/VMCore/Instructions.cpp
+++ b/lib/VMCore/Instructions.cpp
@@ -3009,14 +3009,10 @@ void SwitchInst::removeCase(unsigned idx) {
unsigned NumOps = getNumOperands();
Use *OL = OperandList;
- // Move everything after this operand down.
- //
- // FIXME: we could just swap with the end of the list, then erase. However,
- // client might not expect this to happen. The code as it is thrashes the
- // use/def lists, which is kinda lame.
- for (unsigned i = (idx+1)*2; i != NumOps; i += 2) {
- OL[i-2] = OL[i];
- OL[i-2+1] = OL[i+1];
+ // Overwrite this case with the end of the list.
+ if ((idx + 1) * 2 != NumOps) {
+ OL[idx * 2] = OL[NumOps - 2];
+ OL[idx * 2 + 1] = OL[NumOps - 1];
}
// Nuke the last value.