ELF: Have __rela_iplt_{start,end} surround .rela.iplt with --pack-dyn-relocs=android.
[llvm-project.git] / llvm / test / CodeGen / AMDGPU / promote-alloca-array-aggregate.ll
blob05c727201bbf1d67bb74d5c3306d3d16a4b49347
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -passes=sroa,amdgpu-promote-alloca < %s | FileCheck %s
4 ; Make sure that array alloca loaded and stored as multi-element aggregates are handled correctly
5 ; Strictly the promote-alloca pass shouldn't have to deal with this case as it is non-canonical, but
6 ; the pass should handle it gracefully if it is
7 ; The checks look for lines that previously caused issues in PromoteAlloca (non-canonical). Opt
8 ; should now leave these unchanged
10 %Block = type { [1 x float], i32 }
11 %gl_PerVertex = type { <4 x float>, float, [1 x float], [1 x float] }
12 %struct = type { i32, i32 }
14 @block = external addrspace(1) global %Block
15 @pv = external addrspace(1) global %gl_PerVertex
17 define amdgpu_vs void @promote_1d_aggr() #0 {
18 ; CHECK-LABEL: @promote_1d_aggr(
19 ; CHECK-NEXT:    [[F1:%.*]] = alloca [1 x float], align 4, addrspace(5)
20 ; CHECK-NEXT:    [[FOO:%.*]] = getelementptr [[BLOCK:%.*]], ptr addrspace(1) @block, i32 0, i32 1
21 ; CHECK-NEXT:    [[FOO1:%.*]] = load i32, ptr addrspace(1) [[FOO]], align 4
22 ; CHECK-NEXT:    [[FOO3:%.*]] = load [1 x float], ptr addrspace(1) @block, align 4
23 ; CHECK-NEXT:    [[FOO3_FCA_0_EXTRACT:%.*]] = extractvalue [1 x float] [[FOO3]], 0
24 ; CHECK-NEXT:    [[FOO3_FCA_0_GEP:%.*]] = getelementptr inbounds [1 x float], ptr addrspace(5) [[F1]], i32 0, i32 0
25 ; CHECK-NEXT:    store float [[FOO3_FCA_0_EXTRACT]], ptr addrspace(5) [[FOO3_FCA_0_GEP]], align 4
26 ; CHECK-NEXT:    [[FOO5:%.*]] = getelementptr [1 x float], ptr addrspace(5) [[F1]], i32 0, i32 [[FOO1]]
27 ; CHECK-NEXT:    [[FOO6:%.*]] = load float, ptr addrspace(5) [[FOO5]], align 4
28 ; CHECK-NEXT:    [[FOO9:%.*]] = insertelement <4 x float> undef, float [[FOO6]], i32 0
29 ; CHECK-NEXT:    [[FOO10:%.*]] = insertelement <4 x float> [[FOO9]], float [[FOO6]], i32 1
30 ; CHECK-NEXT:    [[FOO11:%.*]] = insertelement <4 x float> [[FOO10]], float [[FOO6]], i32 2
31 ; CHECK-NEXT:    [[FOO12:%.*]] = insertelement <4 x float> [[FOO11]], float [[FOO6]], i32 3
32 ; CHECK-NEXT:    store <4 x float> [[FOO12]], ptr addrspace(1) @pv, align 16
33 ; CHECK-NEXT:    ret void
35   %i = alloca i32, addrspace(5)
36   %f1 = alloca [1 x float], addrspace(5)
37   %foo = getelementptr %Block, ptr addrspace(1) @block, i32 0, i32 1
38   %foo1 = load i32, ptr addrspace(1) %foo
39   store i32 %foo1, ptr addrspace(5) %i
40   %foo3 = load [1 x float], ptr addrspace(1) @block
41   store [1 x float] %foo3, ptr addrspace(5) %f1
42   %foo4 = load i32, ptr addrspace(5) %i
43   %foo5 = getelementptr [1 x float], ptr addrspace(5) %f1, i32 0, i32 %foo4
44   %foo6 = load float, ptr addrspace(5) %foo5
45   %foo7 = alloca <4 x float>, addrspace(5)
46   %foo8 = load <4 x float>, ptr addrspace(5) %foo7
47   %foo9 = insertelement <4 x float> %foo8, float %foo6, i32 0
48   %foo10 = insertelement <4 x float> %foo9, float %foo6, i32 1
49   %foo11 = insertelement <4 x float> %foo10, float %foo6, i32 2
50   %foo12 = insertelement <4 x float> %foo11, float %foo6, i32 3
51   store <4 x float> %foo12, ptr addrspace(1) @pv
52   ret void
55 %Block2 = type { i32, [2 x float] }
56 @block2 = external addrspace(1) global %Block2
58 define amdgpu_vs void @promote_store_aggr() #0 {
59 ; CHECK-LABEL: @promote_store_aggr(
60 ; CHECK-NEXT:    [[FOO1:%.*]] = load i32, ptr addrspace(1) @block2, align 4
61 ; CHECK-NEXT:    [[FOO3:%.*]] = sitofp i32 [[FOO1]] to float
62 ; CHECK-NEXT:    [[FOO6_FCA_0_INSERT:%.*]] = insertvalue [2 x float] poison, float [[FOO3]], 0
63 ; CHECK-NEXT:    [[FOO6_FCA_1_INSERT:%.*]] = insertvalue [2 x float] [[FOO6_FCA_0_INSERT]], float 2.000000e+00, 1
64 ; CHECK-NEXT:    [[FOO7:%.*]] = getelementptr [[BLOCK2:%.*]], ptr addrspace(1) @block2, i32 0, i32 1
65 ; CHECK-NEXT:    store [2 x float] [[FOO6_FCA_1_INSERT]], ptr addrspace(1) [[FOO7]], align 4
66 ; CHECK-NEXT:    store <4 x float> splat (float 1.000000e+00), ptr addrspace(1) @pv, align 16
67 ; CHECK-NEXT:    ret void
69   %i = alloca i32, addrspace(5)
70   %f1 = alloca [2 x float], addrspace(5)
71   %foo1 = load i32, ptr addrspace(1) @block2
72   store i32 %foo1, ptr addrspace(5) %i
73   %foo2 = load i32, ptr addrspace(5) %i
74   %foo3 = sitofp i32 %foo2 to float
75   store float %foo3, ptr addrspace(5) %f1
76   %foo5 = getelementptr [2 x float], ptr addrspace(5) %f1, i32 0, i32 1
77   store float 2.000000e+00, ptr addrspace(5) %foo5
78   %foo6 = load [2 x float], ptr addrspace(5) %f1
79   %foo7 = getelementptr %Block2, ptr addrspace(1) @block2, i32 0, i32 1
80   store [2 x float] %foo6, ptr addrspace(1) %foo7
81   store <4 x float> <float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00>, ptr addrspace(1) @pv
82   ret void
85 %Block3 = type { [2 x float], i32 }
86 @block3 = external addrspace(1) global %Block3
88 define amdgpu_vs void @promote_load_from_store_aggr() #0 {
89 ; CHECK-LABEL: @promote_load_from_store_aggr(
90 ; CHECK-NEXT:    [[FOO:%.*]] = getelementptr [[BLOCK3:%.*]], ptr addrspace(1) @block3, i32 0, i32 1
91 ; CHECK-NEXT:    [[FOO1:%.*]] = load i32, ptr addrspace(1) [[FOO]], align 4
92 ; CHECK-NEXT:    [[FOO3:%.*]] = load [2 x float], ptr addrspace(1) @block3, align 4
93 ; CHECK-NEXT:    [[FOO3_FCA_0_EXTRACT:%.*]] = extractvalue [2 x float] [[FOO3]], 0
94 ; CHECK-NEXT:    [[TMP1:%.*]] = insertelement <2 x float> undef, float [[FOO3_FCA_0_EXTRACT]], i32 0
95 ; CHECK-NEXT:    [[FOO3_FCA_1_EXTRACT:%.*]] = extractvalue [2 x float] [[FOO3]], 1
96 ; CHECK-NEXT:    [[TMP2:%.*]] = insertelement <2 x float> [[TMP1]], float [[FOO3_FCA_1_EXTRACT]], i32 1
97 ; CHECK-NEXT:    [[TMP3:%.*]] = extractelement <2 x float> [[TMP2]], i32 [[FOO1]]
98 ; CHECK-NEXT:    [[FOO9:%.*]] = insertelement <4 x float> undef, float [[TMP3]], i32 0
99 ; CHECK-NEXT:    [[FOO10:%.*]] = insertelement <4 x float> [[FOO9]], float [[TMP3]], i32 1
100 ; CHECK-NEXT:    [[FOO11:%.*]] = insertelement <4 x float> [[FOO10]], float [[TMP3]], i32 2
101 ; CHECK-NEXT:    [[FOO12:%.*]] = insertelement <4 x float> [[FOO11]], float [[TMP3]], i32 3
102 ; CHECK-NEXT:    store <4 x float> [[FOO12]], ptr addrspace(1) @pv, align 16
103 ; CHECK-NEXT:    ret void
105   %i = alloca i32, addrspace(5)
106   %f1 = alloca [2 x float], addrspace(5)
107   %foo = getelementptr %Block3, ptr addrspace(1) @block3, i32 0, i32 1
108   %foo1 = load i32, ptr addrspace(1) %foo
109   store i32 %foo1, ptr addrspace(5) %i
110   %foo3 = load [2 x float], ptr addrspace(1) @block3
111   store [2 x float] %foo3, ptr addrspace(5) %f1
112   %foo4 = load i32, ptr addrspace(5) %i
113   %foo5 = getelementptr [2 x float], ptr addrspace(5) %f1, i32 0, i32 %foo4
114   %foo6 = load float, ptr addrspace(5) %foo5
115   %foo7 = alloca <4 x float>, addrspace(5)
116   %foo8 = load <4 x float>, ptr addrspace(5) %foo7
117   %foo9 = insertelement <4 x float> %foo8, float %foo6, i32 0
118   %foo10 = insertelement <4 x float> %foo9, float %foo6, i32 1
119   %foo11 = insertelement <4 x float> %foo10, float %foo6, i32 2
120   %foo12 = insertelement <4 x float> %foo11, float %foo6, i32 3
121   store <4 x float> %foo12, ptr addrspace(1) @pv
122   ret void
125 define amdgpu_vs void @promote_memmove_aggr() #0 {
126 ; CHECK-LABEL: @promote_memmove_aggr(
127 ; CHECK-NEXT:    store float 1.000000e+00, ptr addrspace(1) @pv, align 4
128 ; CHECK-NEXT:    ret void
130   %f1 = alloca [5 x float], addrspace(5)
131   store [5 x float] zeroinitializer, ptr addrspace(5) %f1
132   %foo1 = getelementptr [5 x float], ptr addrspace(5) %f1, i32 0, i32 1
133   store float 1.0, ptr addrspace(5) %foo1
134   %foo2 = getelementptr [5 x float], ptr addrspace(5) %f1, i32 0, i32 3
135   store float 2.0, ptr addrspace(5) %foo2
136   call void @llvm.memmove.p5.p5.i32(ptr addrspace(5) align 4 %f1, ptr addrspace(5) align 4 %foo1, i32 16, i1 false)
137   %foo3 = load float, ptr addrspace(5) %f1
138   store float %foo3, ptr addrspace(1) @pv
139   ret void
142 define amdgpu_vs void @promote_memcpy_aggr() #0 {
143 ; CHECK-LABEL: @promote_memcpy_aggr(
144 ; CHECK-NEXT:    [[FOO3:%.*]] = getelementptr [[BLOCK3:%.*]], ptr addrspace(1) @block3, i32 0, i32 0
145 ; CHECK-NEXT:    [[FOO4:%.*]] = load i32, ptr addrspace(1) [[FOO3]], align 4
146 ; CHECK-NEXT:    [[TMP1:%.*]] = insertelement <5 x float> <float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 2.000000e+00, float 0.000000e+00>, float 3.000000e+00, i32 [[FOO4]]
147 ; CHECK-NEXT:    [[TMP2:%.*]] = shufflevector <5 x float> [[TMP1]], <5 x float> poison, <5 x i32> <i32 3, i32 4, i32 2, i32 3, i32 4>
148 ; CHECK-NEXT:    [[TMP3:%.*]] = extractelement <5 x float> [[TMP2]], i32 0
149 ; CHECK-NEXT:    store float [[TMP3]], ptr addrspace(1) @pv, align 4
150 ; CHECK-NEXT:    ret void
152   %f1 = alloca [5 x float], addrspace(5)
153   store [5 x float] zeroinitializer, ptr addrspace(5) %f1
155   %foo2 = getelementptr [5 x float], ptr addrspace(5) %f1, i32 0, i32 3
156   store float 2.0, ptr addrspace(5) %foo2
158   %foo3 = getelementptr %Block3, ptr addrspace(1) @block3, i32 0, i32 0
159   %foo4 = load i32, ptr addrspace(1) %foo3
160   %foo5 = getelementptr [5 x float], ptr addrspace(5) %f1, i32 0, i32 %foo4
161   store float 3.0, ptr addrspace(5) %foo5
163   call void @llvm.memcpy.p5.p5.i32(ptr addrspace(5) align 4 %f1, ptr addrspace(5) align 4 %foo2, i32 8, i1 false)
164   %foo6 = load float, ptr addrspace(5) %f1
165   store float %foo6, ptr addrspace(1) @pv
166   ret void
169 define amdgpu_vs void @promote_memcpy_identity_aggr() #0 {
170 ; CHECK-LABEL: @promote_memcpy_identity_aggr(
171 ; CHECK-NEXT:    store float 0.000000e+00, ptr addrspace(1) @pv, align 4
172 ; CHECK-NEXT:    ret void
174   %f1 = alloca [5 x float], addrspace(5)
175   store [5 x float] zeroinitializer, ptr addrspace(5) %f1
176   %foo1 = getelementptr [5 x float], ptr addrspace(5) %f1, i32 0, i32 1
177   store float 1.0, ptr addrspace(5) %foo1
178   %foo2 = getelementptr [5 x float], ptr addrspace(5) %f1, i32 0, i32 3
179   store float 2.0, ptr addrspace(5) %foo2
180   call void @llvm.memcpy.p5.p5.i32(ptr addrspace(5) align 4 %f1, ptr addrspace(5) align 4 %f1, i32 20, i1 false)
181   %foo3 = load float, ptr addrspace(5) %f1
182   store float %foo3, ptr addrspace(1) @pv
183   ret void
186 ; TODO: promote alloca even there is a memcpy between different alloca
187 define amdgpu_vs void @promote_memcpy_two_aggrs() #0 {
188 ; CHECK-LABEL: @promote_memcpy_two_aggrs(
189 ; CHECK-NEXT:    [[F1:%.*]] = alloca [5 x float], align 4, addrspace(5)
190 ; CHECK-NEXT:    [[F2:%.*]] = alloca [5 x float], align 4, addrspace(5)
191 ; CHECK-NEXT:    [[DOTFCA_0_GEP1:%.*]] = getelementptr inbounds [5 x float], ptr addrspace(5) [[F1]], i32 0, i32 0
192 ; CHECK-NEXT:    store float 0.000000e+00, ptr addrspace(5) [[DOTFCA_0_GEP1]], align 4
193 ; CHECK-NEXT:    [[DOTFCA_1_GEP2:%.*]] = getelementptr inbounds [5 x float], ptr addrspace(5) [[F1]], i32 0, i32 1
194 ; CHECK-NEXT:    store float 0.000000e+00, ptr addrspace(5) [[DOTFCA_1_GEP2]], align 4
195 ; CHECK-NEXT:    [[DOTFCA_2_GEP3:%.*]] = getelementptr inbounds [5 x float], ptr addrspace(5) [[F1]], i32 0, i32 2
196 ; CHECK-NEXT:    store float 0.000000e+00, ptr addrspace(5) [[DOTFCA_2_GEP3]], align 4
197 ; CHECK-NEXT:    [[DOTFCA_3_GEP4:%.*]] = getelementptr inbounds [5 x float], ptr addrspace(5) [[F1]], i32 0, i32 3
198 ; CHECK-NEXT:    store float 0.000000e+00, ptr addrspace(5) [[DOTFCA_3_GEP4]], align 4
199 ; CHECK-NEXT:    [[DOTFCA_4_GEP5:%.*]] = getelementptr inbounds [5 x float], ptr addrspace(5) [[F1]], i32 0, i32 4
200 ; CHECK-NEXT:    store float 0.000000e+00, ptr addrspace(5) [[DOTFCA_4_GEP5]], align 4
201 ; CHECK-NEXT:    [[DOTFCA_0_GEP:%.*]] = getelementptr inbounds [5 x float], ptr addrspace(5) [[F2]], i32 0, i32 0
202 ; CHECK-NEXT:    store float 0.000000e+00, ptr addrspace(5) [[DOTFCA_0_GEP]], align 4
203 ; CHECK-NEXT:    [[DOTFCA_1_GEP:%.*]] = getelementptr inbounds [5 x float], ptr addrspace(5) [[F2]], i32 0, i32 1
204 ; CHECK-NEXT:    store float 0.000000e+00, ptr addrspace(5) [[DOTFCA_1_GEP]], align 4
205 ; CHECK-NEXT:    [[DOTFCA_2_GEP:%.*]] = getelementptr inbounds [5 x float], ptr addrspace(5) [[F2]], i32 0, i32 2
206 ; CHECK-NEXT:    store float 0.000000e+00, ptr addrspace(5) [[DOTFCA_2_GEP]], align 4
207 ; CHECK-NEXT:    [[DOTFCA_3_GEP:%.*]] = getelementptr inbounds [5 x float], ptr addrspace(5) [[F2]], i32 0, i32 3
208 ; CHECK-NEXT:    store float 0.000000e+00, ptr addrspace(5) [[DOTFCA_3_GEP]], align 4
209 ; CHECK-NEXT:    [[DOTFCA_4_GEP:%.*]] = getelementptr inbounds [5 x float], ptr addrspace(5) [[F2]], i32 0, i32 4
210 ; CHECK-NEXT:    store float 0.000000e+00, ptr addrspace(5) [[DOTFCA_4_GEP]], align 4
211 ; CHECK-NEXT:    [[FOO3:%.*]] = getelementptr [[BLOCK3:%.*]], ptr addrspace(1) @block3, i32 0, i32 0
212 ; CHECK-NEXT:    [[FOO4:%.*]] = load i32, ptr addrspace(1) [[FOO3]], align 4
213 ; CHECK-NEXT:    [[FOO5:%.*]] = getelementptr [5 x float], ptr addrspace(5) [[F1]], i32 0, i32 [[FOO4]]
214 ; CHECK-NEXT:    store float 3.000000e+00, ptr addrspace(5) [[FOO5]], align 4
215 ; CHECK-NEXT:    call void @llvm.memcpy.p5.p5.i32(ptr addrspace(5) align 4 [[F2]], ptr addrspace(5) align 4 [[F1]], i32 8, i1 false)
216 ; CHECK-NEXT:    [[FOO6:%.*]] = getelementptr [5 x float], ptr addrspace(5) [[F2]], i32 0, i32 [[FOO4]]
217 ; CHECK-NEXT:    [[FOO7:%.*]] = load float, ptr addrspace(5) [[FOO6]], align 4
218 ; CHECK-NEXT:    store float [[FOO7]], ptr addrspace(1) @pv, align 4
219 ; CHECK-NEXT:    ret void
221   %f1 = alloca [5 x float], addrspace(5)
222   %f2 = alloca [5 x float], addrspace(5)
224   store [5 x float] zeroinitializer, ptr addrspace(5) %f1
225   store [5 x float] zeroinitializer, ptr addrspace(5) %f2
227   %foo3 = getelementptr %Block3, ptr addrspace(1) @block3, i32 0, i32 0
228   %foo4 = load i32, ptr addrspace(1) %foo3
229   %foo5 = getelementptr [5 x float], ptr addrspace(5) %f1, i32 0, i32 %foo4
230   store float 3.0, ptr addrspace(5) %foo5
232   call void @llvm.memcpy.p5.p5.i32(ptr addrspace(5) align 4 %f2, ptr addrspace(5) align 4 %f1, i32 8, i1 false)
234   %foo6 = getelementptr [5 x float], ptr addrspace(5) %f2, i32 0, i32 %foo4
235   %foo7 = load float, ptr addrspace(5) %foo6
236   store float %foo7, ptr addrspace(1) @pv
237   ret void
240 ; TODO: promote alloca even there is a memcpy between the alloca and other memory space.
241 define amdgpu_vs void @promote_memcpy_p1p5_aggr(ptr addrspace(1) inreg %src) #0 {
242 ; CHECK-LABEL: @promote_memcpy_p1p5_aggr(
243 ; CHECK-NEXT:    [[F1:%.*]] = alloca [5 x float], align 4, addrspace(5)
244 ; CHECK-NEXT:    [[DOTFCA_0_GEP:%.*]] = getelementptr inbounds [5 x float], ptr addrspace(5) [[F1]], i32 0, i32 0
245 ; CHECK-NEXT:    store float 0.000000e+00, ptr addrspace(5) [[DOTFCA_0_GEP]], align 4
246 ; CHECK-NEXT:    [[DOTFCA_1_GEP:%.*]] = getelementptr inbounds [5 x float], ptr addrspace(5) [[F1]], i32 0, i32 1
247 ; CHECK-NEXT:    store float 0.000000e+00, ptr addrspace(5) [[DOTFCA_1_GEP]], align 4
248 ; CHECK-NEXT:    [[DOTFCA_2_GEP:%.*]] = getelementptr inbounds [5 x float], ptr addrspace(5) [[F1]], i32 0, i32 2
249 ; CHECK-NEXT:    store float 0.000000e+00, ptr addrspace(5) [[DOTFCA_2_GEP]], align 4
250 ; CHECK-NEXT:    [[DOTFCA_3_GEP:%.*]] = getelementptr inbounds [5 x float], ptr addrspace(5) [[F1]], i32 0, i32 3
251 ; CHECK-NEXT:    store float 0.000000e+00, ptr addrspace(5) [[DOTFCA_3_GEP]], align 4
252 ; CHECK-NEXT:    [[DOTFCA_4_GEP:%.*]] = getelementptr inbounds [5 x float], ptr addrspace(5) [[F1]], i32 0, i32 4
253 ; CHECK-NEXT:    store float 0.000000e+00, ptr addrspace(5) [[DOTFCA_4_GEP]], align 4
254 ; CHECK-NEXT:    [[FOO3:%.*]] = getelementptr [[BLOCK3:%.*]], ptr addrspace(1) @block3, i32 0, i32 0
255 ; CHECK-NEXT:    [[FOO4:%.*]] = load i32, ptr addrspace(1) [[FOO3]], align 4
256 ; CHECK-NEXT:    [[FOO5:%.*]] = getelementptr [5 x float], ptr addrspace(5) [[F1]], i32 0, i32 [[FOO4]]
257 ; CHECK-NEXT:    store float 3.000000e+00, ptr addrspace(5) [[FOO5]], align 4
258 ; CHECK-NEXT:    call void @llvm.memcpy.p1.p5.i32(ptr addrspace(1) align 4 @pv, ptr addrspace(5) align 4 [[F1]], i32 8, i1 false)
259 ; CHECK-NEXT:    ret void
261   %f1 = alloca [5 x float], addrspace(5)
262   store [5 x float] zeroinitializer, ptr addrspace(5) %f1
264   %foo3 = getelementptr %Block3, ptr addrspace(1) @block3, i32 0, i32 0
265   %foo4 = load i32, ptr addrspace(1) %foo3
266   %foo5 = getelementptr [5 x float], ptr addrspace(5) %f1, i32 0, i32 %foo4
267   store float 3.0, ptr addrspace(5) %foo5
269   call void @llvm.memcpy.p1.p5.i32(ptr addrspace(1) align 4 @pv, ptr addrspace(5) align 4 %f1, i32 8, i1 false)
270   ret void
273 define amdgpu_vs void @promote_memcpy_inline_aggr() #0 {
274 ; CHECK-LABEL: @promote_memcpy_inline_aggr(
275 ; CHECK-NEXT:    [[FOO3:%.*]] = getelementptr [[BLOCK3:%.*]], ptr addrspace(1) @block3, i32 0, i32 0
276 ; CHECK-NEXT:    [[FOO4:%.*]] = load i32, ptr addrspace(1) [[FOO3]], align 4
277 ; CHECK-NEXT:    [[TMP1:%.*]] = insertelement <5 x float> zeroinitializer, float 3.000000e+00, i32 [[FOO4]]
278 ; CHECK-NEXT:    [[TMP2:%.*]] = shufflevector <5 x float> [[TMP1]], <5 x float> poison, <5 x i32> <i32 3, i32 4, i32 2, i32 3, i32 4>
279 ; CHECK-NEXT:    [[TMP3:%.*]] = extractelement <5 x float> [[TMP2]], i32 0
280 ; CHECK-NEXT:    store float [[TMP3]], ptr addrspace(1) @pv, align 4
281 ; CHECK-NEXT:    ret void
283   %f1 = alloca [5 x float], addrspace(5)
284   store [5 x float] zeroinitializer, ptr addrspace(5) %f1
286   %foo2 = getelementptr [5 x float], ptr addrspace(5) %f1, i32 0, i32 3
287   %foo3 = getelementptr %Block3, ptr addrspace(1) @block3, i32 0, i32 0
288   %foo4 = load i32, ptr addrspace(1) %foo3
289   %foo5 = getelementptr [5 x float], ptr addrspace(5) %f1, i32 0, i32 %foo4
290   store float 3.0, ptr addrspace(5) %foo5
292   call void @llvm.memcpy.inline.p5.p5.i32(ptr addrspace(5) align 4 %f1, ptr addrspace(5) align 4 %foo2, i32 8, i1 false)
293   %foo6 = load float, ptr addrspace(5) %f1
294   store float %foo6, ptr addrspace(1) @pv
295   ret void
298 declare void @llvm.memcpy.p5.p5.i32(ptr addrspace(5) nocapture writeonly, ptr addrspace(5) nocapture readonly, i32, i1 immarg)
299 declare void @llvm.memcpy.p1.p5.i32(ptr addrspace(1) nocapture writeonly, ptr addrspace(5) nocapture readonly, i32, i1 immarg)
300 declare void @llvm.memcpy.inline.p5.p5.i32(ptr addrspace(5) nocapture writeonly, ptr addrspace(5) nocapture readonly, i32, i1 immarg)
301 declare void @llvm.memmove.p5.p5.i32(ptr addrspace(5) nocapture writeonly, ptr addrspace(5) nocapture readonly, i32, i1 immarg)
303 @tmp_g = external addrspace(1) global { [4 x double], <2 x double>, <3 x double>, <4 x double> }
304 @frag_color = external addrspace(1) global <4 x float>
306 define amdgpu_ps void @promote_double_aggr() #0 {
307 ; CHECK-LABEL: @promote_double_aggr(
308 ; CHECK-NEXT:    [[FOO:%.*]] = getelementptr { [4 x double], <2 x double>, <3 x double>, <4 x double> }, ptr addrspace(1) @tmp_g, i32 0, i32 0, i32 0
309 ; CHECK-NEXT:    [[FOO1:%.*]] = load double, ptr addrspace(1) [[FOO]], align 8
310 ; CHECK-NEXT:    [[FOO2:%.*]] = getelementptr { [4 x double], <2 x double>, <3 x double>, <4 x double> }, ptr addrspace(1) @tmp_g, i32 0, i32 0, i32 1
311 ; CHECK-NEXT:    [[FOO3:%.*]] = load double, ptr addrspace(1) [[FOO2]], align 8
312 ; CHECK-NEXT:    [[FOO4:%.*]] = insertvalue [2 x double] undef, double [[FOO1]], 0
313 ; CHECK-NEXT:    [[FOO5:%.*]] = insertvalue [2 x double] [[FOO4]], double [[FOO3]], 1
314 ; CHECK-NEXT:    [[FOO5_FCA_0_EXTRACT:%.*]] = extractvalue [2 x double] [[FOO5]], 0
315 ; CHECK-NEXT:    [[FOO5_FCA_1_EXTRACT:%.*]] = extractvalue [2 x double] [[FOO5]], 1
316 ; CHECK-NEXT:    [[FOO10:%.*]] = fadd double [[FOO5_FCA_1_EXTRACT]], [[FOO5_FCA_1_EXTRACT]]
317 ; CHECK-NEXT:    [[FOO16:%.*]] = fadd double [[FOO10]], [[FOO5_FCA_1_EXTRACT]]
318 ; CHECK-NEXT:    [[FOO17:%.*]] = fptrunc double [[FOO16]] to float
319 ; CHECK-NEXT:    [[FOO18:%.*]] = insertelement <4 x float> undef, float [[FOO17]], i32 0
320 ; CHECK-NEXT:    [[FOO19:%.*]] = insertelement <4 x float> [[FOO18]], float [[FOO17]], i32 1
321 ; CHECK-NEXT:    [[FOO20:%.*]] = insertelement <4 x float> [[FOO19]], float [[FOO17]], i32 2
322 ; CHECK-NEXT:    [[FOO21:%.*]] = insertelement <4 x float> [[FOO20]], float [[FOO17]], i32 3
323 ; CHECK-NEXT:    store <4 x float> [[FOO21]], ptr addrspace(1) @frag_color, align 16
324 ; CHECK-NEXT:    ret void
326   %s = alloca [2 x double], addrspace(5)
327   %foo = getelementptr { [4 x double], <2 x double>, <3 x double>, <4 x double> }, ptr addrspace(1) @tmp_g, i32 0, i32 0, i32 0
328   %foo1 = load double, ptr addrspace(1) %foo
329   %foo2 = getelementptr { [4 x double], <2 x double>, <3 x double>, <4 x double> }, ptr addrspace(1) @tmp_g, i32 0, i32 0, i32 1
330   %foo3 = load double, ptr addrspace(1) %foo2
331   %foo4 = insertvalue [2 x double] undef, double %foo1, 0
332   %foo5 = insertvalue [2 x double] %foo4, double %foo3, 1
333   store [2 x double] %foo5, ptr addrspace(5) %s
334   %foo6 = getelementptr [2 x double], ptr addrspace(5) %s, i32 0, i32 1
335   %foo7 = load double, ptr addrspace(5) %foo6
336   %foo8 = getelementptr [2 x double], ptr addrspace(5) %s, i32 0, i32 1
337   %foo9 = load double, ptr addrspace(5) %foo8
338   %foo10 = fadd double %foo7, %foo9
339   store double %foo10, ptr addrspace(5) %s
340   %foo13 = load double, ptr addrspace(5) %s
341   %foo14 = getelementptr [2 x double], ptr addrspace(5) %s, i32 0, i32 1
342   %foo15 = load double, ptr addrspace(5) %foo14
343   %foo16 = fadd double %foo13, %foo15
344   %foo17 = fptrunc double %foo16 to float
345   %foo18 = insertelement <4 x float> undef, float %foo17, i32 0
346   %foo19 = insertelement <4 x float> %foo18, float %foo17, i32 1
347   %foo20 = insertelement <4 x float> %foo19, float %foo17, i32 2
348   %foo21 = insertelement <4 x float> %foo20, float %foo17, i32 3
349   store <4 x float> %foo21, ptr addrspace(1) @frag_color
350   ret void
353 ; Don't crash on a type that isn't a valid vector element.
354 define amdgpu_kernel void @alloca_struct() #0 {
355 ; CHECK-LABEL: @alloca_struct(
356 ; CHECK-NEXT:  entry:
357 ; CHECK-NEXT:    ret void
359 entry:
360   %alloca = alloca [2 x %struct], align 4, addrspace(5)
361   ret void