[ARM] More MVE compare vector splat combines for ANDs
[llvm-complete.git] / test / CodeGen / AArch64 / aarch64-interleaved-ld-combine.ll
blob970422164a49dc854b7e7ec57b7cd8a89a31cf52
1 ; RUN: llc < %s | FileCheck --check-prefix AS %s
2 ; RUN: opt -S -interleaved-load-combine < %s | FileCheck %s
4 ; ModuleID = 'aarch64_interleaved-ld-combine.bc'
5 target datalayout = "e-m:e-i64:64-i128:128-n32:64-S128"
6 target triple = "arm64--linux-gnu"
8 ; This should be lowered into LD4
9 define void @aarch64_ilc_const(<4 x float>* %ptr) {
10 entry:
12 ;;; Check LLVM transformation
13 ; CHECK-LABEL: @aarch64_ilc_const(
14 ; CHECK-DAG: [[GEP:%.+]] = getelementptr inbounds <4 x float>, <4 x float>* %ptr, i64 2
15 ; CHECK-DAG: [[CAST:%.+]] = bitcast <4 x float>* [[GEP]] to <16 x float>*
16 ; CHECK-DAG: [[LOAD:%.+]] = load <16 x float>, <16 x float>* [[CAST]], align 16
17 ; CHECK-DAG: %{{.* }}= shufflevector <16 x float> [[LOAD]], <16 x float> undef, <4 x i32> <i32 0, i32 4, i32 8, i32 12>
18 ; CHECK-DAG: %{{.* }}= shufflevector <16 x float> [[LOAD]], <16 x float> undef, <4 x i32> <i32 1, i32 5, i32 9, i32 13>
19 ; CHECK-DAG: %{{.* }}= shufflevector <16 x float> [[LOAD]], <16 x float> undef, <4 x i32> <i32 2, i32 6, i32 10, i32 14>
20 ; CHECK-DAG: %{{.* }}= shufflevector <16 x float> [[LOAD]], <16 x float> undef, <4 x i32> <i32 3, i32 7, i32 11, i32 15>
21 ; CHECK: ret void
23 ;;; Check if it gets lowerd
24 ; AS-LABEL: aarch64_ilc_const
25 ; AS: ld4
26 ; AS: ret
28   %gep1 = getelementptr inbounds <4 x float>, <4 x float>* %ptr, i64  2
29   %gep2 = getelementptr inbounds <4 x float>, <4 x float>* %ptr, i64  3
30   %gep3 = getelementptr inbounds <4 x float>, <4 x float>* %ptr, i64  4
31   %gep4 = getelementptr inbounds <4 x float>, <4 x float>* %ptr, i64  5
32   %ld1 = load <4 x float>, <4 x float>* %gep1, align 16
33   %ld2 = load <4 x float>, <4 x float>* %gep2, align 16
34   %ld3 = load <4 x float>, <4 x float>* %gep3, align 16
35   %ld4 = load <4 x float>, <4 x float>* %gep4, align 16
36   %sv1 = shufflevector <4 x float> %ld1, <4 x float> %ld2, <4 x i32> <i32 0, i32 1, i32 4, i32 5>
37   %sv2 = shufflevector <4 x float> %ld1, <4 x float> %ld2, <4 x i32> <i32 2, i32 3, i32 6, i32 7>
38   %sv3 = shufflevector <4 x float> %ld3, <4 x float> %ld4, <4 x i32> <i32 0, i32 1, i32 4, i32 5>
39   %sv4 = shufflevector <4 x float> %ld3, <4 x float> %ld4, <4 x i32> <i32 2, i32 3, i32 6, i32 7>
40   %m0_3   = shufflevector <4 x float> %sv1, <4 x float> %sv3, <4 x i32> <i32 0, i32 2, i32 4, i32 6>
41   %m4_7   = shufflevector <4 x float> %sv1, <4 x float> %sv3, <4 x i32> <i32 1, i32 3, i32 5, i32 7>
42   %m8_11  = shufflevector <4 x float> %sv2, <4 x float> %sv4, <4 x i32> <i32 0, i32 2, i32 4, i32 6>
43   %m12_15 = shufflevector <4 x float> %sv2, <4 x float> %sv4, <4 x i32> <i32 1, i32 3, i32 5, i32 7>
45   store <4 x float> %m0_3, <4 x float>* %gep1, align 16
46   store <4 x float> %m4_7, <4 x float>* %gep2, align 16
47   store <4 x float> %m8_11, <4 x float>* %gep3, align 16
48   store <4 x float> %m12_15, <4 x float>* %gep4, align 16
49   ret void
52 ; This should be lowered into LD4
53 define void @aarch64_ilc_idx(<4 x float>* %ptr, i64 %idx) {
54 entry:
56 ;;; Check LLVM transformation
57 ; CHECK-LABEL: @aarch64_ilc_idx(
58 ; CHECK-DAG: [[ADD:%.+]] = add i64 %idx, 16
59 ; CHECK-DAG: [[LSHR:%.+]] = lshr i64 [[ADD]], 2
60 ; CHECK-DAG: [[GEP:%.+]] = getelementptr inbounds <4 x float>, <4 x float>* %ptr, i64 [[LSHR]]
61 ; CHECK-DAG: [[CAST:%.+]] = bitcast <4 x float>* [[GEP]] to <16 x float>*
62 ; CHECK-DAG: [[LOAD:%.+]] = load <16 x float>, <16 x float>* [[CAST]], align 16
63 ; CHECK-DAG: %{{.* }}= shufflevector <16 x float> [[LOAD]], <16 x float> undef, <4 x i32> <i32 0, i32 4, i32 8, i32 12>
64 ; CHECK-DAG: %{{.* }}= shufflevector <16 x float> [[LOAD]], <16 x float> undef, <4 x i32> <i32 1, i32 5, i32 9, i32 13>
65 ; CHECK-DAG: %{{.* }}= shufflevector <16 x float> [[LOAD]], <16 x float> undef, <4 x i32> <i32 2, i32 6, i32 10, i32 14>
66 ; CHECK-DAG: %{{.* }}= shufflevector <16 x float> [[LOAD]], <16 x float> undef, <4 x i32> <i32 3, i32 7, i32 11, i32 15>
67 ; CHECK: ret void
69 ; AS-LABEL: aarch64_ilc_idx
70 ; AS-DAG: lsl [[LSL:x[0-9]+]], x1, #2
71 ; AS-DAG: add [[ADD:x[0-9]+]], [[LSL]], #64
72 ; AS-DAG: and [[AND:x[0-9]+]], [[ADD]], #0xfffffffffffffff0
73 ; AS-DAG: add [[ADR:x[0-9]+]], x0, [[AND]]
74 ; AS-DAG: ld4 { v[[V0:[0-9]+]].4s, v[[V1:[0-9]+]].4s, v[[V2:[0-9]+]].4s, v[[V3:[0-9]+]].4s }, {{\[}}[[ADR]]{{\]}}
75 ; AS-DAG: str q[[V0]]
76 ; AS-DAG: str q[[V1]]
77 ; AS-DAG: str q[[V2]]
78 ; AS-DAG: str q[[V3]]
79 ; AS: ret
81   %a2 = add i64 %idx, 20
82   %idx2 = lshr i64 %a2, 2
83   %a3 = add i64 %idx, 24
84   %a1 = add i64 %idx, 16
85   %idx1 = lshr i64 %a1, 2
86   %idx3 = lshr i64 %a3, 2
87   %a4 = add i64 %idx, 28
88   %idx4 = lshr i64 %a4, 2
90   %gep2 = getelementptr inbounds <4 x float>, <4 x float>* %ptr, i64  %idx2
91   %gep4 = getelementptr inbounds <4 x float>, <4 x float>* %ptr, i64  %idx4
92   %gep1 = getelementptr inbounds <4 x float>, <4 x float>* %ptr, i64  %idx1
93   %gep3 = getelementptr inbounds <4 x float>, <4 x float>* %ptr, i64  %idx3
94   %ld1 = load <4 x float>, <4 x float>* %gep1, align 16
95   %ld2 = load <4 x float>, <4 x float>* %gep2, align 16
96   %ld3 = load <4 x float>, <4 x float>* %gep3, align 16
97   %ld4 = load <4 x float>, <4 x float>* %gep4, align 16
98   %sv1 = shufflevector <4 x float> %ld1, <4 x float> %ld2, <4 x i32> <i32 0, i32 1, i32 4, i32 5>
99   %sv2 = shufflevector <4 x float> %ld1, <4 x float> %ld2, <4 x i32> <i32 2, i32 3, i32 6, i32 7>
100   %sv3 = shufflevector <4 x float> %ld3, <4 x float> %ld4, <4 x i32> <i32 0, i32 1, i32 4, i32 5>
101   %sv4 = shufflevector <4 x float> %ld3, <4 x float> %ld4, <4 x i32> <i32 2, i32 3, i32 6, i32 7>
102   %m0_3   = shufflevector <4 x float> %sv1, <4 x float> %sv3, <4 x i32> <i32 0, i32 2, i32 4, i32 6>
103   %m4_7   = shufflevector <4 x float> %sv1, <4 x float> %sv3, <4 x i32> <i32 1, i32 3, i32 5, i32 7>
104   %m8_11  = shufflevector <4 x float> %sv2, <4 x float> %sv4, <4 x i32> <i32 0, i32 2, i32 4, i32 6>
105   %m12_15 = shufflevector <4 x float> %sv2, <4 x float> %sv4, <4 x i32> <i32 1, i32 3, i32 5, i32 7>
107   store <4 x float> %m0_3, <4 x float>* %gep1, align 16
108   store <4 x float> %m4_7, <4 x float>* %gep2, align 16
109   store <4 x float> %m8_11, <4 x float>* %gep3, align 16
110   store <4 x float> %m12_15, <4 x float>* %gep4, align 16
111   ret void
114 ; This should be lowered into LD4, a offset of has to be taken into account
115 %struct.ilc = type <{ float, [0 x <4 x float>] }>
116 define void @aarch64_ilc_struct(%struct.ilc* %ptr, i64 %idx) {
117 entry:
119 ;;; Check LLVM transformation
120 ; CHECK-LABEL: @aarch64_ilc_struct(
121 ; CHECK-DAG: [[LSHR:%.+]] = lshr i64 %idx, 2
122 ; CHECK-DAG: [[GEP:%.+]] = getelementptr %struct.ilc, %struct.ilc* %ptr, i32 0, i32 1, i64 [[LSHR]]
123 ; CHECK-DAG: [[CAST:%.+]] = bitcast <4 x float>* [[GEP]] to <16 x float>*
124 ; CHECK-DAG: [[LOAD:%.+]] = load <16 x float>, <16 x float>* [[CAST]], align 4
125 ; CHECK-DAG: %{{.* }}= shufflevector <16 x float> [[LOAD]], <16 x float> undef, <4 x i32> <i32 0, i32 4, i32 8, i32 12>
126 ; CHECK-DAG: %{{.* }}= shufflevector <16 x float> [[LOAD]], <16 x float> undef, <4 x i32> <i32 1, i32 5, i32 9, i32 13>
127 ; CHECK-DAG: %{{.* }}= shufflevector <16 x float> [[LOAD]], <16 x float> undef, <4 x i32> <i32 2, i32 6, i32 10, i32 14>
128 ; CHECK-DAG: %{{.* }}= shufflevector <16 x float> [[LOAD]], <16 x float> undef, <4 x i32> <i32 3, i32 7, i32 11, i32 15>
129 ; CHECK: ret void
131 ; AS-LABEL: aarch64_ilc_struct
132 ; AS-DAG: lsl [[LSL:x[0-9]+]], x1, #2
133 ; AS-DAG: add [[ADD:x[0-9]+]], x0, #4
134 ; AS-DAG: and [[AND:x[0-9]+]], [[LSL]], #0xfffffffffffffff0
135 ; AS-DAG: add [[ADR:x[0-9]+]], [[ADD]], [[AND]]
136 ; AS-DAG: ld4 { v[[V0:[0-9]+]].4s, v[[V1:[0-9]+]].4s, v[[V2:[0-9]+]].4s, v[[V3:[0-9]+]].4s }, {{\[}}[[ADR]]{{\]}}
137 ; AS-DAG: str q[[V0]]
138 ; AS-DAG: str q[[V1]]
139 ; AS-DAG: str q[[V2]]
140 ; AS-DAG: str q[[V3]]
141 ; AS: ret
143   %a1 = add i64 %idx, 4
144   %idx2 = lshr i64 %a1, 2
145   %a2 = add i64 %idx, 8
146   %idx3 = lshr i64 %a2, 2
147   %a3 = add i64 %idx, 12
148   %idx4 = lshr i64 %a3, 2
150   %gep2 = getelementptr %struct.ilc, %struct.ilc* %ptr, i32 0, i32 1, i64 %idx2
151   %gep3 = getelementptr %struct.ilc, %struct.ilc* %ptr, i32 0, i32 1, i64 %idx3
152   %gep4 = getelementptr %struct.ilc, %struct.ilc* %ptr, i32 0, i32 1, i64 %idx4
153   %idx1 = lshr i64 %idx, 2
154   %gep1 = getelementptr %struct.ilc, %struct.ilc* %ptr, i32 0, i32 1, i64 %idx1
155   %ld1 = load <4 x float>, <4 x float>* %gep1, align 4
156   %ld2 = load <4 x float>, <4 x float>* %gep2, align 4
157   %ld3 = load <4 x float>, <4 x float>* %gep3, align 4
158   %ld4 = load <4 x float>, <4 x float>* %gep4, align 4
159   %sv1 = shufflevector <4 x float> %ld1, <4 x float> %ld2, <4 x i32> <i32 0, i32 1, i32 4, i32 5>
160   %sv2 = shufflevector <4 x float> %ld1, <4 x float> %ld2, <4 x i32> <i32 2, i32 3, i32 6, i32 7>
161   %sv3 = shufflevector <4 x float> %ld3, <4 x float> %ld4, <4 x i32> <i32 0, i32 1, i32 4, i32 5>
162   %sv4 = shufflevector <4 x float> %ld3, <4 x float> %ld4, <4 x i32> <i32 2, i32 3, i32 6, i32 7>
163   %m0_3   = shufflevector <4 x float> %sv1, <4 x float> %sv3, <4 x i32> <i32 0, i32 2, i32 4, i32 6>
164   %m4_7   = shufflevector <4 x float> %sv1, <4 x float> %sv3, <4 x i32> <i32 1, i32 3, i32 5, i32 7>
165   %m8_11  = shufflevector <4 x float> %sv2, <4 x float> %sv4, <4 x i32> <i32 0, i32 2, i32 4, i32 6>
166   %m12_15 = shufflevector <4 x float> %sv2, <4 x float> %sv4, <4 x i32> <i32 1, i32 3, i32 5, i32 7>
168   store <4 x float> %m0_3, <4 x float>* %gep1, align 16
169   store <4 x float> %m4_7, <4 x float>* %gep2, align 16
170   store <4 x float> %m8_11, <4 x float>* %gep3, align 16
171   store <4 x float> %m12_15, <4 x float>* %gep4, align 16
172   ret void
175 ; This should be lowered into LD2
176 define void @aarch64_ilc_idx_ld2(<4 x float>* %ptr, i64 %idx) {
177 entry:
178 ; CHECK-LABEL: @aarch64_ilc_idx_ld2(
179 ; CHECK-DAG: [[LSHR:%.+]] = lshr i64 %idx, 2
180 ; CHECK-DAG: [[GEP:%.+]] = getelementptr inbounds <4 x float>, <4 x float>* %ptr, i64 [[LSHR]]
181 ; CHECK-DAG: [[CAST:%.+]] = bitcast <4 x float>* [[GEP]] to <8 x float>*
182 ; CHECK-DAG: [[LOAD:%.+]] = load <8 x float>, <8 x float>* [[CAST]], align 16
183 ; CHECK: %{{.* }}= shufflevector <8 x float> [[LOAD]], <8 x float> undef, <4 x i32> <i32 0, i32 2, i32 4, i32 6>
184 ; CHECK: %{{.* }}= shufflevector <8 x float> [[LOAD]], <8 x float> undef, <4 x i32> <i32 1, i32 3, i32 5, i32 7>
185 ; CHECK-DAG: ret void
187 ; AS-LABEL: aarch64_ilc_idx_ld2
188 ; AS: ld2
189 ; AS: ret
191   %idx1 = lshr i64 %idx, 2
192   %a1 = add i64 %idx, 4
193   %idx2 = lshr i64 %a1, 2
195   %gep1 = getelementptr inbounds <4 x float>, <4 x float>* %ptr, i64  %idx1
196   %gep2 = getelementptr inbounds <4 x float>, <4 x float>* %ptr, i64  %idx2
197   %ld1 = load <4 x float>, <4 x float>* %gep1, align 16
198   %ld2 = load <4 x float>, <4 x float>* %gep2, align 16
199   %m0_3 = shufflevector <4 x float> %ld1, <4 x float> %ld2, <4 x i32> <i32 0, i32 2, i32 4, i32 6>
200   %m4_7 = shufflevector <4 x float> %ld1, <4 x float> %ld2, <4 x i32> <i32 1, i32 3, i32 5, i32 7>
202   store <4 x float> %m0_3, <4 x float>* %gep1
203   store <4 x float> %m4_7, <4 x float>* %gep2
204   ret void
207 ; This should be lowered into LD3
208 define void @aarch64_ilc_idx_ld3(<4 x float>* %ptr, i64 %idx) {
209 entry:
210 ; CHECK-LABEL: @aarch64_ilc_idx_ld3(
211 ; CHECK-DAG: [[LSHR:%.+]] = lshr i64 %idx, 2
212 ; CHECK-DAG: [[GEP:%.+]] = getelementptr inbounds <4 x float>, <4 x float>* %ptr, i64 [[LSHR]]
213 ; CHECK-DAG: [[CAST:%.+]] = bitcast <4 x float>* [[GEP]] to <12 x float>*
214 ; CHECK-DAG: [[LOAD:%.+]] = load <12 x float>, <12 x float>* [[CAST]], align 16
215 ; CHECK: %{{.* }}= shufflevector <12 x float> [[LOAD]], <12 x float> undef, <4 x i32> <i32 0, i32 3, i32 6, i32 9>
216 ; CHECK: %{{.* }}= shufflevector <12 x float> [[LOAD]], <12 x float> undef, <4 x i32> <i32 1, i32 4, i32 7, i32 10>
217 ; CHECK: %{{.* }}= shufflevector <12 x float> [[LOAD]], <12 x float> undef, <4 x i32> <i32 2, i32 5, i32 8, i32 11>
218 ; CHECK-DAG: ret void
220 ; AS-LABEL: aarch64_ilc_idx_ld3
221 ; AS: ld3
222 ; AS: ret
224   %idx1 = lshr i64 %idx, 2
225   %a1 = add i64 %idx, 4
226   %idx2 = lshr i64 %a1, 2
227   %a2 = add i64 %idx, 8
228   %idx3 = lshr i64 %a2, 2
230   %gep1 = getelementptr inbounds <4 x float>, <4 x float>* %ptr, i64  %idx1
231   %gep2 = getelementptr inbounds <4 x float>, <4 x float>* %ptr, i64  %idx2
232   %gep3 = getelementptr inbounds <4 x float>, <4 x float>* %ptr, i64  %idx3
233   %ld1 = load <4 x float>, <4 x float>* %gep1, align 16
234   %ld2 = load <4 x float>, <4 x float>* %gep2, align 16
235   %ld3 = load <4 x float>, <4 x float>* %gep3, align 16
237   %sv1 = shufflevector <4 x float> %ld1, <4 x float> %ld2, <4 x i32> <i32 0, i32 3, i32 6, i32 undef>
238   %sv2 = shufflevector <4 x float> %ld1, <4 x float> %ld2, <4 x i32> <i32 1, i32 4, i32 7, i32 undef>
239   %sv3 = shufflevector <4 x float> %ld1, <4 x float> %ld2, <4 x i32> <i32 2, i32 5, i32 undef, i32 undef>
240   %m0_3 = shufflevector <4 x float> %sv1, <4 x float> %ld3, <4 x i32> <i32 0, i32 1, i32 2, i32 5>
241   %m4_7 = shufflevector <4 x float> %sv2, <4 x float> %ld3, <4 x i32> <i32 0, i32 1, i32 2, i32 6>
242   %m8_11 = shufflevector <4 x float> %sv3, <4 x float> %ld3, <4 x i32> <i32 0, i32 1, i32 4, i32 7>
244   store <4 x float> %m0_3, <4 x float>* %gep1, align 16
245   store <4 x float> %m4_7, <4 x float>* %gep2, align 16
246   store <4 x float> %m8_11, <4 x float>* %gep3, align 16
247   ret void
249 ;  %sv3 = shufflevector <4 x float> %ld3, <4 x float> %ld4, <4 x i32> <i32 0, i32 undef, i32 4, i32 undef>
251 ; This must not be lowered
252 define void @aarch64_ilc_i32_idx(<4 x float>* %ptr, i32 %idx) {
253 ; CHECK-LABEL: @aarch64_ilc_i32_idx(
254 ; CHECK: %idx1 = lshr i32 %idx, 2
255 ; CHECK-NEXT: %a1 = add i32 %idx, 4
256 ; CHECK-NEXT: %idx2 = lshr i32 %a1, 2
257 ; CHECK-NEXT: %gep1 = getelementptr inbounds <4 x float>, <4 x float>* %ptr, i32 %idx1
258 ; CHECK-NEXT: %gep2 = getelementptr inbounds <4 x float>, <4 x float>* %ptr, i32 %idx2
259 ; CHECK-NEXT: %ld1 = load <4 x float>, <4 x float>* %gep1, align 16
260 ; CHECK-NEXT: %ld2 = load <4 x float>, <4 x float>* %gep2, align 16
261 ; CHECK-NEXT: %m0_3 = shufflevector <4 x float> %ld1, <4 x float> %ld2, <4 x i32> <i32 0, i32 2, i32 4, i32 6>
262 ; CHECK-NEXT: %m4_7 = shufflevector <4 x float> %ld1, <4 x float> %ld2, <4 x i32> <i32 1, i32 3, i32 5, i32 7>
263 ; CHECK-NEXT: store <4 x float> %m0_3, <4 x float>* %gep1, align 16
264 ; CHECK-NEXT: store <4 x float> %m4_7, <4 x float>* %gep2, align 16
265 ; CHECK-NEXT: ret void
267 ; AS-LABEL: aarch64_ilc_i32_idx
268 ; AS-DAG: @function
269 ; AS-NOT: ld2
270 ; AS-NOT: ld3
271 ; AS-NOT: ld4
272 ; AS-DAG: ret
274 entry:
275   %idx1 = lshr i32 %idx, 2
276   %a1 = add i32 %idx, 4
277   %idx2 = lshr i32 %a1, 2
279   %gep1 = getelementptr inbounds <4 x float>, <4 x float>* %ptr, i32 %idx1
280   %gep2 = getelementptr inbounds <4 x float>, <4 x float>* %ptr, i32 %idx2
281   %ld1 = load <4 x float>, <4 x float>* %gep1, align 16
282   %ld2 = load <4 x float>, <4 x float>* %gep2, align 16
283   %m0_3 = shufflevector <4 x float> %ld1, <4 x float> %ld2, <4 x i32> <i32 0, i32 2, i32 4, i32 6>
284   %m4_7 = shufflevector <4 x float> %ld1, <4 x float> %ld2, <4 x i32> <i32 1, i32 3, i32 5, i32 7>
286   store <4 x float> %m0_3, <4 x float>* %gep1, align 16
287   store <4 x float> %m4_7, <4 x float>* %gep2, align 16
288   ret void
291 ; Volatile loads must not be lowered
292 define void @aarch64_ilc_volatile(<4 x float>* %ptr) {
293 ; CHECK-LABEL: @aarch64_ilc_volatile(
294 ; CHECK: %gep1 = getelementptr inbounds <4 x float>, <4 x float>* %ptr, i32 0
295 ; CHECK-NEXT: %gep2 = getelementptr inbounds <4 x float>, <4 x float>* %ptr, i32 1
296 ; CHECK-NEXT: %ld1 = load volatile <4 x float>, <4 x float>* %gep1, align 16
297 ; CHECK-NEXT: %ld2 = load <4 x float>, <4 x float>* %gep2, align 16
298 ; CHECK-NEXT: %m0_3 = shufflevector <4 x float> %ld1, <4 x float> %ld2, <4 x i32> <i32 0, i32 2, i32 4, i32 6>
299 ; CHECK-NEXT: %m4_7 = shufflevector <4 x float> %ld1, <4 x float> %ld2, <4 x i32> <i32 1, i32 3, i32 5, i32 7>
300 ; CHECK-NEXT: store <4 x float> %m0_3, <4 x float>* %gep1, align 16
301 ; CHECK-NEXT: store <4 x float> %m4_7, <4 x float>* %gep2, align 16
302 ; CHECK-NEXT: ret void
304 ; AS-LABEL: aarch64_ilc_volatile
305 ; AS-DAG: @function
306 ; AS-NOT: ld2
307 ; AS-NOT: ld3
308 ; AS-NOT: ld4
309 ; AS-DAG: ret
311 entry:
312   %gep1 = getelementptr inbounds <4 x float>, <4 x float>* %ptr, i32 0
313   %gep2 = getelementptr inbounds <4 x float>, <4 x float>* %ptr, i32 1
314   %ld1 = load volatile <4 x float>, <4 x float>* %gep1, align 16
315   %ld2 = load <4 x float>, <4 x float>* %gep2, align 16
316   %m0_3 = shufflevector <4 x float> %ld1, <4 x float> %ld2, <4 x i32> <i32 0, i32 2, i32 4, i32 6>
317   %m4_7 = shufflevector <4 x float> %ld1, <4 x float> %ld2, <4 x i32> <i32 1, i32 3, i32 5, i32 7>
318   store <4 x float> %m0_3, <4 x float>* %gep1, align 16
319   store <4 x float> %m4_7, <4 x float>* %gep2, align 16
320   ret void
323 ; This must not be lowered
324 define void @aarch64_ilc_depmem(<4 x float>* %ptr, i32 %idx) {
325 entry:
326 ; CHECK-LABEL: @aarch64_ilc_depmem(
327 ; CHECK: %gep1 = getelementptr inbounds <4 x float>, <4 x float>* %ptr, i32 0
328 ; CHECK-NEXT: %gep2 = getelementptr inbounds <4 x float>, <4 x float>* %ptr, i32 1
329 ; CHECK-NEXT: %ld1 = load <4 x float>, <4 x float>* %gep1, align 16
330 ; CHECK-NEXT: store <4 x float> %ld1, <4 x float>* %gep2, align 16
331 ; CHECK-NEXT: %ld2 = load <4 x float>, <4 x float>* %gep2, align 16
332 ; CHECK-NEXT: %m0_3 = shufflevector <4 x float> %ld1, <4 x float> %ld2, <4 x i32> <i32 0, i32 2, i32 4, i32 6>
333 ; CHECK-NEXT: %m4_7 = shufflevector <4 x float> %ld1, <4 x float> %ld2, <4 x i32> <i32 1, i32 3, i32 5, i32 7>
334 ; CHECK-NEXT: store <4 x float> %m0_3, <4 x float>* %gep1, align 16
335 ; CHECK-NEXT: store <4 x float> %m4_7, <4 x float>* %gep2, align 16
336 ; CHECK-NEXT: ret void
338 ; AS-LABEL: aarch64_ilc_depmem
339 ; AS-DAG: @function
340 ; AS-NOT: ld2
341 ; AS-NOT: ld3
342 ; AS-NOT: ld4
343 ; AS-DAG: ret
345   %gep1 = getelementptr inbounds <4 x float>, <4 x float>* %ptr, i32 0
346   %gep2 = getelementptr inbounds <4 x float>, <4 x float>* %ptr, i32 1
347   %ld1 = load <4 x float>, <4 x float>* %gep1, align 16
348   store <4 x float> %ld1, <4 x float>* %gep2, align 16
349   %ld2 = load <4 x float>, <4 x float>* %gep2, align 16
350   %m0_3 = shufflevector <4 x float> %ld1, <4 x float> %ld2, <4 x i32> <i32 0, i32 2, i32 4, i32 6>
351   %m4_7 = shufflevector <4 x float> %ld1, <4 x float> %ld2, <4 x i32> <i32 1, i32 3, i32 5, i32 7>
353   store <4 x float> %m0_3, <4 x float>* %gep1, align 16
354   store <4 x float> %m4_7, <4 x float>* %gep2, align 16
355   ret void
358 ; This cannot be converted - insertion position cannot be determined
359 define void @aarch64_no_insertion_pos(float* %ptr) {
360 entry:
361 ; CHECK-LABEL: @aarch64_no_insertion_pos(
362 ; CHECK: %p0 = getelementptr inbounds float, float* %ptr, i32 0
363 ; CHECK-NEXT: %p1 = getelementptr inbounds float, float* %ptr, i32 4
364 ; CHECK-NEXT: %b0 = bitcast float* %p0 to <5 x float>*
365 ; CHECK-NEXT: %b1 = bitcast float* %p1 to <5 x float>*
366 ; CHECK-NEXT: %l0 = load <5 x float>, <5 x float>* %b0
367 ; CHECK-NEXT: %l1 = load <5 x float>, <5 x float>* %b1
368 ; CHECK-NEXT: %s0 = shufflevector <5 x float> %l0, <5 x float> %l1, <4 x i32> <i32 1, i32 3, i32 6, i32 8>
369 ; CHECK-NEXT: %s1 = shufflevector <5 x float> %l0, <5 x float> %l1, <4 x i32> <i32 2, i32 4, i32 7, i32 9>
370 ; CHECK-NEXT: ret void
372   %p0 = getelementptr inbounds float, float* %ptr, i32 0
373   %p1 = getelementptr inbounds float, float* %ptr, i32 4
374   %b0 = bitcast float* %p0 to <5 x float>*
375   %b1 = bitcast float* %p1 to <5 x float>*
376   %l0 = load <5 x float>, <5 x float>* %b0
377   %l1 = load <5 x float>, <5 x float>* %b1
378   %s0 = shufflevector <5 x float> %l0, <5 x float> %l1, <4 x i32> <i32 1, i32 3, i32 6, i32 8>
379   %s1 = shufflevector <5 x float> %l0, <5 x float> %l1, <4 x i32> <i32 2, i32 4, i32 7, i32 9>
380   ret void
383 ; This cannot be converted - the insertion position does not dominate all
384 ; uses
385 define void @aarch64_insertpos_does_not_dominate(float* %ptr) {
386 entry:
387 ; CHECK-LABEL: @aarch64_insertpos_does_not_dominate(
388 ; CHECK: %p0 = getelementptr inbounds float, float* %ptr, i32 0
389 ; CHECK-NEXT: %p1 = getelementptr inbounds float, float* %ptr, i32 1
390 ; CHECK-NEXT: %b0 = bitcast float* %p0 to <7 x float>*
391 ; CHECK-NEXT: %b1 = bitcast float* %p1 to <7 x float>*
392 ; CHECK-NEXT: %l1 = load <7 x float>, <7 x float>* %b1
393 ; CHECK-NEXT: %s1 = shufflevector <7 x float> %l1, <7 x float> undef, <4 x i32> <i32 0, i32 2, i32 4, i32 6>
394 ; CHECK-NEXT: %l0 = load <7 x float>, <7 x float>* %b0
395 ; CHECK-NEXT: %s0 = shufflevector <7 x float> %l0, <7 x float> undef, <4 x i32> <i32 0, i32 2, i32 4, i32 6>
396 ; CHECK-NEXT: ret void
397   %p0 = getelementptr inbounds float, float* %ptr, i32 0
398   %p1 = getelementptr inbounds float, float* %ptr, i32 1
399   %b0 = bitcast float* %p0 to <7 x float>*
400   %b1 = bitcast float* %p1 to <7 x float>*
401   %l1 = load <7 x float>, <7 x float>* %b1
402   %s1 = shufflevector <7 x float> %l1, <7 x float> undef, <4 x i32> <i32 0, i32 2, i32 4, i32 6>
403   %l0 = load <7 x float>, <7 x float>* %b0
404   %s0 = shufflevector <7 x float> %l0, <7 x float> undef, <4 x i32> <i32 0, i32 2, i32 4, i32 6>
405   ret void