; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ; RUN: llc -mtriple=aarch64-linux-gnu -mattr=+sme2 -verify-machineinstrs < %s | FileCheck %s ; == 8 to 64-bit elements == define @uzp_x2_i8( %zn, %zm) nounwind { ; CHECK-LABEL: uzp_x2_i8: ; CHECK: // %bb.0: ; CHECK-NEXT: uzp { z2.b, z3.b }, z0.b, z1.b ; CHECK-NEXT: add z0.b, z2.b, z0.b ; CHECK-NEXT: ret %uzp = call { , } @llvm.aarch64.sve.uzp.x2.nxv16i8( %zn, %zm) %uzp0 = extractvalue { , } %uzp, 0 %add = add %uzp0, %zn ret %add } define @uzp_x2_i16( %zn, %zm) nounwind { ; CHECK-LABEL: uzp_x2_i16: ; CHECK: // %bb.0: ; CHECK-NEXT: uzp { z2.h, z3.h }, z0.h, z1.h ; CHECK-NEXT: add z0.h, z2.h, z0.h ; CHECK-NEXT: ret %uzp = call { , } @llvm.aarch64.sve.uzp.x2.nxv8i16( %zn, %zm) %uzp0 = extractvalue { , } %uzp, 0 %add = add %uzp0, %zn ret %add } define @uzp_x2_f16( %zn, %zm) nounwind { ; CHECK-LABEL: uzp_x2_f16: ; CHECK: // %bb.0: ; CHECK-NEXT: uzp { z2.h, z3.h }, z0.h, z1.h ; CHECK-NEXT: fadd z0.h, z2.h, z0.h ; CHECK-NEXT: ret %uzp = call { , } @llvm.aarch64.sve.uzp.x2.nxv8f16( %zn, %zm) %uzp0 = extractvalue { , } %uzp, 0 %add = fadd %uzp0, %zn ret %add } define { , } @uzp_x2_bf16( %zn, %zm) nounwind { ; CHECK-LABEL: uzp_x2_bf16: ; CHECK: // %bb.0: ; CHECK-NEXT: uzp { z0.h, z1.h }, z0.h, z1.h ; CHECK-NEXT: ret %uzp = call { , } @llvm.aarch64.sve.uzp.x2.nxv8bf16( %zn, %zm) ret { , } %uzp } define @uzp_x2_i32( %zn, %zm) nounwind { ; CHECK-LABEL: uzp_x2_i32: ; CHECK: // %bb.0: ; CHECK-NEXT: uzp { z2.s, z3.s }, z0.s, z1.s ; CHECK-NEXT: add z0.s, z2.s, z0.s ; CHECK-NEXT: ret %uzp = call { , } @llvm.aarch64.sve.uzp.x2.nxv4i32( %zn, %zm) %uzp0 = extractvalue { , } %uzp, 0 %add = add %uzp0, %zn ret %add } define @uzp_x2_f32( %zn, %zm) nounwind { ; CHECK-LABEL: uzp_x2_f32: ; CHECK: // %bb.0: ; CHECK-NEXT: uzp { z2.s, z3.s }, z0.s, z1.s ; CHECK-NEXT: fadd z0.s, z2.s, z0.s ; CHECK-NEXT: ret %uzp = call { , } @llvm.aarch64.sve.uzp.x2.nxv4f32( %zn, %zm) %uzp0 = extractvalue { , } %uzp, 0 %add = fadd %uzp0, %zn ret %add } define @uzp_x2_i64( %zn, %zm) nounwind { ; CHECK-LABEL: uzp_x2_i64: ; CHECK: // %bb.0: ; CHECK-NEXT: uzp { z2.d, z3.d }, z0.d, z1.d ; CHECK-NEXT: add z0.d, z2.d, z0.d ; CHECK-NEXT: ret %uzp = call { , } @llvm.aarch64.sve.uzp.x2.nxv2i64( %zn, %zm) %uzp0 = extractvalue { , } %uzp, 0 %add = add %uzp0, %zn ret %add } define @uzp_x2_f64( %zn, %zm) nounwind { ; CHECK-LABEL: uzp_x2_f64: ; CHECK: // %bb.0: ; CHECK-NEXT: uzp { z2.d, z3.d }, z0.d, z1.d ; CHECK-NEXT: fadd z0.d, z2.d, z0.d ; CHECK-NEXT: ret %uzp = call { , } @llvm.aarch64.sve.uzp.x2.nxv2f64( %zn, %zm) %uzp0 = extractvalue { , } %uzp, 0 %add = fadd %uzp0, %zn ret %add } ; == 128-bit elements == ; NOTE: For the 128-bit case we only need to check the to ; ensure the tuple result starts at the correct register multiple. The other ; variants all test the same code path. define @uzpq_x2_i8( %zn, %zm) nounwind { ; CHECK-LABEL: uzpq_x2_i8: ; CHECK: // %bb.0: ; CHECK-NEXT: uzp { z2.q, z3.q }, z0.q, z1.q ; CHECK-NEXT: add z0.b, z2.b, z0.b ; CHECK-NEXT: ret %uzp = call { , } @llvm.aarch64.sve.uzpq.x2.nxv16i8( %zn, %zm) %uzp0 = extractvalue { , } %uzp, 0 %add = add %uzp0, %zn ret %add } define { , } @uzpq_x2_i16( %zn, %zm) nounwind { ; CHECK-LABEL: uzpq_x2_i16: ; CHECK: // %bb.0: ; CHECK-NEXT: uzp { z0.q, z1.q }, z0.q, z1.q ; CHECK-NEXT: ret %res = call { , } @llvm.aarch64.sve.uzpq.x2.nxv8i16( %zn, %zm) ret { , } %res } define { , } @uzpq_x2_f16( %zn, %zm) nounwind { ; CHECK-LABEL: uzpq_x2_f16: ; CHECK: // %bb.0: ; CHECK-NEXT: uzp { z0.q, z1.q }, z0.q, z1.q ; CHECK-NEXT: ret %res = call { , } @llvm.aarch64.sve.uzpq.x2.nxv8f16( %zn, %zm) ret { , } %res } define { , } @uzpq_x2_bf16( %zn, %zm) nounwind { ; CHECK-LABEL: uzpq_x2_bf16: ; CHECK: // %bb.0: ; CHECK-NEXT: uzp { z0.q, z1.q }, z0.q, z1.q ; CHECK-NEXT: ret %res = call { , } @llvm.aarch64.sve.uzpq.x2.nxv8bf16( %zn, %zm) ret { , } %res } define { , } @uzpq_x2_i32( %zn, %zm) nounwind { ; CHECK-LABEL: uzpq_x2_i32: ; CHECK: // %bb.0: ; CHECK-NEXT: uzp { z0.q, z1.q }, z0.q, z1.q ; CHECK-NEXT: ret %res = call { , } @llvm.aarch64.sve.uzpq.x2.nxv4i32( %zn, %zm) ret { , } %res } define { , } @uzpq_x2_f32( %zn, %zm) nounwind { ; CHECK-LABEL: uzpq_x2_f32: ; CHECK: // %bb.0: ; CHECK-NEXT: uzp { z0.q, z1.q }, z0.q, z1.q ; CHECK-NEXT: ret %res = call { , } @llvm.aarch64.sve.uzpq.x2.nxv4f32( %zn, %zm) ret { , } %res } define { , } @uzpq_x2_i64( %zn, %zm) nounwind { ; CHECK-LABEL: uzpq_x2_i64: ; CHECK: // %bb.0: ; CHECK-NEXT: uzp { z0.q, z1.q }, z0.q, z1.q ; CHECK-NEXT: ret %res = call { , } @llvm.aarch64.sve.uzpq.x2.nxv2i64( %zn, %zm) ret { , } %res } define { , } @uzpq_x2_f64( %zn, %zm) nounwind { ; CHECK-LABEL: uzpq_x2_f64: ; CHECK: // %bb.0: ; CHECK-NEXT: uzp { z0.q, z1.q }, z0.q, z1.q ; CHECK-NEXT: ret %res = call { , } @llvm.aarch64.sve.uzpq.x2.nxv2f64( %zn, %zm) ret { , } %res } define { , } @uzpq_x2_i8_not_tied( %unused, %zn, %zm) nounwind { ; CHECK-LABEL: uzpq_x2_i8_not_tied: ; CHECK: // %bb.0: ; CHECK-NEXT: uzp { z0.q, z1.q }, z1.q, z2.q ; CHECK-NEXT: ret %res = call { , } @llvm.aarch64.sve.uzpq.x2.nxv16i8( %zn, %zm) ret { , } %res } ; == 8 to 64-bit elements == declare { , } @llvm.aarch64.sve.uzp.x2.nxv16i8( %zn, %zm) declare { , } @llvm.aarch64.sve.uzp.x2.nxv8i16( %zn, %zm) declare { , } @llvm.aarch64.sve.uzp.x2.nxv4i32( %zn, %zm) declare { , } @llvm.aarch64.sve.uzp.x2.nxv2i64( %zn, %zm) declare { , } @llvm.aarch64.sve.uzp.x2.nxv8f16( %zn, %zm) declare { , } @llvm.aarch64.sve.uzp.x2.nxv8bf16( %zn, %zm) declare { , } @llvm.aarch64.sve.uzp.x2.nxv4f32( %zn, %zm) declare { , } @llvm.aarch64.sve.uzp.x2.nxv2f64( %zn, %zm) ; == 128-bit elements == declare { , } @llvm.aarch64.sve.uzpq.x2.nxv16i8( %zn, %zm) declare { , } @llvm.aarch64.sve.uzpq.x2.nxv8i16( %zn, %zm) declare { , } @llvm.aarch64.sve.uzpq.x2.nxv4i32( %zn, %zm) declare { , } @llvm.aarch64.sve.uzpq.x2.nxv2i64( %zn, %zm) declare { , } @llvm.aarch64.sve.uzpq.x2.nxv8f16( %zn, %zm) declare { , } @llvm.aarch64.sve.uzpq.x2.nxv8bf16( %zn, %zm) declare { , } @llvm.aarch64.sve.uzpq.x2.nxv4f32( %zn, %zm) declare { , } @llvm.aarch64.sve.uzpq.x2.nxv2f64( %zn, %zm)