; RUN: llc -mtriple=aarch64-linux-gnu -mattr=+sve < %s 2>%t | FileCheck %s ; RUN: FileCheck --check-prefix=WARN --allow-empty %s <%t ; If this check fails please read test/CodeGen/AArch64/README for instructions on how to resolve it. ; WARN-NOT: warning ;; Splats of legal integer vector types define @sve_splat_16xi8(i8 %val) { ; CHECK-LABEL: @sve_splat_16xi8 ; CHECK: mov z0.b, w0 ; CHECK-NEXT: ret %ins = insertelement undef, i8 %val, i32 0 %splat = shufflevector %ins, undef, zeroinitializer ret %splat } define @sve_splat_8xi16(i16 %val) { ; CHECK-LABEL: @sve_splat_8xi16 ; CHECK: mov z0.h, w0 ; CHECK-NEXT: ret %ins = insertelement undef, i16 %val, i32 0 %splat = shufflevector %ins, undef, zeroinitializer ret %splat } define @sve_splat_4xi32(i32 %val) { ; CHECK-LABEL: @sve_splat_4xi32 ; CHECK: mov z0.s, w0 ; CHECK-NEXT: ret %ins = insertelement undef, i32 %val, i32 0 %splat = shufflevector %ins, undef, zeroinitializer ret %splat } define @sve_splat_2xi64(i64 %val) { ; CHECK-LABEL: @sve_splat_2xi64 ; CHECK: mov z0.d, x0 ; CHECK-NEXT: ret %ins = insertelement undef, i64 %val, i32 0 %splat = shufflevector %ins, undef, zeroinitializer ret %splat } define @sve_splat_16xi8_imm() { ; CHECK-LABEL: @sve_splat_16xi8_imm ; CHECK: mov z0.b, #1 ; CHECK-NEXT: ret %ins = insertelement undef, i8 1, i32 0 %splat = shufflevector %ins, undef, zeroinitializer ret %splat } define @sve_splat_8xi16_imm() { ; CHECK-LABEL: @sve_splat_8xi16_imm ; CHECK: mov z0.h, #1 ; CHECK-NEXT: ret %ins = insertelement undef, i16 1, i32 0 %splat = shufflevector %ins, undef, zeroinitializer ret %splat } define @sve_splat_4xi32_imm() { ; CHECK-LABEL: @sve_splat_4xi32_imm ; CHECK: mov z0.s, #1 ; CHECK-NEXT: ret %ins = insertelement undef, i32 1, i32 0 %splat = shufflevector %ins, undef, zeroinitializer ret %splat } define @sve_splat_2xi64_imm() { ; CHECK-LABEL: @sve_splat_2xi64_imm ; CHECK: mov z0.d, #1 ; CHECK-NEXT: ret %ins = insertelement undef, i64 1, i32 0 %splat = shufflevector %ins, undef, zeroinitializer ret %splat } ;; Promote splats of smaller illegal integer vector types define @sve_splat_2xi8(i8 %val) { ; CHECK-LABEL: @sve_splat_2xi8 ; CHECK: mov z0.d, x0 ; CHECK-NEXT: ret %ins = insertelement undef, i8 %val, i32 0 %splat = shufflevector %ins, undef, zeroinitializer ret %splat } define @sve_splat_4xi8(i8 %val) { ; CHECK-LABEL: @sve_splat_4xi8 ; CHECK: mov z0.s, w0 ; CHECK-NEXT: ret %ins = insertelement undef, i8 %val, i32 0 %splat = shufflevector %ins, undef, zeroinitializer ret %splat } define @sve_splat_8xi8(i8 %val) { ; CHECK-LABEL: @sve_splat_8xi8 ; CHECK: mov z0.h, w0 ; CHECK-NEXT: ret %ins = insertelement undef, i8 %val, i32 0 %splat = shufflevector %ins, undef, zeroinitializer ret %splat } define @sve_splat_2xi16(i16 %val) { ; CHECK-LABEL: @sve_splat_2xi16 ; CHECK: mov z0.d, x0 ; CHECK-NEXT: ret %ins = insertelement undef, i16 %val, i32 0 %splat = shufflevector %ins, undef, zeroinitializer ret %splat } define @sve_splat_4xi16(i16 %val) { ; CHECK-LABEL: @sve_splat_4xi16 ; CHECK: mov z0.s, w0 ; CHECK-NEXT: ret %ins = insertelement undef, i16 %val, i32 0 %splat = shufflevector %ins, undef, zeroinitializer ret %splat } define @sve_splat_2xi32(i32 %val) { ; CHECK-LABEL: @sve_splat_2xi32 ; CHECK: mov z0.d, x0 ; CHECK-NEXT: ret %ins = insertelement undef, i32 %val, i32 0 %splat = shufflevector %ins, undef, zeroinitializer ret %splat } ;; Widen/split splats of wide vector types. define @sve_splat_12xi32(i32 %val) { ; CHECK-LABEL: @sve_splat_12xi32 ; CHECK: mov z0.s, w0 ; CHECK-NEXT: mov z1.d, z0.d ; CHECK-NEXT: mov z2.d, z0.d ; CHECK-NEXT: ret %ins = insertelement undef, i32 %val, i32 0 %splat = shufflevector %ins, undef, zeroinitializer ret %splat } define @sve_splat_2xi1(i1 %val) { ; CHECK-LABEL: @sve_splat_2xi1 ; CHECK: sbfx x8, x0, #0, #1 ; CHECK-NEXT: whilelo p0.d, xzr, x8 ; CHECK-NEXT: ret %ins = insertelement undef, i1 %val, i32 0 %splat = shufflevector %ins, undef, zeroinitializer ret %splat } define @sve_splat_4xi1(i1 %val) { ; CHECK-LABEL: @sve_splat_4xi1 ; CHECK: sbfx x8, x0, #0, #1 ; CHECK-NEXT: whilelo p0.s, xzr, x8 ; CHECK-NEXT: ret %ins = insertelement undef, i1 %val, i32 0 %splat = shufflevector %ins, undef, zeroinitializer ret %splat } define @sve_splat_8xi1(i1 %val) { ; CHECK-LABEL: @sve_splat_8xi1 ; CHECK: sbfx x8, x0, #0, #1 ; CHECK-NEXT: whilelo p0.h, xzr, x8 ; CHECK-NEXT: ret %ins = insertelement undef, i1 %val, i32 0 %splat = shufflevector %ins, undef, zeroinitializer ret %splat } define @sve_splat_16xi1(i1 %val) { ; CHECK-LABEL: @sve_splat_16xi1 ; CHECK: sbfx x8, x0, #0, #1 ; CHECK-NEXT: whilelo p0.b, xzr, x8 ; CHECK-NEXT: ret %ins = insertelement undef, i1 %val, i32 0 %splat = shufflevector %ins, undef, zeroinitializer ret %splat } ;; Splats of legal floating point vector types define @splat_nxv8bf16(bfloat %val) #0 { ; CHECK-LABEL: splat_nxv8bf16: ; CHECK: mov z0.h, h0 ; CHECK-NEXT: ret %1 = insertelement undef, bfloat %val, i32 0 %2 = shufflevector %1, undef, zeroinitializer ret %2 } define @splat_nxv8f16(half %val) { ; CHECK-LABEL: splat_nxv8f16: ; CHECK: mov z0.h, h0 ; CHECK-NEXT: ret %1 = insertelement undef, half %val, i32 0 %2 = shufflevector %1, undef, zeroinitializer ret %2 } define @splat_nxv4f16(half %val) { ; CHECK-LABEL: splat_nxv4f16: ; CHECK: mov z0.h, h0 ; CHECK-NEXT: ret %1 = insertelement undef, half %val, i32 0 %2 = shufflevector %1, undef, zeroinitializer ret %2 } define @splat_nxv2f16(half %val) { ; CHECK-LABEL: splat_nxv2f16: ; CHECK: mov z0.h, h0 ; CHECK-NEXT: ret %1 = insertelement undef, half %val, i32 0 %2 = shufflevector %1, undef, zeroinitializer ret %2 } define @splat_nxv4f32(float %val) { ; CHECK-LABEL: splat_nxv4f32: ; CHECK: mov z0.s, s0 ; CHECK-NEXT: ret %1 = insertelement undef, float %val, i32 0 %2 = shufflevector %1, undef, zeroinitializer ret %2 } define @splat_nxv2f32(float %val) { ; CHECK-LABEL: splat_nxv2f32: ; CHECK: mov z0.s, s0 ; CHECK-NEXT: ret %1 = insertelement undef, float %val, i32 0 %2 = shufflevector %1, undef, zeroinitializer ret %2 } define @splat_nxv2f64(double %val) { ; CHECK-LABEL: splat_nxv2f64: ; CHECK: mov z0.d, d0 ; CHECK-NEXT: ret %1 = insertelement undef, double %val, i32 0 %2 = shufflevector %1, undef, zeroinitializer ret %2 } define @splat_nxv8f16_zero() { ; CHECK-LABEL: splat_nxv8f16_zero: ; CHECK: mov z0.h, #0 ; CHECK-NEXT: ret ret zeroinitializer } define @splat_nxv8bf16_zero() #0 { ; CHECK-LABEL: splat_nxv8bf16_zero: ; CHECK: mov z0.h, #0 ; CHECK-NEXT: ret ret zeroinitializer } define @splat_nxv4f16_zero() { ; CHECK-LABEL: splat_nxv4f16_zero: ; CHECK: mov z0.h, #0 ; CHECK-NEXT: ret ret zeroinitializer } define @splat_nxv2f16_zero() { ; CHECK-LABEL: splat_nxv2f16_zero: ; CHECK: mov z0.h, #0 ; CHECK-NEXT: ret ret zeroinitializer } define @splat_nxv4f32_zero() { ; CHECK-LABEL: splat_nxv4f32_zero: ; CHECK: mov z0.s, #0 ; CHECK-NEXT: ret ret zeroinitializer } define @splat_nxv2f32_zero() { ; CHECK-LABEL: splat_nxv2f32_zero: ; CHECK: mov z0.s, #0 ; CHECK-NEXT: ret ret zeroinitializer } define @splat_nxv2f64_zero() { ; CHECK-LABEL: splat_nxv2f64_zero: ; CHECK: mov z0.d, #0 ; CHECK-NEXT: ret ret zeroinitializer } define @splat_nxv8f16_imm() { ; CHECK-LABEL: splat_nxv8f16_imm: ; CHECK: fmov z0.h, #1.00000000 ; CHECK-NEXT: ret %1 = insertelement undef, half 1.0, i32 0 %2 = shufflevector %1, undef, zeroinitializer ret %2 } define @splat_nxv4f16_imm() { ; CHECK-LABEL: splat_nxv4f16_imm: ; CHECK: fmov z0.h, #1.00000000 ; CHECK-NEXT: ret %1 = insertelement undef, half 1.0, i32 0 %2 = shufflevector %1, undef, zeroinitializer ret %2 } define @splat_nxv2f16_imm() { ; CHECK-LABEL: splat_nxv2f16_imm: ; CHECK: fmov z0.h, #1.00000000 ; CHECK-NEXT: ret %1 = insertelement undef, half 1.0, i32 0 %2 = shufflevector %1, undef, zeroinitializer ret %2 } define @splat_nxv4f32_imm() { ; CHECK-LABEL: splat_nxv4f32_imm: ; CHECK: fmov z0.s, #1.00000000 ; CHECK-NEXT: ret %1 = insertelement undef, float 1.0, i32 0 %2 = shufflevector %1, undef, zeroinitializer ret %2 } define @splat_nxv2f32_imm() { ; CHECK-LABEL: splat_nxv2f32_imm: ; CHECK: fmov z0.s, #1.00000000 ; CHECK-NEXT: ret %1 = insertelement undef, float 1.0, i32 0 %2 = shufflevector %1, undef, zeroinitializer ret %2 } define @splat_nxv2f64_imm() { ; CHECK-LABEL: splat_nxv2f64_imm: ; CHECK: fmov z0.d, #1.00000000 ; CHECK-NEXT: ret %1 = insertelement undef, double 1.0, i32 0 %2 = shufflevector %1, undef, zeroinitializer ret %2 } define @splat_nxv4i32_fold( %x) { ; CHECK-LABEL: splat_nxv4i32_fold: ; CHECK: mov z0.s, #0 ; CHECK-NEXT: ret %r = sub %x, %x ret %r } define @splat_nxv4f32_fold( %x) { ; CHECK-LABEL: splat_nxv4f32_fold: ; CHECK: mov z0.s, #0 ; CHECK-NEXT: ret %r = fsub nnan %x, %x ret %r } ; +bf16 is required for the bfloat version. attributes #0 = { "target-features"="+sve,+bf16" }