diff --git a/lib/Transforms/InstCombine/InstructionCombining.cpp b/lib/Transforms/InstCombine/InstructionCombining.cpp index 54f8b722b7e..6b31a5449f7 100644 --- a/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -2271,9 +2271,9 @@ Instruction *InstCombiner::visitSwitchInst(SwitchInst &SI) { SI.getContext(), C.getCaseValue()->getValue().trunc(NewWidth))); } + Value *Op0 = nullptr; ConstantInt *AddRHS = nullptr; - if (match(Cond, m_Add(m_Value(), m_ConstantInt(AddRHS)))) { - Instruction *I = cast(Cond); + if (match(Cond, m_Add(m_Value(Op0), m_ConstantInt(AddRHS)))) { // Change 'switch (X+4) case 1:' into 'switch (X) case -3'. for (SwitchInst::CaseIt i = SI.case_begin(), e = SI.case_end(); i != e; ++i) { @@ -2289,8 +2289,9 @@ Instruction *InstCombiner::visitSwitchInst(SwitchInst &SI) { "Result of expression should be constant"); i.setValue(cast(NewCaseVal)); } - SI.setCondition(I->getOperand(0)); - Worklist.Add(I); + SI.setCondition(Op0); + if (auto *CondI = dyn_cast(Cond)) + Worklist.Add(CondI); return &SI; } diff --git a/test/Transforms/InstCombine/switch-constant-expr.ll b/test/Transforms/InstCombine/switch-constant-expr.ll new file mode 100644 index 00000000000..c2ea83b2adb --- /dev/null +++ b/test/Transforms/InstCombine/switch-constant-expr.ll @@ -0,0 +1,44 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt < %s -instcombine -S | FileCheck %s + +@g = global i32 0 + +; PR30486 +define i32 @single_case() { +; CHECK-LABEL: @single_case( +; CHECK-NEXT: switch i32 ptrtoint (i32* @g to i32), label %x [ +; CHECK-NEXT: ] +; CHECK: x: +; CHECK-NEXT: ret i32 0 +; + switch i32 add (i32 ptrtoint (i32* @g to i32), i32 -1), label %x [] +x: + ret i32 0 +} + +define i32 @multiple_cases() { +; CHECK-LABEL: @multiple_cases( +; CHECK-NEXT: switch i32 ptrtoint (i32* @g to i32), label %x [ +; CHECK-NEXT: i32 2, label %one +; CHECK-NEXT: i32 3, label %two +; CHECK-NEXT: ] +; CHECK: x: +; CHECK-NEXT: ret i32 0 +; CHECK: one: +; CHECK-NEXT: ret i32 1 +; CHECK: two: +; CHECK-NEXT: ret i32 2 +; + switch i32 add (i32 ptrtoint (i32* @g to i32), i32 -1), label %x [ + i32 1, label %one + i32 2, label %two + ] +x: + ret i32 0 + +one: + ret i32 1 + +two: + ret i32 2 +}