[SimplifyCFG] eliminate switch cases based on known range of switch condition

This was noted in PR24766:
https://llvm.org/bugs/show_bug.cgi?id=24766#c2

We may not know whether the sign bit(s) are zero or one, but we can still
optimize based on knowing that the sign bit is repeated.

Differential Revision: http://reviews.llvm.org/D20275



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@270222 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Sanjay Patel 2016-05-20 14:53:09 +00:00
parent a3d21bd41c
commit f5a8ebbd97
2 changed files with 10 additions and 8 deletions

View File

@ -3914,14 +3914,20 @@ static bool EliminateDeadSwitchCases(SwitchInst *SI, AssumptionCache *AC,
APInt KnownZero(Bits, 0), KnownOne(Bits, 0);
computeKnownBits(Cond, KnownZero, KnownOne, DL, 0, AC, SI);
// We can also eliminate cases by determining that their values are outside of
// the limited range of the condition based on how many significant (non-sign)
// bits are in the condition value.
unsigned ExtraSignBits = ComputeNumSignBits(Cond, DL, 0, AC, SI) - 1;
unsigned MaxSignificantBitsInCond = Bits - ExtraSignBits;
// Gather dead cases.
SmallVector<ConstantInt *, 8> DeadCases;
for (auto &Case : SI->cases()) {
if ((Case.getCaseValue()->getValue() & KnownZero) != 0 ||
(Case.getCaseValue()->getValue() & KnownOne) != KnownOne) {
APInt CaseVal = Case.getCaseValue()->getValue();
if ((CaseVal & KnownZero) != 0 || (CaseVal & KnownOne) != KnownOne ||
(CaseVal.getMinSignedBits() > MaxSignificantBitsInCond)) {
DeadCases.push_back(Case.getCaseValue());
DEBUG(dbgs() << "SimplifyCFG: switch case '" << Case.getCaseValue()
<< "' is dead.\n");
DEBUG(dbgs() << "SimplifyCFG: switch case " << CaseVal << " is dead.\n");
}
}

View File

@ -49,14 +49,10 @@ c:
define i1 @repeated_signbits(i8 %condition) {
; CHECK-LABEL: @repeated_signbits(
; CHECK: switch i32
; CHECK-DAG: i32 -2147483648, label %a
; CHECK-DAG: i32 -129, label %a
; CHECK-DAG: i32 -128, label %a
; CHECK-DAG: i32 -1, label %a
; CHECK-DAG: i32 0, label %a
; CHECK-DAG: i32 127, label %a
; CHECK-DAG: i32 128, label %a
; CHECK-DAG: i32 2147483647, label %a
; CHECK-NEXT: ]
;
entry: