Skip to content

Commit 1ed7f8e

Browse files
committed
[LAA] Support pointer phis in loop by analyzing each incoming pointer.
SCEV does not look through non-header PHIs inside the loop. Such phis can be analyzed by adding separate accesses for each incoming pointer value. This results in 2 more loops vectorized in SPEC2000/186.crafty and avoids regressions when sinking instructions before vectorizing. Reviewed By: Meinersbur Differential Revision: https://reviews.llvm.org/D101286
1 parent f391de8 commit 1ed7f8e

File tree

3 files changed

+48
-8
lines changed

3 files changed

+48
-8
lines changed

llvm/lib/Analysis/LoopAccessAnalysis.cpp

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1938,7 +1938,18 @@ void LoopAccessInfo::analyzeLoop(AAResults *AA, LoopInfo *LI,
19381938
if (blockNeedsPredication(ST->getParent(), TheLoop, DT))
19391939
Loc.AATags.TBAA = nullptr;
19401940

1941-
Accesses.addStore(Loc);
1941+
// SCEV does not look through non-header PHIs inside the loop. Such phis
1942+
// can be analyzed by adding separate accesses for each incoming pointer
1943+
// value.
1944+
auto *PN = dyn_cast<PHINode>(Loc.Ptr);
1945+
if (PN && TheLoop->contains(PN->getParent()) &&
1946+
PN->getParent() != TheLoop->getHeader()) {
1947+
for (const Use &Inc : PN->incoming_values()) {
1948+
MemoryLocation NewLoc = Loc.getWithNewPtr(Inc);
1949+
Accesses.addStore(NewLoc);
1950+
}
1951+
} else
1952+
Accesses.addStore(Loc);
19421953
}
19431954
}
19441955

@@ -1982,7 +1993,17 @@ void LoopAccessInfo::analyzeLoop(AAResults *AA, LoopInfo *LI,
19821993
if (blockNeedsPredication(LD->getParent(), TheLoop, DT))
19831994
Loc.AATags.TBAA = nullptr;
19841995

1985-
Accesses.addLoad(Loc, IsReadOnlyPtr);
1996+
// SCEV does not look through non-header PHIs inside the loop. Such phis can
1997+
// be analyzed by adding separate accesses for each incoming pointer value.
1998+
auto *PN = dyn_cast<PHINode>(Loc.Ptr);
1999+
if (PN && TheLoop->contains(PN->getParent()) &&
2000+
PN->getParent() != TheLoop->getHeader()) {
2001+
for (const Use &Inc : PN->incoming_values()) {
2002+
MemoryLocation NewLoc = Loc.getWithNewPtr(Inc);
2003+
Accesses.addLoad(NewLoc, IsReadOnlyPtr);
2004+
}
2005+
} else
2006+
Accesses.addLoad(Loc, IsReadOnlyPtr);
19862007
}
19872008

19882009
// If we write (or read-write) to a single destination and there are no

llvm/test/Analysis/LoopAccessAnalysis/pointer-phis.ll

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
define i32 @load_with_pointer_phi_no_runtime_checks(%s1* %data) {
77
; CHECK-LABEL: load_with_pointer_phi_no_runtime_checks
88
; CHECK-NEXT: loop.header:
9-
; CHECK-NEXT: Report: cannot identify array bounds
9+
; CHECK-NEXT: Memory dependences are safe
1010
;
1111
entry:
1212
br label %loop.header
@@ -41,7 +41,7 @@ exit: ; preds = %loop.latch
4141
define i32 @store_with_pointer_phi_no_runtime_checks(%s1* %data) {
4242
; CHECK-LABEL: 'store_with_pointer_phi_no_runtime_checks'
4343
; CHECK-NEXT: loop.header:
44-
; CHECK-NEXT: Report: cannot identify array bounds
44+
; CHECK-NEXT: Memory dependences are safe
4545
;
4646
entry:
4747
br label %loop.header
@@ -76,7 +76,23 @@ exit: ; preds = %loop.latch
7676
define i32 @store_with_pointer_phi_runtime_checks(double* %A, double* %B, double* %C) {
7777
; CHECK-LABEL: 'store_with_pointer_phi_runtime_checks'
7878
; CHECK-NEXT: loop.header:
79-
; CHECK-NEXT: Report: cannot identify array bounds
79+
; CHECK-NEXT: Memory dependences are safe with run-time checks
80+
; CHECK: Run-time memory checks:
81+
; CHECK-NEXT: Check 0:
82+
; CHECK-NEXT: Comparing group ([[GROUP_C:.+]]):
83+
; CHECK-NEXT: %gep.2 = getelementptr inbounds double, double* %C, i64 %iv
84+
; CHECK-NEXT: Against group ([[GROUP_B:.+]]):
85+
; CHECK-NEXT: %gep.1 = getelementptr inbounds double, double* %B, i64 %iv
86+
; CHECK-NEXT: Check 1:
87+
; CHECK-NEXT: Comparing group ([[GROUP_C]]):
88+
; CHECK-NEXT: %gep.2 = getelementptr inbounds double, double* %C, i64 %iv
89+
; CHECK-NEXT: Against group ([[GROUP_A:.+]]):
90+
; CHECK-NEXT: %arrayidx = getelementptr inbounds double, double* %A, i64 %iv
91+
; CHECK-NEXT: Check 2:
92+
; CHECK-NEXT: Comparing group ([[GROUP_B]]):
93+
; CHECK-NEXT: %gep.1 = getelementptr inbounds double, double* %B, i64 %iv
94+
; CHECK-NEXT: Against group ([[GROUP_A]]):
95+
; CHECK-NEXT: %arrayidx = getelementptr inbounds double, double* %A, i64 %iv
8096
;
8197
entry:
8298
br label %loop.header

llvm/test/Transforms/LoopVectorize/vectorize-pointer-phis.ll

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44

55
define i32 @load_with_pointer_phi_no_runtime_checks(%s1* %data) {
66
; CHECK-LABEL: @load_with_pointer_phi_no_runtime_checks
7-
; CHECK-NOT: vector.body
7+
; CHECK-NOT: memcheck
8+
; CHECK: vector.body:
89
;
910
entry:
1011
br label %loop.header
@@ -38,7 +39,8 @@ exit: ; preds = %loop.latch
3839

3940
define i32 @store_with_pointer_phi_no_runtime_checks(%s1* %data) {
4041
; CHECK-LABEL: @store_with_pointer_phi_no_runtime_checks
41-
; CHECK-NOT: vector.body
42+
; CHECK-NOT: memcheck
43+
; CHECK: vector.body
4244
;
4345
entry:
4446
br label %loop.header
@@ -72,7 +74,8 @@ exit: ; preds = %loop.latch
7274

7375
define i32 @store_with_pointer_phi_runtime_checks(double* %A, double* %B, double* %C) {
7476
; CHECK-LABEL: @store_with_pointer_phi_runtime_checks
75-
; CHECK-NOT: vector.body
77+
; CHECK: memcheck
78+
; CHECK: vector.body
7679
;
7780
entry:
7881
br label %loop.header

0 commit comments

Comments
 (0)