1; Reproducer for a bad performance regression triggered by switch to the new PM.
2; `barney` ended up with the local variables not being optimized away and that
3; had rather dramatic effect on some GPU code. See
4; https://bugs.llvm.org/show_bug.cgi?id=52037 for the gory details.
5;
6; RUN: llc -mtriple=nvptx64-nvidia-cuda -mcpu=sm_70 -O3 -o - %s | FileCheck %s
7; RUN: %if ptxas %{ llc -mtriple=nvptx64-nvidia-cuda -mcpu=sm_70 -O3 -o - %s | %ptxas-verify -arch=sm_70 %}
8
9; CHECK-LABEL: .visible .entry barney(
10; CHECK-NOT:  .local{{.*}}__local_depot
11; CHECK: ret;
12
13source_filename = "reduced.1.ll"
14target triple = "nvptx64-nvidia-cuda"
15
16%char3 = type { i8, i8, i8 }
17%float4 = type { float, float, float, float }
18%float3 = type { float, float, float }
19%int3 = type { i32, i32, i32 }
20%struct.spam.2 = type { %struct.foo.3, i16*, float, float, i32, float }
21%struct.foo.3 = type <{ %float4*, %float4*, %float4*, i32*, i32*, i32, i32, float }>
22%struct.zot = type { %struct.bar, [8 x i8], %struct.foo, [12 x i8] }
23%struct.bar = type { i32 (...)** }
24%struct.foo = type <{ i16*, %float4, %int3, i32, %float3, [4 x i8], i64, i32, i8, [3 x i8], i32 }>
25
26@global = external local_unnamed_addr addrspace(4) externally_initialized global [27 x %char3], align 1
27@global_1 = linkonce_odr unnamed_addr constant { [3 x i8*] } { [3 x i8*] [i8* inttoptr (i64 16 to i8*), i8* null, i8* null] }, align 8
28
29; Function Attrs: argmemonly mustprogress nofree nounwind willreturn
30declare void @llvm.memcpy.p0i8.p0i8.i64(i8* noalias nocapture writeonly, i8* noalias nocapture readonly, i64, i1 immarg) #0
31
32declare %float4 @snork(float) local_unnamed_addr
33
34declare %float3 @bar_2(float, float) local_unnamed_addr
35
36declare %float3 @zot() local_unnamed_addr
37
38declare %int3 @hoge(i32, i32, i32) local_unnamed_addr
39
40declare i64 @foo() local_unnamed_addr
41
42define void @barney(%struct.spam.2* nocapture readonly %arg) local_unnamed_addr {
43bb:
44  tail call void asm sideeffect "// KEEP", ""() #1
45  %tmp = alloca %struct.zot, align 16
46  %tmp4 = getelementptr inbounds %struct.spam.2, %struct.spam.2* %arg, i64 0, i32 1
47  %tmp5 = load i16*, i16** %tmp4, align 8
48  %tmp6 = bitcast %struct.zot* %tmp to i8*
49  %tmp9 = getelementptr inbounds %struct.zot, %struct.zot* %tmp, i64 0, i32 2, i32 1
50  %0 = bitcast %float4* %tmp9 to i16**
51  store i16* %tmp5, i16** %0, align 8
52  %tmp10 = getelementptr inbounds %struct.zot, %struct.zot* %tmp, i64 0, i32 0, i32 0
53  store i32 (...)** bitcast (i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @global_1, i64 0, inrange i32 0, i64 3) to i32 (...)**), i32 (...)*** %tmp10, align 16
54  %tmp34 = getelementptr %struct.spam.2, %struct.spam.2* %arg, i64 0, i32 0, i32 0
55  %tmp.i1 = tail call i64 @foo()
56  %tmp44.i16 = getelementptr inbounds i16, i16* %tmp5, i64 undef
57  %tmp45.i17 = load i16, i16* %tmp44.i16, align 2
58  %tmp47.i18 = icmp eq i16 %tmp45.i17, -1
59  br i1 %tmp47.i18, label %bb14, label %bb49.i.lr.ph
60
61bb49.i.lr.ph:                                     ; preds = %bb
62  %tmp16 = bitcast %struct.zot* %tmp to i8**
63  %tmp7.i6 = getelementptr inbounds %struct.zot, %struct.zot* %tmp, i64 0, i32 2
64  %extract = lshr i16 %tmp45.i17, 11
65  %extract.t = trunc i16 %extract to i8
66  %1 = getelementptr inbounds %struct.zot, %struct.zot* %tmp, i64 0, i32 2
67  %tmp58.i = getelementptr inbounds %struct.zot, %struct.zot* %tmp, i64 0, i32 2, i32 1, i32 2
68  %tmp59.i = getelementptr inbounds %struct.zot, %struct.zot* %tmp, i64 0, i32 2, i32 4, i32 2
69  %tmp62.i = getelementptr inbounds %struct.zot, %struct.zot* %tmp, i64 0, i32 2, i32 2, i32 2
70  %2 = getelementptr inbounds %struct.foo, %struct.foo* %1, i64 1
71  %3 = bitcast %struct.foo* %2 to i8*
72  %tmp64.i = getelementptr inbounds %struct.zot, %struct.zot* %tmp, i64 0, i32 2, i32 10
73  %tmp19.i.i = load float, float* %tmp58.i, align 16
74  %tmp23.i.i = getelementptr inbounds %struct.zot, %struct.zot* %tmp, i64 0, i32 2, i32 2
75  %4 = bitcast %int3* %tmp23.i.i to float*
76  %tmp24.i.i = load float, float* %4, align 8
77  %5 = getelementptr inbounds %struct.zot, %struct.zot* %tmp, i64 0, i32 2, i32 5, i64 0
78  %6 = bitcast i8* %5 to float*
79  %.repack3.i = getelementptr inbounds %struct.zot, %struct.zot* %tmp, i64 0, i32 2, i32 6
80  %7 = bitcast i64* %.repack3.i to float*
81  %tmp41.i.i = load i32, i32* %tmp62.i, align 16
82  %tmp48.i.i = getelementptr inbounds %struct.zot, %struct.zot* %tmp, i64 0, i32 2, i32 3
83  %tmp49.i.i = load i32, i32* %tmp48.i.i, align 4
84  %tmp54.i.i = getelementptr inbounds %struct.zot, %struct.zot* %tmp, i64 0, i32 2, i32 4
85  %8 = bitcast %float3* %tmp54.i.i to i32*
86  %tmp55.i.i = load i32, i32* %8, align 8
87  %tmp9.i = getelementptr inbounds %struct.zot, %struct.zot* %tmp, i64 0, i32 2, i32 7
88  %9 = bitcast i32* %tmp9.i to i64*
89  %tmp40.i = getelementptr inbounds %struct.zot, %struct.zot* %tmp, i64 0, i32 2, i32 4, i32 1
90  %10 = bitcast float* %tmp40.i to i32*
91  %tmp41.i = load i32, i32* %10, align 4
92  %tmp42.i = zext i32 %tmp41.i to i64
93  %tmp7.i = getelementptr inbounds %struct.zot, %struct.zot* %tmp, i64 0, i32 2
94  %tmp17.pre = load i8*, i8** %tmp16, align 16
95  %tmp60.i.peel = bitcast %struct.foo* %tmp7.i6 to i32**
96  %tmp61.i.peel = load i32*, i32** %tmp60.i.peel, align 16
97  %tmp10.i.i.peel = add nsw i8 %extract.t, -1
98  store i8 %tmp10.i.i.peel, i8* %3, align 4
99  %tmp13.i.i.peel = tail call %float3 @zot() #1
100  %tmp15.i.i.peel = extractvalue %float3 %tmp13.i.i.peel, 0
101  %tmp22.i.i.peel = fsub contract float %tmp19.i.i, %tmp15.i.i.peel
102  %tmp17.i.i.peel = extractvalue %float3 %tmp13.i.i.peel, 2
103  %tmp27.i.i.peel = fsub contract float %tmp24.i.i, %tmp17.i.i.peel
104  %tmp28.i.i.peel = tail call %float3 @bar_2(float %tmp22.i.i.peel, float %tmp27.i.i.peel) #1
105  %tmp28.i.elt.i.peel = extractvalue %float3 %tmp28.i.i.peel, 0
106  store float %tmp28.i.elt.i.peel, float* %tmp59.i, align 16
107  %tmp28.i.elt2.i.peel = extractvalue %float3 %tmp28.i.i.peel, 1
108  store float %tmp28.i.elt2.i.peel, float* %6, align 4
109  %tmp28.i.elt4.i.peel = extractvalue %float3 %tmp28.i.i.peel, 2
110  store float %tmp28.i.elt4.i.peel, float* %7, align 8
111  %tmp38.i.i.peel = zext i8 %tmp10.i.i.peel to i64
112  %tmp39.i5.i.peel = getelementptr inbounds [27 x %char3], [27 x %char3] addrspace(4)* @global, i64 0, i64 %tmp38.i.i.peel
113  %tmp39.i.i.peel = addrspacecast %char3 addrspace(4)* %tmp39.i5.i.peel to %char3*
114  %tmp42.i.i.peel = getelementptr inbounds %char3, %char3* %tmp39.i.i.peel, i64 0, i32 0
115  %tmp43.i.i.peel = load i8, i8* %tmp42.i.i.peel, align 1
116  %tmp44.i.i.peel = sext i8 %tmp43.i.i.peel to i32
117  %tmp45.i.i.peel = add nsw i32 %tmp41.i.i, %tmp44.i.i.peel
118  %tmp50.i.i.peel = getelementptr inbounds %char3, %char3* %tmp39.i.i.peel, i64 0, i32 1
119  %tmp51.i.i.peel = load i8, i8* %tmp50.i.i.peel, align 1
120  %tmp52.i.i.peel = sext i8 %tmp51.i.i.peel to i32
121  %tmp53.i.i.peel = add nsw i32 %tmp49.i.i, %tmp52.i.i.peel
122  %tmp56.i.i.peel = getelementptr inbounds %char3, %char3* %tmp39.i.i.peel, i64 0, i32 2
123  %tmp57.i.i.peel = load i8, i8* %tmp56.i.i.peel, align 1
124  %tmp58.i.i.peel = sext i8 %tmp57.i.i.peel to i32
125  %tmp59.i.i.peel = add nsw i32 %tmp55.i.i, %tmp58.i.i.peel
126  %tmp60.i.i.peel = tail call %int3 @hoge(i32 %tmp45.i.i.peel, i32 %tmp53.i.i.peel, i32 %tmp59.i.i.peel) #1
127  %tmp61.i.i.peel = getelementptr inbounds i32, i32* %tmp61.i.peel, i64 undef
128  %tmp62.i.i.peel = load i32, i32* %tmp61.i.i.peel, align 4
129  store i32 %tmp62.i.i.peel, i32* %tmp64.i, align 8
130  %tmp22.peel = getelementptr inbounds %struct.zot, %struct.zot* %tmp, i64 0, i32 2
131  %11 = bitcast %struct.foo* %tmp22.peel to i8*
132  %tmp24.peel = getelementptr inbounds i8, i8* %11, i64 80
133  %12 = bitcast i8* %tmp24.peel to i32*
134  %tmp25.peel = load i32, i32* %12, align 16
135  %tmp36.peel = load %float4*, %float4** %tmp34, align 8
136  %tmp37.peel = zext i32 %tmp25.peel to i64
137  %tmp38.peel = getelementptr inbounds %float4, %float4* %tmp36.peel, i64 %tmp37.peel
138  %tmp39.peel = bitcast %float4* %tmp38.peel to i8*
139  tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 undef, i8* align 1 %tmp39.peel, i64 undef, i1 false)
140  %tmp40.peel = getelementptr inbounds %struct.zot, %struct.zot* %tmp, i64 0, i32 2, i32 4, i32 2
141  %tmp41.peel25 = getelementptr inbounds float, float* %tmp40.peel, i64 2
142  %tmp42.peel = load float, float* %tmp41.peel25, align 8
143  %tmp44.peel = load float, float* inttoptr (i64 8 to float*), align 8
144  %tmp45.peel = fsub contract float %tmp42.peel, %tmp44.peel
145  %tmp46.peel = tail call %float4 @snork(float %tmp45.peel)
146  %tmp.i.peel = tail call i64 @foo()
147  %tmp10.i.peel = load i64, i64* %9, align 16
148  %tmp11.i.peel = add i64 %tmp10.i.peel, %tmp.i.peel
149  store i64 %tmp11.i.peel, i64* %9, align 16, !tbaa !1
150  %tmp43.i.peel = add i64 %tmp11.i.peel, %tmp42.i
151  %tmp44.i.peel = getelementptr inbounds i16, i16* %tmp5, i64 %tmp43.i.peel
152  %tmp45.i.peel = load i16, i16* %tmp44.i.peel, align 2
153  %tmp47.i.peel = icmp eq i16 %tmp45.i.peel, -1
154  %extract21.peel = lshr i16 %tmp45.i.peel, 11
155  %extract.t22.peel = trunc i16 %extract21.peel to i8
156  br i1 %tmp47.i.peel, label %bb14, label %bb49.i.lr.ph.peel.newph
157
158bb49.i.lr.ph.peel.newph:                          ; preds = %bb49.i.lr.ph
159  %tmp60.i = bitcast %struct.foo* %tmp7.i to i32**
160  %tmp61.i = load i32*, i32** %tmp60.i, align 16
161  %tmp61.i.i = getelementptr inbounds i32, i32* %tmp61.i, i64 undef
162  %tmp18 = getelementptr i8, i8* %tmp17.pre, i64 -24
163  %tmp19 = bitcast i8* %tmp18 to i64*
164  br label %bb49.i
165
166bb49.i:                                           ; preds = %bb49.i, %bb49.i.lr.ph.peel.newph
167  %tmp45.i20.off11 = phi i8 [ %extract.t22.peel, %bb49.i.lr.ph.peel.newph ], [ %extract.t22, %bb49.i ]
168  %tmp10.i.i = add nsw i8 %tmp45.i20.off11, -1
169  store i8 %tmp10.i.i, i8* %3, align 4
170  %tmp13.i.i = tail call %float3 @zot() #1
171  %tmp15.i.i = extractvalue %float3 %tmp13.i.i, 0
172  %tmp22.i.i = fsub contract float %tmp19.i.i, %tmp15.i.i
173  %tmp17.i.i = extractvalue %float3 %tmp13.i.i, 2
174  %tmp27.i.i = fsub contract float %tmp24.i.i, %tmp17.i.i
175  %tmp28.i.i = tail call %float3 @bar_2(float %tmp22.i.i, float %tmp27.i.i) #1
176  %tmp28.i.elt.i = extractvalue %float3 %tmp28.i.i, 0
177  store float %tmp28.i.elt.i, float* %tmp59.i, align 16
178  %tmp28.i.elt2.i = extractvalue %float3 %tmp28.i.i, 1
179  store float %tmp28.i.elt2.i, float* %6, align 4
180  %tmp28.i.elt4.i = extractvalue %float3 %tmp28.i.i, 2
181  store float %tmp28.i.elt4.i, float* %7, align 8
182  %tmp38.i.i = zext i8 %tmp10.i.i to i64
183  %tmp39.i5.i = getelementptr inbounds [27 x %char3], [27 x %char3] addrspace(4)* @global, i64 0, i64 %tmp38.i.i
184  %tmp39.i.i = addrspacecast %char3 addrspace(4)* %tmp39.i5.i to %char3*
185  %tmp42.i.i = getelementptr inbounds %char3, %char3* %tmp39.i.i, i64 0, i32 0
186  %tmp43.i.i = load i8, i8* %tmp42.i.i, align 1
187  %tmp44.i.i = sext i8 %tmp43.i.i to i32
188  %tmp45.i.i = add nsw i32 %tmp41.i.i, %tmp44.i.i
189  %tmp50.i.i = getelementptr inbounds %char3, %char3* %tmp39.i.i, i64 0, i32 1
190  %tmp51.i.i = load i8, i8* %tmp50.i.i, align 1
191  %tmp52.i.i = sext i8 %tmp51.i.i to i32
192  %tmp53.i.i = add nsw i32 %tmp49.i.i, %tmp52.i.i
193  %tmp56.i.i = getelementptr inbounds %char3, %char3* %tmp39.i.i, i64 0, i32 2
194  %tmp57.i.i = load i8, i8* %tmp56.i.i, align 1
195  %tmp58.i.i = sext i8 %tmp57.i.i to i32
196  %tmp59.i.i = add nsw i32 %tmp55.i.i, %tmp58.i.i
197  %tmp60.i.i = tail call %int3 @hoge(i32 %tmp45.i.i, i32 %tmp53.i.i, i32 %tmp59.i.i) #1
198  %tmp62.i.i = load i32, i32* %tmp61.i.i, align 4
199  store i32 %tmp62.i.i, i32* %tmp64.i, align 8
200  %tmp20 = load i64, i64* %tmp19, align 8
201  %tmp22 = getelementptr inbounds i8, i8* %tmp6, i64 %tmp20
202  %tmp24 = getelementptr inbounds i8, i8* %tmp22, i64 80
203  %13 = bitcast i8* %tmp24 to i32*
204  %tmp25 = load i32, i32* %13, align 4
205  %tmp36 = load %float4*, %float4** %tmp34, align 8
206  %tmp37 = zext i32 %tmp25 to i64
207  %tmp38 = getelementptr inbounds %float4, %float4* %tmp36, i64 %tmp37
208  %tmp39 = bitcast %float4* %tmp38 to i8*
209  tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 undef, i8* align 1 %tmp39, i64 undef, i1 false)
210  %tmp40 = getelementptr inbounds i8, i8* %tmp22, i64 48
211  %tmp41 = getelementptr inbounds i8, i8* %tmp40, i64 8
212  %14 = bitcast i8* %tmp41 to float*
213  %tmp42 = load float, float* %14, align 4
214  %tmp44 = load float, float* inttoptr (i64 8 to float*), align 8
215  %tmp45 = fsub contract float %tmp42, %tmp44
216  %tmp46 = tail call %float4 @snork(float %tmp45)
217  %tmp.i = tail call i64 @foo()
218  %tmp10.i = load i64, i64* %9, align 16
219  %tmp11.i = add i64 %tmp10.i, %tmp.i
220  store i64 %tmp11.i, i64* %9, align 16, !tbaa !1
221  %tmp43.i = add i64 %tmp11.i, %tmp42.i
222  %tmp44.i = getelementptr inbounds i16, i16* %tmp5, i64 %tmp43.i
223  %tmp45.i = load i16, i16* %tmp44.i, align 2
224  %tmp47.i = icmp eq i16 %tmp45.i, -1
225  %extract21 = lshr i16 %tmp45.i, 11
226  %extract.t22 = trunc i16 %extract21 to i8
227  br i1 %tmp47.i, label %bb14, label %bb49.i, !llvm.loop !12
228
229bb14:                                             ; preds = %bb49.i.lr.ph, %bb49.i, %bb
230  ret void
231}
232
233attributes #0 = { argmemonly mustprogress nofree nounwind willreturn }
234attributes #1 = { nounwind }
235
236!nvvm.annotations = !{!0}
237
238!0 = !{void (%struct.spam.2*)* @barney, !"kernel", i32 1}
239!1 = !{!2, !11, i64 64}
240!2 = !{!"_ZTSN7cuneibs22neiblist_iterator_coreE", !3, i64 0, !3, i64 8, !6, i64 16, !8, i64 32, !9, i64 44, !10, i64 48, !11, i64 64, !9, i64 72, !4, i64 76, !9, i64 80}
241!3 = !{!"any pointer", !4, i64 0}
242!4 = !{!"omnipotent char", !5, i64 0}
243!5 = !{!"Simple C++ TBAA"}
244!6 = !{!"_ZTS6float4", !7, i64 0, !7, i64 4, !7, i64 8, !7, i64 12}
245!7 = !{!"float", !4, i64 0}
246!8 = !{!"_ZTS4int3", !9, i64 0, !9, i64 4, !9, i64 8}
247!9 = !{!"int", !4, i64 0}
248!10 = !{!"_ZTS6float3", !7, i64 0, !7, i64 4, !7, i64 8}
249!11 = !{!"long", !4, i64 0}
250!12 = distinct !{!12, !13}
251!13 = !{!"llvm.loop.peeled.count", i32 1}
252