• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; RUN: opt -mtriple=amdgcn-amd-amdhsa -load-store-vectorizer -S -o - %s | FileCheck %s
2; Copy of test/CodeGen/AMDGPU/merge-stores.ll with some additions
3
4target datalayout = "e-p:32:32-p1:64:64-p2:64:64-p3:32:32-p4:64:64-p5:32:32-p24:64:64-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64"
5
6; TODO: Vector element tests
7; TODO: Non-zero base offset for load and store combinations
8; TODO: Same base addrspacecasted
9
10
11; CHECK-LABEL: @merge_global_store_2_constants_i8(
12; CHECK: store <2 x i8> <i8 -56, i8 123>, <2 x i8> addrspace(1)* %{{[0-9]+}}, align 2
13define void @merge_global_store_2_constants_i8(i8 addrspace(1)* %out) #0 {
14  %out.gep.1 = getelementptr i8, i8 addrspace(1)* %out, i32 1
15
16  store i8 123, i8 addrspace(1)* %out.gep.1
17  store i8 456, i8 addrspace(1)* %out, align 2
18  ret void
19}
20
21; CHECK-LABEL: @merge_global_store_2_constants_i8_natural_align
22; CHECK: store <2 x i8>
23define void @merge_global_store_2_constants_i8_natural_align(i8 addrspace(1)* %out) #0 {
24  %out.gep.1 = getelementptr i8, i8 addrspace(1)* %out, i32 1
25
26  store i8 123, i8 addrspace(1)* %out.gep.1
27  store i8 456, i8 addrspace(1)* %out
28  ret void
29}
30
31; CHECK-LABEL: @merge_global_store_2_constants_i16
32; CHECK: store <2 x i16> <i16 456, i16 123>, <2 x i16> addrspace(1)* %{{[0-9]+}}, align 4
33define void @merge_global_store_2_constants_i16(i16 addrspace(1)* %out) #0 {
34  %out.gep.1 = getelementptr i16, i16 addrspace(1)* %out, i32 1
35
36  store i16 123, i16 addrspace(1)* %out.gep.1
37  store i16 456, i16 addrspace(1)* %out, align 4
38  ret void
39}
40
41; CHECK-LABEL: @merge_global_store_2_constants_0_i16
42; CHECK: store <2 x i16> zeroinitializer, <2 x i16> addrspace(1)* %{{[0-9]+}}, align 4
43define void @merge_global_store_2_constants_0_i16(i16 addrspace(1)* %out) #0 {
44  %out.gep.1 = getelementptr i16, i16 addrspace(1)* %out, i32 1
45
46  store i16 0, i16 addrspace(1)* %out.gep.1
47  store i16 0, i16 addrspace(1)* %out, align 4
48  ret void
49}
50
51; CHECK-LABEL: @merge_global_store_2_constants_i16_natural_align
52; CHECK: store <2 x i16>
53define void @merge_global_store_2_constants_i16_natural_align(i16 addrspace(1)* %out) #0 {
54  %out.gep.1 = getelementptr i16, i16 addrspace(1)* %out, i32 1
55
56  store i16 123, i16 addrspace(1)* %out.gep.1
57  store i16 456, i16 addrspace(1)* %out
58  ret void
59}
60
61; CHECK-LABEL: @merge_global_store_2_constants_half_natural_align
62; CHECK: store <2 x half>
63define void @merge_global_store_2_constants_half_natural_align(half addrspace(1)* %out) #0 {
64  %out.gep.1 = getelementptr half, half addrspace(1)* %out, i32 1
65
66  store half 2.0, half addrspace(1)* %out.gep.1
67  store half 1.0, half addrspace(1)* %out
68  ret void
69}
70
71; CHECK-LABEL: @merge_global_store_2_constants_i32
72; CHECK: store <2 x i32> <i32 456, i32 123>, <2 x i32> addrspace(1)* %{{[0-9]+}}, align 4
73define void @merge_global_store_2_constants_i32(i32 addrspace(1)* %out) #0 {
74  %out.gep.1 = getelementptr i32, i32 addrspace(1)* %out, i32 1
75
76  store i32 123, i32 addrspace(1)* %out.gep.1
77  store i32 456, i32 addrspace(1)* %out
78  ret void
79}
80
81; CHECK-LABEL: @merge_global_store_2_constants_i32_f32
82; CHECK: store <2 x i32> <i32 456, i32 1065353216>, <2 x i32> addrspace(1)* %{{[0-9]+}}, align 4
83define void @merge_global_store_2_constants_i32_f32(i32 addrspace(1)* %out) #0 {
84  %out.gep.1 = getelementptr i32, i32 addrspace(1)* %out, i32 1
85  %out.gep.1.bc = bitcast i32 addrspace(1)* %out.gep.1 to float addrspace(1)*
86  store float 1.0, float addrspace(1)* %out.gep.1.bc
87  store i32 456, i32 addrspace(1)* %out
88  ret void
89}
90
91; CHECK-LABEL: @merge_global_store_2_constants_f32_i32
92; CHECK  store <2 x float> <float 4.000000e+00, float 0x370EC00000000000>, <2 x float> addrspace(1)* %{{[0-9]+$}}
93define void @merge_global_store_2_constants_f32_i32(float addrspace(1)* %out) #0 {
94  %out.gep.1 = getelementptr float, float addrspace(1)* %out, i32 1
95  %out.gep.1.bc = bitcast float addrspace(1)* %out.gep.1 to i32 addrspace(1)*
96  store i32 123, i32 addrspace(1)* %out.gep.1.bc
97  store float 4.0, float addrspace(1)* %out
98  ret void
99}
100
101; CHECK-LABEL: @merge_global_store_4_constants_i32
102; CHECK: store <4 x i32> <i32 1234, i32 123, i32 456, i32 333>, <4 x i32> addrspace(1)* %{{[0-9]+}}, align 4
103define void @merge_global_store_4_constants_i32(i32 addrspace(1)* %out) #0 {
104  %out.gep.1 = getelementptr i32, i32 addrspace(1)* %out, i32 1
105  %out.gep.2 = getelementptr i32, i32 addrspace(1)* %out, i32 2
106  %out.gep.3 = getelementptr i32, i32 addrspace(1)* %out, i32 3
107
108  store i32 123, i32 addrspace(1)* %out.gep.1
109  store i32 456, i32 addrspace(1)* %out.gep.2
110  store i32 333, i32 addrspace(1)* %out.gep.3
111  store i32 1234, i32 addrspace(1)* %out
112  ret void
113}
114
115; CHECK-LABEL: @merge_global_store_4_constants_f32_order
116; CHECK: store <4 x float> <float 8.000000e+00, float 1.000000e+00, float 2.000000e+00, float 4.000000e+00>, <4 x float> addrspace(1)* %{{[0-9]+}}
117define void @merge_global_store_4_constants_f32_order(float addrspace(1)* %out) #0 {
118  %out.gep.1 = getelementptr float, float addrspace(1)* %out, i32 1
119  %out.gep.2 = getelementptr float, float addrspace(1)* %out, i32 2
120  %out.gep.3 = getelementptr float, float addrspace(1)* %out, i32 3
121
122  store float 8.0, float addrspace(1)* %out
123  store float 1.0, float addrspace(1)* %out.gep.1
124  store float 2.0, float addrspace(1)* %out.gep.2
125  store float 4.0, float addrspace(1)* %out.gep.3
126  ret void
127}
128
129; First store is out of order.
130; CHECK-LABEL: @merge_global_store_4_constants_f32
131; CHECK: store <4 x float> <float 8.000000e+00, float 1.000000e+00, float 2.000000e+00, float 4.000000e+00>, <4 x float> addrspace(1)* %{{[0-9]+}}, align 4
132define void @merge_global_store_4_constants_f32(float addrspace(1)* %out) #0 {
133  %out.gep.1 = getelementptr float, float addrspace(1)* %out, i32 1
134  %out.gep.2 = getelementptr float, float addrspace(1)* %out, i32 2
135  %out.gep.3 = getelementptr float, float addrspace(1)* %out, i32 3
136
137  store float 1.0, float addrspace(1)* %out.gep.1
138  store float 2.0, float addrspace(1)* %out.gep.2
139  store float 4.0, float addrspace(1)* %out.gep.3
140  store float 8.0, float addrspace(1)* %out
141  ret void
142}
143
144; CHECK-LABEL: @merge_global_store_4_constants_mixed_i32_f32
145; CHECK: store <4 x i32> <i32 1090519040, i32 11, i32 1073741824, i32 17>, <4 x i32> addrspace(1)* %{{[0-9]+}}, align 4
146define void @merge_global_store_4_constants_mixed_i32_f32(float addrspace(1)* %out) #0 {
147  %out.gep.1 = getelementptr float, float addrspace(1)* %out, i32 1
148  %out.gep.2 = getelementptr float, float addrspace(1)* %out, i32 2
149  %out.gep.3 = getelementptr float, float addrspace(1)* %out, i32 3
150
151  %out.gep.1.bc = bitcast float addrspace(1)* %out.gep.1 to i32 addrspace(1)*
152  %out.gep.3.bc = bitcast float addrspace(1)* %out.gep.3 to i32 addrspace(1)*
153
154  store i32 11, i32 addrspace(1)* %out.gep.1.bc
155  store float 2.0, float addrspace(1)* %out.gep.2
156  store i32 17, i32 addrspace(1)* %out.gep.3.bc
157  store float 8.0, float addrspace(1)* %out
158  ret void
159}
160
161; CHECK-LABEL: @merge_global_store_3_constants_i32
162; CHECK: store <3 x i32> <i32 1234, i32 123, i32 456>, <3 x i32> addrspace(1)* %{{[0-9]+}}, align 4
163define void @merge_global_store_3_constants_i32(i32 addrspace(1)* %out) #0 {
164  %out.gep.1 = getelementptr i32, i32 addrspace(1)* %out, i32 1
165  %out.gep.2 = getelementptr i32, i32 addrspace(1)* %out, i32 2
166
167  store i32 123, i32 addrspace(1)* %out.gep.1
168  store i32 456, i32 addrspace(1)* %out.gep.2
169  store i32 1234, i32 addrspace(1)* %out
170  ret void
171}
172
173; CHECK-LABEL: @merge_global_store_2_constants_i64
174; CHECK: store <2 x i64> <i64 456, i64 123>, <2 x i64> addrspace(1)* %{{[0-9]+}}, align 8
175define void @merge_global_store_2_constants_i64(i64 addrspace(1)* %out) #0 {
176  %out.gep.1 = getelementptr i64, i64 addrspace(1)* %out, i64 1
177
178  store i64 123, i64 addrspace(1)* %out.gep.1
179  store i64 456, i64 addrspace(1)* %out
180  ret void
181}
182
183; CHECK-LABEL: @merge_global_store_4_constants_i64
184; CHECK: store <2 x i64> <i64 456, i64 333>, <2 x i64> addrspace(1)* %{{[0-9]+}}, align 8
185; CHECK: store <2 x i64> <i64 1234, i64 123>, <2 x i64> addrspace(1)* %{{[0-9]+}}, align 8
186define void @merge_global_store_4_constants_i64(i64 addrspace(1)* %out) #0 {
187  %out.gep.1 = getelementptr i64, i64 addrspace(1)* %out, i64 1
188  %out.gep.2 = getelementptr i64, i64 addrspace(1)* %out, i64 2
189  %out.gep.3 = getelementptr i64, i64 addrspace(1)* %out, i64 3
190
191  store i64 123, i64 addrspace(1)* %out.gep.1
192  store i64 456, i64 addrspace(1)* %out.gep.2
193  store i64 333, i64 addrspace(1)* %out.gep.3
194  store i64 1234, i64 addrspace(1)* %out
195  ret void
196}
197
198; CHECK-LABEL: @merge_global_store_2_adjacent_loads_i32
199; CHECK: [[LOAD:%[0-9]+]] = load <2 x i32>
200; CHECK: [[ELT0:%[0-9]+]] = extractelement <2 x i32> [[LOAD]], i32 0
201; CHECK: [[ELT1:%[0-9]+]] = extractelement <2 x i32> [[LOAD]], i32 1
202; CHECK: [[INSERT0:%[0-9]+]] = insertelement <2 x i32> undef, i32 [[ELT0]], i32 0
203; CHECK: [[INSERT1:%[0-9]+]] = insertelement <2 x i32> [[INSERT0]], i32 [[ELT1]], i32 1
204; CHECK: store <2 x i32> [[INSERT1]]
205define void @merge_global_store_2_adjacent_loads_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %in) #0 {
206  %out.gep.1 = getelementptr i32, i32 addrspace(1)* %out, i32 1
207  %in.gep.1 = getelementptr i32, i32 addrspace(1)* %in, i32 1
208
209  %lo = load i32, i32 addrspace(1)* %in
210  %hi = load i32, i32 addrspace(1)* %in.gep.1
211
212  store i32 %lo, i32 addrspace(1)* %out
213  store i32 %hi, i32 addrspace(1)* %out.gep.1
214  ret void
215}
216
217; CHECK-LABEL: @merge_global_store_2_adjacent_loads_i32_nonzero_base
218; CHECK: extractelement
219; CHECK: extractelement
220; CHECK: insertelement
221; CHECK: insertelement
222; CHECK: store <2 x i32>
223define void @merge_global_store_2_adjacent_loads_i32_nonzero_base(i32 addrspace(1)* %out, i32 addrspace(1)* %in) #0 {
224  %in.gep.0 = getelementptr i32, i32 addrspace(1)* %in, i32 2
225  %in.gep.1 = getelementptr i32, i32 addrspace(1)* %in, i32 3
226
227  %out.gep.0 = getelementptr i32, i32 addrspace(1)* %out, i32 2
228  %out.gep.1 = getelementptr i32, i32 addrspace(1)* %out, i32 3
229  %lo = load i32, i32 addrspace(1)* %in.gep.0
230  %hi = load i32, i32 addrspace(1)* %in.gep.1
231
232  store i32 %lo, i32 addrspace(1)* %out.gep.0
233  store i32 %hi, i32 addrspace(1)* %out.gep.1
234  ret void
235}
236
237; CHECK-LABEL: @merge_global_store_2_adjacent_loads_shuffle_i32
238; CHECK: [[LOAD:%[0-9]+]] = load <2 x i32>
239; CHECK: [[ELT0:%[0-9]+]] = extractelement <2 x i32> [[LOAD]], i32 0
240; CHECK: [[ELT1:%[0-9]+]] = extractelement <2 x i32> [[LOAD]], i32 1
241; CHECK: [[INSERT0:%[0-9]+]] = insertelement <2 x i32> undef, i32 [[ELT1]], i32 0
242; CHECK: [[INSERT1:%[0-9]+]] = insertelement <2 x i32> [[INSERT0]], i32 [[ELT0]], i32 1
243; CHECK: store <2 x i32> [[INSERT1]]
244define void @merge_global_store_2_adjacent_loads_shuffle_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %in) #0 {
245  %out.gep.1 = getelementptr i32, i32 addrspace(1)* %out, i32 1
246  %in.gep.1 = getelementptr i32, i32 addrspace(1)* %in, i32 1
247
248  %lo = load i32, i32 addrspace(1)* %in
249  %hi = load i32, i32 addrspace(1)* %in.gep.1
250
251  store i32 %hi, i32 addrspace(1)* %out
252  store i32 %lo, i32 addrspace(1)* %out.gep.1
253  ret void
254}
255
256; CHECK-LABEL: @merge_global_store_4_adjacent_loads_i32
257; CHECK: load <4 x i32>
258; CHECK: store <4 x i32>
259define void @merge_global_store_4_adjacent_loads_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %in) #0 {
260  %out.gep.1 = getelementptr i32, i32 addrspace(1)* %out, i32 1
261  %out.gep.2 = getelementptr i32, i32 addrspace(1)* %out, i32 2
262  %out.gep.3 = getelementptr i32, i32 addrspace(1)* %out, i32 3
263  %in.gep.1 = getelementptr i32, i32 addrspace(1)* %in, i32 1
264  %in.gep.2 = getelementptr i32, i32 addrspace(1)* %in, i32 2
265  %in.gep.3 = getelementptr i32, i32 addrspace(1)* %in, i32 3
266
267  %x = load i32, i32 addrspace(1)* %in
268  %y = load i32, i32 addrspace(1)* %in.gep.1
269  %z = load i32, i32 addrspace(1)* %in.gep.2
270  %w = load i32, i32 addrspace(1)* %in.gep.3
271
272  store i32 %x, i32 addrspace(1)* %out
273  store i32 %y, i32 addrspace(1)* %out.gep.1
274  store i32 %z, i32 addrspace(1)* %out.gep.2
275  store i32 %w, i32 addrspace(1)* %out.gep.3
276  ret void
277}
278
279; CHECK-LABEL: @merge_global_store_3_adjacent_loads_i32
280; CHECK: load <3 x i32>
281; CHECK: store <3 x i32>
282define void @merge_global_store_3_adjacent_loads_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %in) #0 {
283  %out.gep.1 = getelementptr i32, i32 addrspace(1)* %out, i32 1
284  %out.gep.2 = getelementptr i32, i32 addrspace(1)* %out, i32 2
285  %in.gep.1 = getelementptr i32, i32 addrspace(1)* %in, i32 1
286  %in.gep.2 = getelementptr i32, i32 addrspace(1)* %in, i32 2
287
288  %x = load i32, i32 addrspace(1)* %in
289  %y = load i32, i32 addrspace(1)* %in.gep.1
290  %z = load i32, i32 addrspace(1)* %in.gep.2
291
292  store i32 %x, i32 addrspace(1)* %out
293  store i32 %y, i32 addrspace(1)* %out.gep.1
294  store i32 %z, i32 addrspace(1)* %out.gep.2
295  ret void
296}
297
298; CHECK-LABEL: @merge_global_store_4_adjacent_loads_f32
299; CHECK: load <4 x float>
300; CHECK: store <4 x float>
301define void @merge_global_store_4_adjacent_loads_f32(float addrspace(1)* %out, float addrspace(1)* %in) #0 {
302  %out.gep.1 = getelementptr float, float addrspace(1)* %out, i32 1
303  %out.gep.2 = getelementptr float, float addrspace(1)* %out, i32 2
304  %out.gep.3 = getelementptr float, float addrspace(1)* %out, i32 3
305  %in.gep.1 = getelementptr float, float addrspace(1)* %in, i32 1
306  %in.gep.2 = getelementptr float, float addrspace(1)* %in, i32 2
307  %in.gep.3 = getelementptr float, float addrspace(1)* %in, i32 3
308
309  %x = load float, float addrspace(1)* %in
310  %y = load float, float addrspace(1)* %in.gep.1
311  %z = load float, float addrspace(1)* %in.gep.2
312  %w = load float, float addrspace(1)* %in.gep.3
313
314  store float %x, float addrspace(1)* %out
315  store float %y, float addrspace(1)* %out.gep.1
316  store float %z, float addrspace(1)* %out.gep.2
317  store float %w, float addrspace(1)* %out.gep.3
318  ret void
319}
320
321; CHECK-LABEL: @merge_global_store_4_adjacent_loads_i32_nonzero_base
322; CHECK: load <4 x i32>
323; CHECK: store <4 x i32>
324define void @merge_global_store_4_adjacent_loads_i32_nonzero_base(i32 addrspace(1)* %out, i32 addrspace(1)* %in) #0 {
325  %in.gep.0 = getelementptr i32, i32 addrspace(1)* %in, i32 11
326  %in.gep.1 = getelementptr i32, i32 addrspace(1)* %in, i32 12
327  %in.gep.2 = getelementptr i32, i32 addrspace(1)* %in, i32 13
328  %in.gep.3 = getelementptr i32, i32 addrspace(1)* %in, i32 14
329  %out.gep.0 = getelementptr i32, i32 addrspace(1)* %out, i32 7
330  %out.gep.1 = getelementptr i32, i32 addrspace(1)* %out, i32 8
331  %out.gep.2 = getelementptr i32, i32 addrspace(1)* %out, i32 9
332  %out.gep.3 = getelementptr i32, i32 addrspace(1)* %out, i32 10
333
334  %x = load i32, i32 addrspace(1)* %in.gep.0
335  %y = load i32, i32 addrspace(1)* %in.gep.1
336  %z = load i32, i32 addrspace(1)* %in.gep.2
337  %w = load i32, i32 addrspace(1)* %in.gep.3
338
339  store i32 %x, i32 addrspace(1)* %out.gep.0
340  store i32 %y, i32 addrspace(1)* %out.gep.1
341  store i32 %z, i32 addrspace(1)* %out.gep.2
342  store i32 %w, i32 addrspace(1)* %out.gep.3
343  ret void
344}
345
346; CHECK-LABEL: @merge_global_store_4_adjacent_loads_inverse_i32
347; CHECK: load <4 x i32>
348; CHECK: store <4 x i32>
349define void @merge_global_store_4_adjacent_loads_inverse_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %in) #0 {
350  %out.gep.1 = getelementptr i32, i32 addrspace(1)* %out, i32 1
351  %out.gep.2 = getelementptr i32, i32 addrspace(1)* %out, i32 2
352  %out.gep.3 = getelementptr i32, i32 addrspace(1)* %out, i32 3
353  %in.gep.1 = getelementptr i32, i32 addrspace(1)* %in, i32 1
354  %in.gep.2 = getelementptr i32, i32 addrspace(1)* %in, i32 2
355  %in.gep.3 = getelementptr i32, i32 addrspace(1)* %in, i32 3
356
357  %x = load i32, i32 addrspace(1)* %in
358  %y = load i32, i32 addrspace(1)* %in.gep.1
359  %z = load i32, i32 addrspace(1)* %in.gep.2
360  %w = load i32, i32 addrspace(1)* %in.gep.3
361
362  ; Make sure the barrier doesn't stop this
363  tail call void @llvm.amdgcn.s.barrier() #1
364
365  store i32 %w, i32 addrspace(1)* %out.gep.3
366  store i32 %z, i32 addrspace(1)* %out.gep.2
367  store i32 %y, i32 addrspace(1)* %out.gep.1
368  store i32 %x, i32 addrspace(1)* %out
369
370  ret void
371}
372
373; CHECK-LABEL: @merge_global_store_4_adjacent_loads_shuffle_i32
374; CHECK: load <4 x i32>
375; CHECK: store <4 x i32>
376define void @merge_global_store_4_adjacent_loads_shuffle_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %in) #0 {
377  %out.gep.1 = getelementptr i32, i32 addrspace(1)* %out, i32 1
378  %out.gep.2 = getelementptr i32, i32 addrspace(1)* %out, i32 2
379  %out.gep.3 = getelementptr i32, i32 addrspace(1)* %out, i32 3
380  %in.gep.1 = getelementptr i32, i32 addrspace(1)* %in, i32 1
381  %in.gep.2 = getelementptr i32, i32 addrspace(1)* %in, i32 2
382  %in.gep.3 = getelementptr i32, i32 addrspace(1)* %in, i32 3
383
384  %x = load i32, i32 addrspace(1)* %in
385  %y = load i32, i32 addrspace(1)* %in.gep.1
386  %z = load i32, i32 addrspace(1)* %in.gep.2
387  %w = load i32, i32 addrspace(1)* %in.gep.3
388
389  ; Make sure the barrier doesn't stop this
390  tail call void @llvm.amdgcn.s.barrier() #1
391
392  store i32 %w, i32 addrspace(1)* %out
393  store i32 %z, i32 addrspace(1)* %out.gep.1
394  store i32 %y, i32 addrspace(1)* %out.gep.2
395  store i32 %x, i32 addrspace(1)* %out.gep.3
396
397  ret void
398}
399
400; CHECK-LABEL: @merge_global_store_4_adjacent_loads_i8
401; CHECK: load <4 x i8>
402; CHECK: extractelement <4 x i8>
403; CHECK: extractelement <4 x i8>
404; CHECK: extractelement <4 x i8>
405; CHECK: extractelement <4 x i8>
406; CHECK: insertelement <4 x i8>
407; CHECK: insertelement <4 x i8>
408; CHECK: insertelement <4 x i8>
409; CHECK: insertelement <4 x i8>
410; CHECK: store <4 x i8>
411define void @merge_global_store_4_adjacent_loads_i8(i8 addrspace(1)* %out, i8 addrspace(1)* %in) #0 {
412  %out.gep.1 = getelementptr i8, i8 addrspace(1)* %out, i8 1
413  %out.gep.2 = getelementptr i8, i8 addrspace(1)* %out, i8 2
414  %out.gep.3 = getelementptr i8, i8 addrspace(1)* %out, i8 3
415  %in.gep.1 = getelementptr i8, i8 addrspace(1)* %in, i8 1
416  %in.gep.2 = getelementptr i8, i8 addrspace(1)* %in, i8 2
417  %in.gep.3 = getelementptr i8, i8 addrspace(1)* %in, i8 3
418
419  %x = load i8, i8 addrspace(1)* %in, align 4
420  %y = load i8, i8 addrspace(1)* %in.gep.1
421  %z = load i8, i8 addrspace(1)* %in.gep.2
422  %w = load i8, i8 addrspace(1)* %in.gep.3
423
424  store i8 %x, i8 addrspace(1)* %out, align 4
425  store i8 %y, i8 addrspace(1)* %out.gep.1
426  store i8 %z, i8 addrspace(1)* %out.gep.2
427  store i8 %w, i8 addrspace(1)* %out.gep.3
428  ret void
429}
430
431; CHECK-LABEL: @merge_global_store_4_adjacent_loads_i8_natural_align
432; CHECK: load <4 x i8>
433; CHECK: store <4 x i8>
434define void @merge_global_store_4_adjacent_loads_i8_natural_align(i8 addrspace(1)* %out, i8 addrspace(1)* %in) #0 {
435  %out.gep.1 = getelementptr i8, i8 addrspace(1)* %out, i8 1
436  %out.gep.2 = getelementptr i8, i8 addrspace(1)* %out, i8 2
437  %out.gep.3 = getelementptr i8, i8 addrspace(1)* %out, i8 3
438  %in.gep.1 = getelementptr i8, i8 addrspace(1)* %in, i8 1
439  %in.gep.2 = getelementptr i8, i8 addrspace(1)* %in, i8 2
440  %in.gep.3 = getelementptr i8, i8 addrspace(1)* %in, i8 3
441
442  %x = load i8, i8 addrspace(1)* %in
443  %y = load i8, i8 addrspace(1)* %in.gep.1
444  %z = load i8, i8 addrspace(1)* %in.gep.2
445  %w = load i8, i8 addrspace(1)* %in.gep.3
446
447  store i8 %x, i8 addrspace(1)* %out
448  store i8 %y, i8 addrspace(1)* %out.gep.1
449  store i8 %z, i8 addrspace(1)* %out.gep.2
450  store i8 %w, i8 addrspace(1)* %out.gep.3
451  ret void
452}
453
454; CHECK-LABEL: @merge_global_store_4_vector_elts_loads_v4i32
455; CHECK: load <4 x i32>
456; CHECK: store <4 x i32>
457define void @merge_global_store_4_vector_elts_loads_v4i32(i32 addrspace(1)* %out, <4 x i32> addrspace(1)* %in) #0 {
458  %out.gep.1 = getelementptr i32, i32 addrspace(1)* %out, i32 1
459  %out.gep.2 = getelementptr i32, i32 addrspace(1)* %out, i32 2
460  %out.gep.3 = getelementptr i32, i32 addrspace(1)* %out, i32 3
461  %vec = load <4 x i32>, <4 x i32> addrspace(1)* %in
462
463  %x = extractelement <4 x i32> %vec, i32 0
464  %y = extractelement <4 x i32> %vec, i32 1
465  %z = extractelement <4 x i32> %vec, i32 2
466  %w = extractelement <4 x i32> %vec, i32 3
467
468  store i32 %x, i32 addrspace(1)* %out
469  store i32 %y, i32 addrspace(1)* %out.gep.1
470  store i32 %z, i32 addrspace(1)* %out.gep.2
471  store i32 %w, i32 addrspace(1)* %out.gep.3
472  ret void
473}
474
475; CHECK-LABEL: @merge_local_store_2_constants_i8
476; CHECK: store <2 x i8> <i8 -56, i8 123>, <2 x i8> addrspace(3)* %{{[0-9]+}}, align 2
477define void @merge_local_store_2_constants_i8(i8 addrspace(3)* %out) #0 {
478  %out.gep.1 = getelementptr i8, i8 addrspace(3)* %out, i32 1
479
480  store i8 123, i8 addrspace(3)* %out.gep.1
481  store i8 456, i8 addrspace(3)* %out, align 2
482  ret void
483}
484
485; CHECK-LABEL: @merge_local_store_2_constants_i32
486; CHECK: store <2 x i32> <i32 456, i32 123>, <2 x i32> addrspace(3)* %{{[0-9]+}}, align 4
487define void @merge_local_store_2_constants_i32(i32 addrspace(3)* %out) #0 {
488  %out.gep.1 = getelementptr i32, i32 addrspace(3)* %out, i32 1
489
490  store i32 123, i32 addrspace(3)* %out.gep.1
491  store i32 456, i32 addrspace(3)* %out
492  ret void
493}
494
495; CHECK-LABEL: @merge_local_store_2_constants_i32_align_2
496; CHECK: store i32
497; CHECK: store i32
498define void @merge_local_store_2_constants_i32_align_2(i32 addrspace(3)* %out) #0 {
499  %out.gep.1 = getelementptr i32, i32 addrspace(3)* %out, i32 1
500
501  store i32 123, i32 addrspace(3)* %out.gep.1, align 2
502  store i32 456, i32 addrspace(3)* %out, align 2
503  ret void
504}
505
506; CHECK-LABEL: @merge_local_store_4_constants_i32
507; CHECK: store <2 x i32> <i32 456, i32 333>, <2 x i32> addrspace(3)*
508; CHECK: store <2 x i32> <i32 1234, i32 123>, <2 x i32> addrspace(3)*
509define void @merge_local_store_4_constants_i32(i32 addrspace(3)* %out) #0 {
510  %out.gep.1 = getelementptr i32, i32 addrspace(3)* %out, i32 1
511  %out.gep.2 = getelementptr i32, i32 addrspace(3)* %out, i32 2
512  %out.gep.3 = getelementptr i32, i32 addrspace(3)* %out, i32 3
513
514  store i32 123, i32 addrspace(3)* %out.gep.1
515  store i32 456, i32 addrspace(3)* %out.gep.2
516  store i32 333, i32 addrspace(3)* %out.gep.3
517  store i32 1234, i32 addrspace(3)* %out
518  ret void
519}
520
521; CHECK-LABEL: @merge_global_store_5_constants_i32
522; CHECK: store <4 x i32> <i32 9, i32 12, i32 16, i32 -12>, <4 x i32> addrspace(1)* %{{[0-9]+}}, align 4
523; CHECK: store i32
524define void @merge_global_store_5_constants_i32(i32 addrspace(1)* %out) {
525  store i32 9, i32 addrspace(1)* %out, align 4
526  %idx1 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 1
527  store i32 12, i32 addrspace(1)* %idx1, align 4
528  %idx2 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 2
529  store i32 16, i32 addrspace(1)* %idx2, align 4
530  %idx3 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 3
531  store i32 -12, i32 addrspace(1)* %idx3, align 4
532  %idx4 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 4
533  store i32 11, i32 addrspace(1)* %idx4, align 4
534  ret void
535}
536
537; CHECK-LABEL: @merge_global_store_6_constants_i32
538; CHECK: store <4 x i32> <i32 13, i32 15, i32 62, i32 63>, <4 x i32> addrspace(1)* %{{[0-9]+}}, align 4
539; CHECK: store <2 x i32> <i32 11, i32 123>, <2 x i32> addrspace(1)* %{{[0-9]+}}, align 4
540define void @merge_global_store_6_constants_i32(i32 addrspace(1)* %out) {
541  store i32 13, i32 addrspace(1)* %out, align 4
542  %idx1 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 1
543  store i32 15, i32 addrspace(1)* %idx1, align 4
544  %idx2 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 2
545  store i32 62, i32 addrspace(1)* %idx2, align 4
546  %idx3 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 3
547  store i32 63, i32 addrspace(1)* %idx3, align 4
548  %idx4 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 4
549  store i32 11, i32 addrspace(1)* %idx4, align 4
550  %idx5 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 5
551  store i32 123, i32 addrspace(1)* %idx5, align 4
552  ret void
553}
554
555; CHECK-LABEL: @merge_global_store_7_constants_i32
556; CHECK: store <4 x i32> <i32 34, i32 999, i32 65, i32 33>, <4 x i32> addrspace(1)* %{{[0-9]+}}, align 4
557; CHECK: store <3 x i32> <i32 98, i32 91, i32 212>, <3 x i32> addrspace(1)* %{{[0-9]+}}, align 4
558define void @merge_global_store_7_constants_i32(i32 addrspace(1)* %out) {
559  store i32 34, i32 addrspace(1)* %out, align 4
560  %idx1 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 1
561  store i32 999, i32 addrspace(1)* %idx1, align 4
562  %idx2 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 2
563  store i32 65, i32 addrspace(1)* %idx2, align 4
564  %idx3 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 3
565  store i32 33, i32 addrspace(1)* %idx3, align 4
566  %idx4 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 4
567  store i32 98, i32 addrspace(1)* %idx4, align 4
568  %idx5 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 5
569  store i32 91, i32 addrspace(1)* %idx5, align 4
570  %idx6 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 6
571  store i32 212, i32 addrspace(1)* %idx6, align 4
572  ret void
573}
574
575; CHECK-LABEL: @merge_global_store_8_constants_i32
576; CHECK: store <4 x i32> <i32 34, i32 999, i32 65, i32 33>, <4 x i32> addrspace(1)* %{{[0-9]+}}, align 4
577; CHECK: store <4 x i32> <i32 98, i32 91, i32 212, i32 999>, <4 x i32> addrspace(1)* %{{[0-9]+}}, align 4
578define void @merge_global_store_8_constants_i32(i32 addrspace(1)* %out) {
579  store i32 34, i32 addrspace(1)* %out, align 4
580  %idx1 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 1
581  store i32 999, i32 addrspace(1)* %idx1, align 4
582  %idx2 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 2
583  store i32 65, i32 addrspace(1)* %idx2, align 4
584  %idx3 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 3
585  store i32 33, i32 addrspace(1)* %idx3, align 4
586  %idx4 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 4
587  store i32 98, i32 addrspace(1)* %idx4, align 4
588  %idx5 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 5
589  store i32 91, i32 addrspace(1)* %idx5, align 4
590  %idx6 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 6
591  store i32 212, i32 addrspace(1)* %idx6, align 4
592  %idx7 = getelementptr inbounds i32, i32 addrspace(1)* %out, i64 7
593  store i32 999, i32 addrspace(1)* %idx7, align 4
594  ret void
595}
596
597; CHECK-LABEL: @copy_v3i32_align4
598; CHECK: %vec = load <3 x i32>, <3 x i32> addrspace(1)* %in, align 4
599; CHECK: store <3 x i32> %vec, <3 x i32> addrspace(1)* %out
600define void @copy_v3i32_align4(<3 x i32> addrspace(1)* noalias %out, <3 x i32> addrspace(1)* noalias %in) #0 {
601  %vec = load <3 x i32>, <3 x i32> addrspace(1)* %in, align 4
602  store <3 x i32> %vec, <3 x i32> addrspace(1)* %out
603  ret void
604}
605
606; CHECK-LABEL: @copy_v3i64_align4
607; CHECK: %vec = load <3 x i64>, <3 x i64> addrspace(1)* %in, align 4
608; CHECK: store <3 x i64> %vec, <3 x i64> addrspace(1)* %out
609define void @copy_v3i64_align4(<3 x i64> addrspace(1)* noalias %out, <3 x i64> addrspace(1)* noalias %in) #0 {
610  %vec = load <3 x i64>, <3 x i64> addrspace(1)* %in, align 4
611  store <3 x i64> %vec, <3 x i64> addrspace(1)* %out
612  ret void
613}
614
615; CHECK-LABEL: @copy_v3f32_align4
616; CHECK: %vec = load <3 x float>, <3 x float> addrspace(1)* %in, align 4
617; CHECK: store <3 x float>
618define void @copy_v3f32_align4(<3 x float> addrspace(1)* noalias %out, <3 x float> addrspace(1)* noalias %in) #0 {
619  %vec = load <3 x float>, <3 x float> addrspace(1)* %in, align 4
620  %fadd = fadd <3 x float> %vec, <float 1.0, float 2.0, float 4.0>
621  store <3 x float> %fadd, <3 x float> addrspace(1)* %out
622  ret void
623}
624
625; CHECK-LABEL: @copy_v3f64_align4
626; CHECK: %vec = load <3 x double>, <3 x double> addrspace(1)* %in, align 4
627; CHECK: store <3 x double> %fadd, <3 x double> addrspace(1)* %out
628define void @copy_v3f64_align4(<3 x double> addrspace(1)* noalias %out, <3 x double> addrspace(1)* noalias %in) #0 {
629  %vec = load <3 x double>, <3 x double> addrspace(1)* %in, align 4
630  %fadd = fadd <3 x double> %vec, <double 1.0, double 2.0, double 4.0>
631  store <3 x double> %fadd, <3 x double> addrspace(1)* %out
632  ret void
633}
634
635declare void @llvm.amdgcn.s.barrier() #1
636
637attributes #0 = { nounwind }
638attributes #1 = { convergent nounwind }
639