1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 12:41:49 +01:00

[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

llvm-svn: 284000
This commit is contained in:
Simon Pilgrim 2016-10-12 10:20:15 +00:00
parent 9730f4a915
commit 72f99d6988
2 changed files with 49 additions and 4 deletions

View File

@ -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<Instruction>(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<ConstantInt>(NewCaseVal));
}
SI.setCondition(I->getOperand(0));
Worklist.Add(I);
SI.setCondition(Op0);
if (auto *CondI = dyn_cast<Instruction>(Cond))
Worklist.Add(CondI);
return &SI;
}

View File

@ -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
}