mirror of
https://github.com/RPCS3/llvm.git
synced 2026-07-19 23:23:38 -04: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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@284000 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
Reference in New Issue
Block a user