1; RUN: opt -aa-pipeline=basic-aa -passes='print<memoryssa>,verify<memoryssa>' -disable-output < %s 2>&1 | FileCheck %s
2
3%struct.hoge = type { i32, %struct.widget }
4%struct.widget = type { i64 }
5
6define hidden void @quux(%struct.hoge *%f) align 2 {
7  %tmp = getelementptr inbounds %struct.hoge, %struct.hoge* %f, i64 0, i32 1, i32 0
8  %tmp24 = getelementptr inbounds %struct.hoge, %struct.hoge* %f, i64 0, i32 1
9  %tmp25 = bitcast %struct.widget* %tmp24 to i64**
10  br label %bb26
11
12bb26:                                             ; preds = %bb77, %0
13; CHECK:  3 = MemoryPhi({%0,liveOnEntry},{bb77,2})
14; CHECK-NEXT:   br i1 undef, label %bb68, label %bb77
15  br i1 undef, label %bb68, label %bb77
16
17bb68:                                             ; preds = %bb26
18; CHECK:  MemoryUse(liveOnEntry)
19; CHECK-NEXT:   %tmp69 = load i64, i64* null, align 8
20  %tmp69 = load i64, i64* null, align 8
21; CHECK:  1 = MemoryDef(3)
22; CHECK-NEXT:   store i64 %tmp69, i64* %tmp, align 8
23  store i64 %tmp69, i64* %tmp, align 8
24  br label %bb77
25
26bb77:                                             ; preds = %bb68, %bb26
27; CHECK:  2 = MemoryPhi({bb26,3},{bb68,1})
28; CHECK:  MemoryUse(2)
29; CHECK-NEXT:   %tmp78 = load i64*, i64** %tmp25, align 8
30  %tmp78 = load i64*, i64** %tmp25, align 8
31  %tmp79 = getelementptr inbounds i64, i64* %tmp78, i64 undef
32  br label %bb26
33}
34
35define hidden void @quux_no_null_opt(%struct.hoge *%f) align 2 #0 {
36; CHECK-LABEL: quux_no_null_opt(
37  %tmp = getelementptr inbounds %struct.hoge, %struct.hoge* %f, i64 0, i32 1, i32 0
38  %tmp24 = getelementptr inbounds %struct.hoge, %struct.hoge* %f, i64 0, i32 1
39  %tmp25 = bitcast %struct.widget* %tmp24 to i64**
40  br label %bb26
41
42bb26:                                             ; preds = %bb77, %0
43; CHECK:  3 = MemoryPhi({%0,liveOnEntry},{bb77,2})
44; CHECK-NEXT:   br i1 undef, label %bb68, label %bb77
45  br i1 undef, label %bb68, label %bb77
46
47bb68:                                             ; preds = %bb26
48; CHECK:  MemoryUse(3)
49; CHECK-NEXT:   %tmp69 = load i64, i64* null, align 8
50  %tmp69 = load i64, i64* null, align 8
51; CHECK:  1 = MemoryDef(3)
52; CHECK-NEXT:   store i64 %tmp69, i64* %tmp, align 8
53  store i64 %tmp69, i64* %tmp, align 8
54  br label %bb77
55
56bb77:                                             ; preds = %bb68, %bb26
57; CHECK:  2 = MemoryPhi({bb26,3},{bb68,1})
58; CHECK:  MemoryUse(2)
59; CHECK-NEXT:   %tmp78 = load i64*, i64** %tmp25, align 8
60  %tmp78 = load i64*, i64** %tmp25, align 8
61  %tmp79 = getelementptr inbounds i64, i64* %tmp78, i64 undef
62  br label %bb26
63}
64
65; CHECK-LABEL: define void @quux_skip
66define void @quux_skip(%struct.hoge* noalias %f, i64* noalias %g) align 2 {
67  %tmp = getelementptr inbounds %struct.hoge, %struct.hoge* %f, i64 0, i32 1, i32 0
68  %tmp24 = getelementptr inbounds %struct.hoge, %struct.hoge* %f, i64 0, i32 1
69  %tmp25 = bitcast %struct.widget* %tmp24 to i64**
70  br label %bb26
71
72bb26:                                             ; preds = %bb77, %0
73; CHECK: 3 = MemoryPhi({%0,liveOnEntry},{bb77,2})
74; CHECK-NEXT: br i1 undef, label %bb68, label %bb77
75  br i1 undef, label %bb68, label %bb77
76
77bb68:                                             ; preds = %bb26
78; CHECK: MemoryUse(3)
79; CHECK-NEXT: %tmp69 = load i64, i64* %g, align 8
80  %tmp69 = load i64, i64* %g, align 8
81; CHECK: 1 = MemoryDef(3)
82; CHECK-NEXT: store i64 %tmp69, i64* %g, align 8
83  store i64 %tmp69, i64* %g, align 8
84  br label %bb77
85
86bb77:                                             ; preds = %bb68, %bb26
87; CHECK: 2 = MemoryPhi({bb26,3},{bb68,1})
88; CHECK: MemoryUse(liveOnEntry)
89; CHECK-NEXT: %tmp78 = load i64*, i64** %tmp25, align 8
90  %tmp78 = load i64*, i64** %tmp25, align 8
91  br label %bb26
92}
93
94; CHECK-LABEL: define void @quux_dominated
95define void @quux_dominated(%struct.hoge* noalias %f, i64* noalias %g) align 2 {
96  %tmp = getelementptr inbounds %struct.hoge, %struct.hoge* %f, i64 0, i32 1, i32 0
97  %tmp24 = getelementptr inbounds %struct.hoge, %struct.hoge* %f, i64 0, i32 1
98  %tmp25 = bitcast %struct.widget* %tmp24 to i64**
99  br label %bb26
100
101bb26:                                             ; preds = %bb77, %0
102; CHECK: 3 = MemoryPhi({%0,liveOnEntry},{bb77,2})
103; CHECK: MemoryUse(3)
104; CHECK-NEXT: load i64*, i64** %tmp25, align 8
105  load i64*, i64** %tmp25, align 8
106  br i1 undef, label %bb68, label %bb77
107
108bb68:                                             ; preds = %bb26
109; CHECK: MemoryUse(3)
110; CHECK-NEXT: %tmp69 = load i64, i64* %g, align 8
111  %tmp69 = load i64, i64* %g, align 8
112; CHECK: 1 = MemoryDef(3)
113; CHECK-NEXT: store i64 %tmp69, i64* %g, align 8
114  store i64 %tmp69, i64* %g, align 8
115  br label %bb77
116
117bb77:                                             ; preds = %bb68, %bb26
118; CHECK: 4 = MemoryPhi({bb26,3},{bb68,1})
119; CHECK: 2 = MemoryDef(4)
120; CHECK-NEXT: store i64* null, i64** %tmp25, align 8
121  store i64* null, i64** %tmp25, align 8
122  br label %bb26
123}
124
125; CHECK-LABEL: define void @quux_nodominate
126define void @quux_nodominate(%struct.hoge* noalias %f, i64* noalias %g) align 2 {
127  %tmp = getelementptr inbounds %struct.hoge, %struct.hoge* %f, i64 0, i32 1, i32 0
128  %tmp24 = getelementptr inbounds %struct.hoge, %struct.hoge* %f, i64 0, i32 1
129  %tmp25 = bitcast %struct.widget* %tmp24 to i64**
130  br label %bb26
131
132bb26:                                             ; preds = %bb77, %0
133; CHECK: 3 = MemoryPhi({%0,liveOnEntry},{bb77,2})
134; CHECK: MemoryUse(liveOnEntry)
135; CHECK-NEXT: load i64*, i64** %tmp25, align 8
136  load i64*, i64** %tmp25, align 8
137  br i1 undef, label %bb68, label %bb77
138
139bb68:                                             ; preds = %bb26
140; CHECK: MemoryUse(3)
141; CHECK-NEXT: %tmp69 = load i64, i64* %g, align 8
142  %tmp69 = load i64, i64* %g, align 8
143; CHECK: 1 = MemoryDef(3)
144; CHECK-NEXT: store i64 %tmp69, i64* %g, align 8
145  store i64 %tmp69, i64* %g, align 8
146  br label %bb77
147
148bb77:                                             ; preds = %bb68, %bb26
149; CHECK: 2 = MemoryPhi({bb26,3},{bb68,1})
150; CHECK-NEXT: br label %bb26
151  br label %bb26
152}
153
154attributes #0 = { null_pointer_is_valid }
155