summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorCraig Topper <craig.topper@intel.com>2018-05-31 22:16:55 +0000
committerCraig Topper <craig.topper@intel.com>2018-05-31 22:16:55 +0000
commit9a6c0bdcbd387c67fc3016db40f7d261bd0691bc (patch)
treeb62e218d8ad7728743a4450e95ec10c87534fda0 /llvm/lib
parent38671237a62ae9954a241cdeaf3a3180482ecf2b (diff)
downloadbcm5719-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.cpp8
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)).
OpenPOWER on IntegriCloud