; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ; RUN: llc < %s | FileCheck %s target triple = "aarch64-unknown-linux-gnu" ; ; SQABS (sve2_int_un_pred_arit) ; ; Check movprfx is not inserted when dstReg == srcReg define @sqabs_i8_dupreg( %a) #0 { ; CHECK-LABEL: sqabs_i8_dupreg: ; CHECK: // %bb.0: ; CHECK-NEXT: ptrue p0.b ; CHECK-NEXT: sqabs z0.b, p0/m, z0.b ; CHECK-NEXT: ret %pg = tail call @llvm.aarch64.sve.ptrue.nxv16i1(i32 31) %ret = tail call @llvm.aarch64.sve.sqabs.nxv16i8( undef, %pg, %a) ret %ret } ; Check movprfx is inserted when passthru is undef define @sqabs_i8_undef( %a, %b) #0 { ; CHECK-LABEL: sqabs_i8_undef: ; CHECK: // %bb.0: ; CHECK-NEXT: ptrue p0.b ; CHECK-NEXT: movprfx z0, z1 ; CHECK-NEXT: sqabs z0.b, p0/m, z1.b ; CHECK-NEXT: ret %pg = tail call @llvm.aarch64.sve.ptrue.nxv16i1(i32 31) %ret = tail call @llvm.aarch64.sve.sqabs.nxv16i8( undef, %pg, %b) ret %ret } ; Check movprfx is inserted when predicate is all active, making the passthru dead define @sqabs_i8_active( %a, %b) #0 { ; CHECK-LABEL: sqabs_i8_active: ; CHECK: // %bb.0: ; CHECK-NEXT: ptrue p0.b ; CHECK-NEXT: movprfx z0, z1 ; CHECK-NEXT: sqabs z0.b, p0/m, z1.b ; CHECK-NEXT: ret %pg = tail call @llvm.aarch64.sve.ptrue.nxv16i1(i32 31) %ret = tail call @llvm.aarch64.sve.sqabs.nxv16i8( %a, %pg, %b) ret %ret } ; Check movprfx is not inserted when predicate is not all active, making the passthru used define @sqabs_i8_not_active( %a, %b) #0 { ; CHECK-LABEL: sqabs_i8_not_active: ; CHECK: // %bb.0: ; CHECK-NEXT: ptrue p0.d ; CHECK-NEXT: sqabs z0.b, p0/m, z1.b ; CHECK-NEXT: ret %pg = tail call @llvm.aarch64.sve.ptrue.nxv2i1(i32 31) %pg.to = tail call @llvm.aarch64.sve.convert.to.svbool.nxv2i1( %pg) %ret = tail call @llvm.aarch64.sve.sqabs.nxv16i8( %a, %pg.to, %b) ret %ret } define @sqabs_i16_dupreg( %a) #0 { ; CHECK-LABEL: sqabs_i16_dupreg: ; CHECK: // %bb.0: ; CHECK-NEXT: ptrue p0.h ; CHECK-NEXT: sqabs z0.h, p0/m, z0.h ; CHECK-NEXT: ret %pg = tail call @llvm.aarch64.sve.ptrue.nxv8i1(i32 31) %ret = tail call @llvm.aarch64.sve.sqabs.nxv8i16( undef, %pg, %a) ret %ret } define @sqabs_i16_undef( %a, %b) #0 { ; CHECK-LABEL: sqabs_i16_undef: ; CHECK: // %bb.0: ; CHECK-NEXT: ptrue p0.h ; CHECK-NEXT: movprfx z0, z1 ; CHECK-NEXT: sqabs z0.h, p0/m, z1.h ; CHECK-NEXT: ret %pg = tail call @llvm.aarch64.sve.ptrue.nxv8i1(i32 31) %ret = tail call @llvm.aarch64.sve.sqabs.nxv8i16( undef, %pg, %b) ret %ret } define @sqabs_i16_active( %a, %b) #0 { ; CHECK-LABEL: sqabs_i16_active: ; CHECK: // %bb.0: ; CHECK-NEXT: ptrue p0.h ; CHECK-NEXT: movprfx z0, z1 ; CHECK-NEXT: sqabs z0.h, p0/m, z1.h ; CHECK-NEXT: ret %pg = tail call @llvm.aarch64.sve.ptrue.nxv8i1(i32 31) %ret = tail call @llvm.aarch64.sve.sqabs.nxv8i16( %a, %pg, %b) ret %ret } define @sqabs_i16_not_active( %a, %b) #0 { ; CHECK-LABEL: sqabs_i16_not_active: ; CHECK: // %bb.0: ; CHECK-NEXT: ptrue p0.d ; CHECK-NEXT: sqabs z0.h, p0/m, z1.h ; CHECK-NEXT: ret %pg = tail call @llvm.aarch64.sve.ptrue.nxv2i1(i32 31) %pg.to = tail call @llvm.aarch64.sve.convert.to.svbool.nxv2i1( %pg) %pg.from = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( %pg.to) %ret = tail call @llvm.aarch64.sve.sqabs.nxv8i16( %a, %pg.from, %b) ret %ret } define @sqabs_i32_dupreg( %a) #0 { ; CHECK-LABEL: sqabs_i32_dupreg: ; CHECK: // %bb.0: ; CHECK-NEXT: ptrue p0.s ; CHECK-NEXT: sqabs z0.s, p0/m, z0.s ; CHECK-NEXT: ret %pg = tail call @llvm.aarch64.sve.ptrue.nxv4i1(i32 31) %ret = tail call @llvm.aarch64.sve.sqabs.nxv4i32( undef, %pg, %a) ret %ret } define @sqabs_i32_undef( %a, %b) #0 { ; CHECK-LABEL: sqabs_i32_undef: ; CHECK: // %bb.0: ; CHECK-NEXT: ptrue p0.s ; CHECK-NEXT: movprfx z0, z1 ; CHECK-NEXT: sqabs z0.s, p0/m, z1.s ; CHECK-NEXT: ret %pg = tail call @llvm.aarch64.sve.ptrue.nxv4i1(i32 31) %ret = tail call @llvm.aarch64.sve.sqabs.nxv4i32( undef, %pg, %b) ret %ret } define @sqabs_i32_active( %a, %b) #0 { ; CHECK-LABEL: sqabs_i32_active: ; CHECK: // %bb.0: ; CHECK-NEXT: ptrue p0.s ; CHECK-NEXT: movprfx z0, z1 ; CHECK-NEXT: sqabs z0.s, p0/m, z1.s ; CHECK-NEXT: ret %pg = tail call @llvm.aarch64.sve.ptrue.nxv4i1(i32 31) %ret = tail call @llvm.aarch64.sve.sqabs.nxv4i32( %a, %pg, %b) ret %ret } define @sqabs_i32_not_active( %a, %b) #0 { ; CHECK-LABEL: sqabs_i32_not_active: ; CHECK: // %bb.0: ; CHECK-NEXT: ptrue p0.d ; CHECK-NEXT: sqabs z0.s, p0/m, z1.s ; CHECK-NEXT: ret %pg = tail call @llvm.aarch64.sve.ptrue.nxv2i1(i32 31) %pg.to = tail call @llvm.aarch64.sve.convert.to.svbool.nxv2i1( %pg) %pg.from = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( %pg.to) %ret = tail call @llvm.aarch64.sve.sqabs.nxv4i32( %a, %pg.from, %b) ret %ret } define @sqabs_i64_dupreg( %a) #0 { ; CHECK-LABEL: sqabs_i64_dupreg: ; CHECK: // %bb.0: ; CHECK-NEXT: ptrue p0.d ; CHECK-NEXT: sqabs z0.d, p0/m, z0.d ; CHECK-NEXT: ret %pg = tail call @llvm.aarch64.sve.ptrue.nxv2i1(i32 31) %ret = tail call @llvm.aarch64.sve.sqabs.nxv2i64( undef, %pg, %a) ret %ret } define @sqabs_i64_undef( %a, %b) #0 { ; CHECK-LABEL: sqabs_i64_undef: ; CHECK: // %bb.0: ; CHECK-NEXT: ptrue p0.d ; CHECK-NEXT: movprfx z0, z1 ; CHECK-NEXT: sqabs z0.d, p0/m, z1.d ; CHECK-NEXT: ret %pg = tail call @llvm.aarch64.sve.ptrue.nxv2i1(i32 31) %ret = tail call @llvm.aarch64.sve.sqabs.nxv2i64( undef, %pg, %b) ret %ret } define @sqabs_i64_active( %a, %b) #0 { ; CHECK-LABEL: sqabs_i64_active: ; CHECK: // %bb.0: ; CHECK-NEXT: ptrue p0.d ; CHECK-NEXT: movprfx z0, z1 ; CHECK-NEXT: sqabs z0.d, p0/m, z1.d ; CHECK-NEXT: ret %pg = tail call @llvm.aarch64.sve.ptrue.nxv2i1(i32 31) %ret = tail call @llvm.aarch64.sve.sqabs.nxv2i64( %a, %pg, %b) ret %ret } define @sqabs_i64_not_active( %a, %b, %pg) #0 { ; CHECK-LABEL: sqabs_i64_not_active: ; CHECK: // %bb.0: ; CHECK-NEXT: sqabs z0.d, p0/m, z1.d ; CHECK-NEXT: ret %ret = tail call @llvm.aarch64.sve.sqabs.nxv2i64( %a, %pg, %b) ret %ret } ; ; URECPE (sve2_int_un_pred_arit_s) ; define @urecpe_i32_dupreg( %a) #0 { ; CHECK-LABEL: urecpe_i32_dupreg: ; CHECK: // %bb.0: ; CHECK-NEXT: ptrue p0.s ; CHECK-NEXT: urecpe z0.s, p0/m, z0.s ; CHECK-NEXT: ret %pg = tail call @llvm.aarch64.sve.ptrue.nxv4i1(i32 31) %ret = tail call @llvm.aarch64.sve.urecpe.nxv4i32( undef, %pg, %a) ret %ret } define @urecpe_i32_undef( %a, %b) #0 { ; CHECK-LABEL: urecpe_i32_undef: ; CHECK: // %bb.0: ; CHECK-NEXT: ptrue p0.s ; CHECK-NEXT: movprfx z0, z1 ; CHECK-NEXT: urecpe z0.s, p0/m, z1.s ; CHECK-NEXT: ret %pg = tail call @llvm.aarch64.sve.ptrue.nxv4i1(i32 31) %ret = tail call @llvm.aarch64.sve.urecpe.nxv4i32( undef, %pg, %b) ret %ret } define @urecpe_i32_active( %a, %b) #0 { ; CHECK-LABEL: urecpe_i32_active: ; CHECK: // %bb.0: ; CHECK-NEXT: ptrue p0.s ; CHECK-NEXT: movprfx z0, z1 ; CHECK-NEXT: urecpe z0.s, p0/m, z1.s ; CHECK-NEXT: ret %pg = tail call @llvm.aarch64.sve.ptrue.nxv4i1(i32 31) %ret = tail call @llvm.aarch64.sve.urecpe.nxv4i32( %a, %pg, %b) ret %ret } define @urecpe_i32_not_active( %a, %b) #0 { ; CHECK-LABEL: urecpe_i32_not_active: ; CHECK: // %bb.0: ; CHECK-NEXT: ptrue p0.d ; CHECK-NEXT: urecpe z0.s, p0/m, z1.s ; CHECK-NEXT: ret %pg = tail call @llvm.aarch64.sve.ptrue.nxv2i1(i32 31) %pg.to = tail call @llvm.aarch64.sve.convert.to.svbool.nxv2i1( %pg) %pg.from = tail call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( %pg.to) %ret = tail call @llvm.aarch64.sve.urecpe.nxv4i32( %a, %pg.from, %b) ret %ret } declare @llvm.aarch64.sve.ptrue.nxv16i1(i32) declare @llvm.aarch64.sve.ptrue.nxv8i1(i32) declare @llvm.aarch64.sve.ptrue.nxv4i1(i32) declare @llvm.aarch64.sve.ptrue.nxv2i1(i32) declare @llvm.aarch64.sve.convert.to.svbool.nxv8i1() declare @llvm.aarch64.sve.convert.to.svbool.nxv4i1() declare @llvm.aarch64.sve.convert.to.svbool.nxv2i1() declare @llvm.aarch64.sve.convert.from.svbool.nxv8i1() declare @llvm.aarch64.sve.convert.from.svbool.nxv4i1() declare @llvm.aarch64.sve.convert.from.svbool.nxv2i1() declare @llvm.aarch64.sve.sqabs.nxv16i8(, , ) declare @llvm.aarch64.sve.sqabs.nxv8i16(, , ) declare @llvm.aarch64.sve.sqabs.nxv4i32(, , ) declare @llvm.aarch64.sve.sqabs.nxv2i64(, , ) declare @llvm.aarch64.sve.urecpe.nxv4i32(, , ) attributes #0 = { nounwind "target-features"="+sve2" }