Files
clang-p2996/llvm/test/CodeGen/AArch64/load.ll
Sander de Smalen 61510b51c3 Revert "[AArch64] Enable subreg liveness tracking by default."
This reverts commit 9c319d5bb4.

Some issues were discovered with the bootstrap builds, which
seem like they were caused by this commit. I'm reverting to investigate.
2024-12-12 17:22:15 +00:00

482 lines
12 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
; RUN: llc -mtriple=aarch64-none-linux-gnu %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-SD
; RUN: llc -mtriple=aarch64-none-linux-gnu -global-isel %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-GI
; ===== Legal Scalars =====
define i8 @load_i8(ptr %ptr) {
; CHECK-LABEL: load_i8:
; CHECK: // %bb.0:
; CHECK-NEXT: ldrb w0, [x0]
; CHECK-NEXT: ret
%a = load i8, ptr %ptr
ret i8 %a
}
define i16 @load_i8_s16(ptr %ptr) {
; CHECK-LABEL: load_i8_s16:
; CHECK: // %bb.0:
; CHECK-NEXT: ldrsb w0, [x0]
; CHECK-NEXT: ret
%a = load i8, ptr %ptr
%s = sext i8 %a to i16
ret i16 %s
}
define i16 @load_i8_u16(ptr %ptr) {
; CHECK-LABEL: load_i8_u16:
; CHECK: // %bb.0:
; CHECK-NEXT: ldrb w0, [x0]
; CHECK-NEXT: ret
%a = load i8, ptr %ptr
%s = zext i8 %a to i16
ret i16 %s
}
define i32 @load_i8_s32(ptr %ptr) {
; CHECK-LABEL: load_i8_s32:
; CHECK: // %bb.0:
; CHECK-NEXT: ldrsb w0, [x0]
; CHECK-NEXT: ret
%a = load i8, ptr %ptr
%s = sext i8 %a to i32
ret i32 %s
}
define i32 @load_i8_u32(ptr %ptr) {
; CHECK-LABEL: load_i8_u32:
; CHECK: // %bb.0:
; CHECK-NEXT: ldrb w0, [x0]
; CHECK-NEXT: ret
%a = load i8, ptr %ptr
%s = zext i8 %a to i32
ret i32 %s
}
define i64 @load_i8_s64(ptr %ptr) {
; CHECK-LABEL: load_i8_s64:
; CHECK: // %bb.0:
; CHECK-NEXT: ldrsb x0, [x0]
; CHECK-NEXT: ret
%a = load i8, ptr %ptr
%s = sext i8 %a to i64
ret i64 %s
}
define i64 @load_i8_u64(ptr %ptr) {
; CHECK-LABEL: load_i8_u64:
; CHECK: // %bb.0:
; CHECK-NEXT: ldrb w0, [x0]
; CHECK-NEXT: ret
%a = load i8, ptr %ptr
%s = zext i8 %a to i64
ret i64 %s
}
define i16 @load_i16(ptr %ptr) {
; CHECK-LABEL: load_i16:
; CHECK: // %bb.0:
; CHECK-NEXT: ldrh w0, [x0]
; CHECK-NEXT: ret
%a = load i16, ptr %ptr
ret i16 %a
}
define i32 @load_i16_s32(ptr %ptr) {
; CHECK-LABEL: load_i16_s32:
; CHECK: // %bb.0:
; CHECK-NEXT: ldrsh w0, [x0]
; CHECK-NEXT: ret
%a = load i16, ptr %ptr
%s = sext i16 %a to i32
ret i32 %s
}
define i32 @load_i16_u32(ptr %ptr) {
; CHECK-LABEL: load_i16_u32:
; CHECK: // %bb.0:
; CHECK-NEXT: ldrh w0, [x0]
; CHECK-NEXT: ret
%a = load i16, ptr %ptr
%s = zext i16 %a to i32
ret i32 %s
}
define i64 @load_i16_s64(ptr %ptr) {
; CHECK-LABEL: load_i16_s64:
; CHECK: // %bb.0:
; CHECK-NEXT: ldrsh x0, [x0]
; CHECK-NEXT: ret
%a = load i16, ptr %ptr
%s = sext i16 %a to i64
ret i64 %s
}
define i64 @load_i16_u64(ptr %ptr) {
; CHECK-LABEL: load_i16_u64:
; CHECK: // %bb.0:
; CHECK-NEXT: ldrh w0, [x0]
; CHECK-NEXT: ret
%a = load i16, ptr %ptr
%s = zext i16 %a to i64
ret i64 %s
}
define i32 @load_i32(ptr %ptr) {
; CHECK-LABEL: load_i32:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr w0, [x0]
; CHECK-NEXT: ret
%a = load i32, ptr %ptr
ret i32 %a
}
define i64 @load_i32_s64(ptr %ptr) {
; CHECK-LABEL: load_i32_s64:
; CHECK: // %bb.0:
; CHECK-NEXT: ldrsw x0, [x0]
; CHECK-NEXT: ret
%a = load i32, ptr %ptr
%s = sext i32 %a to i64
ret i64 %s
}
define i64 @load_i32_u64(ptr %ptr) {
; CHECK-LABEL: load_i32_u64:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr w0, [x0]
; CHECK-NEXT: ret
%a = load i32, ptr %ptr
%s = zext i32 %a to i64
ret i64 %s
}
define i64 @load_i64(ptr %ptr) {
; CHECK-LABEL: load_i64:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr x0, [x0]
; CHECK-NEXT: ret
%a = load i64, ptr %ptr
ret i64 %a
}
; ===== Legal Vector Types =====
define <8 x i8> @load_v8i8(ptr %ptr) {
; CHECK-LABEL: load_v8i8:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr d0, [x0]
; CHECK-NEXT: ret
%a = load <8 x i8>, ptr %ptr
ret <8 x i8> %a
}
define <16 x i8> @load_v16i8(ptr %ptr) {
; CHECK-LABEL: load_v16i8:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr q0, [x0]
; CHECK-NEXT: ret
%a = load <16 x i8>, ptr %ptr
ret <16 x i8> %a
}
define <4 x i16> @load_v4i16(ptr %ptr) {
; CHECK-LABEL: load_v4i16:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr d0, [x0]
; CHECK-NEXT: ret
%a = load <4 x i16>, ptr %ptr
ret <4 x i16> %a
}
define <8 x i16> @load_v8i16(ptr %ptr) {
; CHECK-LABEL: load_v8i16:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr q0, [x0]
; CHECK-NEXT: ret
%a = load <8 x i16>, ptr %ptr
ret <8 x i16> %a
}
define <2 x i32> @load_v2i32(ptr %ptr) {
; CHECK-LABEL: load_v2i32:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr d0, [x0]
; CHECK-NEXT: ret
%a = load <2 x i32>, ptr %ptr
ret <2 x i32> %a
}
define <4 x i32> @load_v4i32(ptr %ptr) {
; CHECK-LABEL: load_v4i32:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr q0, [x0]
; CHECK-NEXT: ret
%a = load <4 x i32>, ptr %ptr
ret <4 x i32> %a
}
define <2 x i64> @load_v2i64(ptr %ptr) {
; CHECK-LABEL: load_v2i64:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr q0, [x0]
; CHECK-NEXT: ret
%a = load <2 x i64>, ptr %ptr
ret <2 x i64> %a
}
; ===== Smaller/Larger Width Vectors with Legal Element Sizes =====
define <2 x i8> @load_v2i8(ptr %ptr, <2 x i8> %b) {
; CHECK-SD-LABEL: load_v2i8:
; CHECK-SD: // %bb.0:
; CHECK-SD-NEXT: ld1 { v0.b }[0], [x0]
; CHECK-SD-NEXT: add x8, x0, #1
; CHECK-SD-NEXT: ld1 { v0.b }[4], [x8]
; CHECK-SD-NEXT: // kill: def $d0 killed $d0 killed $q0
; CHECK-SD-NEXT: ret
;
; CHECK-GI-LABEL: load_v2i8:
; CHECK-GI: // %bb.0:
; CHECK-GI-NEXT: ld1 { v0.b }[0], [x0]
; CHECK-GI-NEXT: ldr b1, [x0, #1]
; CHECK-GI-NEXT: mov v0.s[1], v1.s[0]
; CHECK-GI-NEXT: // kill: def $d0 killed $d0 killed $q0
; CHECK-GI-NEXT: ret
%a = load <2 x i8>, ptr %ptr
ret <2 x i8> %a
}
define i32 @load_v4i8(ptr %ptr, <4 x i8> %b) {
; CHECK-LABEL: load_v4i8:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr w0, [x0]
; CHECK-NEXT: ret
%a = load <4 x i8>, ptr %ptr
%c = bitcast <4 x i8> %a to i32
ret i32 %c
}
define <32 x i8> @load_v32i8(ptr %ptr) {
; CHECK-LABEL: load_v32i8:
; CHECK: // %bb.0:
; CHECK-NEXT: ldp q0, q1, [x0]
; CHECK-NEXT: ret
%a = load <32 x i8>, ptr %ptr
ret <32 x i8> %a
}
define <2 x i16> @load_v2i16(ptr %ptr) {
; CHECK-SD-LABEL: load_v2i16:
; CHECK-SD: // %bb.0:
; CHECK-SD-NEXT: ld1 { v0.h }[0], [x0]
; CHECK-SD-NEXT: add x8, x0, #2
; CHECK-SD-NEXT: ld1 { v0.h }[2], [x8]
; CHECK-SD-NEXT: // kill: def $d0 killed $d0 killed $q0
; CHECK-SD-NEXT: ret
;
; CHECK-GI-LABEL: load_v2i16:
; CHECK-GI: // %bb.0:
; CHECK-GI-NEXT: ld1 { v0.h }[0], [x0]
; CHECK-GI-NEXT: ldr h1, [x0, #2]
; CHECK-GI-NEXT: mov v0.s[1], v1.s[0]
; CHECK-GI-NEXT: // kill: def $d0 killed $d0 killed $q0
; CHECK-GI-NEXT: ret
%a = load <2 x i16>, ptr %ptr
ret <2 x i16> %a
}
define <16 x i16> @load_v16i16(ptr %ptr) {
; CHECK-LABEL: load_v16i16:
; CHECK: // %bb.0:
; CHECK-NEXT: ldp q0, q1, [x0]
; CHECK-NEXT: ret
%a = load <16 x i16>, ptr %ptr
ret <16 x i16> %a
}
define <1 x i32> @load_v1i32(ptr %ptr) {
; CHECK-LABEL: load_v1i32:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr s0, [x0]
; CHECK-NEXT: ret
%a = load <1 x i32>, ptr %ptr
ret <1 x i32> %a
}
define <8 x i32> @load_v8i32(ptr %ptr) {
; CHECK-LABEL: load_v8i32:
; CHECK: // %bb.0:
; CHECK-NEXT: ldp q0, q1, [x0]
; CHECK-NEXT: ret
%a = load <8 x i32>, ptr %ptr
ret <8 x i32> %a
}
define <4 x i64> @load_v4i64(ptr %ptr) {
; CHECK-LABEL: load_v4i64:
; CHECK: // %bb.0:
; CHECK-NEXT: ldp q0, q1, [x0]
; CHECK-NEXT: ret
%a = load <4 x i64>, ptr %ptr
ret <4 x i64> %a
}
; ===== Vectors with Non-Pow 2 Widths =====
define <3 x i8> @load_v3i8(ptr %ptr) {
; CHECK-SD-LABEL: load_v3i8:
; CHECK-SD: // %bb.0:
; CHECK-SD-NEXT: ldr s0, [x0]
; CHECK-SD-NEXT: umov w0, v0.b[0]
; CHECK-SD-NEXT: umov w1, v0.b[1]
; CHECK-SD-NEXT: umov w2, v0.b[2]
; CHECK-SD-NEXT: ret
;
; CHECK-GI-LABEL: load_v3i8:
; CHECK-GI: // %bb.0:
; CHECK-GI-NEXT: ldrb w8, [x0]
; CHECK-GI-NEXT: ldrb w1, [x0, #1]
; CHECK-GI-NEXT: ldrb w2, [x0, #2]
; CHECK-GI-NEXT: mov w0, w8
; CHECK-GI-NEXT: ret
%a = load <3 x i8>, ptr %ptr
ret <3 x i8> %a
}
define <7 x i8> @load_v7i8(ptr %ptr) {
; CHECK-SD-LABEL: load_v7i8:
; CHECK-SD: // %bb.0:
; CHECK-SD-NEXT: ldr d0, [x0]
; CHECK-SD-NEXT: ret
;
; CHECK-GI-LABEL: load_v7i8:
; CHECK-GI: // %bb.0:
; CHECK-GI-NEXT: ldr b0, [x0]
; CHECK-GI-NEXT: ldr b1, [x0, #1]
; CHECK-GI-NEXT: mov v0.b[0], v0.b[0]
; CHECK-GI-NEXT: mov v0.b[1], v1.b[0]
; CHECK-GI-NEXT: ldr b1, [x0, #2]
; CHECK-GI-NEXT: mov v0.b[2], v1.b[0]
; CHECK-GI-NEXT: ldr b1, [x0, #3]
; CHECK-GI-NEXT: mov v0.b[3], v1.b[0]
; CHECK-GI-NEXT: ldr b1, [x0, #4]
; CHECK-GI-NEXT: mov v0.b[4], v1.b[0]
; CHECK-GI-NEXT: ldr b1, [x0, #5]
; CHECK-GI-NEXT: mov v0.b[5], v1.b[0]
; CHECK-GI-NEXT: ldr b1, [x0, #6]
; CHECK-GI-NEXT: mov v0.b[6], v1.b[0]
; CHECK-GI-NEXT: // kill: def $d0 killed $d0 killed $q0
; CHECK-GI-NEXT: ret
%a = load <7 x i8>, ptr %ptr
ret <7 x i8> %a
}
define <3 x i16> @load_v3i16(ptr %ptr) {
; CHECK-SD-LABEL: load_v3i16:
; CHECK-SD: // %bb.0:
; CHECK-SD-NEXT: ldr d0, [x0]
; CHECK-SD-NEXT: ret
;
; CHECK-GI-LABEL: load_v3i16:
; CHECK-GI: // %bb.0:
; CHECK-GI-NEXT: ldr h0, [x0]
; CHECK-GI-NEXT: add x8, x0, #2
; CHECK-GI-NEXT: ld1 { v0.h }[1], [x8]
; CHECK-GI-NEXT: add x8, x0, #4
; CHECK-GI-NEXT: ld1 { v0.h }[2], [x8]
; CHECK-GI-NEXT: // kill: def $d0 killed $d0 killed $q0
; CHECK-GI-NEXT: ret
%a = load <3 x i16>, ptr %ptr
ret <3 x i16> %a
}
define <7 x i16> @load_v7i16(ptr %ptr) {
; CHECK-SD-LABEL: load_v7i16:
; CHECK-SD: // %bb.0:
; CHECK-SD-NEXT: ldr q0, [x0]
; CHECK-SD-NEXT: ret
;
; CHECK-GI-LABEL: load_v7i16:
; CHECK-GI: // %bb.0:
; CHECK-GI-NEXT: ldr h0, [x0]
; CHECK-GI-NEXT: add x8, x0, #2
; CHECK-GI-NEXT: ld1 { v0.h }[1], [x8]
; CHECK-GI-NEXT: add x8, x0, #4
; CHECK-GI-NEXT: ld1 { v0.h }[2], [x8]
; CHECK-GI-NEXT: add x8, x0, #6
; CHECK-GI-NEXT: ld1 { v0.h }[3], [x8]
; CHECK-GI-NEXT: add x8, x0, #8
; CHECK-GI-NEXT: ld1 { v0.h }[4], [x8]
; CHECK-GI-NEXT: add x8, x0, #10
; CHECK-GI-NEXT: ld1 { v0.h }[5], [x8]
; CHECK-GI-NEXT: add x8, x0, #12
; CHECK-GI-NEXT: ld1 { v0.h }[6], [x8]
; CHECK-GI-NEXT: ret
%a = load <7 x i16>, ptr %ptr
ret <7 x i16> %a
}
define <3 x i32> @load_v3i32(ptr %ptr) {
; CHECK-SD-LABEL: load_v3i32:
; CHECK-SD: // %bb.0:
; CHECK-SD-NEXT: ldr q0, [x0]
; CHECK-SD-NEXT: ret
;
; CHECK-GI-LABEL: load_v3i32:
; CHECK-GI: // %bb.0:
; CHECK-GI-NEXT: ldr s0, [x0]
; CHECK-GI-NEXT: add x8, x0, #4
; CHECK-GI-NEXT: ld1 { v0.s }[1], [x8]
; CHECK-GI-NEXT: add x8, x0, #8
; CHECK-GI-NEXT: ld1 { v0.s }[2], [x8]
; CHECK-GI-NEXT: ret
%a = load <3 x i32>, ptr %ptr
ret <3 x i32> %a
}
define <2 x i128> @load_v2i128(ptr %p) {
; CHECK-SD-LABEL: load_v2i128:
; CHECK-SD: // %bb.0:
; CHECK-SD-NEXT: ldp x8, x1, [x0]
; CHECK-SD-NEXT: ldp x2, x3, [x0, #16]
; CHECK-SD-NEXT: mov x0, x8
; CHECK-SD-NEXT: ret
;
; CHECK-GI-LABEL: load_v2i128:
; CHECK-GI: // %bb.0:
; CHECK-GI-NEXT: ldp q0, q1, [x0]
; CHECK-GI-NEXT: mov d2, v0.d[1]
; CHECK-GI-NEXT: mov d3, v1.d[1]
; CHECK-GI-NEXT: fmov x0, d0
; CHECK-GI-NEXT: fmov x2, d1
; CHECK-GI-NEXT: fmov x1, d2
; CHECK-GI-NEXT: fmov x3, d3
; CHECK-GI-NEXT: ret
%a = load <2 x i128>, ptr %p
ret <2 x i128> %a
}
define <2 x fp128> @load_v2f128(ptr %p) {
; CHECK-LABEL: load_v2f128:
; CHECK: // %bb.0:
; CHECK-NEXT: ldp q0, q1, [x0]
; CHECK-NEXT: ret
%a = load <2 x fp128>, ptr %p
ret <2 x fp128> %a
}
define i32 @load_i8_s16_extrasuse(ptr %ptr, ptr %ptr2) {
; CHECK-LABEL: load_i8_s16_extrasuse:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr w8, [x0]
; CHECK-NEXT: sxtb w0, w8
; CHECK-NEXT: str w8, [x1]
; CHECK-NEXT: ret
%a = load i32, ptr %ptr
%s = shl i32 %a, 24
%b = ashr i32 %s, 24
store i32 %a, ptr %ptr2
ret i32 %b
}