Merging r258471:
[oota-llvm.git] / test / CodeGen / AArch64 / arm64-narrow-ldst-merge.ll
1 ; RUN: llc < %s -mtriple aarch64--none-eabi -mcpu=cortex-a57 -verify-machineinstrs | FileCheck %s --check-prefix=CHECK --check-prefix=LE
2 ; RUN: llc < %s -mtriple aarch64_be--none-eabi -mcpu=cortex-a57 -verify-machineinstrs | FileCheck %s --check-prefix=CHECK --check-prefix=BE
3
4 ; CHECK-LABEL: Ldrh_merge
5 ; CHECK-NOT: ldrh
6 ; CHECK: ldr [[NEW_DEST:w[0-9]+]]
7 ; CHECK-DAG: and [[LO_PART:w[0-9]+]], [[NEW_DEST]], #0xffff
8 ; CHECK-DAG: lsr [[HI_PART:w[0-9]+]], [[NEW_DEST]], #16
9 ; LE: sub {{w[0-9]+}}, [[LO_PART]], [[HI_PART]]
10 ; BE: sub {{w[0-9]+}}, [[HI_PART]], [[LO_PART]]
11 define i16 @Ldrh_merge(i16* nocapture readonly %p) {
12   %1 = load i16, i16* %p, align 2
13   %arrayidx2 = getelementptr inbounds i16, i16* %p, i64 1
14   %2 = load i16, i16* %arrayidx2, align 2
15   %add = sub nuw nsw i16 %1, %2
16   ret i16 %add
17 }
18
19 ; CHECK-LABEL: Ldurh_merge
20 ; CHECK-NOT: ldurh
21 ; CHECK: ldur [[NEW_DEST:w[0-9]+]]
22 ; CHECK-DAG: and [[LO_PART:w[0-9]+]], [[NEW_DEST]], #0xffff
23 ; CHECK-DAG: lsr  [[HI_PART:w[0-9]+]], [[NEW_DEST]]
24 ; LE: sub {{w[0-9]+}}, [[LO_PART]], [[HI_PART]]
25 ; BE: sub {{w[0-9]+}}, [[HI_PART]], [[LO_PART]]
26 define i16 @Ldurh_merge(i16* nocapture readonly %p)  {
27 entry:
28   %arrayidx = getelementptr inbounds i16, i16* %p, i64 -2
29   %0 = load i16, i16* %arrayidx
30   %arrayidx3 = getelementptr inbounds i16, i16* %p, i64 -1
31   %1 = load i16, i16* %arrayidx3
32   %add = sub nuw nsw i16 %0, %1
33   ret i16 %add
34 }
35
36 ; CHECK-LABEL: Ldrh_4_merge
37 ; CHECK-NOT: ldrh
38 ; CHECK: ldp [[WORD1:w[0-9]+]], [[WORD2:w[0-9]+]], [x0]
39 ; CHECK-DAG: and [[WORD1LO:w[0-9]+]], [[WORD1]], #0xffff
40 ; CHECK-DAG: lsr [[WORD1HI:w[0-9]+]], [[WORD1]], #16
41 ; CHECK-DAG: and [[WORD2LO:w[0-9]+]], [[WORD2]], #0xffff
42 ; CHECK-DAG: lsr [[WORD2HI:w[0-9]+]], [[WORD2]], #16
43 ; LE-DAG: sub [[TEMP1:w[0-9]+]], [[WORD1HI]], [[WORD1LO]]
44 ; BE-DAG: sub [[TEMP1:w[0-9]+]], [[WORD1LO]], [[WORD1HI]]
45 ; LE: udiv [[TEMP2:w[0-9]+]], [[TEMP1]], [[WORD2LO]]
46 ; BE: udiv [[TEMP2:w[0-9]+]], [[TEMP1]], [[WORD2HI]]
47 ; LE: sub w0, [[TEMP2]], [[WORD2HI]]
48 ; BE: sub w0, [[TEMP2]], [[WORD2LO]]
49 define i16 @Ldrh_4_merge(i16* nocapture readonly %P) {
50   %arrayidx = getelementptr inbounds i16, i16* %P, i64 0
51   %l0 = load i16, i16* %arrayidx
52   %arrayidx2 = getelementptr inbounds i16, i16* %P, i64 1
53   %l1 = load i16, i16* %arrayidx2
54   %arrayidx7 = getelementptr inbounds i16, i16* %P, i64 2
55   %l2 = load i16, i16* %arrayidx7
56   %arrayidx12 = getelementptr inbounds i16, i16* %P, i64 3
57   %l3 = load i16, i16* %arrayidx12
58   %add4 = sub nuw nsw i16 %l1, %l0
59   %add9 = udiv i16 %add4, %l2
60   %add14 = sub nuw nsw i16 %add9, %l3
61   ret i16 %add14
62 }
63
64 ; CHECK-LABEL: Ldrsh_merge
65 ; CHECK: ldr [[NEW_DEST:w[0-9]+]]
66 ; CHECK-DAG: asr [[LO_PART:w[0-9]+]], [[NEW_DEST]], #16
67 ; CHECK-DAG: sxth [[HI_PART:w[0-9]+]], [[NEW_DEST]]
68 ; LE: sub {{w[0-9]+}}, [[LO_PART]], [[HI_PART]]
69 ; BE: sub {{w[0-9]+}}, [[HI_PART]], [[LO_PART]]
70
71 define i32 @Ldrsh_merge(i16* %p) nounwind {
72   %add.ptr0 = getelementptr inbounds i16, i16* %p, i64 4
73   %tmp = load i16, i16* %add.ptr0
74   %add.ptr = getelementptr inbounds i16, i16* %p, i64 5
75   %tmp1 = load i16, i16* %add.ptr
76   %sexttmp = sext i16 %tmp to i32
77   %sexttmp1 = sext i16 %tmp1 to i32
78   %add = sub nsw i32 %sexttmp1, %sexttmp
79   ret i32 %add
80 }
81
82 ; CHECK-LABEL: Ldrsh_zsext_merge
83 ; CHECK: ldr [[NEW_DEST:w[0-9]+]]
84 ; LE-DAG: and [[LO_PART:w[0-9]+]], [[NEW_DEST]], #0xffff
85 ; LE-DAG: asr [[HI_PART:w[0-9]+]], [[NEW_DEST]], #16
86 ; BE-DAG: sxth [[LO_PART:w[0-9]+]], [[NEW_DEST]]
87 ; BE-DAG: lsr [[HI_PART:w[0-9]+]], [[NEW_DEST]], #16
88 ; LE: sub {{w[0-9]+}}, [[LO_PART]], [[HI_PART]]
89 ; BE: sub {{w[0-9]+}}, [[HI_PART]], [[LO_PART]]
90 define i32 @Ldrsh_zsext_merge(i16* %p) nounwind {
91   %add.ptr0 = getelementptr inbounds i16, i16* %p, i64 4
92   %tmp = load i16, i16* %add.ptr0
93   %add.ptr = getelementptr inbounds i16, i16* %p, i64 5
94   %tmp1 = load i16, i16* %add.ptr
95   %sexttmp = zext i16 %tmp to i32
96   %sexttmp1 = sext i16 %tmp1 to i32
97   %add = sub nsw i32 %sexttmp, %sexttmp1
98   ret i32 %add
99 }
100
101 ; CHECK-LABEL: Ldrsh_szext_merge
102 ; CHECK: ldr [[NEW_DEST:w[0-9]+]]
103 ; LE-DAG: sxth [[LO_PART:w[0-9]+]], [[NEW_DEST]]
104 ; LE-DAG: lsr [[HI_PART:w[0-9]+]], [[NEW_DEST]], #16
105 ; BE-DAG: and [[LO_PART:w[0-9]+]], [[NEW_DEST]], #0xffff
106 ; BE-DAG: asr [[HI_PART:w[0-9]+]], [[NEW_DEST]], #16
107 ; LE: sub {{w[0-9]+}}, [[LO_PART]], [[HI_PART]]
108 ; BE: sub {{w[0-9]+}}, [[HI_PART]], [[LO_PART]]
109 define i32 @Ldrsh_szext_merge(i16* %p) nounwind {
110   %add.ptr0 = getelementptr inbounds i16, i16* %p, i64 4
111   %tmp = load i16, i16* %add.ptr0
112   %add.ptr = getelementptr inbounds i16, i16* %p, i64 5
113   %tmp1 = load i16, i16* %add.ptr
114   %sexttmp = sext i16 %tmp to i32
115   %sexttmp1 = zext i16 %tmp1 to i32
116   %add = sub nsw i32 %sexttmp, %sexttmp1
117   ret i32 %add
118 }
119
120 ; CHECK-LABEL: Ldrb_merge
121 ; CHECK: ldrh [[NEW_DEST:w[0-9]+]]
122 ; CHECK-DAG: and [[LO_PART:w[0-9]+]], [[NEW_DEST]], #0xff
123 ; CHECK-DAG: ubfx [[HI_PART:w[0-9]+]], [[NEW_DEST]], #8, #8
124 ; LE: sub {{w[0-9]+}}, [[LO_PART]], [[HI_PART]]
125 ; BE: sub {{w[0-9]+}}, [[HI_PART]], [[LO_PART]]
126 define i32 @Ldrb_merge(i8* %p) nounwind {
127   %add.ptr0 = getelementptr inbounds i8, i8* %p, i64 2
128   %tmp = load i8, i8* %add.ptr0
129   %add.ptr = getelementptr inbounds i8, i8* %p, i64 3
130   %tmp1 = load i8, i8* %add.ptr
131   %sexttmp = zext i8 %tmp to i32
132   %sexttmp1 = zext i8 %tmp1 to i32
133   %add = sub nsw i32 %sexttmp, %sexttmp1
134   ret i32 %add
135 }
136
137 ; CHECK-LABEL: Ldrsb_merge
138 ; CHECK: ldrh [[NEW_DEST:w[0-9]+]]
139 ; CHECK-DAG: sxtb [[LO_PART:w[0-9]+]], [[NEW_DEST]]
140 ; CHECK-DAG: sbfx [[HI_PART:w[0-9]+]], [[NEW_DEST]], #8, #8
141 ; LE: sub {{w[0-9]+}}, [[LO_PART]], [[HI_PART]]
142 ; BE: sub {{w[0-9]+}}, [[HI_PART]], [[LO_PART]]
143 define i32 @Ldrsb_merge(i8* %p) nounwind {
144   %add.ptr0 = getelementptr inbounds i8, i8* %p, i64 2
145   %tmp = load i8, i8* %add.ptr0
146   %add.ptr = getelementptr inbounds i8, i8* %p, i64 3
147   %tmp1 = load i8, i8* %add.ptr
148   %sexttmp = sext i8 %tmp to i32
149   %sexttmp1 = sext i8 %tmp1 to i32
150   %add = sub nsw i32 %sexttmp, %sexttmp1
151   ret i32 %add
152 }
153
154 ; CHECK-LABEL: Ldrsb_zsext_merge
155 ; CHECK: ldrh [[NEW_DEST:w[0-9]+]]
156 ; LE-DAG: and [[LO_PART:w[0-9]+]], [[NEW_DEST]], #0xff
157 ; LE-DAG: sbfx [[HI_PART:w[0-9]+]], [[NEW_DEST]], #8, #8
158 ; BE-DAG: sxtb [[LO_PART:w[0-9]+]], [[NEW_DEST]]
159 ; BE-DAG: ubfx [[HI_PART:w[0-9]+]], [[NEW_DEST]], #8, #8
160 ; LE: sub {{w[0-9]+}}, [[LO_PART]], [[HI_PART]]
161 ; BE: sub {{w[0-9]+}}, [[HI_PART]], [[LO_PART]]
162 define i32 @Ldrsb_zsext_merge(i8* %p) nounwind {
163   %add.ptr0 = getelementptr inbounds i8, i8* %p, i64 2
164   %tmp = load i8, i8* %add.ptr0
165   %add.ptr = getelementptr inbounds i8, i8* %p, i64 3
166   %tmp1 = load i8, i8* %add.ptr
167   %sexttmp = zext i8 %tmp to i32
168   %sexttmp1 = sext i8 %tmp1 to i32
169   %add = sub nsw i32 %sexttmp, %sexttmp1
170   ret i32 %add
171 }
172
173 ; CHECK-LABEL: Ldrsb_szext_merge
174 ; CHECK: ldrh [[NEW_DEST:w[0-9]+]]
175 ; LE-DAG: sxtb [[LO_PART:w[0-9]+]], [[NEW_DEST]]
176 ; LE-DAG: ubfx [[HI_PART:w[0-9]+]], [[NEW_DEST]], #8, #8
177 ; BE-DAG: and [[LO_PART:w[0-9]+]], [[NEW_DEST]], #0xff
178 ; BE-DAG: sbfx [[HI_PART:w[0-9]+]], [[NEW_DEST]], #8, #8
179 ; LE: sub {{w[0-9]+}}, [[LO_PART]], [[HI_PART]]
180 ; BE: sub {{w[0-9]+}}, [[HI_PART]], [[LO_PART]]
181 define i32 @Ldrsb_szext_merge(i8* %p) nounwind {
182   %add.ptr0 = getelementptr inbounds i8, i8* %p, i64 2
183   %tmp = load i8, i8* %add.ptr0
184   %add.ptr = getelementptr inbounds i8, i8* %p, i64 3
185   %tmp1 = load i8, i8* %add.ptr
186   %sexttmp = sext i8 %tmp to i32
187   %sexttmp1 = zext i8 %tmp1 to i32
188   %add = sub nsw i32 %sexttmp, %sexttmp1
189   ret i32 %add
190 }
191
192 ; CHECK-LABEL: Ldursh_merge
193 ; CHECK: ldur [[NEW_DEST:w[0-9]+]]
194 ; CHECK-DAG: asr  [[LO_PART:w[0-9]+]], [[NEW_DEST]], #16
195 ; CHECK-DAG: sxth [[HI_PART:w[0-9]+]], [[NEW_DEST]]
196 ; LE: sub {{w[0-9]+}}, [[LO_PART]], [[HI_PART]]
197 ; BE: sub {{w[0-9]+}}, [[HI_PART]], [[LO_PART]]
198 define i32 @Ldursh_merge(i16* %p) nounwind {
199   %add.ptr0 = getelementptr inbounds i16, i16* %p, i64 -1
200   %tmp = load i16, i16* %add.ptr0
201   %add.ptr = getelementptr inbounds i16, i16* %p, i64 -2
202   %tmp1 = load i16, i16* %add.ptr
203   %sexttmp = sext i16 %tmp to i32
204   %sexttmp1 = sext i16 %tmp1 to i32
205   %add = sub nsw i32 %sexttmp, %sexttmp1
206   ret i32 %add
207 }
208
209 ; CHECK-LABEL: Ldursh_zsext_merge
210 ; CHECK: ldur [[NEW_DEST:w[0-9]+]]
211 ; LE-DAG: lsr  [[LO_PART:w[0-9]+]], [[NEW_DEST]], #16
212 ; LE-DAG: sxth [[HI_PART:w[0-9]+]], [[NEW_DEST]]
213 ; BE-DAG: asr  [[LO_PART:w[0-9]+]], [[NEW_DEST]], #16
214 ; BE-DAG: and [[HI_PART:w[0-9]+]], [[NEW_DEST]], #0xffff
215 ; LE: sub {{w[0-9]+}}, [[LO_PART]], [[HI_PART]]
216 ; BE: sub {{w[0-9]+}}, [[HI_PART]], [[LO_PART]]
217 define i32 @Ldursh_zsext_merge(i16* %p) nounwind {
218   %add.ptr0 = getelementptr inbounds i16, i16* %p, i64 -1
219   %tmp = load i16, i16* %add.ptr0
220   %add.ptr = getelementptr inbounds i16, i16* %p, i64 -2
221   %tmp1 = load i16, i16* %add.ptr
222   %sexttmp = zext i16 %tmp to i32
223   %sexttmp1 = sext i16 %tmp1 to i32
224   %add = sub nsw i32 %sexttmp, %sexttmp1
225   ret i32 %add
226 }
227
228 ; CHECK-LABEL: Ldursh_szext_merge
229 ; CHECK: ldur [[NEW_DEST:w[0-9]+]]
230 ; LE-DAG: asr  [[LO_PART:w[0-9]+]], [[NEW_DEST]], #16
231 ; LE-DAG: and [[HI_PART:w[0-9]+]], [[NEW_DEST]], #0xffff
232 ; BE-DAG: lsr  [[LO_PART:w[0-9]+]], [[NEW_DEST]], #16
233 ; BE-DAG: sxth [[HI_PART:w[0-9]+]], [[NEW_DEST]]
234 ; LE: sub {{w[0-9]+}}, [[LO_PART]], [[HI_PART]]
235 ; BE: sub {{w[0-9]+}}, [[HI_PART]], [[LO_PART]]
236 define i32 @Ldursh_szext_merge(i16* %p) nounwind {
237   %add.ptr0 = getelementptr inbounds i16, i16* %p, i64 -1
238   %tmp = load i16, i16* %add.ptr0
239   %add.ptr = getelementptr inbounds i16, i16* %p, i64 -2
240   %tmp1 = load i16, i16* %add.ptr
241   %sexttmp = sext i16 %tmp to i32
242   %sexttmp1 = zext i16 %tmp1 to i32
243   %add = sub nsw i32 %sexttmp, %sexttmp1
244   ret i32 %add
245 }
246
247 ; CHECK-LABEL: Ldurb_merge
248 ; CHECK: ldurh [[NEW_DEST:w[0-9]+]]
249 ; CHECK-DAG: ubfx  [[LO_PART:w[0-9]+]], [[NEW_DEST]], #8, #8
250 ; CHECK-DAG: and [[HI_PART:w[0-9]+]], [[NEW_DEST]], #0xff
251 ; LE: sub {{w[0-9]+}}, [[LO_PART]], [[HI_PART]]
252 ; BE: sub {{w[0-9]+}}, [[HI_PART]], [[LO_PART]]
253 define i32 @Ldurb_merge(i8* %p) nounwind {
254   %add.ptr0 = getelementptr inbounds i8, i8* %p, i64 -1
255   %tmp = load i8, i8* %add.ptr0
256   %add.ptr = getelementptr inbounds i8, i8* %p, i64 -2
257   %tmp1 = load i8, i8* %add.ptr
258   %sexttmp = zext i8 %tmp to i32
259   %sexttmp1 = zext i8 %tmp1 to i32
260   %add = sub nsw i32 %sexttmp, %sexttmp1
261   ret i32 %add
262 }
263
264 ; CHECK-LABEL: Ldursb_merge
265 ; CHECK: ldurh [[NEW_DEST:w[0-9]+]]
266 ; CHECK-DAG: sbfx [[LO_PART:w[0-9]+]], [[NEW_DEST]], #8, #8
267 ; CHECK-DAG: sxtb [[HI_PART:w[0-9]+]], [[NEW_DEST]]
268 ; LE: sub {{w[0-9]+}}, [[LO_PART]], [[HI_PART]]
269 ; BE: sub {{w[0-9]+}}, [[HI_PART]], [[LO_PART]]
270 define i32 @Ldursb_merge(i8* %p) nounwind {
271   %add.ptr0 = getelementptr inbounds i8, i8* %p, i64 -1
272   %tmp = load i8, i8* %add.ptr0
273   %add.ptr = getelementptr inbounds i8, i8* %p, i64 -2
274   %tmp1 = load i8, i8* %add.ptr
275   %sexttmp = sext i8 %tmp to i32
276   %sexttmp1 = sext i8 %tmp1 to i32
277   %add = sub nsw i32 %sexttmp, %sexttmp1
278   ret i32 %add
279 }
280
281 ; CHECK-LABEL: Ldursb_zsext_merge
282 ; CHECK: ldurh [[NEW_DEST:w[0-9]+]]
283 ; LE-DAG: ubfx [[LO_PART:w[0-9]+]], [[NEW_DEST]], #8, #8
284 ; LE-DAG: sxtb [[HI_PART:w[0-9]+]], [[NEW_DEST]]
285 ; BE-DAG: sbfx [[LO_PART:w[0-9]+]], [[NEW_DEST]], #8, #8
286 ; BE-DAG: and [[HI_PART:w[0-9]+]], [[NEW_DEST]], #0xff
287 ; LE: sub {{w[0-9]+}}, [[LO_PART]], [[HI_PART]]
288 ; BE: sub {{w[0-9]+}}, [[HI_PART]], [[LO_PART]]
289 define i32 @Ldursb_zsext_merge(i8* %p) nounwind {
290   %add.ptr0 = getelementptr inbounds i8, i8* %p, i64 -1
291   %tmp = load i8, i8* %add.ptr0
292   %add.ptr = getelementptr inbounds i8, i8* %p, i64 -2
293   %tmp1 = load i8, i8* %add.ptr
294   %sexttmp = zext i8 %tmp to i32
295   %sexttmp1 = sext i8 %tmp1 to i32
296   %add = sub nsw i32 %sexttmp, %sexttmp1
297   ret i32 %add
298 }
299
300 ; CHECK-LABEL: Ldursb_szext_merge
301 ; CHECK: ldurh [[NEW_DEST:w[0-9]+]]
302 ; LE-DAG: sbfx [[LO_PART:w[0-9]+]], [[NEW_DEST]], #8, #8
303 ; LE-DAG: and [[HI_PART:w[0-9]+]], [[NEW_DEST]], #0xff
304 ; BE-DAG: ubfx [[LO_PART:w[0-9]+]], [[NEW_DEST]], #8, #8
305 ; BE-DAG: sxtb [[HI_PART:w[0-9]+]], [[NEW_DEST]]
306 ; LE: sub {{w[0-9]+}}, [[LO_PART]], [[HI_PART]]
307 ; BE: sub {{w[0-9]+}}, [[HI_PART]], [[LO_PART]]
308 define i32 @Ldursb_szext_merge(i8* %p) nounwind {
309   %add.ptr0 = getelementptr inbounds i8, i8* %p, i64 -1
310   %tmp = load i8, i8* %add.ptr0
311   %add.ptr = getelementptr inbounds i8, i8* %p, i64 -2
312   %tmp1 = load i8, i8* %add.ptr
313   %sexttmp = sext i8 %tmp to i32
314   %sexttmp1 = zext i8 %tmp1 to i32
315   %add = sub nsw i32 %sexttmp, %sexttmp1
316   ret i32 %add
317 }
318
319 ; CHECK-LABEL: Strh_zero
320 ; CHECK: str wzr
321 define void @Strh_zero(i16* nocapture %P, i32 %n) {
322 entry:
323  %idxprom = sext i32 %n to i64
324   %arrayidx = getelementptr inbounds i16, i16* %P, i64 %idxprom
325  store i16 0, i16* %arrayidx
326   %add = add nsw i32 %n, 1
327   %idxprom1 = sext i32 %add to i64
328   %arrayidx2 = getelementptr inbounds i16, i16* %P, i64 %idxprom1
329   store i16 0, i16* %arrayidx2
330   ret void
331 }
332
333 ; CHECK-LABEL: Strh_zero_4
334 ; CHECK: stp wzr, wzr
335 define void @Strh_zero_4(i16* nocapture %P, i32 %n) {
336 entry:
337   %idxprom = sext i32 %n to i64
338   %arrayidx = getelementptr inbounds i16, i16* %P, i64 %idxprom
339   store i16 0, i16* %arrayidx
340   %add = add nsw i32 %n, 1
341   %idxprom1 = sext i32 %add to i64
342   %arrayidx2 = getelementptr inbounds i16, i16* %P, i64 %idxprom1
343   store i16 0, i16* %arrayidx2
344   %add3 = add nsw i32 %n, 2
345   %idxprom4 = sext i32 %add3 to i64
346   %arrayidx5 = getelementptr inbounds i16, i16* %P, i64 %idxprom4
347   store i16 0, i16* %arrayidx5
348   %add6 = add nsw i32 %n, 3
349   %idxprom7 = sext i32 %add6 to i64
350   %arrayidx8 = getelementptr inbounds i16, i16* %P, i64 %idxprom7
351   store i16 0, i16* %arrayidx8
352   ret void
353 }
354
355 ; CHECK-LABEL: Sturb_zero
356 ; CHECK: sturh wzr
357 define void @Sturb_zero(i8* nocapture %P, i32 %n) #0 {
358 entry:
359   %sub = add nsw i32 %n, -2
360   %idxprom = sext i32 %sub to i64
361   %arrayidx = getelementptr inbounds i8, i8* %P, i64 %idxprom
362   store i8 0, i8* %arrayidx
363   %sub2= add nsw i32 %n, -1
364   %idxprom1 = sext i32 %sub2 to i64
365   %arrayidx2 = getelementptr inbounds i8, i8* %P, i64 %idxprom1
366   store i8 0, i8* %arrayidx2
367   ret void
368 }
369
370 ; CHECK-LABEL: Sturh_zero
371 ; CHECK: stur wzr
372 define void @Sturh_zero(i16* nocapture %P, i32 %n) {
373 entry:
374   %sub = add nsw i32 %n, -2
375   %idxprom = sext i32 %sub to i64
376   %arrayidx = getelementptr inbounds i16, i16* %P, i64 %idxprom
377   store i16 0, i16* %arrayidx
378   %sub1 = add nsw i32 %n, -3
379   %idxprom2 = sext i32 %sub1 to i64
380   %arrayidx3 = getelementptr inbounds i16, i16* %P, i64 %idxprom2
381   store i16 0, i16* %arrayidx3
382   ret void
383 }
384
385 ; CHECK-LABEL: Sturh_zero_4
386 ; CHECK: stp wzr, wzr
387 define void @Sturh_zero_4(i16* nocapture %P, i32 %n) {
388 entry:
389   %sub = add nsw i32 %n, -3
390   %idxprom = sext i32 %sub to i64
391   %arrayidx = getelementptr inbounds i16, i16* %P, i64 %idxprom
392   store i16 0, i16* %arrayidx
393   %sub1 = add nsw i32 %n, -4
394   %idxprom2 = sext i32 %sub1 to i64
395   %arrayidx3 = getelementptr inbounds i16, i16* %P, i64 %idxprom2
396   store i16 0, i16* %arrayidx3
397   %sub4 = add nsw i32 %n, -2
398   %idxprom5 = sext i32 %sub4 to i64
399   %arrayidx6 = getelementptr inbounds i16, i16* %P, i64 %idxprom5
400   store i16 0, i16* %arrayidx6
401   %sub7 = add nsw i32 %n, -1
402   %idxprom8 = sext i32 %sub7 to i64
403   %arrayidx9 = getelementptr inbounds i16, i16* %P, i64 %idxprom8
404   store i16 0, i16* %arrayidx9
405   ret void
406 }