llvm/llvm/test/CodeGen/AArch64/sve2p1-intrinsics-multivec-loads.ll

; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -mtriple=aarch64-linux-gnu -mattr=+sve2p1,+bf16 < %s | FileCheck %s

;;LD2Q

define { <vscale x 16 x i8>, <vscale x 16 x i8> } @ld2q_si_i8_off16(<vscale x 16 x i1> %pg, ptr %addr ) {
; CHECK-LABEL: ld2q_si_i8_off16:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld2q { z0.q, z1.q }, p0/z, [x0, #-16, mul vl]
; CHECK-NEXT:    ret
  %base = getelementptr <vscale x 16 x i8>, ptr %addr, i64 -16
  %base_ptr = bitcast ptr %base to ptr
  %res = call { <vscale x 16 x i8>, <vscale x 16 x i8> } @llvm.aarch64.sve.ld2q.sret.nxv16i8(<vscale x 16 x i1> %pg, ptr %base_ptr);
  ret { <vscale x 16 x i8>, <vscale x 16 x i8> } %res
}

define { <vscale x 16 x i8>, <vscale x 16 x i8> } @ld2q_si_i8_off14(<vscale x 16 x i1> %pg, ptr %addr ) {
; CHECK-LABEL: ld2q_si_i8_off14:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld2q { z0.q, z1.q }, p0/z, [x0, #14, mul vl]
; CHECK-NEXT:    ret
  %base = getelementptr <vscale x 16 x i8>, ptr %addr, i64 14
  %base_ptr = bitcast ptr %base to ptr
  %res = call { <vscale x 16 x i8>, <vscale x 16 x i8> } @llvm.aarch64.sve.ld2q.sret.nxv16i8(<vscale x 16 x i1> %pg, ptr %base_ptr);
  ret { <vscale x 16 x i8>, <vscale x 16 x i8> } %res
}

define { <vscale x 16 x i8>, <vscale x 16 x i8> } @ld2q_ss_i8(<vscale x 16 x i1> %pg,  ptr %addr, i64 %a) {
; CHECK-LABEL: ld2q_ss_i8:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld2q { z0.q, z1.q }, p0/z, [x0, x1, lsl #4]
; CHECK-NEXT:    ret
  %addr2 = getelementptr i128, ptr  %addr, i64 %a
  %res = call { <vscale x 16 x i8>, <vscale x 16 x i8> } @llvm.aarch64.sve.ld2q.sret.nxv16i8(<vscale x 16 x i1> %pg, ptr %addr2);
  ret { <vscale x 16 x i8>, <vscale x 16 x i8> } %res
}

define { <vscale x 16 x i8>, <vscale x 16 x i8> } @ld2q_i8(<vscale x 16 x i1> %pg,  ptr %addr) {
; CHECK-LABEL: ld2q_i8:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld2q { z0.q, z1.q }, p0/z, [x0]
; CHECK-NEXT:    ret
  %res = call { <vscale x 16 x i8>, <vscale x 16 x i8> } @llvm.aarch64.sve.ld2q.sret.nxv16i8(<vscale x 16 x i1> %pg, ptr %addr);
  ret { <vscale x 16 x i8>, <vscale x 16 x i8> } %res
}

define { <vscale x 8 x i16>, <vscale x 8 x i16> } @ld2q_si_i16(<vscale x 8 x i1> %pg, ptr %addr ) {
; CHECK-LABEL: ld2q_si_i16:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld2q { z0.q, z1.q }, p0/z, [x0, #-16, mul vl]
; CHECK-NEXT:    ret
  %base = getelementptr <vscale x 8 x i16>, ptr %addr, i64 -16
  %base_ptr = bitcast ptr %base to ptr
  %res = call { <vscale x 8 x i16>, <vscale x 8 x i16> } @llvm.aarch64.sve.ld2q.sret.nxv8i16(<vscale x 8 x i1> %pg, ptr %base_ptr);
  ret { <vscale x 8 x i16>, <vscale x 8 x i16> } %res
}

define { <vscale x 8 x i16>, <vscale x 8 x i16> } @ld2q_ss_i16(<vscale x 8 x i1> %pg,  ptr %addr, i64 %a) {
; CHECK-LABEL: ld2q_ss_i16:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld2q { z0.q, z1.q }, p0/z, [x0, x1, lsl #4]
; CHECK-NEXT:    ret
  %addr2 = getelementptr i128, ptr  %addr, i64 %a
  %res = call { <vscale x 8 x i16>, <vscale x 8 x i16> } @llvm.aarch64.sve.ld2q.sret.nxv8i16(<vscale x 8 x i1> %pg, ptr %addr2);
  ret { <vscale x 8 x i16>, <vscale x 8 x i16> } %res
}

define { <vscale x 8 x i16>, <vscale x 8 x i16> } @ld2q_i16(<vscale x 8 x i1> %pg,  ptr %addr) {
; CHECK-LABEL: ld2q_i16:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld2q { z0.q, z1.q }, p0/z, [x0]
; CHECK-NEXT:    ret
  %res = call { <vscale x 8 x i16>, <vscale x 8 x i16> } @llvm.aarch64.sve.ld2q.sret.nxv8i16(<vscale x 8 x i1> %pg, ptr %addr);
  ret { <vscale x 8 x i16>, <vscale x 8 x i16> } %res
}

define { <vscale x 4 x i32>, <vscale x 4 x i32> } @ld2q_si_i32(<vscale x 4 x i1> %pg, ptr %addr ) {
; CHECK-LABEL: ld2q_si_i32:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld2q { z0.q, z1.q }, p0/z, [x0, #-16, mul vl]
; CHECK-NEXT:    ret
  %base = getelementptr <vscale x 4 x i32>,  ptr %addr, i64 -16
  %res = call { <vscale x 4 x i32>, <vscale x 4 x i32> } @llvm.aarch64.sve.ld2q.sret.nxv4i32(<vscale x 4 x i1> %pg, ptr %base);
  ret { <vscale x 4 x i32>, <vscale x 4 x i32> } %res
}

define { <vscale x 4 x i32>, <vscale x 4 x i32> } @ld2q_ss_i32(<vscale x 4 x i1> %pg,  ptr %addr, i64 %a) {
; CHECK-LABEL: ld2q_ss_i32:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld2q { z0.q, z1.q }, p0/z, [x0, x1, lsl #4]
; CHECK-NEXT:    ret
  %addr2 = getelementptr i128, ptr  %addr, i64 %a
  %res = call { <vscale x 4 x i32>, <vscale x 4 x i32> } @llvm.aarch64.sve.ld2q.sret.nxv4i32(<vscale x 4 x i1> %pg, ptr %addr2);
  ret { <vscale x 4 x i32>, <vscale x 4 x i32> } %res
}

define { <vscale x 4 x i32>, <vscale x 4 x i32> } @ld2q_i32(<vscale x 4 x i1> %pg,  ptr %addr) {
; CHECK-LABEL: ld2q_i32:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld2q { z0.q, z1.q }, p0/z, [x0]
; CHECK-NEXT:    ret
  %res = call { <vscale x 4 x i32>, <vscale x 4 x i32> } @llvm.aarch64.sve.ld2q.sret.nxv4i32(<vscale x 4 x i1> %pg, ptr %addr);
  ret { <vscale x 4 x i32>, <vscale x 4 x i32> } %res
}

define { <vscale x 2 x i64>, <vscale x 2 x i64> } @ld2q_si_i64(<vscale x 2 x i1> %pg, ptr %addr ) {
; CHECK-LABEL: ld2q_si_i64:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld2q { z0.q, z1.q }, p0/z, [x0, #-16, mul vl]
; CHECK-NEXT:    ret
  %base = getelementptr <vscale x 2 x i64>, ptr %addr, i64 -16
  %base_ptr = bitcast ptr %base to ptr
  %res = call { <vscale x 2 x i64>, <vscale x 2 x i64> } @llvm.aarch64.sve.ld2q.sret.nxv2i64(<vscale x 2 x i1> %pg, ptr %base_ptr);
  ret { <vscale x 2 x i64>, <vscale x 2 x i64> } %res
}

define { <vscale x 2 x i64>, <vscale x 2 x i64> } @ld2q_ss_i64(<vscale x 2 x i1> %pg,  ptr %addr, i64 %a) {
; CHECK-LABEL: ld2q_ss_i64:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld2q { z0.q, z1.q }, p0/z, [x0, x1, lsl #4]
; CHECK-NEXT:    ret
  %addr2 = getelementptr i128, ptr  %addr, i64 %a
  %res = call { <vscale x 2 x i64>, <vscale x 2 x i64> } @llvm.aarch64.sve.ld2q.sret.nxv2i64(<vscale x 2 x i1> %pg, ptr %addr2);
  ret { <vscale x 2 x i64>, <vscale x 2 x i64> } %res
}

define { <vscale x 2 x i64>, <vscale x 2 x i64> } @ld2q_i64(<vscale x 2 x i1> %pg,  ptr %addr) {
; CHECK-LABEL: ld2q_i64:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld2q { z0.q, z1.q }, p0/z, [x0]
; CHECK-NEXT:    ret
  %res = call { <vscale x 2 x i64>, <vscale x 2 x i64> } @llvm.aarch64.sve.ld2q.sret.nxv2i64(<vscale x 2 x i1> %pg, ptr %addr);
  ret { <vscale x 2 x i64>, <vscale x 2 x i64> } %res
}

define { <vscale x 8 x half>, <vscale x 8 x half> } @ld2q_si_f16(<vscale x 8 x i1> %pg, ptr %addr ) {
; CHECK-LABEL: ld2q_si_f16:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld2q { z0.q, z1.q }, p0/z, [x0, #-16, mul vl]
; CHECK-NEXT:    ret
  %base = getelementptr <vscale x 8 x half>, ptr %addr, i64 -16
  %base_ptr = bitcast ptr %base to ptr
  %res = call { <vscale x 8 x half>, <vscale x 8 x half> } @llvm.aarch64.sve.ld2q.sret.nxv8f16(<vscale x 8 x i1> %pg, ptr %base_ptr);
  ret { <vscale x 8 x half>, <vscale x 8 x half> } %res
}

define { <vscale x 8 x half>, <vscale x 8 x half> } @ld2q_ss_f16(<vscale x 8 x i1> %pg,  ptr %addr, i64 %a) {
; CHECK-LABEL: ld2q_ss_f16:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld2q { z0.q, z1.q }, p0/z, [x0, x1, lsl #4]
; CHECK-NEXT:    ret
  %addr2 = getelementptr i128, ptr  %addr, i64 %a
  %res = call { <vscale x 8 x half>, <vscale x 8 x half> } @llvm.aarch64.sve.ld2q.sret.nxv8f16(<vscale x 8 x i1> %pg, ptr %addr2);
  ret { <vscale x 8 x half>, <vscale x 8 x half> } %res
}

define { <vscale x 8 x half>, <vscale x 8 x half> } @ld2q_f16(<vscale x 8 x i1> %pg,  ptr %addr) {
; CHECK-LABEL: ld2q_f16:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld2q { z0.q, z1.q }, p0/z, [x0]
; CHECK-NEXT:    ret
  %res = call { <vscale x 8 x half>, <vscale x 8 x half> } @llvm.aarch64.sve.ld2q.sret.nxv8f16(<vscale x 8 x i1> %pg, ptr %addr);
  ret { <vscale x 8 x half>, <vscale x 8 x half> } %res
}

define { <vscale x 4 x float>, <vscale x 4 x float> } @ld2q_si_f32(<vscale x 4 x i1> %pg, ptr %addr ) {
; CHECK-LABEL: ld2q_si_f32:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld2q { z0.q, z1.q }, p0/z, [x0, #-16, mul vl]
; CHECK-NEXT:    ret
 %base = getelementptr <vscale x 4 x float>, ptr %addr, i64 -16
  %base_ptr = bitcast ptr %base to ptr
  %res = call { <vscale x 4 x float>, <vscale x 4 x float> } @llvm.aarch64.sve.ld2q.sret.nxv4f32(<vscale x 4 x i1> %pg, ptr %base_ptr);
  ret { <vscale x 4 x float>, <vscale x 4 x float> } %res
}

define { <vscale x 4 x float>, <vscale x 4 x float> } @ld2q_ss_f32(<vscale x 4 x i1> %pg,  ptr %addr, i64 %a) {
; CHECK-LABEL: ld2q_ss_f32:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld2q { z0.q, z1.q }, p0/z, [x0, x1, lsl #4]
; CHECK-NEXT:    ret
  %addr2 = getelementptr i128, ptr  %addr, i64 %a
  %res = call { <vscale x 4 x float>, <vscale x 4 x float> } @llvm.aarch64.sve.ld2q.sret.nxv4f32(<vscale x 4 x i1> %pg, ptr %addr2);
  ret { <vscale x 4 x float>, <vscale x 4 x float> } %res
}

define { <vscale x 4 x float>, <vscale x 4 x float> } @ld2q_f32(<vscale x 4 x i1> %pg,  ptr %addr) {
; CHECK-LABEL: ld2q_f32:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld2q { z0.q, z1.q }, p0/z, [x0]
; CHECK-NEXT:    ret
  %res = call { <vscale x 4 x float>, <vscale x 4 x float> } @llvm.aarch64.sve.ld2q.sret.nxv4f32(<vscale x 4 x i1> %pg, ptr %addr);
  ret { <vscale x 4 x float>, <vscale x 4 x float> } %res
}

define { <vscale x 2 x double>, <vscale x 2 x double> } @ld2q_si_f64(<vscale x 2 x i1> %pg, ptr %addr ) {
; CHECK-LABEL: ld2q_si_f64:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld2q { z0.q, z1.q }, p0/z, [x0, #-16, mul vl]
; CHECK-NEXT:    ret
  %base = getelementptr <vscale x 2 x double>, ptr %addr, i64 -16
  %base_ptr = bitcast ptr %base to ptr
  %res = call { <vscale x 2 x double>, <vscale x 2 x double> } @llvm.aarch64.sve.ld2q.sret.nxv2f64(<vscale x 2 x i1> %pg, ptr %base_ptr);
  ret { <vscale x 2 x double>, <vscale x 2 x double> } %res
}

define { <vscale x 2 x double>, <vscale x 2 x double> } @ld2q_ss_f64(<vscale x 2 x i1> %pg,  ptr %addr, i64 %a) {
; CHECK-LABEL: ld2q_ss_f64:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld2q { z0.q, z1.q }, p0/z, [x0, x1, lsl #4]
; CHECK-NEXT:    ret
  %addr2 = getelementptr i128, ptr  %addr, i64  %a
  %res = call { <vscale x 2 x double>, <vscale x 2 x double> } @llvm.aarch64.sve.ld2q.sret.nxv2f64(<vscale x 2 x i1> %pg, ptr %addr2);
  ret { <vscale x 2 x double>, <vscale x 2 x double> } %res
}

define { <vscale x 2 x double>, <vscale x 2 x double> } @ld2q_f64(<vscale x 2 x i1> %pg,  ptr %addr) {
; CHECK-LABEL: ld2q_f64:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld2q { z0.q, z1.q }, p0/z, [x0]
; CHECK-NEXT:    ret
  %res = call { <vscale x 2 x double>, <vscale x 2 x double> } @llvm.aarch64.sve.ld2q.sret.nxv2f64(<vscale x 2 x i1> %pg, ptr %addr);
  ret { <vscale x 2 x double>, <vscale x 2 x double> } %res
}

define { <vscale x 8 x bfloat>, <vscale x 8 x bfloat> } @ld2q_si_bf16(<vscale x 8 x i1> %pg, ptr %addr ) {
; CHECK-LABEL: ld2q_si_bf16:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld2q { z0.q, z1.q }, p0/z, [x0, #-16, mul vl]
; CHECK-NEXT:    ret
  %base = getelementptr <vscale x 8 x bfloat>, ptr %addr, i64 -16
  %base_ptr = bitcast ptr %base to ptr
  %res = call { <vscale x 8 x bfloat>, <vscale x 8 x bfloat> } @llvm.aarch64.sve.ld2q.sret.nxv8bf16(<vscale x 8 x i1> %pg, ptr %base_ptr);
  ret { <vscale x 8 x bfloat>, <vscale x 8 x bfloat> } %res
}

define { <vscale x 8 x bfloat>, <vscale x 8 x bfloat> } @ld2q_ss_bf16(<vscale x 8 x i1> %pg,  ptr %addr, i64 %a) {
; CHECK-LABEL: ld2q_ss_bf16:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld2q { z0.q, z1.q }, p0/z, [x0, x1, lsl #4]
; CHECK-NEXT:    ret
  %addr2 = getelementptr i128, ptr  %addr, i64 %a
  %res = call { <vscale x 8 x bfloat>, <vscale x 8 x bfloat> } @llvm.aarch64.sve.ld2q.sret.nxv8bf16(<vscale x 8 x i1> %pg, ptr %addr2);
  ret { <vscale x 8 x bfloat>, <vscale x 8 x bfloat> } %res
}

define { <vscale x 8 x bfloat>, <vscale x 8 x bfloat> } @ld2q_bf16(<vscale x 8 x i1> %pg,  ptr %addr) {
; CHECK-LABEL: ld2q_bf16:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld2q { z0.q, z1.q }, p0/z, [x0]
; CHECK-NEXT:    ret
  %res = call { <vscale x 8 x bfloat>, <vscale x 8 x bfloat> } @llvm.aarch64.sve.ld2q.sret.nxv8bf16(<vscale x 8 x i1> %pg, ptr %addr);
  ret { <vscale x 8 x bfloat>, <vscale x 8 x bfloat> } %res
}

;; LD3Q
define { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> } @ld3q_si_i8_off24(<vscale x 16 x i1> %pg, ptr %addr ) {
; CHECK-LABEL: ld3q_si_i8_off24:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld3q { z0.q - z2.q }, p0/z, [x0, #-24, mul vl]
; CHECK-NEXT:    ret
  %base = getelementptr <vscale x 16 x i8>, ptr %addr, i64 -24
  %base_ptr = bitcast ptr %base to ptr
  %res = call { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> } @llvm.aarch64.sve.ld3q.sret.nxv16i8(<vscale x 16 x i1> %pg, ptr %base_ptr);
  ret { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> } %res
}

define { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> } @ld3q_si_i8_off21(<vscale x 16 x i1> %pg, ptr %addr ) {
; CHECK-LABEL: ld3q_si_i8_off21:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld3q { z0.q - z2.q }, p0/z, [x0, #21, mul vl]
; CHECK-NEXT:    ret
  %base = getelementptr <vscale x 16 x i8>, ptr %addr, i64 21
  %base_ptr = bitcast ptr %base to ptr
  %res = call { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> } @llvm.aarch64.sve.ld3q.sret.nxv16i8(<vscale x 16 x i1> %pg, ptr %base_ptr);
  ret { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> } %res
}

define { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> } @ld3q_ss_i8(<vscale x 16 x i1> %pg,  ptr %addr, i64 %a) {
; CHECK-LABEL: ld3q_ss_i8:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld3q { z0.q - z2.q }, p0/z, [x0, x1, lsl #4]
; CHECK-NEXT:    ret
  %addr2 = getelementptr i128, ptr  %addr, i64 %a
  %res = call { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> } @llvm.aarch64.sve.ld3q.sret.nxv16i8(<vscale x 16 x i1> %pg, ptr %addr2);
  ret { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> } %res
}

define { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>} @ld3q_i8(<vscale x 16 x i1> %pg,  ptr %addr) {
; CHECK-LABEL: ld3q_i8:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld3q { z0.q - z2.q }, p0/z, [x0]
; CHECK-NEXT:    ret
  %res = call { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>} @llvm.aarch64.sve.ld3q.sret.nxv16i8(<vscale x 16 x i1> %pg, ptr %addr);
  ret { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>} %res
}

define { <vscale x 8 x i16>, <vscale x 8 x i16>, <vscale x 8 x i16> } @ld3q_si_i16(<vscale x 8 x i1> %pg, ptr %addr ) {
; CHECK-LABEL: ld3q_si_i16:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld3q { z0.q - z2.q }, p0/z, [x0, #-24, mul vl]
; CHECK-NEXT:    ret
  %base = getelementptr <vscale x 8 x i16>, ptr %addr, i64 -24
  %base_ptr = bitcast ptr %base to ptr
  %res = call { <vscale x 8 x i16>, <vscale x 8 x i16>, <vscale x 8 x i16> } @llvm.aarch64.sve.ld3q.sret.nxv8i16(<vscale x 8 x i1> %pg, ptr %base_ptr);
  ret { <vscale x 8 x i16>, <vscale x 8 x i16>, <vscale x 8 x i16> } %res
}

define { <vscale x 8 x i16>, <vscale x 8 x i16>, <vscale x 8 x i16> } @ld3q_ss_i16(<vscale x 8 x i1> %pg,  ptr %addr, i64 %a) {
; CHECK-LABEL: ld3q_ss_i16:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld3q { z0.q - z2.q }, p0/z, [x0, x1, lsl #4]
; CHECK-NEXT:    ret
  %addr2 = getelementptr i128, ptr  %addr, i64 %a
  %res = call { <vscale x 8 x i16>, <vscale x 8 x i16>, <vscale x 8 x i16> } @llvm.aarch64.sve.ld3q.sret.nxv8i16(<vscale x 8 x i1> %pg, ptr %addr2);
  ret { <vscale x 8 x i16>, <vscale x 8 x i16>, <vscale x 8 x i16> } %res
}

define { <vscale x 8 x i16>, <vscale x 8 x i16>, <vscale x 8 x i16> } @ld3q_i16(<vscale x 8 x i1> %pg,  ptr %addr) {
; CHECK-LABEL: ld3q_i16:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld3q { z0.q - z2.q }, p0/z, [x0]
; CHECK-NEXT:    ret
  %res = call { <vscale x 8 x i16>, <vscale x 8 x i16>, <vscale x 8 x i16> } @llvm.aarch64.sve.ld3q.sret.nxv8i16(<vscale x 8 x i1> %pg, ptr %addr);
  ret { <vscale x 8 x i16>, <vscale x 8 x i16>, <vscale x 8 x i16> } %res
}

define { <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32> } @ld3q_si_i32(<vscale x 4 x i1> %pg, ptr %addr ) {
; CHECK-LABEL: ld3q_si_i32:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld3q { z0.q - z2.q }, p0/z, [x0, #-24, mul vl]
; CHECK-NEXT:    ret
  %base = getelementptr <vscale x 4 x i32>, ptr %addr, i64 -24
  %base_ptr = bitcast ptr %base to ptr
  %res = call { <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32> } @llvm.aarch64.sve.ld3q.sret.nxv4i32(<vscale x 4 x i1> %pg, ptr %base_ptr);
  ret { <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32> } %res
}

define { <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32> } @ld3q_ss_i32(<vscale x 4 x i1> %pg,  ptr %addr, i64 %a) {
; CHECK-LABEL: ld3q_ss_i32:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld3q { z0.q - z2.q }, p0/z, [x0, x1, lsl #4]
; CHECK-NEXT:    ret
  %addr2 = getelementptr i128, ptr  %addr, i64 %a
  %res = call { <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32> } @llvm.aarch64.sve.ld3q.sret.nxv4i32(<vscale x 4 x i1> %pg, ptr %addr2);
  ret { <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32> } %res
}

define { <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32> } @ld3q_i32(<vscale x 4 x i1> %pg,  ptr %addr) {
; CHECK-LABEL: ld3q_i32:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld3q { z0.q - z2.q }, p0/z, [x0]
; CHECK-NEXT:    ret
  %res = call { <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32> } @llvm.aarch64.sve.ld3q.sret.nxv4i32(<vscale x 4 x i1> %pg, ptr %addr);
  ret { <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32> } %res
}

define { <vscale x 2 x i64>, <vscale x 2 x i64>, <vscale x 2 x i64> } @ld3q_si_i64(<vscale x 2 x i1> %pg, ptr %addr ) {
; CHECK-LABEL: ld3q_si_i64:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld3q { z0.q - z2.q }, p0/z, [x0, #-24, mul vl]
; CHECK-NEXT:    ret
  %addr2 = getelementptr <vscale x 4 x i32>, ptr  %addr, i64 -24
  %res = call { <vscale x 2 x i64>, <vscale x 2 x i64>, <vscale x 2 x i64> } @llvm.aarch64.sve.ld3q.sret.nxv2i64(<vscale x 2 x i1> %pg, ptr %addr2);
  ret  {<vscale x 2 x i64>, <vscale x 2 x i64>, <vscale x 2 x i64> } %res
}

define { <vscale x 2 x i64>, <vscale x 2 x i64>, <vscale x 2 x i64> } @ld3q_ss_i64(<vscale x 2 x i1> %pg,  ptr %addr, i64 %a) {
; CHECK-LABEL: ld3q_ss_i64:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld3q { z0.q - z2.q }, p0/z, [x0, x1, lsl #4]
; CHECK-NEXT:    ret
  %addr2 = getelementptr i128, ptr  %addr, i64 %a
  %res = call { <vscale x 2 x i64>, <vscale x 2 x i64>, <vscale x 2 x i64> } @llvm.aarch64.sve.ld3q.sret.nxv2i64(<vscale x 2 x i1> %pg, ptr %addr2);
  ret { <vscale x 2 x i64>, <vscale x 2 x i64>, <vscale x 2 x i64> } %res
}

define { <vscale x 2 x i64>, <vscale x 2 x i64>, <vscale x 2 x i64> } @ld3q_i64(<vscale x 2 x i1> %pg,  ptr %addr) {
; CHECK-LABEL: ld3q_i64:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld3q { z0.q - z2.q }, p0/z, [x0]
; CHECK-NEXT:    ret
  %res = call { <vscale x 2 x i64>, <vscale x 2 x i64>, <vscale x 2 x i64> } @llvm.aarch64.sve.ld3q.sret.nxv2i64(<vscale x 2 x i1> %pg, ptr %addr);
  ret { <vscale x 2 x i64>, <vscale x 2 x i64>, <vscale x 2 x i64> } %res
}

define { <vscale x 8 x half>, <vscale x 8 x half>, <vscale x 8 x half> } @ld3q_si_f16(<vscale x 8 x i1> %pg, ptr %addr ) {
; CHECK-LABEL: ld3q_si_f16:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld3q { z0.q - z2.q }, p0/z, [x0, #-24, mul vl]
; CHECK-NEXT:    ret
  %base = getelementptr <vscale x 8 x half>, ptr %addr, i64 -24
  %base_ptr = bitcast ptr %base to ptr
  %res = call { <vscale x 8 x half>, <vscale x 8 x half>, <vscale x 8 x half> } @llvm.aarch64.sve.ld3q.sret.nxv8f16(<vscale x 8 x i1> %pg, ptr %base_ptr);
  ret { <vscale x 8 x half>, <vscale x 8 x half>, <vscale x 8 x half> } %res
}

define { <vscale x 8 x half>, <vscale x 8 x half>, <vscale x 8 x half> } @ld3q_ss_f16(<vscale x 8 x i1> %pg,  ptr %addr, i64 %a) {
; CHECK-LABEL: ld3q_ss_f16:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld3q { z0.q - z2.q }, p0/z, [x0, x1, lsl #4]
; CHECK-NEXT:    ret
  %addr2 = getelementptr i128, ptr  %addr, i64 %a
  %res = call { <vscale x 8 x half>, <vscale x 8 x half>, <vscale x 8 x half> } @llvm.aarch64.sve.ld3q.sret.nxv8f16(<vscale x 8 x i1> %pg, ptr %addr2);
  ret { <vscale x 8 x half>, <vscale x 8 x half>, <vscale x 8 x half> } %res
}

define { <vscale x 8 x half>, <vscale x 8 x half>, <vscale x 8 x half> } @ld3q_f16(<vscale x 8 x i1> %pg,  ptr %addr) {
; CHECK-LABEL: ld3q_f16:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld3q { z0.q - z2.q }, p0/z, [x0]
; CHECK-NEXT:    ret
  %res = call { <vscale x 8 x half>, <vscale x 8 x half>, <vscale x 8 x half> } @llvm.aarch64.sve.ld3q.sret.nxv8f16(<vscale x 8 x i1> %pg, ptr %addr);
  ret { <vscale x 8 x half>, <vscale x 8 x half>, <vscale x 8 x half> } %res
}

define { <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float> } @ld3q_si_f32(<vscale x 4 x i1> %pg, ptr %addr ) {
; CHECK-LABEL: ld3q_si_f32:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld3q { z0.q - z2.q }, p0/z, [x0, #-24, mul vl]
; CHECK-NEXT:    ret
 %base = getelementptr <vscale x 4 x float>, ptr %addr, i64 -24
  %base_ptr = bitcast ptr %base to ptr
  %res = call { <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float> } @llvm.aarch64.sve.ld3q.sret.nxv4f32(<vscale x 4 x i1> %pg, ptr %base_ptr);
  ret { <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float> } %res
}

define { <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float> } @ld3q_ss_f32(<vscale x 4 x i1> %pg,  ptr %addr, i64 %a) {
; CHECK-LABEL: ld3q_ss_f32:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld3q { z0.q - z2.q }, p0/z, [x0, x1, lsl #4]
; CHECK-NEXT:    ret
  %addr2 = getelementptr i128, ptr  %addr, i64 %a
  %res = call { <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float> } @llvm.aarch64.sve.ld3q.sret.nxv4f32(<vscale x 4 x i1> %pg, ptr %addr2);
  ret { <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float> } %res
}

define { <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float> } @ld3q_f32(<vscale x 4 x i1> %pg,  ptr %addr) {
; CHECK-LABEL: ld3q_f32:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld3q { z0.q - z2.q }, p0/z, [x0]
; CHECK-NEXT:    ret
  %res = call { <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float> } @llvm.aarch64.sve.ld3q.sret.nxv4f32(<vscale x 4 x i1> %pg, ptr %addr);
  ret { <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float> } %res
}

define { <vscale x 2 x double>, <vscale x 2 x double>, <vscale x 2 x double> } @ld3q_si_f64(<vscale x 2 x i1> %pg, ptr %addr ) {
; CHECK-LABEL: ld3q_si_f64:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld3q { z0.q - z2.q }, p0/z, [x0, #-24, mul vl]
; CHECK-NEXT:    ret
  %base = getelementptr <vscale x 2 x double>, ptr %addr, i64 -24
  %base_ptr = bitcast ptr %base to ptr
  %res = call { <vscale x 2 x double>, <vscale x 2 x double>, <vscale x 2 x double> } @llvm.aarch64.sve.ld3q.sret.nxv2f64(<vscale x 2 x i1> %pg, ptr %base_ptr);
  ret { <vscale x 2 x double>, <vscale x 2 x double>, <vscale x 2 x double> } %res
}

define { <vscale x 2 x double>, <vscale x 2 x double>, <vscale x 2 x double> } @ld3q_ss_f64(<vscale x 2 x i1> %pg,  ptr %addr, i64 %a) {
; CHECK-LABEL: ld3q_ss_f64:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld3q { z0.q - z2.q }, p0/z, [x0, x1, lsl #4]
; CHECK-NEXT:    ret
  %addr2 = getelementptr i128, ptr  %addr, i64  %a
  %res = call { <vscale x 2 x double>, <vscale x 2 x double>, <vscale x 2 x double> } @llvm.aarch64.sve.ld3q.sret.nxv2f64(<vscale x 2 x i1> %pg, ptr %addr2);
  ret { <vscale x 2 x double>, <vscale x 2 x double>, <vscale x 2 x double> } %res
}

define { <vscale x 2 x double>, <vscale x 2 x double>, <vscale x 2 x double> } @ld3q_f64(<vscale x 2 x i1> %pg,  ptr %addr) {
; CHECK-LABEL: ld3q_f64:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld3q { z0.q - z2.q }, p0/z, [x0]
; CHECK-NEXT:    ret
  %res = call { <vscale x 2 x double>, <vscale x 2 x double>, <vscale x 2 x double> } @llvm.aarch64.sve.ld3q.sret.nxv2f64(<vscale x 2 x i1> %pg, ptr %addr);
  ret { <vscale x 2 x double>, <vscale x 2 x double>, <vscale x 2 x double> } %res
}

define { <vscale x 8 x bfloat>, <vscale x 8 x bfloat>, <vscale x 8 x bfloat> } @ld3q_si_bf16(<vscale x 8 x i1> %pg, ptr %addr ) {
; CHECK-LABEL: ld3q_si_bf16:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld3q { z0.q - z2.q }, p0/z, [x0, #-24, mul vl]
; CHECK-NEXT:    ret
  %base = getelementptr <vscale x 8 x bfloat>, ptr %addr, i64 -24
  %base_ptr = bitcast ptr %base to ptr
  %res = call { <vscale x 8 x bfloat>, <vscale x 8 x bfloat>, <vscale x 8 x bfloat> } @llvm.aarch64.sve.ld3q.sret.nxv8bf16(<vscale x 8 x i1> %pg, ptr %base_ptr);
  ret { <vscale x 8 x bfloat>, <vscale x 8 x bfloat>, <vscale x 8 x bfloat> } %res
}

define { <vscale x 8 x bfloat>, <vscale x 8 x bfloat>, <vscale x 8 x bfloat> } @ld3q_ss_bf16(<vscale x 8 x i1> %pg,  ptr %addr, i64 %a) {
; CHECK-LABEL: ld3q_ss_bf16:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld3q { z0.q - z2.q }, p0/z, [x0, x1, lsl #4]
; CHECK-NEXT:    ret
  %addr2 = getelementptr i128, ptr  %addr, i64 %a
  %res = call { <vscale x 8 x bfloat>, <vscale x 8 x bfloat>, <vscale x 8 x bfloat> } @llvm.aarch64.sve.ld3q.sret.nxv8bf16(<vscale x 8 x i1> %pg, ptr %addr2);
  ret { <vscale x 8 x bfloat>, <vscale x 8 x bfloat>, <vscale x 8 x bfloat> } %res
}

define { <vscale x 8 x bfloat>, <vscale x 8 x bfloat>, <vscale x 8 x bfloat> } @ld3q_bf16(<vscale x 8 x i1> %pg,  ptr %addr) {
; CHECK-LABEL: ld3q_bf16:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld3q { z0.q - z2.q }, p0/z, [x0]
; CHECK-NEXT:    ret
  %res = call { <vscale x 8 x bfloat>, <vscale x 8 x bfloat>, <vscale x 8 x bfloat> } @llvm.aarch64.sve.ld3q.sret.nxv8bf16(<vscale x 8 x i1> %pg, ptr %addr);
  ret { <vscale x 8 x bfloat>, <vscale x 8 x bfloat>, <vscale x 8 x bfloat> } %res
}

;; LD4Q
define { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> } @ld4q_si_i8_off32(<vscale x 16 x i1> %pg, ptr %addr ) {
; CHECK-LABEL: ld4q_si_i8_off32:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld4q { z0.q - z3.q }, p0/z, [x0, #-32, mul vl]
; CHECK-NEXT:    ret
  %base = getelementptr <vscale x 16 x i8>, ptr %addr, i64 -32
  %base_ptr = bitcast ptr %base to ptr
  %res = call { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> } @llvm.aarch64.sve.ld4q.sret.nxv16i8(<vscale x 16 x i1> %pg, ptr %base_ptr);
  ret { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> } %res
}

define { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> } @ld4q_si_i8_off28(<vscale x 16 x i1> %pg, ptr %addr ) {
; CHECK-LABEL: ld4q_si_i8_off28:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld4q { z0.q - z3.q }, p0/z, [x0, #28, mul vl]
; CHECK-NEXT:    ret
  %base = getelementptr <vscale x 16 x i8>, ptr %addr, i64 28
  %base_ptr = bitcast ptr %base to ptr
  %res = call { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> } @llvm.aarch64.sve.ld4q.sret.nxv16i8(<vscale x 16 x i1> %pg, ptr %base_ptr);
  ret { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> } %res
}

define { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> } @ld4q_ss_i8(<vscale x 16 x i1> %pg,  ptr %addr, i64 %a) {
; CHECK-LABEL: ld4q_ss_i8:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld4q { z0.q - z3.q }, p0/z, [x0, x1, lsl #4]
; CHECK-NEXT:    ret
  %addr2 = getelementptr i128, ptr  %addr, i64 %a
  %res = call { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> } @llvm.aarch64.sve.ld4q.sret.nxv16i8(<vscale x 16 x i1> %pg, ptr %addr2);
  ret { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> } %res
}

define { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>} @ld4q_i8(<vscale x 16 x i1> %pg,  ptr %addr) {
; CHECK-LABEL: ld4q_i8:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld4q { z0.q - z3.q }, p0/z, [x0]
; CHECK-NEXT:    ret
  %res = call { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>} @llvm.aarch64.sve.ld4q.sret.nxv16i8(<vscale x 16 x i1> %pg, ptr %addr);
  ret { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>} %res
}

define { <vscale x 8 x i16>, <vscale x 8 x i16>, <vscale x 8 x i16>, <vscale x 8 x i16> } @ld4q_si_i16(<vscale x 8 x i1> %pg, ptr %addr ) {
; CHECK-LABEL: ld4q_si_i16:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld4q { z0.q - z3.q }, p0/z, [x0, #-32, mul vl]
; CHECK-NEXT:    ret
  %base = getelementptr <vscale x 8 x i16>, ptr %addr, i64 -32
  %base_ptr = bitcast ptr %base to ptr
  %res = call { <vscale x 8 x i16>, <vscale x 8 x i16>, <vscale x 8 x i16>, <vscale x 8 x i16> } @llvm.aarch64.sve.ld4q.sret.nxv8i16(<vscale x 8 x i1> %pg, ptr %base_ptr);
  ret { <vscale x 8 x i16>, <vscale x 8 x i16>, <vscale x 8 x i16>, <vscale x 8 x i16> } %res
}

define { <vscale x 8 x i16>, <vscale x 8 x i16>, <vscale x 8 x i16>, <vscale x 8 x i16> } @ld4q_ss_i16(<vscale x 8 x i1> %pg,  ptr %addr, i64 %a) {
; CHECK-LABEL: ld4q_ss_i16:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld4q { z0.q - z3.q }, p0/z, [x0, x1, lsl #4]
; CHECK-NEXT:    ret
  %addr2 = getelementptr i128, ptr  %addr, i64 %a
  %res = call { <vscale x 8 x i16>, <vscale x 8 x i16>, <vscale x 8 x i16>, <vscale x 8 x i16> } @llvm.aarch64.sve.ld4q.sret.nxv8i16(<vscale x 8 x i1> %pg, ptr %addr2);
  ret { <vscale x 8 x i16>, <vscale x 8 x i16>, <vscale x 8 x i16>, <vscale x 8 x i16> } %res
}

define { <vscale x 8 x i16>, <vscale x 8 x i16>, <vscale x 8 x i16>, <vscale x 8 x i16> } @ld4q_i16(<vscale x 8 x i1> %pg,  ptr %addr) {
; CHECK-LABEL: ld4q_i16:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld4q { z0.q - z3.q }, p0/z, [x0]
; CHECK-NEXT:    ret
  %res = call { <vscale x 8 x i16>, <vscale x 8 x i16>, <vscale x 8 x i16>, <vscale x 8 x i16> } @llvm.aarch64.sve.ld4q.sret.nxv8i16(<vscale x 8 x i1> %pg, ptr %addr);
  ret { <vscale x 8 x i16>, <vscale x 8 x i16>, <vscale x 8 x i16>, <vscale x 8 x i16> } %res
}

define { <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32> } @ld4q_si_i32(<vscale x 4 x i1> %pg, ptr %addr ) {
; CHECK-LABEL: ld4q_si_i32:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld4q { z0.q - z3.q }, p0/z, [x0, #-32, mul vl]
; CHECK-NEXT:    ret
  %base = getelementptr <vscale x 4 x i32>, ptr %addr, i64 -32
  %base_ptr = bitcast ptr %base to ptr
  %res = call { <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32> } @llvm.aarch64.sve.ld4q.sret.nxv4i32(<vscale x 4 x i1> %pg, ptr %base_ptr);
  ret { <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32> } %res
}

define { <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32> } @ld4q_ss_i32(<vscale x 4 x i1> %pg,  ptr %addr, i64 %a) {
; CHECK-LABEL: ld4q_ss_i32:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld4q { z0.q - z3.q }, p0/z, [x0, x1, lsl #4]
; CHECK-NEXT:    ret
  %addr2 = getelementptr i128, ptr  %addr, i64 %a
  %res = call { <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32> } @llvm.aarch64.sve.ld4q.sret.nxv4i32(<vscale x 4 x i1> %pg, ptr %addr2);
  ret { <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32> } %res
}

define { <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32> } @ld4q_i32(<vscale x 4 x i1> %pg,  ptr %addr) {
; CHECK-LABEL: ld4q_i32:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld4q { z0.q - z3.q }, p0/z, [x0]
; CHECK-NEXT:    ret
  %res = call { <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32> } @llvm.aarch64.sve.ld4q.sret.nxv4i32(<vscale x 4 x i1> %pg, ptr %addr);
  ret { <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32> } %res
}

define { <vscale x 2 x i64>, <vscale x 2 x i64>, <vscale x 2 x i64>, <vscale x 2 x i64> } @ld4q_si_i64(<vscale x 2 x i1> %pg, ptr %addr ) {
; CHECK-LABEL: ld4q_si_i64:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld4q { z0.q - z3.q }, p0/z, [x0, #-32, mul vl]
; CHECK-NEXT:    ret
  %base = getelementptr <vscale x 2 x i64>, ptr %addr, i64 -32
  %base_ptr = bitcast ptr %base to ptr
  %res = call { <vscale x 2 x i64>, <vscale x 2 x i64>, <vscale x 2 x i64>, <vscale x 2 x i64> } @llvm.aarch64.sve.ld4q.sret.nxv2i64(<vscale x 2 x i1> %pg, ptr %base_ptr);
  ret { <vscale x 2 x i64>, <vscale x 2 x i64>, <vscale x 2 x i64>, <vscale x 2 x i64> } %res
}

define { <vscale x 2 x i64>, <vscale x 2 x i64>, <vscale x 2 x i64>, <vscale x 2 x i64> } @ld4q_ss_i64(<vscale x 2 x i1> %pg,  ptr %addr, i64 %a) {
; CHECK-LABEL: ld4q_ss_i64:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld4q { z0.q - z3.q }, p0/z, [x0, x1, lsl #4]
; CHECK-NEXT:    ret
  %addr2 = getelementptr i128, ptr  %addr, i64 %a
  %res = call { <vscale x 2 x i64>, <vscale x 2 x i64>, <vscale x 2 x i64>, <vscale x 2 x i64> } @llvm.aarch64.sve.ld4q.sret.nxv2i64(<vscale x 2 x i1> %pg, ptr %addr2);
  ret { <vscale x 2 x i64>, <vscale x 2 x i64>, <vscale x 2 x i64>, <vscale x 2 x i64> } %res
}

define { <vscale x 2 x i64>, <vscale x 2 x i64>, <vscale x 2 x i64>, <vscale x 2 x i64> } @ld4q_i64(<vscale x 2 x i1> %pg,  ptr %addr) {
; CHECK-LABEL: ld4q_i64:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld4q { z0.q - z3.q }, p0/z, [x0]
; CHECK-NEXT:    ret
  %res = call { <vscale x 2 x i64>, <vscale x 2 x i64>, <vscale x 2 x i64>, <vscale x 2 x i64> } @llvm.aarch64.sve.ld4q.sret.nxv2i64(<vscale x 2 x i1> %pg, ptr %addr);
  ret { <vscale x 2 x i64>, <vscale x 2 x i64>, <vscale x 2 x i64>, <vscale x 2 x i64> } %res
}

define { <vscale x 8 x half>, <vscale x 8 x half>, <vscale x 8 x half>, <vscale x 8 x half> } @ld4q_si_f16(<vscale x 8 x i1> %pg, ptr %addr ) {
; CHECK-LABEL: ld4q_si_f16:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld4q { z0.q - z3.q }, p0/z, [x0, #-32, mul vl]
; CHECK-NEXT:    ret
  %base = getelementptr <vscale x 8 x half>, ptr %addr, i64 -32
  %base_ptr = bitcast ptr %base to ptr
  %res = call { <vscale x 8 x half>, <vscale x 8 x half>, <vscale x 8 x half>, <vscale x 8 x half> } @llvm.aarch64.sve.ld4q.sret.nxv8f16(<vscale x 8 x i1> %pg, ptr %base_ptr);
  ret { <vscale x 8 x half>, <vscale x 8 x half>, <vscale x 8 x half>, <vscale x 8 x half> } %res
}

define { <vscale x 8 x half>, <vscale x 8 x half>, <vscale x 8 x half>, <vscale x 8 x half> } @ld4q_ss_f16(<vscale x 8 x i1> %pg,  ptr %addr, i64 %a) {
; CHECK-LABEL: ld4q_ss_f16:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld4q { z0.q - z3.q }, p0/z, [x0, x1, lsl #4]
; CHECK-NEXT:    ret
  %addr2 = getelementptr i128, ptr  %addr, i64 %a
  %res = call { <vscale x 8 x half>, <vscale x 8 x half>, <vscale x 8 x half>, <vscale x 8 x half> } @llvm.aarch64.sve.ld4q.sret.nxv8f16(<vscale x 8 x i1> %pg, ptr %addr2);
  ret { <vscale x 8 x half>, <vscale x 8 x half>, <vscale x 8 x half>, <vscale x 8 x half> } %res
}

define { <vscale x 8 x half>, <vscale x 8 x half>, <vscale x 8 x half>, <vscale x 8 x half> } @ld4q_f16(<vscale x 8 x i1> %pg,  ptr %addr) {
; CHECK-LABEL: ld4q_f16:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld4q { z0.q - z3.q }, p0/z, [x0]
; CHECK-NEXT:    ret
  %res = call { <vscale x 8 x half>, <vscale x 8 x half>, <vscale x 8 x half>, <vscale x 8 x half> } @llvm.aarch64.sve.ld4q.sret.nxv8f16(<vscale x 8 x i1> %pg, ptr %addr);
  ret { <vscale x 8 x half>, <vscale x 8 x half>, <vscale x 8 x half>, <vscale x 8 x half> } %res
}

define { <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float> } @ld4q_si_f32(<vscale x 4 x i1> %pg, ptr %addr ) {
; CHECK-LABEL: ld4q_si_f32:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld4q { z0.q - z3.q }, p0/z, [x0, #-32, mul vl]
; CHECK-NEXT:    ret
 %base = getelementptr <vscale x 4 x float>, ptr %addr, i64 -32
  %base_ptr = bitcast ptr %base to ptr
  %res = call { <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float> } @llvm.aarch64.sve.ld4q.sret.nxv4f32(<vscale x 4 x i1> %pg, ptr %base_ptr);
  ret { <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float> } %res
}

define { <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float> } @ld4q_ss_f32(<vscale x 4 x i1> %pg,  ptr %addr, i64 %a) {
; CHECK-LABEL: ld4q_ss_f32:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld4q { z0.q - z3.q }, p0/z, [x0, x1, lsl #4]
; CHECK-NEXT:    ret
  %addr2 = getelementptr i128, ptr  %addr, i64 %a
  %res = call { <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float> } @llvm.aarch64.sve.ld4q.sret.nxv4f32(<vscale x 4 x i1> %pg, ptr %addr2);
  ret { <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float> } %res
}

define { <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float> } @ld4q_f32(<vscale x 4 x i1> %pg,  ptr %addr) {
; CHECK-LABEL: ld4q_f32:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld4q { z0.q - z3.q }, p0/z, [x0]
; CHECK-NEXT:    ret
  %res = call { <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float> } @llvm.aarch64.sve.ld4q.sret.nxv4f32(<vscale x 4 x i1> %pg, ptr %addr);
  ret { <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float> } %res
}

define { <vscale x 2 x double>, <vscale x 2 x double>, <vscale x 2 x double>, <vscale x 2 x double> } @ld4q_si_f64(<vscale x 2 x i1> %pg, ptr %addr ) {
; CHECK-LABEL: ld4q_si_f64:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld4q { z0.q - z3.q }, p0/z, [x0, #-32, mul vl]
; CHECK-NEXT:    ret
  %base = getelementptr <vscale x 2 x double>, ptr %addr, i64 -32
  %base_ptr = bitcast ptr %base to ptr
  %res = call { <vscale x 2 x double>, <vscale x 2 x double>, <vscale x 2 x double>, <vscale x 2 x double> } @llvm.aarch64.sve.ld4q.sret.nxv2f64(<vscale x 2 x i1> %pg, ptr %base_ptr);
  ret { <vscale x 2 x double>, <vscale x 2 x double>, <vscale x 2 x double>, <vscale x 2 x double> } %res
}

define { <vscale x 2 x double>, <vscale x 2 x double>, <vscale x 2 x double>, <vscale x 2 x double> } @ld4q_ss_f64(<vscale x 2 x i1> %pg,  ptr %addr, i64 %a) {
; CHECK-LABEL: ld4q_ss_f64:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld4q { z0.q - z3.q }, p0/z, [x0, x1, lsl #4]
; CHECK-NEXT:    ret
  %addr2 = getelementptr i128, ptr  %addr, i64  %a
  %res = call { <vscale x 2 x double>, <vscale x 2 x double>, <vscale x 2 x double>, <vscale x 2 x double> } @llvm.aarch64.sve.ld4q.sret.nxv2f64(<vscale x 2 x i1> %pg, ptr %addr2);
  ret { <vscale x 2 x double>, <vscale x 2 x double>, <vscale x 2 x double>, <vscale x 2 x double> } %res
}

define { <vscale x 2 x double>, <vscale x 2 x double>, <vscale x 2 x double>, <vscale x 2 x double> } @ld4q_f64(<vscale x 2 x i1> %pg,  ptr %addr) {
; CHECK-LABEL: ld4q_f64:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld4q { z0.q - z3.q }, p0/z, [x0]
; CHECK-NEXT:    ret
  %res = call { <vscale x 2 x double>, <vscale x 2 x double>, <vscale x 2 x double>, <vscale x 2 x double> } @llvm.aarch64.sve.ld4q.sret.nxv2f64(<vscale x 2 x i1> %pg, ptr %addr);
  ret { <vscale x 2 x double>, <vscale x 2 x double>, <vscale x 2 x double>, <vscale x 2 x double> } %res
}

define { <vscale x 8 x bfloat>, <vscale x 8 x bfloat>, <vscale x 8 x bfloat>, <vscale x 8 x bfloat> } @ld4q_si_bf16(<vscale x 8 x i1> %pg, ptr %addr ) {
; CHECK-LABEL: ld4q_si_bf16:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld4q { z0.q - z3.q }, p0/z, [x0, #-32, mul vl]
; CHECK-NEXT:    ret
  %base = getelementptr <vscale x 8 x bfloat>, ptr %addr, i64 -32
  %base_ptr = bitcast ptr %base to ptr
  %res = call { <vscale x 8 x bfloat>, <vscale x 8 x bfloat>, <vscale x 8 x bfloat>, <vscale x 8 x bfloat> } @llvm.aarch64.sve.ld4q.sret.nxv8bf16(<vscale x 8 x i1> %pg, ptr %base_ptr);
  ret { <vscale x 8 x bfloat>, <vscale x 8 x bfloat>, <vscale x 8 x bfloat>, <vscale x 8 x bfloat> } %res
}

define { <vscale x 8 x bfloat>, <vscale x 8 x bfloat>, <vscale x 8 x bfloat>, <vscale x 8 x bfloat> } @ld4q_ss_bf16(<vscale x 8 x i1> %pg,  ptr %addr, i64 %a) {
; CHECK-LABEL: ld4q_ss_bf16:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld4q { z0.q - z3.q }, p0/z, [x0, x1, lsl #4]
; CHECK-NEXT:    ret
  %addr2 = getelementptr i128, ptr  %addr, i64 %a
  %res = call { <vscale x 8 x bfloat>, <vscale x 8 x bfloat>, <vscale x 8 x bfloat>, <vscale x 8 x bfloat> } @llvm.aarch64.sve.ld4q.sret.nxv8bf16(<vscale x 8 x i1> %pg, ptr %addr2);
  ret { <vscale x 8 x bfloat>, <vscale x 8 x bfloat>, <vscale x 8 x bfloat>, <vscale x 8 x bfloat> } %res
}

define { <vscale x 8 x bfloat>, <vscale x 8 x bfloat>, <vscale x 8 x bfloat>, <vscale x 8 x bfloat> } @ld4q_bf16(<vscale x 8 x i1> %pg,  ptr %addr) {
; CHECK-LABEL: ld4q_bf16:
; CHECK:       // %bb.0:
; CHECK-NEXT:    ld4q { z0.q - z3.q }, p0/z, [x0]
; CHECK-NEXT:    ret
  %res = call { <vscale x 8 x bfloat>, <vscale x 8 x bfloat>, <vscale x 8 x bfloat>, <vscale x 8 x bfloat> } @llvm.aarch64.sve.ld4q.sret.nxv8bf16(<vscale x 8 x i1> %pg, ptr %addr);
  ret { <vscale x 8 x bfloat>, <vscale x 8 x bfloat>, <vscale x 8 x bfloat>, <vscale x 8 x bfloat> } %res
}


declare { <vscale x 2 x i64>, <vscale x 2 x i64>, <vscale x 2 x i64>, <vscale x 2 x i64> } @llvm.aarch64.sve.ldnt1.pn.x4.nxv2i64(target("aarch64.svcount"), ptr)
declare { <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32> } @llvm.aarch64.sve.ldnt1.pn.x4.nxv4i32(target("aarch64.svcount"), ptr)
declare { <vscale x 8 x i16>, <vscale x 8 x i16>, <vscale x 8 x i16>, <vscale x 8 x i16> } @llvm.aarch64.sve.ldnt1.pn.x4.nxv8i16(target("aarch64.svcount"), ptr)
declare { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> } @llvm.aarch64.sve.ldnt1.pn.x4.nxv16i8(target("aarch64.svcount"), ptr)
declare { <vscale x 2 x double>, <vscale x 2 x double>, <vscale x 2 x double>, <vscale x 2 x double> } @llvm.aarch64.sve.ldnt1.pn.x4.nxv2f64(target("aarch64.svcount"), ptr)
declare { <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float> } @llvm.aarch64.sve.ldnt1.pn.x4.nxv4f32(target("aarch64.svcount"), ptr)
declare { <vscale x 8 x half>, <vscale x 8 x half>, <vscale x 8 x half>, <vscale x 8 x half> } @llvm.aarch64.sve.ldnt1.pn.x4.nxv8f16(target("aarch64.svcount"), ptr)
declare { <vscale x 8 x bfloat>, <vscale x 8 x bfloat>, <vscale x 8 x bfloat>, <vscale x 8 x bfloat> } @llvm.aarch64.sve.ldnt1.pn.x4.nxv8bf16(target("aarch64.svcount"), ptr)

declare { <vscale x 16 x i8>, <vscale x 16 x i8> } @llvm.aarch64.sve.ld2q.sret.nxv16i8(<vscale x 16 x i1>, ptr)
declare { <vscale x 8 x i16>, <vscale x 8 x i16> } @llvm.aarch64.sve.ld2q.sret.nxv8i16(<vscale x 8 x i1>, ptr)
declare { <vscale x 4 x i32>, <vscale x 4 x i32> } @llvm.aarch64.sve.ld2q.sret.nxv4i32(<vscale x 4 x i1>, ptr)
declare { <vscale x 2 x i64>, <vscale x 2 x i64> } @llvm.aarch64.sve.ld2q.sret.nxv2i64(<vscale x 2 x i1>, ptr)

declare { <vscale x 8 x half>, <vscale x 8 x half> } @llvm.aarch64.sve.ld2q.sret.nxv8f16(<vscale x 8 x i1>, ptr)
declare { <vscale x 4 x float>, <vscale x 4 x float> } @llvm.aarch64.sve.ld2q.sret.nxv4f32(<vscale x 4 x i1>, ptr)
declare { <vscale x 2 x double>, <vscale x 2 x double> } @llvm.aarch64.sve.ld2q.sret.nxv2f64(<vscale x 2 x i1>, ptr)
declare { <vscale x 8 x bfloat>, <vscale x 8 x bfloat> } @llvm.aarch64.sve.ld2q.sret.nxv8bf16(<vscale x 8 x i1>, ptr)

declare { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> } @llvm.aarch64.sve.ld3q.sret.nxv16i8(<vscale x 16 x i1>, ptr)
declare { <vscale x 8 x i16>, <vscale x 8 x i16>, <vscale x 8 x i16> } @llvm.aarch64.sve.ld3q.sret.nxv8i16(<vscale x 8 x i1>, ptr)
declare { <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32> } @llvm.aarch64.sve.ld3q.sret.nxv4i32(<vscale x 4 x i1>, ptr)
declare { <vscale x 2 x i64>, <vscale x 2 x i64>, <vscale x 2 x i64> } @llvm.aarch64.sve.ld3q.sret.nxv2i64(<vscale x 2 x i1>, ptr)

declare { <vscale x 8 x half>, <vscale x 8 x half>, <vscale x 8 x half> } @llvm.aarch64.sve.ld3q.sret.nxv8f16(<vscale x 8 x i1>, ptr)
declare { <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float> } @llvm.aarch64.sve.ld3q.sret.nxv4f32(<vscale x 4 x i1>, ptr)
declare { <vscale x 2 x double>, <vscale x 2 x double>, <vscale x 2 x double> } @llvm.aarch64.sve.ld3q.sret.nxv2f64(<vscale x 2 x i1>, ptr)
declare { <vscale x 8 x bfloat>, <vscale x 8 x bfloat>, <vscale x 8 x bfloat> } @llvm.aarch64.sve.ld3q.sret.nxv8bf16(<vscale x 8 x i1>, ptr)

declare { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> } @llvm.aarch64.sve.ld4q.sret.nxv16i8(<vscale x 16 x i1>, ptr)
declare { <vscale x 8 x i16>, <vscale x 8 x i16>, <vscale x 8 x i16>, <vscale x 8 x i16> } @llvm.aarch64.sve.ld4q.sret.nxv8i16(<vscale x 8 x i1>, ptr)
declare { <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32> } @llvm.aarch64.sve.ld4q.sret.nxv4i32(<vscale x 4 x i1>, ptr)
declare { <vscale x 2 x i64>, <vscale x 2 x i64>, <vscale x 2 x i64>, <vscale x 2 x i64> } @llvm.aarch64.sve.ld4q.sret.nxv2i64(<vscale x 2 x i1>, ptr)

declare { <vscale x 8 x half>, <vscale x 8 x half>, <vscale x 8 x half>, <vscale x 8 x half> } @llvm.aarch64.sve.ld4q.sret.nxv8f16(<vscale x 8 x i1>, ptr)
declare { <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float> } @llvm.aarch64.sve.ld4q.sret.nxv4f32(<vscale x 4 x i1>, ptr)
declare { <vscale x 2 x double>, <vscale x 2 x double>, <vscale x 2 x double>, <vscale x 2 x double> } @llvm.aarch64.sve.ld4q.sret.nxv2f64(<vscale x 2 x i1>, ptr)
declare { <vscale x 8 x bfloat>, <vscale x 8 x bfloat>, <vscale x 8 x bfloat>, <vscale x 8 x bfloat> } @llvm.aarch64.sve.ld4q.sret.nxv8bf16(<vscale x 8 x i1>, ptr)