forked from OSchip/llvm-project
Fix PR5421 by APInt'izing switch lowering.
llvm-svn: 86354
This commit is contained in:
parent
9b669b3c4f
commit
8e1d7222a7
|
@ -1743,19 +1743,19 @@ bool SelectionDAGLowering::handleJTSwitchCase(CaseRec& CR,
|
|||
Case& FrontCase = *CR.Range.first;
|
||||
Case& BackCase = *(CR.Range.second-1);
|
||||
|
||||
const APInt& First = cast<ConstantInt>(FrontCase.Low)->getValue();
|
||||
const APInt& Last = cast<ConstantInt>(BackCase.High)->getValue();
|
||||
const APInt &First = cast<ConstantInt>(FrontCase.Low)->getValue();
|
||||
const APInt &Last = cast<ConstantInt>(BackCase.High)->getValue();
|
||||
|
||||
size_t TSize = 0;
|
||||
APInt TSize(First.getBitWidth(), 0);
|
||||
for (CaseItr I = CR.Range.first, E = CR.Range.second;
|
||||
I!=E; ++I)
|
||||
TSize += I->size();
|
||||
|
||||
if (!areJTsAllowed(TLI) || TSize <= 3)
|
||||
if (!areJTsAllowed(TLI) || TSize.ult(APInt(First.getBitWidth(), 4)))
|
||||
return false;
|
||||
|
||||
APInt Range = ComputeRange(First, Last);
|
||||
double Density = (double)TSize / Range.roundToDouble();
|
||||
double Density = TSize.roundToDouble() / Range.roundToDouble();
|
||||
if (Density < 0.4)
|
||||
return false;
|
||||
|
||||
|
@ -1849,32 +1849,34 @@ bool SelectionDAGLowering::handleBTSplitSwitchCase(CaseRec& CR,
|
|||
// Size is the number of Cases represented by this range.
|
||||
unsigned Size = CR.Range.second - CR.Range.first;
|
||||
|
||||
const APInt& First = cast<ConstantInt>(FrontCase.Low)->getValue();
|
||||
const APInt& Last = cast<ConstantInt>(BackCase.High)->getValue();
|
||||
const APInt &First = cast<ConstantInt>(FrontCase.Low)->getValue();
|
||||
const APInt &Last = cast<ConstantInt>(BackCase.High)->getValue();
|
||||
double FMetric = 0;
|
||||
CaseItr Pivot = CR.Range.first + Size/2;
|
||||
|
||||
// Select optimal pivot, maximizing sum density of LHS and RHS. This will
|
||||
// (heuristically) allow us to emit JumpTable's later.
|
||||
size_t TSize = 0;
|
||||
APInt TSize(First.getBitWidth(), 0);
|
||||
for (CaseItr I = CR.Range.first, E = CR.Range.second;
|
||||
I!=E; ++I)
|
||||
TSize += I->size();
|
||||
|
||||
size_t LSize = FrontCase.size();
|
||||
size_t RSize = TSize-LSize;
|
||||
APInt LSize = FrontCase.size();
|
||||
APInt RSize = TSize-LSize;
|
||||
DEBUG(errs() << "Selecting best pivot: \n"
|
||||
<< "First: " << First << ", Last: " << Last <<'\n'
|
||||
<< "LSize: " << LSize << ", RSize: " << RSize << '\n');
|
||||
for (CaseItr I = CR.Range.first, J=I+1, E = CR.Range.second;
|
||||
J!=E; ++I, ++J) {
|
||||
const APInt& LEnd = cast<ConstantInt>(I->High)->getValue();
|
||||
const APInt& RBegin = cast<ConstantInt>(J->Low)->getValue();
|
||||
const APInt &LEnd = cast<ConstantInt>(I->High)->getValue();
|
||||
const APInt &RBegin = cast<ConstantInt>(J->Low)->getValue();
|
||||
APInt Range = ComputeRange(LEnd, RBegin);
|
||||
assert((Range - 2ULL).isNonNegative() &&
|
||||
"Invalid case distance");
|
||||
double LDensity = (double)LSize / (LEnd - First + 1ULL).roundToDouble();
|
||||
double RDensity = (double)RSize / (Last - RBegin + 1ULL).roundToDouble();
|
||||
double LDensity = (double)LSize.roundToDouble() /
|
||||
(LEnd - First + 1ULL).roundToDouble();
|
||||
double RDensity = (double)RSize.roundToDouble() /
|
||||
(Last - RBegin + 1ULL).roundToDouble();
|
||||
double Metric = Range.logBase2()*(LDensity+RDensity);
|
||||
// Should always split in some non-trivial place
|
||||
DEBUG(errs() <<"=>Step\n"
|
||||
|
|
|
@ -193,9 +193,9 @@ class SelectionDAGLowering {
|
|||
Case() : Low(0), High(0), BB(0) { }
|
||||
Case(Constant* low, Constant* high, MachineBasicBlock* bb) :
|
||||
Low(low), High(high), BB(bb) { }
|
||||
uint64_t size() const {
|
||||
uint64_t rHigh = cast<ConstantInt>(High)->getSExtValue();
|
||||
uint64_t rLow = cast<ConstantInt>(Low)->getSExtValue();
|
||||
APInt size() const {
|
||||
const APInt &rHigh = cast<ConstantInt>(High)->getValue();
|
||||
const APInt &rLow = cast<ConstantInt>(Low)->getValue();
|
||||
return (rHigh - rLow + 1ULL);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,8 +1,22 @@
|
|||
; RUN: llc < %s
|
||||
|
||||
|
||||
; PR5421
|
||||
define void @test1() {
|
||||
entry:
|
||||
switch i128 undef, label %exit [
|
||||
i128 55340232221128654848, label %exit
|
||||
i128 92233720368547758080, label %exit
|
||||
i128 73786976294838206464, label %exit
|
||||
i128 147573952589676412928, label %exit
|
||||
]
|
||||
exit:
|
||||
unreachable
|
||||
}
|
||||
|
||||
|
||||
; PR1197
|
||||
|
||||
|
||||
define void @exp_attr__expand_n_attribute_reference() {
|
||||
define void @test2() {
|
||||
entry:
|
||||
br i1 false, label %cond_next954, label %cond_true924
|
||||
|
||||
|
|
Loading…
Reference in New Issue