@@ -210,24 +210,108 @@ define void @t17(i64 %a) {
210
210
ret void
211
211
}
212
212
213
- define i32 @LdOffset_i8 (ptr %a ) {
213
+ ; LDRBBroX
214
+ define i8 @LdOffset_i8 (ptr %a ) {
214
215
; CHECK-LABEL: LdOffset_i8:
215
216
; CHECK: // %bb.0:
216
217
; CHECK-NEXT: mov w8, #56952 // =0xde78
217
218
; CHECK-NEXT: movk w8, #15, lsl #16
218
219
; CHECK-NEXT: ldrb w0, [x0, x8]
220
+ ; CHECK-NEXT: ret
221
+ %arrayidx = getelementptr inbounds i8 , ptr %a , i64 1039992
222
+ %val = load i8 , ptr %arrayidx , align 1
223
+ ret i8 %val
224
+ }
225
+
226
+ ; LDRBBroX
227
+ define i32 @LdOffset_i8_zext32 (ptr %a ) {
228
+ ; CHECK-LABEL: LdOffset_i8_zext32:
229
+ ; CHECK: // %bb.0:
230
+ ; CHECK-NEXT: mov w8, #56952 // =0xde78
231
+ ; CHECK-NEXT: movk w8, #15, lsl #16
232
+ ; CHECK-NEXT: ldrb w0, [x0, x8]
219
233
; CHECK-NEXT: ret
220
234
%arrayidx = getelementptr inbounds i8 , ptr %a , i64 1039992
221
235
%val = load i8 , ptr %arrayidx , align 1
222
236
%conv = zext i8 %val to i32
223
237
ret i32 %conv
224
238
}
225
239
226
- define i32 @LdOffset_i16 (ptr %a ) {
240
+ ; LDRSBWroX
241
+ define i32 @LdOffset_i8_sext32 (ptr %a ) {
242
+ ; CHECK-LABEL: LdOffset_i8_sext32:
243
+ ; CHECK: // %bb.0:
244
+ ; CHECK-NEXT: mov w8, #56952 // =0xde78
245
+ ; CHECK-NEXT: movk w8, #15, lsl #16
246
+ ; CHECK-NEXT: ldrsb w0, [x0, x8]
247
+ ; CHECK-NEXT: ret
248
+ %arrayidx = getelementptr inbounds i8 , ptr %a , i64 1039992
249
+ %val = load i8 , ptr %arrayidx , align 1
250
+ %conv = sext i8 %val to i32
251
+ ret i32 %conv
252
+ }
253
+
254
+ ; LDRBBroX
255
+ define i64 @LdOffset_i8_zext64 (ptr %a ) {
256
+ ; CHECK-LABEL: LdOffset_i8_zext64:
257
+ ; CHECK: // %bb.0:
258
+ ; CHECK-NEXT: mov w8, #56952 // =0xde78
259
+ ; CHECK-NEXT: movk w8, #15, lsl #16
260
+ ; CHECK-NEXT: ldrb w0, [x0, x8]
261
+ ; CHECK-NEXT: ret
262
+ %arrayidx = getelementptr inbounds i8 , ptr %a , i64 1039992
263
+ %val = load i8 , ptr %arrayidx , align 1
264
+ %conv = zext i8 %val to i64
265
+ ret i64 %conv
266
+ }
267
+
268
+ ; LDRSBXroX
269
+ define i64 @LdOffset_i8_sext64 (ptr %a ) {
270
+ ; CHECK-LABEL: LdOffset_i8_sext64:
271
+ ; CHECK: // %bb.0:
272
+ ; CHECK-NEXT: mov w8, #56952 // =0xde78
273
+ ; CHECK-NEXT: movk w8, #15, lsl #16
274
+ ; CHECK-NEXT: ldrsb x0, [x0, x8]
275
+ ; CHECK-NEXT: ret
276
+ %arrayidx = getelementptr inbounds i8 , ptr %a , i64 1039992
277
+ %val = load i8 , ptr %arrayidx , align 1
278
+ %conv = sext i8 %val to i64
279
+ ret i64 %conv
280
+ }
281
+
282
+ ; LDRHHroX
283
+ define i16 @LdOffset_i16 (ptr %a ) {
227
284
; CHECK-LABEL: LdOffset_i16:
228
285
; CHECK: // %bb.0:
229
286
; CHECK-NEXT: mov w8, #48368 // =0xbcf0
230
287
; CHECK-NEXT: movk w8, #31, lsl #16
288
+ ; CHECK-NEXT: ldrh w0, [x0, x8]
289
+ ; CHECK-NEXT: ret
290
+ %arrayidx = getelementptr inbounds i16 , ptr %a , i64 1039992
291
+ %val = load i16 , ptr %arrayidx , align 2
292
+ ret i16 %val
293
+ }
294
+
295
+ ; LDRHHroX
296
+ define i32 @LdOffset_i16_zext32 (ptr %a ) {
297
+ ; CHECK-LABEL: LdOffset_i16_zext32:
298
+ ; CHECK: // %bb.0:
299
+ ; CHECK-NEXT: mov w8, #48368 // =0xbcf0
300
+ ; CHECK-NEXT: movk w8, #31, lsl #16
301
+ ; CHECK-NEXT: ldrh w0, [x0, x8]
302
+ ; CHECK-NEXT: ret
303
+ %arrayidx = getelementptr inbounds i16 , ptr %a , i64 1039992
304
+ %val = load i16 , ptr %arrayidx , align 2
305
+ %conv = zext i16 %val to i32
306
+ ret i32 %conv
307
+ }
308
+
309
+ ; LDRSHWroX
310
+ define i32 @LdOffset_i16_sext32 (ptr %a ) {
311
+ ; CHECK-LABEL: LdOffset_i16_sext32:
312
+ ; CHECK: // %bb.0:
313
+ ; CHECK-NEXT: mov w8, #48368 // =0xbcf0
314
+ ; CHECK-NEXT: movk w8, #31, lsl #16
231
315
; CHECK-NEXT: ldrsh w0, [x0, x8]
232
316
; CHECK-NEXT: ret
233
317
%arrayidx = getelementptr inbounds i16 , ptr %a , i64 1039992
@@ -236,6 +320,35 @@ define i32 @LdOffset_i16(ptr %a) {
236
320
ret i32 %conv
237
321
}
238
322
323
+ ; LDRHHroX
324
+ define i64 @LdOffset_i16_zext64 (ptr %a ) {
325
+ ; CHECK-LABEL: LdOffset_i16_zext64:
326
+ ; CHECK: // %bb.0:
327
+ ; CHECK-NEXT: mov w8, #48368 // =0xbcf0
328
+ ; CHECK-NEXT: movk w8, #31, lsl #16
329
+ ; CHECK-NEXT: ldrh w0, [x0, x8]
330
+ ; CHECK-NEXT: ret
331
+ %arrayidx = getelementptr inbounds i16 , ptr %a , i64 1039992
332
+ %val = load i16 , ptr %arrayidx , align 2
333
+ %conv = zext i16 %val to i64
334
+ ret i64 %conv
335
+ }
336
+
337
+ ; LDRSHXroX
338
+ define i64 @LdOffset_i16_sext64 (ptr %a ) {
339
+ ; CHECK-LABEL: LdOffset_i16_sext64:
340
+ ; CHECK: // %bb.0:
341
+ ; CHECK-NEXT: mov w8, #48368 // =0xbcf0
342
+ ; CHECK-NEXT: movk w8, #31, lsl #16
343
+ ; CHECK-NEXT: ldrsh x0, [x0, x8]
344
+ ; CHECK-NEXT: ret
345
+ %arrayidx = getelementptr inbounds i16 , ptr %a , i64 1039992
346
+ %val = load i16 , ptr %arrayidx , align 2
347
+ %conv = sext i16 %val to i64
348
+ ret i64 %conv
349
+ }
350
+
351
+ ; LDRWroX
239
352
define i32 @LdOffset_i32 (ptr %a ) {
240
353
; CHECK-LABEL: LdOffset_i32:
241
354
; CHECK: // %bb.0:
@@ -248,6 +361,133 @@ define i32 @LdOffset_i32(ptr %a) {
248
361
ret i32 %val
249
362
}
250
363
364
+ ; LDRWroX
365
+ define i64 @LdOffset_i32_zext64 (ptr %a ) {
366
+ ; CHECK-LABEL: LdOffset_i32_zext64:
367
+ ; CHECK: // %bb.0:
368
+ ; CHECK-NEXT: mov w8, #31200 // =0x79e0
369
+ ; CHECK-NEXT: movk w8, #63, lsl #16
370
+ ; CHECK-NEXT: ldr w0, [x0, x8]
371
+ ; CHECK-NEXT: ret
372
+ %arrayidx = getelementptr inbounds i32 , ptr %a , i64 1039992
373
+ %val = load i32 , ptr %arrayidx , align 2
374
+ %conv = zext i32 %val to i64
375
+ ret i64 %conv
376
+ }
377
+
378
+ ; LDRSWroX
379
+ define i64 @LdOffset_i32_sext64 (ptr %a ) {
380
+ ; CHECK-LABEL: LdOffset_i32_sext64:
381
+ ; CHECK: // %bb.0:
382
+ ; CHECK-NEXT: mov w8, #31200 // =0x79e0
383
+ ; CHECK-NEXT: movk w8, #63, lsl #16
384
+ ; CHECK-NEXT: ldrsw x0, [x0, x8]
385
+ ; CHECK-NEXT: ret
386
+ %arrayidx = getelementptr inbounds i32 , ptr %a , i64 1039992
387
+ %val = load i32 , ptr %arrayidx , align 2
388
+ %conv = sext i32 %val to i64
389
+ ret i64 %conv
390
+ }
391
+
392
+ ; LDRXroX
393
+ define i64 @LdOffset_i64 (ptr %a ) {
394
+ ; CHECK-LABEL: LdOffset_i64:
395
+ ; CHECK: // %bb.0:
396
+ ; CHECK-NEXT: mov w8, #62400 // =0xf3c0
397
+ ; CHECK-NEXT: movk w8, #126, lsl #16
398
+ ; CHECK-NEXT: ldr x0, [x0, x8]
399
+ ; CHECK-NEXT: ret
400
+ %arrayidx = getelementptr inbounds i64 , ptr %a , i64 1039992
401
+ %val = load i64 , ptr %arrayidx , align 4
402
+ ret i64 %val
403
+ }
404
+
405
+ ; LDRDroX
406
+ define <2 x i32 > @LdOffset_v2i32 (ptr %a ) {
407
+ ; CHECK-LABEL: LdOffset_v2i32:
408
+ ; CHECK: // %bb.0:
409
+ ; CHECK-NEXT: mov w8, #62400 // =0xf3c0
410
+ ; CHECK-NEXT: movk w8, #126, lsl #16
411
+ ; CHECK-NEXT: ldr d0, [x0, x8]
412
+ ; CHECK-NEXT: ret
413
+ %arrayidx = getelementptr inbounds <2 x i32 >, ptr %a , i64 1039992
414
+ %val = load <2 x i32 >, ptr %arrayidx , align 4
415
+ ret <2 x i32 > %val
416
+ }
417
+
418
+ ; LDRQroX
419
+ define <2 x i64 > @LdOffset_v2i64 (ptr %a ) {
420
+ ; CHECK-LABEL: LdOffset_v2i64:
421
+ ; CHECK: // %bb.0:
422
+ ; CHECK-NEXT: mov w8, #59264 // =0xe780
423
+ ; CHECK-NEXT: movk w8, #253, lsl #16
424
+ ; CHECK-NEXT: ldr q0, [x0, x8]
425
+ ; CHECK-NEXT: ret
426
+ %arrayidx = getelementptr inbounds <2 x i64 >, ptr %a , i64 1039992
427
+ %val = load <2 x i64 >, ptr %arrayidx , align 4
428
+ ret <2 x i64 > %val
429
+ }
430
+
431
+ ; LDRSBWroX
432
+ define double @LdOffset_i8_f64 (ptr %a ) {
433
+ ; CHECK-LABEL: LdOffset_i8_f64:
434
+ ; CHECK: // %bb.0:
435
+ ; CHECK-NEXT: mov w8, #56952 // =0xde78
436
+ ; CHECK-NEXT: movk w8, #15, lsl #16
437
+ ; CHECK-NEXT: ldrsb w8, [x0, x8]
438
+ ; CHECK-NEXT: scvtf d0, w8
439
+ ; CHECK-NEXT: ret
440
+ %arrayidx = getelementptr inbounds i8 , ptr %a , i64 1039992
441
+ %val = load i8 , ptr %arrayidx , align 1
442
+ %conv = sitofp i8 %val to double
443
+ ret double %conv
444
+ }
445
+
446
+ ; LDRSHWroX
447
+ define double @LdOffset_i16_f64 (ptr %a ) {
448
+ ; CHECK-LABEL: LdOffset_i16_f64:
449
+ ; CHECK: // %bb.0:
450
+ ; CHECK-NEXT: mov w8, #48368 // =0xbcf0
451
+ ; CHECK-NEXT: movk w8, #31, lsl #16
452
+ ; CHECK-NEXT: ldrsh w8, [x0, x8]
453
+ ; CHECK-NEXT: scvtf d0, w8
454
+ ; CHECK-NEXT: ret
455
+ %arrayidx = getelementptr inbounds i16 , ptr %a , i64 1039992
456
+ %val = load i16 , ptr %arrayidx , align 2
457
+ %conv = sitofp i16 %val to double
458
+ ret double %conv
459
+ }
460
+
461
+ ; LDRSroX
462
+ define double @LdOffset_i32_f64 (ptr %a ) {
463
+ ; CHECK-LABEL: LdOffset_i32_f64:
464
+ ; CHECK: // %bb.0:
465
+ ; CHECK-NEXT: mov w8, #31200 // =0x79e0
466
+ ; CHECK-NEXT: movk w8, #63, lsl #16
467
+ ; CHECK-NEXT: ldr s0, [x0, x8]
468
+ ; CHECK-NEXT: ucvtf d0, d0
469
+ ; CHECK-NEXT: ret
470
+ %arrayidx = getelementptr inbounds i32 , ptr %a , i64 1039992
471
+ %val = load i32 , ptr %arrayidx , align 4
472
+ %conv = uitofp i32 %val to double
473
+ ret double %conv
474
+ }
475
+
476
+ ; LDRDroX
477
+ define double @LdOffset_i64_f64 (ptr %a ) {
478
+ ; CHECK-LABEL: LdOffset_i64_f64:
479
+ ; CHECK: // %bb.0:
480
+ ; CHECK-NEXT: mov w8, #62400 // =0xf3c0
481
+ ; CHECK-NEXT: movk w8, #126, lsl #16
482
+ ; CHECK-NEXT: ldr d0, [x0, x8]
483
+ ; CHECK-NEXT: scvtf d0, d0
484
+ ; CHECK-NEXT: ret
485
+ %arrayidx = getelementptr inbounds i64 , ptr %a , i64 1039992
486
+ %val = load i64 , ptr %arrayidx , align 8
487
+ %conv = sitofp i64 %val to double
488
+ ret double %conv
489
+ }
490
+
251
491
define i64 @LdOffset_i64_multi_offset (ptr %a ) {
252
492
; CHECK-LABEL: LdOffset_i64_multi_offset:
253
493
; CHECK: // %bb.0:
@@ -295,3 +535,27 @@ define i32 @LdOffset_i16_odd_offset(ptr nocapture noundef readonly %a) {
295
535
ret i32 %conv
296
536
}
297
537
538
+ ; Already encoded with a single mov MOVNWi
539
+ define i8 @LdOffset_i8_movnwi (ptr %a ) {
540
+ ; CHECK-LABEL: LdOffset_i8_movnwi:
541
+ ; CHECK: // %bb.0:
542
+ ; CHECK-NEXT: mov w8, #16777215 // =0xffffff
543
+ ; CHECK-NEXT: ldrb w0, [x0, x8]
544
+ ; CHECK-NEXT: ret
545
+ %arrayidx = getelementptr inbounds i8 , ptr %a , i64 16777215
546
+ %val = load i8 , ptr %arrayidx , align 1
547
+ ret i8 %val
548
+ }
549
+
550
+ ; Negative test: the offset is too large to encoded with a add
551
+ define i8 @LdOffset_i8_too_large (ptr %a ) {
552
+ ; CHECK-LABEL: LdOffset_i8_too_large:
553
+ ; CHECK: // %bb.0:
554
+ ; CHECK-NEXT: mov w8, #1 // =0x1
555
+ ; CHECK-NEXT: movk w8, #256, lsl #16
556
+ ; CHECK-NEXT: ldrb w0, [x0, x8]
557
+ ; CHECK-NEXT: ret
558
+ %arrayidx = getelementptr inbounds i8 , ptr %a , i64 16777217
559
+ %val = load i8 , ptr %arrayidx , align 1
560
+ ret i8 %val
561
+ }
0 commit comments