Skip to content

Commit 9a60d2c

Browse files
committedJan 8, 2018
[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 llvm-svn: 322006
1 parent cf6e6c8 commit 9a60d2c

File tree

2 files changed

+89
-4
lines changed

2 files changed

+89
-4
lines changed
 

‎llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp

+24-4
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "llvm/Transforms/Scalar/CorrelatedValuePropagation.h"
1515
#include "llvm/ADT/DepthFirstIterator.h"
1616
#include "llvm/ADT/Optional.h"
17+
#include "llvm/ADT/PostOrderIterator.h"
1718
#include "llvm/ADT/SmallVector.h"
1819
#include "llvm/ADT/Statistic.h"
1920
#include "llvm/Analysis/GlobalsModRef.h"
@@ -120,16 +121,27 @@ static bool processSelect(SelectInst *S, LazyValueInfo *LVI) {
120121
return true;
121122
}
122123

123-
static bool processPHI(PHINode *P, LazyValueInfo *LVI,
124-
const SimplifyQuery &SQ) {
124+
static bool processPHI(PHINode *P, LazyValueInfo *LVI, const SimplifyQuery &SQ,
125+
DenseSet<BasicBlock *> &ReachableBlocks) {
125126
bool Changed = false;
126127

127128
BasicBlock *BB = P->getParent();
128129
for (unsigned i = 0, e = P->getNumIncomingValues(); i < e; ++i) {
129130
Value *Incoming = P->getIncomingValue(i);
130131
if (isa<Constant>(Incoming)) continue;
131132

132-
Value *V = LVI->getConstantOnEdge(Incoming, P->getIncomingBlock(i), BB, P);
133+
// If the incoming value is coming from an unreachable block, replace
134+
// it with undef and go on. This is good for two reasons:
135+
// 1) We skip an LVI query for an unreachable block
136+
// 2) We transform the incoming value so that the code below doesn't
137+
// mess around with IR in unreachable blocks.
138+
BasicBlock *IncomingBB = P->getIncomingBlock(i);
139+
if (!ReachableBlocks.count(IncomingBB)) {
140+
P->setIncomingValue(i, UndefValue::get(P->getType()));
141+
continue;
142+
}
143+
144+
Value *V = LVI->getConstantOnEdge(Incoming, IncomingBB, BB, P);
133145

134146
// Look if the incoming value is a select with a scalar condition for which
135147
// 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) {
561573

562574
static bool runImpl(Function &F, LazyValueInfo *LVI, const SimplifyQuery &SQ) {
563575
bool FnChanged = false;
576+
577+
// Compute reachability from the entry block of this function via an RPO
578+
// walk. We use this information when processing PHIs.
579+
DenseSet<BasicBlock *> ReachableBlocks;
580+
ReversePostOrderTraversal<Function *> RPOT(&F);
581+
for (BasicBlock *BB : RPOT)
582+
ReachableBlocks.insert(BB);
583+
564584
// Visiting in a pre-order depth-first traversal causes us to simplify early
565585
// blocks before querying later blocks (which require us to analyze early
566586
// blocks). Eagerly simplifying shallow blocks means there is strictly less
@@ -575,7 +595,7 @@ static bool runImpl(Function &F, LazyValueInfo *LVI, const SimplifyQuery &SQ) {
575595
BBChanged |= processSelect(cast<SelectInst>(II), LVI);
576596
break;
577597
case Instruction::PHI:
578-
BBChanged |= processPHI(cast<PHINode>(II), LVI, SQ);
598+
BBChanged |= processPHI(cast<PHINode>(II), LVI, SQ, ReachableBlocks);
579599
break;
580600
case Instruction::ICmp:
581601
case Instruction::FCmp:
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2+
; RUN: opt -correlated-propagation -S %s | FileCheck %s
3+
4+
target triple = "x86_64-apple-darwin17.4.0"
5+
6+
define void @patatino() {
7+
; CHECK-LABEL: @patatino(
8+
; CHECK-NEXT: br i1 undef, label [[BB3:%.*]], label [[BB4:%.*]]
9+
; CHECK: bb3:
10+
; CHECK-NEXT: br label [[BB3]]
11+
; CHECK: bb4:
12+
; CHECK-NEXT: br i1 undef, label [[BB40:%.*]], label [[BB22:%.*]]
13+
; CHECK: bb7:
14+
; CHECK-NEXT: br label [[BB14:%.*]]
15+
; CHECK: bb12:
16+
; CHECK-NEXT: br label [[BB14]]
17+
; CHECK: bb14:
18+
; CHECK-NEXT: [[TMP19:%.*]] = icmp sgt i32 undef, undef
19+
; CHECK-NEXT: [[TMP20:%.*]] = select i1 [[TMP19]], i64 [[TMP20]], i64 0
20+
; CHECK-NEXT: br i1 undef, label [[BB40]], label [[BB7:%.*]]
21+
; CHECK: bb22:
22+
; CHECK-NEXT: br label [[BB24:%.*]]
23+
; CHECK: bb24:
24+
; CHECK-NEXT: br label [[BB32:%.*]]
25+
; CHECK: bb32:
26+
; CHECK-NEXT: br i1 undef, label [[BB40]], label [[BB24]]
27+
; CHECK: bb40:
28+
; CHECK-NEXT: ret void
29+
;
30+
br i1 undef, label %bb3, label %bb4
31+
32+
bb3:
33+
br label %bb3
34+
35+
bb4:
36+
br i1 undef, label %bb40, label %bb22
37+
38+
bb7:
39+
br label %bb14
40+
41+
bb12:
42+
br label %bb14
43+
44+
; This block is unreachable. Due to the non-standard definition of
45+
; dominance in LLVM where uses in unreachable blocks are dominated
46+
; by anything, it contains an instruction of the form
47+
; %def = OP %def, %something
48+
bb14:
49+
%tmp19 = icmp sgt i32 undef, undef
50+
%tmp20 = select i1 %tmp19, i64 %tmp20, i64 0
51+
br i1 undef, label %bb40, label %bb7
52+
53+
bb22:
54+
br label %bb24
55+
56+
bb24:
57+
br label %bb32
58+
59+
bb32:
60+
br i1 undef, label %bb40, label %bb24
61+
62+
bb40:
63+
%tmp41 = phi i64 [ 4, %bb4 ], [ %tmp20, %bb14 ], [ undef, %bb32 ]
64+
ret void
65+
}

0 commit comments

Comments
 (0)
Please sign in to comment.