diff options
author | Craig Topper <craig.topper@intel.com> | 2018-05-31 22:16:55 +0000 |
---|---|---|
committer | Craig Topper <craig.topper@intel.com> | 2018-05-31 22:16:55 +0000 |
commit | 9a6c0bdcbd387c67fc3016db40f7d261bd0691bc (patch) | |
tree | b62e218d8ad7728743a4450e95ec10c87534fda0 /llvm/lib | |
parent | 38671237a62ae9954a241cdeaf3a3180482ecf2b (diff) | |
download | bcm5719-llvm-9a6c0bdcbd387c67fc3016db40f7d261bd0691bc.tar.gz bcm5719-llvm-9a6c0bdcbd387c67fc3016db40f7d261bd0691bc.zip |
[LoopIdiomRecognize] Only convert loops to ctlz if we can prove that the input is non-negative.
Summary:
Loop idiom recognize tries to convert loops like
```
int foo(int x) {
int cnt = 0;
while (x) {
x >>= 1;
++cnt;
}
return cnt;
}
```
into calls to ctlz, but if x is initially negative this loop should be infinite.
It happens that the cases that motivated this change have an absolute value of x before the loop. So this patch restricts the transform to cases where we know x is positive. Note: We are relying on the absolute value of INT_MIN to be undefined so we can assume that the result is always positive.
Fixes PR37479
Reviewers: spatel, hfinkel, efriedma, javed.absar
Reviewed By: efriedma
Subscribers: dmgreen, llvm-commits
Differential Revision: https://reviews.llvm.org/D47348
llvm-svn: 333702
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp | 8 |
1 files changed, 8 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp index abd6a81da1e..8b016eceff0 100644 --- a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp +++ b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp @@ -1316,6 +1316,7 @@ static bool detectCTLZIdiom(Loop *CurLoop, PHINode *&PhiX, return false; // step 2: detect instructions corresponding to "x.next = x >> 1" + // TODO: Support loops that use LShr. if (!DefX || DefX->getOpcode() != Instruction::AShr) return false; ConstantInt *Shft = dyn_cast<ConstantInt>(DefX->getOperand(1)); @@ -1397,6 +1398,13 @@ bool LoopIdiomRecognize::recognizeAndInsertCTLZ() { // parent function RunOnLoop. BasicBlock *PH = CurLoop->getLoopPreheader(); Value *InitX = PhiX->getIncomingValueForBlock(PH); + + // Make sure the initial value can't be negative otherwise the ashr in the + // loop might never reach zero which would make the loop infinite. + // TODO: Support loops that use lshr and wouldn't need this check. + if (!isKnownNonNegative(InitX, *DL)) + return false; + // If we check X != 0 before entering the loop we don't need a zero // check in CTLZ intrinsic, but only if Cnt Phi is not used outside of the // loop (if it is used we count CTLZ(X >> 1)). |