mirror of
https://github.com/RPCSX/llvm.git
synced 2025-03-03 18:37:56 +00:00
[SCEV] Be less conservative when extending bitwidths for computing ranges.
Summary: In getRangeForAffineAR we compute ranges for affine exprs E = A + B*C, where ranges for A, B, and C are known. To avoid overflow, we need to operate on a bigger bitwidth, and originally we chose 2*x+1 for this (x being the original bitwidth). However, it is safe to use just 2*x: A+B*C <= (2^x - 1) + (2^x - 1)*(2^x - 1) = = 2^x - 1 + 2^2x - 2^x - 2^x + 1 = = 2^2x - 2^x <= 2^2x - 1 Unnecessary extending of bitwidths results in noticeable slowdowns: ranges perform arithmetic operations using APInt, which are much slower when bitwidths are bigger than 64. Reviewers: sanjoy, majnemer, chandlerc Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D27795 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@290211 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
4138b67a0a
commit
2f3327339d
@ -4679,19 +4679,18 @@ ConstantRange ScalarEvolution::getRangeForAffineAR(const SCEV *Start,
|
|||||||
|
|
||||||
MaxBECount = getNoopOrZeroExtend(MaxBECount, Start->getType());
|
MaxBECount = getNoopOrZeroExtend(MaxBECount, Start->getType());
|
||||||
ConstantRange MaxBECountRange = getUnsignedRange(MaxBECount);
|
ConstantRange MaxBECountRange = getUnsignedRange(MaxBECount);
|
||||||
ConstantRange ZExtMaxBECountRange =
|
ConstantRange ZExtMaxBECountRange = MaxBECountRange.zextOrTrunc(BitWidth * 2);
|
||||||
MaxBECountRange.zextOrTrunc(BitWidth * 2 + 1);
|
|
||||||
|
|
||||||
ConstantRange StepSRange = getSignedRange(Step);
|
ConstantRange StepSRange = getSignedRange(Step);
|
||||||
ConstantRange SExtStepSRange = StepSRange.sextOrTrunc(BitWidth * 2 + 1);
|
ConstantRange SExtStepSRange = StepSRange.sextOrTrunc(BitWidth * 2);
|
||||||
|
|
||||||
ConstantRange StartURange = getUnsignedRange(Start);
|
ConstantRange StartURange = getUnsignedRange(Start);
|
||||||
ConstantRange EndURange =
|
ConstantRange EndURange =
|
||||||
StartURange.add(MaxBECountRange.multiply(StepSRange));
|
StartURange.add(MaxBECountRange.multiply(StepSRange));
|
||||||
|
|
||||||
// Check for unsigned overflow.
|
// Check for unsigned overflow.
|
||||||
ConstantRange ZExtStartURange = StartURange.zextOrTrunc(BitWidth * 2 + 1);
|
ConstantRange ZExtStartURange = StartURange.zextOrTrunc(BitWidth * 2);
|
||||||
ConstantRange ZExtEndURange = EndURange.zextOrTrunc(BitWidth * 2 + 1);
|
ConstantRange ZExtEndURange = EndURange.zextOrTrunc(BitWidth * 2);
|
||||||
if (ZExtStartURange.add(ZExtMaxBECountRange.multiply(SExtStepSRange)) ==
|
if (ZExtStartURange.add(ZExtMaxBECountRange.multiply(SExtStepSRange)) ==
|
||||||
ZExtEndURange) {
|
ZExtEndURange) {
|
||||||
APInt Min = APIntOps::umin(StartURange.getUnsignedMin(),
|
APInt Min = APIntOps::umin(StartURange.getUnsignedMin(),
|
||||||
@ -4711,8 +4710,8 @@ ConstantRange ScalarEvolution::getRangeForAffineAR(const SCEV *Start,
|
|||||||
// Check for signed overflow. This must be done with ConstantRange
|
// Check for signed overflow. This must be done with ConstantRange
|
||||||
// arithmetic because we could be called from within the ScalarEvolution
|
// arithmetic because we could be called from within the ScalarEvolution
|
||||||
// overflow checking code.
|
// overflow checking code.
|
||||||
ConstantRange SExtStartSRange = StartSRange.sextOrTrunc(BitWidth * 2 + 1);
|
ConstantRange SExtStartSRange = StartSRange.sextOrTrunc(BitWidth * 2);
|
||||||
ConstantRange SExtEndSRange = EndSRange.sextOrTrunc(BitWidth * 2 + 1);
|
ConstantRange SExtEndSRange = EndSRange.sextOrTrunc(BitWidth * 2);
|
||||||
if (SExtStartSRange.add(ZExtMaxBECountRange.multiply(SExtStepSRange)) ==
|
if (SExtStartSRange.add(ZExtMaxBECountRange.multiply(SExtStepSRange)) ==
|
||||||
SExtEndSRange) {
|
SExtEndSRange) {
|
||||||
APInt Min =
|
APInt Min =
|
||||||
|
Loading…
x
Reference in New Issue
Block a user