summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavide Italiano <davide@freebsd.org>2017-05-23 22:32:56 +0000
committerDavide Italiano <davide@freebsd.org>2017-05-23 22:32:56 +0000
commit4bc91190eaebd980b7d66706585256e05bd18830 (patch)
tree14550f2ea7c311eec8b3185049d0b5d53419bb04
parentae50c56d651d5b8dccf59a4c6a2ff2a30973a62f (diff)
downloadbcm5719-llvm-4bc91190eaebd980b7d66706585256e05bd18830.tar.gz
bcm5719-llvm-4bc91190eaebd980b7d66706585256e05bd18830.zip
[LIR] Strengthen the check for recurrence variable in popcnt/CTLZ.
Fixes PR33114. Differential Revision: https://reviews.llvm.org/D33420 llvm-svn: 303700
-rw-r--r--llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp25
-rw-r--r--llvm/test/Transforms/LoopIdiom/pr33114.ll35
2 files changed, 51 insertions, 9 deletions
diff --git a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
index 97337ea5ba6..8f0bf8672a5 100644
--- a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
@@ -1035,6 +1035,17 @@ static Value *matchCondition(BranchInst *BI, BasicBlock *LoopEntry) {
return nullptr;
}
+// Check if the recurrence variable `VarX` is in the right form to create
+// the idiom. Returns the value coerced to a PHINode if so.
+static PHINode *getRecurrenceVar(Value *VarX, Instruction *DefX,
+ BasicBlock *LoopEntry) {
+ auto *PhiX = dyn_cast<PHINode>(VarX);
+ if (PhiX && PhiX->getParent() == LoopEntry &&
+ (PhiX->getOperand(0) == DefX || PhiX->getOperand(1) == DefX))
+ return PhiX;
+ return nullptr;
+}
+
/// Return true iff the idiom is detected in the loop.
///
/// Additionally:
@@ -1110,13 +1121,9 @@ static bool detectPopcountIdiom(Loop *CurLoop, BasicBlock *PreCondBB,
}
// step 3: Check the recurrence of variable X
- {
- PhiX = dyn_cast<PHINode>(VarX1);
- if (!PhiX ||
- (PhiX->getOperand(0) != DefX2 && PhiX->getOperand(1) != DefX2)) {
- return false;
- }
- }
+ PhiX = getRecurrenceVar(VarX1, DefX2, LoopEntry);
+ if (!PhiX)
+ return false;
// step 4: Find the instruction which count the population: cnt2 = cnt1 + 1
{
@@ -1227,8 +1234,8 @@ static bool detectCTLZIdiom(Loop *CurLoop, PHINode *&PhiX,
VarX = DefX->getOperand(0);
// step 3: Check the recurrence of variable X
- PhiX = dyn_cast<PHINode>(VarX);
- if (!PhiX || (PhiX->getOperand(0) != DefX && PhiX->getOperand(1) != DefX))
+ PhiX = getRecurrenceVar(VarX, DefX, LoopEntry);
+ if (!PhiX)
return false;
// step 4: Find the instruction which count the CTLZ: cnt.next = cnt + 1
diff --git a/llvm/test/Transforms/LoopIdiom/pr33114.ll b/llvm/test/Transforms/LoopIdiom/pr33114.ll
new file mode 100644
index 00000000000..fa44d8e31e7
--- /dev/null
+++ b/llvm/test/Transforms/LoopIdiom/pr33114.ll
@@ -0,0 +1,35 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; Check that we're not crashing while looking at the recurrence variable.
+; RUN: opt -S -loop-idiom %s | FileCheck %s
+
+define void @tinkywinky() {
+; CHECK-LABEL: @tinkywinky(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br i1 true, label [[EXIT:%.*]], label [[PH:%.*]]
+; CHECK: ph:
+; CHECK-NEXT: [[MYPHI:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ]
+; CHECK-NEXT: br label [[IF_END:%.*]]
+; CHECK: if.end:
+; CHECK-NEXT: [[PATATINO:%.*]] = ashr i32 [[MYPHI]], undef
+; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[PATATINO]], 0
+; CHECK-NEXT: br i1 [[TOBOOL]], label [[EXIT_LOOPEXIT:%.*]], label [[IF_END]]
+; CHECK: exit.loopexit:
+; CHECK-NEXT: br label [[EXIT]]
+; CHECK: exit:
+; CHECK-NEXT: ret void
+;
+entry:
+ br i1 true, label %exit, label %ph
+
+ph:
+ %myphi = phi i32 [ 1, %entry ]
+ br label %if.end
+
+if.end:
+ %patatino = ashr i32 %myphi, undef
+ %tobool = icmp eq i32 %patatino, 0
+ br i1 %tobool, label %exit, label %if.end
+
+exit:
+ ret void
+}
OpenPOWER on IntegriCloud