From 3f978ba958364083b97ff86df2ef66fcb20afbc8 Mon Sep 17 00:00:00 2001 From: Simon Pilgrim Date: Wed, 12 Oct 2016 10:20:15 +0000 Subject: [PATCH] [InstCombine] Fix constexpr issue in select combining As discussed by Andrea on PR30486, we have an unsafe cast to an Instruction type in the select combine which doesn't take into account that it could be a ConstantExpr instead. Differential Revision: https://reviews.llvm.org/D25466 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@284000 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../InstCombine/InstructionCombining.cpp | 9 ++-- .../InstCombine/switch-constant-expr.ll | 44 +++++++++++++++++++ 2 files changed, 49 insertions(+), 4 deletions(-) create mode 100644 test/Transforms/InstCombine/switch-constant-expr.ll 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 +} -- 2.50.0