summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Wennborg <hans@hanshq.net>2018-01-30 09:52:39 +0000
committerHans Wennborg <hans@hanshq.net>2018-01-30 09:52:39 +0000
commit029e482f3927d9c341a2a4fd0dfeff64b24b2b83 (patch)
treea7c5a546bc1212026df8a7f9a37ad40966ccc174
parent6148a4925e2eef4a34f61c9f379bb81d61e8eac1 (diff)
Merging r322006:
------------------------------------------------------------------------ r322006 | davide | 2018-01-08 17:34:06 +0100 (Mon, 08 Jan 2018) | 19 lines [CVP] Replace incoming values from unreachable blocks with undef. This is an attempt of fixing PR35807. Due to the non-standard definition of dominance in LLVM, where uses in unreachable blocks are dominated by anything, you can have, in an unreachable block: %patatino = OP1 %patatino, CONSTANT When `SimplifyInstruction` receives a PHI where an incoming value is of the aforementioned form, in some cases, loops indefinitely. What I propose here instead is keeping track of the incoming values from unreachable blocks, and replacing them with undef. It fixes this case, and it seems to be good regardless (even if we can't prove that the value is constant, as it's coming from an unreachable block, we can ignore it). Differential Revision: https://reviews.llvm.org/D41812 ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_60@323738 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Transforms/Scalar/CorrelatedValuePropagation.cpp28
-rw-r--r--test/Transforms/CorrelatedValuePropagation/pr35807.ll65
2 files changed, 89 insertions, 4 deletions
diff --git a/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp b/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
index 8f468ebf894..7b898a3943d 100644
--- a/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
+++ b/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
@@ -14,6 +14,7 @@
#include "llvm/Transforms/Scalar/CorrelatedValuePropagation.h"
#include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/PostOrderIterator.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/GlobalsModRef.h"
@@ -120,8 +121,8 @@ static bool processSelect(SelectInst *S, LazyValueInfo *LVI) {
return true;
}
-static bool processPHI(PHINode *P, LazyValueInfo *LVI,
- const SimplifyQuery &SQ) {
+static bool processPHI(PHINode *P, LazyValueInfo *LVI, const SimplifyQuery &SQ,
+ DenseSet<BasicBlock *> &ReachableBlocks) {
bool Changed = false;
BasicBlock *BB = P->getParent();
@@ -129,7 +130,18 @@ static bool processPHI(PHINode *P, LazyValueInfo *LVI,
Value *Incoming = P->getIncomingValue(i);
if (isa<Constant>(Incoming)) continue;
- Value *V = LVI->getConstantOnEdge(Incoming, P->getIncomingBlock(i), BB, P);
+ // If the incoming value is coming from an unreachable block, replace
+ // it with undef and go on. This is good for two reasons:
+ // 1) We skip an LVI query for an unreachable block
+ // 2) We transform the incoming value so that the code below doesn't
+ // mess around with IR in unreachable blocks.
+ BasicBlock *IncomingBB = P->getIncomingBlock(i);
+ if (!ReachableBlocks.count(IncomingBB)) {
+ P->setIncomingValue(i, UndefValue::get(P->getType()));
+ continue;
+ }
+
+ Value *V = LVI->getConstantOnEdge(Incoming, IncomingBB, BB, P);
// Look if the incoming value is a select with a scalar condition for which
// LVI can tells us the value. In that case replace the incoming value with
@@ -561,6 +573,14 @@ static Constant *getConstantAt(Value *V, Instruction *At, LazyValueInfo *LVI) {
static bool runImpl(Function &F, LazyValueInfo *LVI, const SimplifyQuery &SQ) {
bool FnChanged = false;
+
+ // Compute reachability from the entry block of this function via an RPO
+ // walk. We use this information when processing PHIs.
+ DenseSet<BasicBlock *> ReachableBlocks;
+ ReversePostOrderTraversal<Function *> RPOT(&F);
+ for (BasicBlock *BB : RPOT)
+ ReachableBlocks.insert(BB);
+
// Visiting in a pre-order depth-first traversal causes us to simplify early
// blocks before querying later blocks (which require us to analyze early
// blocks). Eagerly simplifying shallow blocks means there is strictly less
@@ -575,7 +595,7 @@ static bool runImpl(Function &F, LazyValueInfo *LVI, const SimplifyQuery &SQ) {
BBChanged |= processSelect(cast<SelectInst>(II), LVI);
break;
case Instruction::PHI:
- BBChanged |= processPHI(cast<PHINode>(II), LVI, SQ);
+ BBChanged |= processPHI(cast<PHINode>(II), LVI, SQ, ReachableBlocks);
break;
case Instruction::ICmp:
case Instruction::FCmp:
diff --git a/test/Transforms/CorrelatedValuePropagation/pr35807.ll b/test/Transforms/CorrelatedValuePropagation/pr35807.ll
new file mode 100644
index 00000000000..8f72b596d28
--- /dev/null
+++ b/test/Transforms/CorrelatedValuePropagation/pr35807.ll
@@ -0,0 +1,65 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -correlated-propagation -S %s | FileCheck %s
+
+target triple = "x86_64-apple-darwin17.4.0"
+
+define void @patatino() {
+; CHECK-LABEL: @patatino(
+; CHECK-NEXT: br i1 undef, label [[BB3:%.*]], label [[BB4:%.*]]
+; CHECK: bb3:
+; CHECK-NEXT: br label [[BB3]]
+; CHECK: bb4:
+; CHECK-NEXT: br i1 undef, label [[BB40:%.*]], label [[BB22:%.*]]
+; CHECK: bb7:
+; CHECK-NEXT: br label [[BB14:%.*]]
+; CHECK: bb12:
+; CHECK-NEXT: br label [[BB14]]
+; CHECK: bb14:
+; CHECK-NEXT: [[TMP19:%.*]] = icmp sgt i32 undef, undef
+; CHECK-NEXT: [[TMP20:%.*]] = select i1 [[TMP19]], i64 [[TMP20]], i64 0
+; CHECK-NEXT: br i1 undef, label [[BB40]], label [[BB7:%.*]]
+; CHECK: bb22:
+; CHECK-NEXT: br label [[BB24:%.*]]
+; CHECK: bb24:
+; CHECK-NEXT: br label [[BB32:%.*]]
+; CHECK: bb32:
+; CHECK-NEXT: br i1 undef, label [[BB40]], label [[BB24]]
+; CHECK: bb40:
+; CHECK-NEXT: ret void
+;
+ br i1 undef, label %bb3, label %bb4
+
+bb3:
+ br label %bb3
+
+bb4:
+ br i1 undef, label %bb40, label %bb22
+
+bb7:
+ br label %bb14
+
+bb12:
+ br label %bb14
+
+; This block is unreachable. Due to the non-standard definition of
+; dominance in LLVM where uses in unreachable blocks are dominated
+; by anything, it contains an instruction of the form
+; %def = OP %def, %something
+bb14:
+ %tmp19 = icmp sgt i32 undef, undef
+ %tmp20 = select i1 %tmp19, i64 %tmp20, i64 0
+ br i1 undef, label %bb40, label %bb7
+
+bb22:
+ br label %bb24
+
+bb24:
+ br label %bb32
+
+bb32:
+ br i1 undef, label %bb40, label %bb24
+
+bb40:
+ %tmp41 = phi i64 [ 4, %bb4 ], [ %tmp20, %bb14 ], [ undef, %bb32 ]
+ ret void
+}