1; RUN: opt -simple-loop-unswitch -enable-nontrivial-unswitch -verify-memoryssa -S %s | FileCheck %s
2; REQUIRES: asserts
3
4target triple = "x86_64-unknown-linux-gnu"
5
6declare void @foo()
7
8; In Test1, there are no definitions. MemorySSA updates insert trivial phis and remove them.
9; Verify all are removed, considering the SLU pass leaves unreachable blocks hanging when the MSSA updates are done.
10; CHECK-LABEL: @Test1
11define void @Test1(i32) {
12header:
13  br label %outer
14
15outer.loopexit.split:                             ; preds = %continue
16  br label %outer.loopexit
17
18outer.loopexit:                                   ; preds = %outer.loopexit.split.us, %outer.loopexit.split
19  br label %outer
20
21outer:                                            ; preds = %outer.loopexit, %header
22  br i1 false, label %outer.split.us, label %outer.split
23
24outer.split.us:                                   ; preds = %outer
25  br label %inner.us
26
27inner.us:                                         ; preds = %continue.us, %outer.split.us
28  br label %overflow.us
29
30overflow.us:                                      ; preds = %inner.us
31  br label %continue.us
32
33continue.us:                                      ; preds = %overflow.us
34  br i1 true, label %outer.loopexit.split.us, label %inner.us
35
36outer.loopexit.split.us:                          ; preds = %continue.us
37  br label %outer.loopexit
38
39outer.split:                                      ; preds = %outer
40  br label %inner
41
42inner:                                            ; preds = %continue, %outer.split
43  br label %switchme
44
45switchme:                                         ; preds = %inner
46  switch i32 %0, label %continue [
47    i32 88, label %go_out
48    i32 99, label %case2
49  ]
50
51case2:                                            ; preds = %switchme
52  br label %continue
53
54continue:                                         ; preds = %case2, %switchme
55  br i1 true, label %outer.loopexit.split, label %inner
56
57go_out:                                           ; preds = %switchme
58  unreachable
59}
60
61; In Test2 there is a single def (call to foo). There are already Phis in place that are cloned when unswitching.
62; Ensure MemorySSA remains correct. Due to SLU's pruned cloning, continue.us2 becomes unreachable, with an empty Phi that is later cleaned.
63; CHECK-LABEL: @Test2
64define void @Test2(i32) {
65header:
66  br label %outer
67
68outer.loopexit.split:                             ; preds = %continue
69  br label %outer.loopexit
70
71outer.loopexit:                                   ; preds = %outer.loopexit.split.us, %outer.loopexit.split
72  br label %outer
73
74outer:                                            ; preds = %outer.loopexit, %header
75  br i1 false, label %outer.split.us, label %outer.split
76
77outer.split.us:                                   ; preds = %outer
78  br label %inner.us
79
80inner.us:                                         ; preds = %continue.us, %outer.split.us
81  br label %overflow.us
82
83overflow.us:                                      ; preds = %inner.us
84  br label %continue.us
85
86continue.us:                                      ; preds = %overflow.us
87  br i1 true, label %outer.loopexit.split.us, label %inner.us
88
89outer.loopexit.split.us:                          ; preds = %continue.us
90  br label %outer.loopexit
91
92outer.split:                                      ; preds = %outer
93  br label %inner
94
95inner:                                            ; preds = %continue, %outer.split
96  br label %switchme
97
98switchme:                                         ; preds = %inner
99  switch i32 %0, label %continue [
100    i32 88, label %go_out
101    i32 99, label %case2
102  ]
103
104case2:                                            ; preds = %switchme
105  call void @foo()
106  br label %continue
107
108continue:                                         ; preds = %case2, %switchme
109  br i1 true, label %outer.loopexit.split, label %inner
110
111go_out:                                           ; preds = %switchme
112  unreachable
113}
114