llvm.org GIT mirror llvm / 88de695
[MemorySSA] Avoid adding Phis in the presence of unreachable blocks. Summary: If a block has all incoming values with the same MemoryAccess (ignoring incoming values from unreachable blocks), then use that incoming MemoryAccess and do not create a Phi in the first place. Revert IDF work-around added in rL372673; it should not be required unless the Def inserted is the first in its block. The patch also cleans up a series of tests, added during the many iterations on insertDef. The patch also fixes PR43438. The same issue that occurs in insertDef with "adding phis, hence the IDF of Phis is needed", can also occur in fixupDefs: the `getPreviousRecursive` call only adds Phis walking on the predecessor edges, which means there may be the case of a Phi added walking the CFG "backwards" which triggers the needs for an additional Phi in successor blocks. Such Phis are added during fixupDefs only in the presence of unreachable blocks. Hence this highlights the need to avoid adding Phis in blocks with unreachable predecessors in the first place. Reviewers: george.burgess.iv Subscribers: Prazek, sanjoy.google, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D67995 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@372932 91177308-0d34-0410-b5e6-96231b3b80d8 Alina Sbirlea 1 year, 25 days ago
9 changed file(s) with 379 addition(s) and 316 deletion(s). Raw diff Collapse all Expand all
7070 // Recurse to get the values in our predecessors for placement of a
7171 // potential phi node. This will insert phi nodes if we cycle in order to
7272 // break the cycle and have an operand.
73 for (auto *Pred : predecessors(BB))
74 if (MSSA->DT->isReachableFromEntry(Pred))
75 PhiOps.push_back(getPreviousDefFromEnd(Pred, CachedPreviousDef));
76 else
73 bool UniqueIncomingAccess = true;
74 MemoryAccess *SingleAccess = nullptr;
75 for (auto *Pred : predecessors(BB)) {
76 if (MSSA->DT->isReachableFromEntry(Pred)) {
77 auto *IncomingAccess = getPreviousDefFromEnd(Pred, CachedPreviousDef);
78 if (!SingleAccess)
79 SingleAccess = IncomingAccess;
80 else if (IncomingAccess != SingleAccess)
81 UniqueIncomingAccess = false;
82 PhiOps.push_back(IncomingAccess);
83 } else
7784 PhiOps.push_back(MSSA->getLiveOnEntryDef());
85 }
7886
7987 // Now try to simplify the ops to avoid placing a phi.
8088 // This may return null if we never created a phi yet, that's okay
8391 // See if we can avoid the phi by simplifying it.
8492 auto *Result = tryRemoveTrivialPhi(Phi, PhiOps);
8593 // If we couldn't simplify, we may have to create a phi
86 if (Result == Phi) {
94 if (Result == Phi && UniqueIncomingAccess && SingleAccess)
95 Result = SingleAccess;
96 else if (Result == Phi && !(UniqueIncomingAccess && SingleAccess)) {
8797 if (!Phi)
8898 Phi = MSSA->createMemoryPhi(BB);
8999
314324
315325 SmallVector FixupList(InsertedPHIs.begin(), InsertedPHIs.end());
316326
317 SmallPtrSet DefiningBlocks;
318
327 // Remember the index where we may insert new phis.
328 unsigned NewPhiIndex = InsertedPHIs.size();
319329 if (!DefBeforeSameBlock) {
320330 // If there was a local def before us, we must have the same effect it
321331 // did. Because every may-def is the same, any phis/etc we would create, it
334344 auto Iter = MD->getDefsIterator();
335345 ++Iter;
336346 auto IterEnd = MSSA->getBlockDefs(MD->getBlock())->end();
337 if (Iter == IterEnd)
347 if (Iter == IterEnd) {
348 SmallPtrSet DefiningBlocks;
338349 DefiningBlocks.insert(MD->getBlock());
339
350 for (const auto &VH : InsertedPHIs)
351 if (const auto *RealPHI = cast_or_null(VH))
352 DefiningBlocks.insert(RealPHI->getBlock());
353 ForwardIDFCalculator IDFs(*MSSA->DT);
354 SmallVector IDFBlocks;
355 IDFs.setDefiningBlocks(DefiningBlocks);
356 IDFs.calculate(IDFBlocks);
357 SmallVector, 4> NewInsertedPHIs;
358 for (auto *BBIDF : IDFBlocks) {
359 auto *MPhi = MSSA->getMemoryAccess(BBIDF);
360 if (!MPhi) {
361 MPhi = MSSA->createMemoryPhi(BBIDF);
362 NewInsertedPHIs.push_back(MPhi);
363 }
364 // Add the phis created into the IDF blocks to NonOptPhis, so they are
365 // not optimized out as trivial by the call to getPreviousDefFromEnd
366 // below. Once they are complete, all these Phis are added to the
367 // FixupList, and removed from NonOptPhis inside fixupDefs(). Existing
368 // Phis in IDF may need fixing as well, and potentially be trivial
369 // before this insertion, hence add all IDF Phis. See PR43044.
370 NonOptPhis.insert(MPhi);
371 }
372 for (auto &MPhi : NewInsertedPHIs) {
373 auto *BBIDF = MPhi->getBlock();
374 for (auto *Pred : predecessors(BBIDF)) {
375 DenseMap> CachedPreviousDef;
376 MPhi->addIncoming(getPreviousDefFromEnd(Pred, CachedPreviousDef),
377 Pred);
378 }
379 }
380
381 // Re-take the index where we're adding the new phis, because the above
382 // call to getPreviousDefFromEnd, may have inserted into InsertedPHIs.
383 NewPhiIndex = InsertedPHIs.size();
384 for (auto &MPhi : NewInsertedPHIs) {
385 InsertedPHIs.push_back(&*MPhi);
386 FixupList.push_back(&*MPhi);
387 }
388 }
340389 FixupList.push_back(MD);
341390 }
342391
343 ForwardIDFCalculator IDFs(*MSSA->DT);
344 SmallVector IDFBlocks;
345 for (const auto &VH : InsertedPHIs)
346 if (const auto *RealPHI = cast_or_null(VH))
347 DefiningBlocks.insert(RealPHI->getBlock());
348 IDFs.setDefiningBlocks(DefiningBlocks);
349 IDFs.calculate(IDFBlocks);
350 SmallVector, 4> NewInsertedPHIs;
351 for (auto *BBIDF : IDFBlocks) {
352 auto *MPhi = MSSA->getMemoryAccess(BBIDF);
353 if (!MPhi) {
354 MPhi = MSSA->createMemoryPhi(BBIDF);
355 NewInsertedPHIs.push_back(MPhi);
356 }
357 // Add the phis created into the IDF blocks to NonOptPhis, so they are not
358 // optimized out as trivial by the call to getPreviousDefFromEnd below. Once
359 // they are complete, all these Phis are added to the FixupList, and removed
360 // from NonOptPhis inside fixupDefs(). Existing Phis in IDF may need fixing
361 // as well, and potentially be trivial before this insertion, hence add all
362 // IDF Phis. See PR43044.
363 NonOptPhis.insert(MPhi);
364 }
365
366 for (auto &MPhi : NewInsertedPHIs) {
367 auto *BBIDF = MPhi->getBlock();
368 for (auto *Pred : predecessors(BBIDF)) {
369 DenseMap> CachedPreviousDef;
370 MPhi->addIncoming(getPreviousDefFromEnd(Pred, CachedPreviousDef), Pred);
371 }
372 }
373
374 // Remember the index where we may insert new phis.
375 unsigned NewPhiIndex = InsertedPHIs.size();
376 for (auto &MPhi : NewInsertedPHIs) {
377 InsertedPHIs.push_back(&*MPhi);
378 FixupList.push_back(&*MPhi);
379 }
380392 // Remember the index where we stopped inserting new phis above, since the
381393 // fixupDefs call in the loop below may insert more, that are already minimal.
382394 unsigned NewPhiIndexEnd = InsertedPHIs.size();
+0
-189
test/Analysis/MemorySSA/PR42940.ll less more
None ; RUN: opt -licm -enable-mssa-loop-dependency -verify-memoryssa -S %s | FileCheck %s
1 ; REQUIRES: asserts
2
3 target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
4 target triple = "s390x-ibm-linux"
5
6 @g_77 = external dso_local global i16, align 2
7
8 ; CHECK-LABEL: @f1()
9 define void @f1() {
10 entry:
11 store i16 undef, i16* @g_77, align 2
12 br label %loop_pre
13
14 unreachablelabel: ; No predecessors
15 br label %loop_pre
16
17 loop_pre:
18 br label %for.cond.header
19
20 for.cond.header:
21 store i32 0, i32* undef, align 4
22 br i1 undef, label %for.body, label %for.end
23
24 for.body:
25 %tmp1 = load volatile i16, i16* undef, align 2
26 br label %for.end
27
28 for.end:
29 br i1 undef, label %func.exit, label %for.cond.header
30
31 func.exit:
32 ret void
33 }
34
35 @g_159 = external dso_local global i32, align 4
36
37 ; CHECK-LABEL: @f2()
38 define void @f2() {
39 entry:
40 br label %for.header.first
41
42 for.header.first:
43 br label %for.body.first
44
45 for.body.first:
46 store i32 0, i32* @g_159, align 4
47 br i1 undef, label %for.body.first, label %for.end.first
48
49 for.end.first:
50 br i1 undef, label %lor.end, label %for.header.first
51
52 lor.end:
53 br label %for.pre
54
55 unreachablelabel: ; No predecessors
56 br label %for.pre
57
58 for.pre:
59 br label %for.header.second
60
61 for.header.second:
62 store i32 undef, i32* undef, align 4
63 br label %for.header.second
64 }
65
66 @g_271 = external dso_local global i8, align 2
67 @g_427 = external dso_local unnamed_addr global [9 x i16], align 2
68
69 ; CHECK-LABEL: @f3()
70 define void @f3() {
71 entry:
72 br label %for.preheader
73
74 for.preheader:
75 store volatile i8 undef, i8* @g_271, align 2
76 br i1 undef, label %for.preheader, label %for.end
77
78 for.end:
79 br label %lbl_1058.i
80
81 unreachablelabel: ; No predecessors
82 br label %lbl_1058.i
83
84 lbl_1058.i:
85 br label %for.cond3.preheader.i
86
87 for.cond3.preheader.i:
88 %tmp1 = load i16, i16* getelementptr inbounds ([9 x i16], [9 x i16]* @g_427, i64 0, i64 2), align 2
89 %conv620.i129 = zext i16 %tmp1 to i32
90 %cmp621.i130 = icmp ugt i32 undef, %conv620.i129
91 %conv622.i131 = zext i1 %cmp621.i130 to i32
92 store i32 %conv622.i131, i32* undef, align 4
93 br i1 undef, label %func.exit, label %for.cond3.preheader.i
94
95 func.exit:
96 ret void
97 }
98
99 @g_6 = external dso_local unnamed_addr global [3 x i32], align 4
100 @g_244 = external dso_local global i64, align 8
101 @g_1164 = external dso_local global i64, align 8
102
103 ; CHECK-LABEL: @f4()
104 define void @f4() {
105 entry:
106 br label %for.cond8.preheader
107
108 for.cond8.preheader:
109 store i32 0, i32* getelementptr inbounds ([3 x i32], [3 x i32]* @g_6, i64 0, i64 2), align 4
110 br i1 undef, label %if.end, label %for.cond8.preheader
111
112 if.end:
113 br i1 undef, label %cleanup1270, label %for.cond504.preheader
114
115 for.cond504.preheader:
116 store i64 undef, i64* @g_244, align 8
117 br label %cleanup1270
118
119 for.cond559.preheader:
120 store i64 undef, i64* @g_1164, align 8
121 br i1 undef, label %for.cond559.preheader, label %cleanup1270
122
123 cleanup1270:
124 ret void
125 }
126
127 @g_1504 = external dso_local local_unnamed_addr global i16****, align 8
128
129 define void @f5() {
130 bb:
131 tail call fastcc void @f21()
132 br label %bb12.outer
133
134 bb12.outer.loopexit: ; No predecessors!
135 br label %bb12.outer
136
137 bb12.outer: ; preds = %bb12.outer.loopexit, %bb
138 br i1 undef, label %bb12.outer.split.us, label %bb12.preheader
139
140 bb12.preheader: ; preds = %bb12.outer
141 br label %bb12
142
143 bb12.outer.split.us: ; preds = %bb12.outer
144 br label %bb16.us.us
145
146 bb16.us.us: ; preds = %bb16.us.us, %bb12.outer.split.us
147 br label %bb16.us.us
148
149 bb12: ; preds = %bb77.1, %bb12.preheader
150 br i1 undef, label %bb25.preheader, label %bb77
151
152 bb25.preheader: ; preds = %bb12.1, %bb12
153 br label %bb25
154
155 bb25: ; preds = %l0, %bb25.preheader
156 br i1 undef, label %bb62, label %bb71.thread
157
158 bb62: ; preds = %bb25
159 br i1 undef, label %bb92.loopexit, label %l0
160
161 l0: ; preds = %bb62
162 br label %bb25
163
164 bb71.thread: ; preds = %bb25
165 br label %bb92
166
167 bb77: ; preds = %bb12
168 %tmp78 = load i16****, i16***** @g_1504, align 8
169 %tmp79 = load volatile i16***, i16**** %tmp78, align 8
170 br i1 undef, label %bb91, label %bb12.1
171
172 bb91: ; preds = %bb77.1, %bb77
173 unreachable
174
175 bb92.loopexit: ; preds = %bb62
176 br label %bb92
177
178 bb92: ; preds = %bb92.loopexit, %bb71.thread
179 ret void
180
181 bb12.1: ; preds = %bb77
182 br i1 undef, label %bb25.preheader, label %bb77.1
183
184 bb77.1: ; preds = %bb12.1
185 br i1 undef, label %bb91, label %bb12
186 }
187
188 declare void @f21()
+0
-52
test/Analysis/MemorySSA/PR43044.ll less more
None ; RUN: opt -loop-rotate -licm -enable-mssa-loop-dependency -verify-memoryssa %s -S | FileCheck %s
1 ; REQUIRES: asserts
2
3 target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
4 target triple = "s390x-ibm-linux"
5
6 declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture)
7
8 ; CHECK-LABEL: @func_42()
9 define void @func_42() {
10 entry:
11 br label %for.cond1050
12
13 for.cond1050.loopexit: ; preds = %for.cond1373
14 br label %for.cond1050
15
16 for.cond1050: ; preds = %for.cond1050.loopexit, %entry
17 %storemerge6 = phi i32 [ 2, %entry ], [ 0, %for.cond1050.loopexit ]
18 %cmp1051 = icmp sgt i32 %storemerge6, -1
19 br i1 %cmp1051, label %for.cond1055.preheader, label %cleanup1400.loopexit1
20
21 for.cond1055.preheader: ; preds = %for.cond1050
22 store i64 0, i64* null, align 8
23 %0 = load i64, i64* null, align 8
24 %tobool1383 = icmp eq i64 %0, 0
25 br i1 %tobool1383, label %for.cond1055.preheader.cleanup1400.loopexit.split_crit_edge, label %for.cond1055.preheader.for.cond1055.preheader.split_crit_edge
26
27 for.cond1055.preheader.for.cond1055.preheader.split_crit_edge: ; preds = %for.cond1055.preheader
28 br label %for.body1376
29
30 for.cond1055.preheader.cleanup1400.loopexit.split_crit_edge: ; preds = %for.cond1055.preheader
31 br label %cleanup1400.loopexit.split
32
33 for.cond1373: ; preds = %for.body1376
34 br i1 true, label %for.body1376, label %for.cond1050.loopexit
35
36 for.body1376: ; preds = %for.cond1373, %for.cond1055.preheader.for.cond1055.preheader.split_crit_edge
37 br i1 false, label %cleanup1400.loopexit, label %for.cond1373
38
39 cleanup1400.loopexit: ; preds = %for.body1376
40 br label %cleanup1400.loopexit.split
41
42 cleanup1400.loopexit.split: ; preds = %cleanup1400.loopexit, %for.cond1055.preheader.cleanup1400.loopexit.split_crit_edge
43 br label %cleanup1400
44
45 cleanup1400.loopexit1: ; preds = %for.cond1050
46 br label %cleanup1400
47
48 cleanup1400: ; preds = %cleanup1400.loopexit1, %cleanup1400.loopexit.split
49 call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull undef)
50 unreachable
51 }
1010 ; Function Attrs: norecurse noreturn nounwind
1111 define dso_local void @func_65() local_unnamed_addr {
1212 ; CHECK-LABEL: @func_65()
13 br label %1
13 label0:
14 br label %label1
1415
15 ;
16 br label %2
16 label1: ; preds = %.thread, %label0
17 br label %label2
1718
18 ;
19 br label %3
19 label2: ; preds = %.critedge, %label1
20 br label %label3
2021
21 ;
22 %storemerge = phi i32 [ 0, %2 ], [ %6, %5 ]
22 label3: ; preds = %label5, %label2
23 %storemerge = phi i32 [ 0, %label2 ], [ %tmp6, %label5 ]
2324 store i32 %storemerge, i32* @g_185, align 4
24 %4 = icmp ult i32 %storemerge, 2
25 br i1 %4, label %5, label %.thread.loopexit
25 %tmp4 = icmp ult i32 %storemerge, 2
26 br i1 %tmp4, label %label5, label %.thread.loopexit
2627
27 ;
28 %6 = add i32 %storemerge, 1
29 %7 = zext i32 %6 to i64
30 %8 = getelementptr [8 x [4 x [6 x i32]]], [8 x [4 x [6 x i32]]]* @g_120, i64 0, i64 undef, i64 %7, i64 undef
31 %9 = load i32, i32* %8, align 4
32 %10 = icmp eq i32 %9, 0
33 br i1 %10, label %3, label %11
28 label5: ; preds = %label3
29 %tmp6 = add i32 %storemerge, 1
30 %tmp7 = zext i32 %tmp6 to i64
31 %tmp8 = getelementptr [8 x [4 x [6 x i32]]], [8 x [4 x [6 x i32]]]* @g_120, i64 0, i64 undef, i64 %tmp7, i64 undef
32 %tmp9 = load i32, i32* %tmp8, align 4
33 %tmp10 = icmp eq i32 %tmp9, 0
34 br i1 %tmp10, label %label3, label %label11
3435
35 ;
36 %storemerge.lcssa4 = phi i32 [ %storemerge, %5 ]
37 %12 = icmp eq i32 %storemerge.lcssa4, 0
38 br i1 %12, label %.critedge, label %.thread.loopexit3
36 label11: ; preds = %label5
37 %storemerge.lcssa4 = phi i32 [ %storemerge, %label5 ]
38 %tmp12 = icmp eq i32 %storemerge.lcssa4, 0
39 br i1 %tmp12, label %.critedge, label %.thread.loopexit3
3940
40 .critedge: ; preds = %11
41 .critedge: ; preds = %label11
4142 store i16 0, i16* @g_329, align 2
42 br label %2
43 br label %label2
4344
44 .thread.loopexit: ; preds = %3
45 .thread.loopexit: ; preds = %label3
4546 br label %.thread
4647
47 .thread.loopexit3: ; preds = %11
48 .thread.loopexit3: ; preds = %label11
4849 br label %.thread
4950
5051 .thread: ; preds = %.thread.loopexit3, %.thread.loopexit
51 br label %1
52 br label %label1
5253 }
5354
None ; RUN: opt -S -licm -enable-mssa-loop-dependency %s | FileCheck %s
1 ; REQUIRES: asserts
0 ; RUN: opt -disable-output -licm -print-memoryssa -enable-mssa-loop-dependency=true < %s 2>&1 | FileCheck %s
21 target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
32 target triple = "s390x-ibm-linux"
43
76 @g_1087 = external dso_local global i32**, align 8
87
98 ; CHECK-LABEL: @f1()
9 ; CHECK: 5 = MemoryPhi(
10 ; CHECK-NOT: 7 = MemoryPhi(
1011 define dso_local fastcc void @f1() unnamed_addr #0 {
1112 label0:
1213 br i1 undef, label %thread-pre-split.i.preheader, label %label5
0 ; RUN: opt -licm -enable-mssa-loop-dependency -verify-memoryssa -S %s | FileCheck %s
1 ; REQUIRES: asserts
2
3 target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
4 target triple = "s390x-ibm-linux"
5
6 @g_77 = external dso_local global i16, align 2
7
8 ; CHECK-LABEL: @f1()
9 define void @f1() {
10 entry:
11 store i16 undef, i16* @g_77, align 2
12 br label %loop_pre
13
14 unreachablelabel: ; No predecessors
15 br label %loop_pre
16
17 loop_pre:
18 br label %for.cond.header
19
20 for.cond.header:
21 store i32 0, i32* undef, align 4
22 br i1 undef, label %for.body, label %for.end
23
24 for.body:
25 %tmp1 = load volatile i16, i16* undef, align 2
26 br label %for.end
27
28 for.end:
29 br i1 undef, label %func.exit, label %for.cond.header
30
31 func.exit:
32 ret void
33 }
34
35 @g_159 = external dso_local global i32, align 4
36
37 ; CHECK-LABEL: @f2()
38 define void @f2() {
39 entry:
40 br label %for.header.first
41
42 for.header.first:
43 br label %for.body.first
44
45 for.body.first:
46 store i32 0, i32* @g_159, align 4
47 br i1 undef, label %for.body.first, label %for.end.first
48
49 for.end.first:
50 br i1 undef, label %lor.end, label %for.header.first
51
52 lor.end:
53 br label %for.pre
54
55 unreachablelabel: ; No predecessors
56 br label %for.pre
57
58 for.pre:
59 br label %for.header.second
60
61 for.header.second:
62 store i32 undef, i32* undef, align 4
63 br label %for.header.second
64 }
65
66 @g_271 = external dso_local global i8, align 2
67 @g_427 = external dso_local unnamed_addr global [9 x i16], align 2
68
69 ; CHECK-LABEL: @f3()
70 define void @f3() {
71 entry:
72 br label %for.preheader
73
74 for.preheader:
75 store volatile i8 undef, i8* @g_271, align 2
76 br i1 undef, label %for.preheader, label %for.end
77
78 for.end:
79 br label %lbl_1058.i
80
81 unreachablelabel: ; No predecessors
82 br label %lbl_1058.i
83
84 lbl_1058.i:
85 br label %for.cond3.preheader.i
86
87 for.cond3.preheader.i:
88 %tmp1 = load i16, i16* getelementptr inbounds ([9 x i16], [9 x i16]* @g_427, i64 0, i64 2), align 2
89 %conv620.i129 = zext i16 %tmp1 to i32
90 %cmp621.i130 = icmp ugt i32 undef, %conv620.i129
91 %conv622.i131 = zext i1 %cmp621.i130 to i32
92 store i32 %conv622.i131, i32* undef, align 4
93 br i1 undef, label %func.exit, label %for.cond3.preheader.i
94
95 func.exit:
96 ret void
97 }
98
99 @g_6 = external dso_local unnamed_addr global [3 x i32], align 4
100 @g_244 = external dso_local global i64, align 8
101 @g_1164 = external dso_local global i64, align 8
102
103 ; CHECK-LABEL: @f4()
104 define void @f4() {
105 entry:
106 br label %for.cond8.preheader
107
108 for.cond8.preheader:
109 store i32 0, i32* getelementptr inbounds ([3 x i32], [3 x i32]* @g_6, i64 0, i64 2), align 4
110 br i1 undef, label %if.end, label %for.cond8.preheader
111
112 if.end:
113 br i1 undef, label %cleanup1270, label %for.cond504.preheader
114
115 for.cond504.preheader:
116 store i64 undef, i64* @g_244, align 8
117 br label %cleanup1270
118
119 for.cond559.preheader:
120 store i64 undef, i64* @g_1164, align 8
121 br i1 undef, label %for.cond559.preheader, label %cleanup1270
122
123 cleanup1270:
124 ret void
125 }
126
127 @g_1504 = external dso_local local_unnamed_addr global i16****, align 8
128
129 define void @f5() {
130 bb:
131 tail call fastcc void @f21()
132 br label %bb12.outer
133
134 bb12.outer.loopexit: ; No predecessors!
135 br label %bb12.outer
136
137 bb12.outer: ; preds = %bb12.outer.loopexit, %bb
138 br i1 undef, label %bb12.outer.split.us, label %bb12.preheader
139
140 bb12.preheader: ; preds = %bb12.outer
141 br label %bb12
142
143 bb12.outer.split.us: ; preds = %bb12.outer
144 br label %bb16.us.us
145
146 bb16.us.us: ; preds = %bb16.us.us, %bb12.outer.split.us
147 br label %bb16.us.us
148
149 bb12: ; preds = %bb77.1, %bb12.preheader
150 br i1 undef, label %bb25.preheader, label %bb77
151
152 bb25.preheader: ; preds = %bb12.1, %bb12
153 br label %bb25
154
155 bb25: ; preds = %l0, %bb25.preheader
156 br i1 undef, label %bb62, label %bb71.thread
157
158 bb62: ; preds = %bb25
159 br i1 undef, label %bb92.loopexit, label %l0
160
161 l0: ; preds = %bb62
162 br label %bb25
163
164 bb71.thread: ; preds = %bb25
165 br label %bb92
166
167 bb77: ; preds = %bb12
168 %tmp78 = load i16****, i16***** @g_1504, align 8
169 %tmp79 = load volatile i16***, i16**** %tmp78, align 8
170 br i1 undef, label %bb91, label %bb12.1
171
172 bb91: ; preds = %bb77.1, %bb77
173 unreachable
174
175 bb92.loopexit: ; preds = %bb62
176 br label %bb92
177
178 bb92: ; preds = %bb92.loopexit, %bb71.thread
179 ret void
180
181 bb12.1: ; preds = %bb77
182 br i1 undef, label %bb25.preheader, label %bb77.1
183
184 bb77.1: ; preds = %bb12.1
185 br i1 undef, label %bb91, label %bb12
186 }
187
188 declare void @f21()
0 ; RUN: opt -loop-rotate -licm -enable-mssa-loop-dependency -verify-memoryssa %s -S | FileCheck %s
1 ; REQUIRES: asserts
2
3 target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
4 target triple = "s390x-ibm-linux"
5
6 declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture)
7
8 ; CHECK-LABEL: @func_42()
9 define void @func_42() {
10 entry:
11 br label %for.cond1050
12
13 for.cond1050.loopexit: ; preds = %for.cond1373
14 br label %for.cond1050
15
16 for.cond1050: ; preds = %for.cond1050.loopexit, %entry
17 %storemerge6 = phi i32 [ 2, %entry ], [ 0, %for.cond1050.loopexit ]
18 %cmp1051 = icmp sgt i32 %storemerge6, -1
19 br i1 %cmp1051, label %for.cond1055.preheader, label %cleanup1400.loopexit1
20
21 for.cond1055.preheader: ; preds = %for.cond1050
22 store i64 0, i64* null, align 8
23 %0 = load i64, i64* null, align 8
24 %tobool1383 = icmp eq i64 %0, 0
25 br i1 %tobool1383, label %for.cond1055.preheader.cleanup1400.loopexit.split_crit_edge, label %for.cond1055.preheader.for.cond1055.preheader.split_crit_edge
26
27 for.cond1055.preheader.for.cond1055.preheader.split_crit_edge: ; preds = %for.cond1055.preheader
28 br label %for.body1376
29
30 for.cond1055.preheader.cleanup1400.loopexit.split_crit_edge: ; preds = %for.cond1055.preheader
31 br label %cleanup1400.loopexit.split
32
33 for.cond1373: ; preds = %for.body1376
34 br i1 true, label %for.body1376, label %for.cond1050.loopexit
35
36 for.body1376: ; preds = %for.cond1373, %for.cond1055.preheader.for.cond1055.preheader.split_crit_edge
37 br i1 false, label %cleanup1400.loopexit, label %for.cond1373
38
39 cleanup1400.loopexit: ; preds = %for.body1376
40 br label %cleanup1400.loopexit.split
41
42 cleanup1400.loopexit.split: ; preds = %cleanup1400.loopexit, %for.cond1055.preheader.cleanup1400.loopexit.split_crit_edge
43 br label %cleanup1400
44
45 cleanup1400.loopexit1: ; preds = %for.cond1050
46 br label %cleanup1400
47
48 cleanup1400: ; preds = %cleanup1400.loopexit1, %cleanup1400.loopexit.split
49 call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull undef)
50 unreachable
51 }
None ; RUN: opt -S -licm -enable-mssa-loop-dependency=true < %s | FileCheck %s
1 ; REQUIRES: asserts
0 ; RUN: opt -disable-output -licm -print-memoryssa -enable-mssa-loop-dependency=true < %s 2>&1 | FileCheck %s
21 @v_274 = external dso_local global i64, align 1
32 @v_295 = external dso_local global i16, align 1
43 @v_335 = external dso_local global i32, align 1
54
65 ; CHECK-LABEL: @main()
6 ; CHECK-NOT: 5 = MemoryPhi(
7 ; CHECK-NOT: 6 = MemoryPhi(
8 ; CHECK: 4 = MemoryPhi(
9 ; CHECK-NOT: 7 = MemoryPhi(
710 define dso_local void @main() {
811 entry:
912 store i32 undef, i32* @v_335, align 1
0 ; RUN: opt -disable-output -licm -print-memoryssa -enable-mssa-loop-dependency=true < %s 2>&1 | FileCheck %s
1 target triple = "x86_64-unknown-linux-gnu"
2
3 ; CHECK-LABEL: @main()
4 ; CHECK: 5 = MemoryPhi(
5 ; CHECK-NOT: 7 = MemoryPhi(
6 @v_67 = external dso_local global i32, align 1
7 @v_76 = external dso_local global i16, align 1
8 @v_86 = external dso_local global i16 *, align 1
9
10 define dso_local void @main() {
11 entry:
12 %v_59 = alloca i16, align 2
13 br label %for.cond
14
15 for.cond: ; preds = %for.body, %entry
16 br i1 undef, label %for.body, label %for.end
17
18 for.body: ; preds = %for.cond
19 store i16 undef, i16* %v_59, align 2
20 br label %for.cond
21
22 for.end: ; preds = %for.cond
23 br i1 undef, label %if.else568, label %cond.end82
24
25 cond.false69: ; No predecessors!
26 br label %cond.end82
27
28 cond.end82: ; preds = %cond.false69, %cond.true55
29 br i1 undef, label %if.else568, label %land.lhs.true87
30
31 land.lhs.true87: ; preds = %cond.end82
32 br i1 undef, label %if.then88, label %if.else568
33
34 if.then88: ; preds = %land.lhs.true87
35 store i16 * @v_76, i16 ** @v_86, align 1
36 br label %if.end569
37
38 if.else568: ; preds = %land.lhs.true87, %cond.end82, %for.end
39 store volatile i32 undef, i32 * @v_67, align 1
40 br label %if.end569
41
42 if.end569: ; preds = %if.else568, %if.then88
43 ret void
44 }
45