Skip to content

Commit d140866

Browse files
authored
[MemorySSA] Don't create phi nodes in fixupDefs() (#156021)
The general flow when inserting MemoryDefs is: * Insert the def and set it's defining access (may insert phis) * Insert IDF phis * Update defining access for defs after the new one (fixupDefs) * Rename uses if requested fixupDefs() uses getPreviousDef() which can create new MemoryPHIs, but for which we're not going to insert IDF phis, so the required dominance property may not hold. I believe this is a leftover from a time before the "Insert IDF phis" step existed. Now that step should already ensure that all necessary MemoryPhis have been inserted, and we only need to update them. The fixupDefs() implementation was also returning after updating a single access, which is not right. Fixes #47875. Fixes #117157. Fixes #152998. Fixes #155161. Fixes #155184.
1 parent d0246fe commit d140866

File tree

2 files changed

+86
-15
lines changed

2 files changed

+86
-15
lines changed

llvm/lib/Analysis/MemorySSAUpdater.cpp

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -411,17 +411,11 @@ void MemorySSAUpdater::insertDef(MemoryDef *MD, bool RenameUses) {
411411
FixupList.push_back(MD);
412412
}
413413

414-
// Remember the index where we stopped inserting new phis above, since the
415-
// fixupDefs call in the loop below may insert more, that are already minimal.
414+
// Update defining access of following defs.
416415
unsigned NewPhiIndexEnd = InsertedPHIs.size();
417-
418-
while (!FixupList.empty()) {
419-
unsigned StartingPHISize = InsertedPHIs.size();
420-
fixupDefs(FixupList);
421-
FixupList.clear();
422-
// Put any new phis on the fixup list, and process them
423-
FixupList.append(InsertedPHIs.begin() + StartingPHISize, InsertedPHIs.end());
424-
}
416+
fixupDefs(FixupList);
417+
assert(NewPhiIndexEnd == InsertedPHIs.size() &&
418+
"Should not insert new phis during fixupDefs()");
425419

426420
// Optimize potentially non-minimal phis added in this method.
427421
unsigned NewPhiSize = NewPhiIndexEnd - NewPhiIndex;
@@ -504,11 +498,8 @@ void MemorySSAUpdater::fixupDefs(const SmallVectorImpl<WeakVH> &Vars) {
504498
assert(MSSA->dominates(NewDef, FirstDef) &&
505499
"Should have dominated the new access");
506500

507-
// This may insert new phi nodes, because we are not guaranteed the
508-
// block we are processing has a single pred, and depending where the
509-
// store was inserted, it may require phi nodes below it.
510-
cast<MemoryDef>(FirstDef)->setDefiningAccess(getPreviousDef(FirstDef));
511-
return;
501+
cast<MemoryDef>(FirstDef)->setDefiningAccess(NewDef);
502+
continue;
512503
}
513504
// We didn't find a def, so we must continue.
514505
for (const auto *S : successors(FixupBlock)) {
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2+
; RUN: opt -S -passes=licm -verify-memoryssa < %s | FileCheck %s
3+
4+
define void @test(ptr %p) {
5+
; CHECK-LABEL: define void @test(
6+
; CHECK-SAME: ptr [[P:%.*]]) {
7+
; CHECK-NEXT: [[ENTRY:.*:]]
8+
; CHECK-NEXT: br label %[[LOOP0:.*]]
9+
; CHECK: [[LOOP0]]:
10+
; CHECK-NEXT: br label %[[LOOP1:.*]]
11+
; CHECK: [[LOOP1]]:
12+
; CHECK-NEXT: [[DEC10:%.*]] = phi i64 [ 0, %[[LOOP0]] ], [ 1, %[[LOOP1]] ]
13+
; CHECK-NEXT: br i1 false, label %[[LOOP1_EXIT:.*]], label %[[LOOP1]]
14+
; CHECK: [[LOOP1_EXIT]]:
15+
; CHECK-NEXT: [[DEC10_LCSSA:%.*]] = phi i64 [ [[DEC10]], %[[LOOP1]] ]
16+
; CHECK-NEXT: switch i32 0, label %[[LOOP0_LATCH:.*]] [
17+
; CHECK-NEXT: i32 0, label %[[LOOP0_LATCH]]
18+
; CHECK-NEXT: i32 2, label %[[LOOP3_PREHEADER:.*]]
19+
; CHECK-NEXT: i32 1, label %[[LOOP2:.*]]
20+
; CHECK-NEXT: ]
21+
; CHECK: [[LOOP2]]:
22+
; CHECK-NEXT: br i1 false, label %[[LOOP0_LATCH]], label %[[LOOP3_PREHEADER]]
23+
; CHECK: [[LOOP3_PREHEADER]]:
24+
; CHECK-NEXT: br label %[[LOOP3:.*]]
25+
; CHECK: [[LOOP3]]:
26+
; CHECK-NEXT: switch i32 0, label %[[EXIT:.*]] [
27+
; CHECK-NEXT: i32 0, label %[[LOOP3]]
28+
; CHECK-NEXT: i32 1, label %[[LOOP2_LATCH:.*]]
29+
; CHECK-NEXT: ]
30+
; CHECK: [[LOOP2_LATCH]]:
31+
; CHECK-NEXT: br label %[[LOOP2]]
32+
; CHECK: [[LOOP0_LATCH]]:
33+
; CHECK-NEXT: br label %[[LOOP0]]
34+
; CHECK: [[EXIT]]:
35+
; CHECK-NEXT: [[DEC10_LCSSA_LCSSA:%.*]] = phi i64 [ [[DEC10_LCSSA]], %[[LOOP3]] ]
36+
; CHECK-NEXT: store i64 [[DEC10_LCSSA_LCSSA]], ptr [[P]], align 4
37+
; CHECK-NEXT: store i64 1, ptr [[P]], align 4
38+
; CHECK-NEXT: ret void
39+
;
40+
entry:
41+
br label %loop0
42+
43+
loop0: ; preds = %loop0.latch, %entry
44+
br label %loop1
45+
46+
loop1: ; preds = %loop1, %loop0
47+
%dec10 = phi i64 [ 0, %loop0 ], [ 1, %loop1 ]
48+
store i64 %dec10, ptr %p
49+
br i1 false, label %loop1.exit, label %loop1
50+
51+
loop1.exit: ; preds = %loop1
52+
switch i32 0, label %loop0.latch [
53+
i32 0, label %loop0.latch
54+
i32 2, label %loop3.preheader
55+
i32 1, label %loop2
56+
]
57+
58+
loop2: ; preds = %loop2.latch, %loop1.exit
59+
br i1 false, label %loop0.latch, label %loop3.preheader
60+
61+
loop3.preheader: ; preds = %loop1.exit, %loop2
62+
br label %loop3
63+
64+
loop3: ; preds = %loop3.preheader, %loop3
65+
switch i32 0, label %exit [
66+
i32 0, label %loop3
67+
i32 1, label %loop2.latch
68+
]
69+
70+
loop2.latch: ; preds = %loop3
71+
br label %loop2
72+
73+
loop0.latch: ; preds = %loop2, %loop1.exit, %loop1.exit
74+
store i64 0, ptr %p
75+
br label %loop0
76+
77+
exit: ; preds = %loop3
78+
store i64 1, ptr %p
79+
ret void
80+
}

0 commit comments

Comments
 (0)