diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td index e4ad27d4bcfc0..f7121373593fb 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td @@ -381,6 +381,9 @@ def NoUseScalarIncVL : Predicate<"!Subtarget->useScalarIncVL()">; def UseSVEFPLD1R : Predicate<"!Subtarget->noSVEFPLD1R()">; +def UseUnaryUndefPseudos + : Predicate<"!(Subtarget->isSVEorStreamingSVEAvailable() && (Subtarget->hasSVE2p2() || Subtarget->hasSME2p2()))">; + def AArch64LocalRecover : SDNode<"ISD::LOCAL_RECOVER", SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>, SDTCisInt<1>]>>; diff --git a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td index 4f146b3ee59e9..b516fe720e10c 100644 --- a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td @@ -664,6 +664,14 @@ let Predicates = [HasSVEorSME] in { defm FABS_ZPmZ : sve_int_un_pred_arit_bitwise_fp<0b100, "fabs", AArch64fabs_mt>; defm FNEG_ZPmZ : sve_int_un_pred_arit_bitwise_fp<0b101, "fneg", AArch64fneg_mt>; + let Predicates = [HasSVEorSME, UseUnaryUndefPseudos] in { + defm FABS_ZPmZ : sve_fp_un_pred_arit_hsd; + defm FNEG_ZPmZ : sve_fp_un_pred_arit_hsd; + + defm ABS_ZPmZ : sve_int_un_pred_arit_bhsd; + defm NEG_ZPmZ : sve_int_un_pred_arit_bhsd; + } + foreach VT = [nxv2bf16, nxv4bf16, nxv8bf16] in { // No dedicated instruction, so just clear the sign bit. def : Pat<(VT (fabs VT:$op)), @@ -2411,6 +2419,10 @@ let Predicates = [HasSVEorSME] in { (nxv2i64 (splat_vector (i64 0xFFFFFFFF)))), nxv2f64:$Zd)), (UCVTF_ZPmZ_StoD_UNDEF ZPR:$Zd, PPR:$Pg, ZPR:$Zs)>; + let Predicates = [HasSVEorSME, UseUnaryUndefPseudos] in { + defm FCVT_ZPmZ : sve_fp_2op_p_zd_pat<"int_aarch64_sve_fcvt">; + } + defm FRINTN_ZPmZ : sve_fp_2op_p_zd_HSD<0b00000, "frintn", AArch64frintn_mt>; defm FRINTP_ZPmZ : sve_fp_2op_p_zd_HSD<0b00001, "frintp", AArch64frintp_mt>; defm FRINTM_ZPmZ : sve_fp_2op_p_zd_HSD<0b00010, "frintm", AArch64frintm_mt>; @@ -4246,21 +4258,21 @@ defm TBLQ_ZZZ : sve2p1_tblq<"tblq", int_aarch64_sve_tblq>; //===----------------------------------------------------------------------===// let Predicates = [HasSVE2p2orSME2p2] in { // SVE Floating-point convert precision, zeroing predicate - defm FCVT_ZPzZ : sve_fp_z2op_p_zd_b_0<"fcvt">; + defm FCVT_ZPzZ : sve_fp_z2op_p_zd_b_0<"fcvt", "int_aarch64_sve_fcvt">; // SVE2p2 floating-point convert precision down (placing odd), zeroing predicate defm FCVTNT_ZPzZ : sve_fp_fcvtntz<"fcvtnt">; def FCVTXNT_ZPzZ_DtoS : sve_fp_fcvt2z<0b0010, "fcvtxnt", ZPR32, ZPR64>; // Placing even - def FCVTX_ZPzZ_DtoS : sve_fp_z2op_p_zd<0b0001010, "fcvtx", ZPR64, ZPR32>; + defm FCVTX_ZPzZ : sve_fp_z2op_p_zd<"fcvtx", int_aarch64_sve_fcvtx_f32f64>; // SVE2p2 floating-point convert precision up, zeroing predicate - defm FCVTLT_ZPzZ : sve_fp_fcvtltz<"fcvtlt">; + defm FCVTLT_ZPzZ : sve_fp_fcvtltz<"fcvtlt", "int_aarch64_sve_fcvtlt">; // SVE2p2 floating-point convert single-to-bf (placing odd), zeroing predicate def BFCVTNT_ZPzZ : sve_fp_fcvt2z<0b1010, "bfcvtnt", ZPR16, ZPR32>; // Placing corresponding - def BFCVT_ZPzZ_StoH : sve_fp_z2op_p_zd<0b1001010, "bfcvt", ZPR32, ZPR16>; + defm BFCVT_ZPzZ_StoH : sve_fp_z2op_p_zd_bfcvt<0b1001010, "bfcvt", int_aarch64_sve_fcvt_bf16f32_v2>; // Floating-point convert to integer, zeroing predicate defm FCVTZS_ZPzZ : sve_fp_z2op_p_zd_d<0b0, "fcvtzs">; @@ -4310,16 +4322,16 @@ let Predicates = [HasSVE2p2orSME2p2] in { defm NOT_ZPzZ : sve_int_un_pred_arit_bitwise_z<0b110, "not">; // floating point - defm FABS_ZPzZ : sve_int_un_pred_arit_bitwise_fp_z<0b100, "fabs">; - defm FNEG_ZPzZ : sve_int_un_pred_arit_bitwise_fp_z<0b101, "fneg">; + defm FABS_ZPzZ : sve_int_un_pred_arit_bitwise_fp_z<0b100, "fabs", AArch64fabs_mt>; + defm FNEG_ZPzZ : sve_int_un_pred_arit_bitwise_fp_z<0b101, "fneg", AArch64fneg_mt>; // SVE2p2 integer unary arithmetic, zeroing predicate defm SXTB_ZPzZ : sve_int_un_pred_arit_h_z<0b000, "sxtb">; defm UXTB_ZPzZ : sve_int_un_pred_arit_h_z<0b001, "uxtb">; defm SXTH_ZPzZ : sve_int_un_pred_arit_w_z<0b010, "sxth">; defm UXTH_ZPzZ : sve_int_un_pred_arit_w_z<0b011, "uxth">; - defm ABS_ZPzZ : sve_int_un_pred_arit_z< 0b110, "abs">; - defm NEG_ZPzZ : sve_int_un_pred_arit_z< 0b111, "neg">; + defm ABS_ZPzZ : sve_int_un_pred_arit_z< 0b110, "abs", AArch64abs_mt>; + defm NEG_ZPzZ : sve_int_un_pred_arit_z< 0b111, "neg", AArch64neg_mt>; def SXTW_ZPzZ_D : sve_int_un_pred_arit_z<0b11, 0b1000, "sxtw", ZPR64>; def UXTW_ZPzZ_D : sve_int_un_pred_arit_z<0b11, 0b1010, "uxtw", ZPR64>; diff --git a/llvm/lib/Target/AArch64/SVEInstrFormats.td b/llvm/lib/Target/AArch64/SVEInstrFormats.td index 6de6aed3b2a81..7d6dd033e177c 100644 --- a/llvm/lib/Target/AArch64/SVEInstrFormats.td +++ b/llvm/lib/Target/AArch64/SVEInstrFormats.td @@ -482,6 +482,8 @@ let Predicates = [HasSVEorSME] in { //===----------------------------------------------------------------------===// // SVE pattern match helpers. //===----------------------------------------------------------------------===// +def SVEDup0 : ComplexPattern; +def SVEDup0Undef : ComplexPattern; class SVE_1_Op_Pat @@ -502,6 +504,11 @@ multiclass SVE_1_Op_PassthruUndef_Pat; } +class SVE_1_Op_PassthruUndefZero_Pat + : Pat<(vtd (op pg:$Op1, vts:$Op2, (vtd (SVEDup0Undef)))), + (inst $Op1, $Op2)>; + // Used to match FP_ROUND_MERGE_PASSTHRU, which has an additional flag for the // type of rounding. This is matched by timm0_1 in pattern below and ignored. class SVE_1_Op_Passthru_Round_Pat; } -def SVEDup0 : ComplexPattern; - class SVE_1_Op_PassthruZero_Pat : Pat<(vtd (op (vtd (SVEDup0)), vt1:$Op1, vt2:$Op2)), @@ -571,6 +576,11 @@ multiclass SVE_3_Op_Undef_Pat; } +class SVE_3_Op_UndefZero_Pat + : Pat<(vtd (op (vt1 (SVEDup0Undef)), vt2:$Op1, vt3:$Op2)), + (inst $Op1, $Op2)>; + class SVE_4_Op_Pat @@ -606,8 +616,6 @@ class SVE_4_Op_Imm_Pat; -def SVEDup0Undef : ComplexPattern; - let AddedComplexity = 1 in { class SVE_3_Op_Pat_SelZero @@ -2850,9 +2858,12 @@ multiclass sve_fp_fcvtntz { def _DtoS : sve_fp_fcvt2z<0b1110, asm, ZPR32, ZPR64>; } -multiclass sve_fp_fcvtltz { +multiclass sve_fp_fcvtltz { def _HtoS : sve_fp_fcvt2z<0b1001, asm, ZPR32, ZPR16>; def _StoD : sve_fp_fcvt2z<0b1111, asm, ZPR64, ZPR32>; + + def : SVE_3_Op_UndefZero_Pat(op # _f32f16), nxv4f32, nxv4i1, nxv8f16, !cast(NAME # _HtoS)>; + def : SVE_3_Op_UndefZero_Pat(op # _f64f32), nxv2f64, nxv2i1, nxv4f32, !cast(NAME # _StoD)>; } //===----------------------------------------------------------------------===// @@ -3136,6 +3147,16 @@ multiclass sve_fp_2op_p_zdr opc, string asm, defm : SVE_1_Op_PassthruUndef_Round_Pat(NAME # _UNDEF)>; } +multiclass sve_fp_2op_p_zd_pat { + defm : SVE_3_Op_Undef_Pat(op # _f16f32), nxv8f16, nxv4i1, nxv4f32, !cast(NAME # _StoH)>; + defm : SVE_3_Op_Undef_Pat(op # _f16f64), nxv8f16, nxv2i1, nxv2f64, !cast(NAME # _DtoH)>; + defm : SVE_3_Op_Undef_Pat(op # _f32f64), nxv4f32, nxv2i1, nxv2f64, !cast(NAME # _DtoS)>; + + defm : SVE_3_Op_Undef_Pat(op # _f32f16), nxv4f32, nxv4i1, nxv8f16, !cast(NAME # _HtoS)>; + defm : SVE_3_Op_Undef_Pat(op # _f64f16), nxv2f64, nxv2i1, nxv8f16, !cast(NAME # _HtoD)>; + defm : SVE_3_Op_Undef_Pat(op # _f64f32), nxv2f64, nxv2i1, nxv4f32, !cast(NAME # _StoD)>; +} + multiclass sve_fp_2op_p_zd_HSD opc, string asm, SDPatternOperator op> { def _H : sve_fp_2op_p_zd<{ 0b01, opc }, asm, ZPR16, ZPR16, ElementSizeH>, SVEPseudo2Instr; @@ -3259,6 +3280,12 @@ class sve_fp_z2op_p_zd opc,string asm, RegisterOperand i_zprtype, let mayRaiseFPException = 1; } +multiclass sve_fp_z2op_p_zd { + def _DtoS : sve_fp_z2op_p_zd<0b0001010, asm, ZPR64, ZPR32>; + + def : SVE_3_Op_UndefZero_Pat(NAME # _DtoS)>; +} + multiclass sve_fp_z2op_p_zd_hsd opc, string asm> { def _H : sve_fp_z2op_p_zd<{ 0b01, opc }, asm, ZPR16, ZPR16>; def _S : sve_fp_z2op_p_zd<{ 0b10, opc }, asm, ZPR32, ZPR32>; @@ -3270,6 +3297,12 @@ multiclass sve_fp_z2op_p_zd_frint opc, string asm> { def _D : sve_fp_z2op_p_zd<{ 0b0010, opc{1}, 1, opc{0} }, asm, ZPR64, ZPR64>; } +multiclass sve_fp_z2op_p_zd_bfcvt opc, string asm, SDPatternOperator op> { + def _StoH : sve_fp_z2op_p_zd; + + def : SVE_3_Op_UndefZero_Pat(NAME # _StoH)>; +} + multiclass sve_fp_z2op_p_zd_d { def _HtoH : sve_fp_z2op_p_zd<{ 0b011101, U }, asm, ZPR16, ZPR16>; def _HtoS : sve_fp_z2op_p_zd<{ 0b011110, U }, asm, ZPR16, ZPR32>; @@ -3296,13 +3329,20 @@ multiclass sve_fp_z2op_p_zd_d_flogb { def _D : sve_fp_z2op_p_zd<0b0011011, asm, ZPR64, ZPR64>; } -multiclass sve_fp_z2op_p_zd_b_0 { +multiclass sve_fp_z2op_p_zd_b_0 { def _StoH : sve_fp_z2op_p_zd<0b1001000, asm, ZPR32, ZPR16>; def _HtoS : sve_fp_z2op_p_zd<0b1001001, asm, ZPR16, ZPR32>; def _DtoH : sve_fp_z2op_p_zd<0b1101000, asm, ZPR64, ZPR16>; def _HtoD : sve_fp_z2op_p_zd<0b1101001, asm, ZPR16, ZPR64>; def _DtoS : sve_fp_z2op_p_zd<0b1101010, asm, ZPR64, ZPR32>; def _StoD : sve_fp_z2op_p_zd<0b1101011, asm, ZPR32, ZPR64>; + + def : SVE_3_Op_UndefZero_Pat(op # _f16f32), nxv8f16, nxv4i1, nxv4f32, !cast(NAME # _StoH)>; + def : SVE_3_Op_UndefZero_Pat(op # _f16f64), nxv8f16, nxv2i1, nxv2f64, !cast(NAME # _DtoH)>; + def : SVE_3_Op_UndefZero_Pat(op # _f32f64), nxv4f32, nxv2i1, nxv2f64, !cast(NAME # _DtoS)>; + def : SVE_3_Op_UndefZero_Pat(op # _f32f16), nxv4f32, nxv4i1, nxv8f16, !cast(NAME # _HtoS)>; + def : SVE_3_Op_UndefZero_Pat(op # _f64f16), nxv2f64, nxv2i1, nxv8f16, !cast(NAME # _HtoD)>; + def : SVE_3_Op_UndefZero_Pat(op # _f64f32), nxv2f64, nxv2i1, nxv4f32, !cast(NAME # _StoD)>; } //===----------------------------------------------------------------------===// @@ -4820,23 +4860,18 @@ multiclass sve_int_un_pred_arit opc, string asm, def : SVE_1_Op_Passthru_Pat(NAME # _H)>; def : SVE_1_Op_Passthru_Pat(NAME # _S)>; def : SVE_1_Op_Passthru_Pat(NAME # _D)>; - - def _B_UNDEF : PredOneOpPassthruPseudo; - def _H_UNDEF : PredOneOpPassthruPseudo; - def _S_UNDEF : PredOneOpPassthruPseudo; - def _D_UNDEF : PredOneOpPassthruPseudo; - - defm : SVE_1_Op_PassthruUndef_Pat(NAME # _B_UNDEF)>; - defm : SVE_1_Op_PassthruUndef_Pat(NAME # _H_UNDEF)>; - defm : SVE_1_Op_PassthruUndef_Pat(NAME # _S_UNDEF)>; - defm : SVE_1_Op_PassthruUndef_Pat(NAME # _D_UNDEF)>; } -multiclass sve_int_un_pred_arit_z opc, string asm> { +multiclass sve_int_un_pred_arit_z opc, string asm, SDPatternOperator op> { def _B : sve_int_un_pred_arit_z<0b00, { opc, 0b0 }, asm, ZPR8>; def _H : sve_int_un_pred_arit_z<0b01, { opc, 0b0 }, asm, ZPR16>; def _S : sve_int_un_pred_arit_z<0b10, { opc, 0b0 }, asm, ZPR32>; def _D : sve_int_un_pred_arit_z<0b11, { opc, 0b0 }, asm, ZPR64>; + + def : SVE_1_Op_PassthruUndefZero_Pat(NAME # _B)>; + def : SVE_1_Op_PassthruUndefZero_Pat(NAME # _H)>; + def : SVE_1_Op_PassthruUndefZero_Pat(NAME # _S)>; + def : SVE_1_Op_PassthruUndefZero_Pat(NAME # _D)>; } multiclass sve_int_un_pred_arit_h opc, string asm, @@ -4950,7 +4985,22 @@ multiclass sve_int_un_pred_arit_bitwise_fp opc, string asm, def : SVE_1_Op_Passthru_Pat(NAME # _S)>; def : SVE_1_Op_Passthru_Pat(NAME # _S)>; def : SVE_1_Op_Passthru_Pat(NAME # _D)>; +} + +multiclass sve_int_un_pred_arit_bitwise_fp_z opc, string asm, SDPatternOperator op> { + def _H : sve_int_un_pred_arit_z<0b01, { opc, 0b1 }, asm, ZPR16>; + def _S : sve_int_un_pred_arit_z<0b10, { opc, 0b1 }, asm, ZPR32>; + def _D : sve_int_un_pred_arit_z<0b11, { opc, 0b1 }, asm, ZPR64>; + + def : SVE_1_Op_PassthruUndefZero_Pat(NAME # _H)>; + def : SVE_1_Op_PassthruUndefZero_Pat(NAME # _H)>; + def : SVE_1_Op_PassthruUndefZero_Pat(NAME # _H)>; + def : SVE_1_Op_PassthruUndefZero_Pat(NAME # _S)>; + def : SVE_1_Op_PassthruUndefZero_Pat(NAME # _S)>; + def : SVE_1_Op_PassthruUndefZero_Pat(NAME # _D)>; +} +multiclass sve_fp_un_pred_arit_hsd { def _H_UNDEF : PredOneOpPassthruPseudo; def _S_UNDEF : PredOneOpPassthruPseudo; def _D_UNDEF : PredOneOpPassthruPseudo; @@ -4963,10 +5013,16 @@ multiclass sve_int_un_pred_arit_bitwise_fp opc, string asm, defm : SVE_1_Op_PassthruUndef_Pat(NAME # _D_UNDEF)>; } -multiclass sve_int_un_pred_arit_bitwise_fp_z opc, string asm> { - def _H : sve_int_un_pred_arit_z<0b01, { opc, 0b1 }, asm, ZPR16>; - def _S : sve_int_un_pred_arit_z<0b10, { opc, 0b1 }, asm, ZPR32>; - def _D : sve_int_un_pred_arit_z<0b11, { opc, 0b1 }, asm, ZPR64>; +multiclass sve_int_un_pred_arit_bhsd { + def _B_UNDEF : PredOneOpPassthruPseudo; + def _H_UNDEF : PredOneOpPassthruPseudo; + def _S_UNDEF : PredOneOpPassthruPseudo; + def _D_UNDEF : PredOneOpPassthruPseudo; + + defm : SVE_1_Op_PassthruUndef_Pat(NAME # _B_UNDEF)>; + defm : SVE_1_Op_PassthruUndef_Pat(NAME # _H_UNDEF)>; + defm : SVE_1_Op_PassthruUndef_Pat(NAME # _S_UNDEF)>; + defm : SVE_1_Op_PassthruUndef_Pat(NAME # _D_UNDEF)>; } //===----------------------------------------------------------------------===// diff --git a/llvm/test/CodeGen/AArch64/zeroing-forms-abs-neg.ll b/llvm/test/CodeGen/AArch64/zeroing-forms-abs-neg.ll new file mode 100644 index 0000000000000..1caee994220f0 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/zeroing-forms-abs-neg.ll @@ -0,0 +1,666 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 +; RUN: llc -mattr=+sve < %s | FileCheck %s +; RUN: llc -mattr=+sve2p2 < %s | FileCheck %s -check-prefix CHECK-2p2 + +; RUN: llc -mattr=+sme -force-streaming < %s | FileCheck %s +; RUN: llc -mattr=+sme2p2 -force-streaming < %s | FileCheck %s -check-prefix CHECK-2p2 + +target triple = "aarch64-linux" + +define @test_svabs_f64_x_1( %pg, %x) { +; CHECK-LABEL: test_svabs_f64_x_1: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: fabs z0.d, p0/m, z0.d +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svabs_f64_x_1: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: fabs z0.d, p0/z, z0.d +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.fabs.nxv2f64( undef, %pg, %x) + ret %0 +} + +define @test_svabs_f64_x_2( %pg, double %z0, %x) { +; CHECK-LABEL: test_svabs_f64_x_2: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: movprfx z0, z1 +; CHECK-NEXT: fabs z0.d, p0/m, z1.d +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svabs_f64_x_2: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: fabs z0.d, p0/z, z1.d +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.fabs.nxv2f64( undef, %pg, %x) + ret %0 +} + +define @test_svabs_f64_z( %pg, double %z0, %x) { +; CHECK-LABEL: test_svabs_f64_z: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: mov z0.d, #0 // =0x0 +; CHECK-NEXT: fabs z0.d, p0/m, z1.d +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svabs_f64_z: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: fabs z0.d, p0/z, z1.d +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.fabs.nxv2f64( zeroinitializer, %pg, %x) + ret %0 +} + +define @test_svabs_f32_x_1( %pg, %x) { +; CHECK-LABEL: test_svabs_f32_x_1: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: fabs z0.s, p0/m, z0.s +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svabs_f32_x_1: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: fabs z0.s, p0/z, z0.s +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.fabs.nxv4f32( undef, %pg, %x) + ret %0 +} + +define @test_svabs_f32_x_2( %pg, double %z0, %x) { +; CHECK-LABEL: test_svabs_f32_x_2: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: movprfx z0, z1 +; CHECK-NEXT: fabs z0.s, p0/m, z1.s +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svabs_f32_x_2: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: fabs z0.s, p0/z, z1.s +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.fabs.nxv4f32( undef, %pg, %x) + ret %0 +} + +define @test_svabs_f32_z( %pg, double %z0, %x) { +; CHECK-LABEL: test_svabs_f32_z: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: mov z0.s, #0 // =0x0 +; CHECK-NEXT: fabs z0.s, p0/m, z1.s +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svabs_f32_z: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: fabs z0.s, p0/z, z1.s +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.fabs.nxv4f32( zeroinitializer, %pg, %x) + ret %0 +} + +define @test_svabs_f16_x_1( %pg, %x) { +; CHECK-LABEL: test_svabs_f16_x_1: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: fabs z0.h, p0/m, z0.h +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svabs_f16_x_1: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: fabs z0.h, p0/z, z0.h +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.fabs.nxv8f16( undef, %pg, %x) + ret %0 +} + +define @test_svabs_f16_x_2( %pg, double %z0, %x) { +; CHECK-LABEL: test_svabs_f16_x_2: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: movprfx z0, z1 +; CHECK-NEXT: fabs z0.h, p0/m, z1.h +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svabs_f16_x_2: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: fabs z0.h, p0/z, z1.h +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.fabs.nxv8f16( undef, %pg, %x) + ret %0 +} + +define @test_svabs_f16_z( %pg, double %z0, %x) { +; CHECK-LABEL: test_svabs_f16_z: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: mov z0.h, #0 // =0x0 +; CHECK-NEXT: fabs z0.h, p0/m, z1.h +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svabs_f16_z: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: fabs z0.h, p0/z, z1.h +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.fabs.nxv8f16( zeroinitializer, %pg, %x) + ret %0 +} + +define @test_svabs_s8_x_1( %pg, %x) { +; CHECK-LABEL: test_svabs_s8_x_1: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: abs z0.b, p0/m, z0.b +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svabs_s8_x_1: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: abs z0.b, p0/z, z0.b +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.abs.nxv16i8( undef, %pg, %x) + ret %0 +} + +define @test_svabs_s8_x_2( %pg, double %z0, %x) { +; CHECK-LABEL: test_svabs_s8_x_2: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: movprfx z0, z1 +; CHECK-NEXT: abs z0.b, p0/m, z1.b +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svabs_s8_x_2: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: abs z0.b, p0/z, z1.b +; CHECK-2p2-NEXT: ret +entry: + %1 = tail call @llvm.aarch64.sve.abs.nxv16i8( undef, %pg, %x) + ret %1 +} + +define @test_svabs_s8_z( %pg, double %z0, %x) { +; CHECK-LABEL: test_svabs_s8_z: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: mov z0.b, #0 // =0x0 +; CHECK-NEXT: abs z0.b, p0/m, z1.b +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svabs_s8_z: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: abs z0.b, p0/z, z1.b +; CHECK-2p2-NEXT: ret +entry: + %1 = tail call @llvm.aarch64.sve.abs.nxv16i8( zeroinitializer, %pg, %x) + ret %1 +} + +define @test_svabs_s16_x_1( %pg, %x) { +; CHECK-LABEL: test_svabs_s16_x_1: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: abs z0.h, p0/m, z0.h +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svabs_s16_x_1: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: abs z0.h, p0/z, z0.h +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.abs.nxv8i16( undef, %pg, %x) + ret %0 +} + +define @test_svabs_s16_x_2( %pg, double %z0, %x) { +; CHECK-LABEL: test_svabs_s16_x_2: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: movprfx z0, z1 +; CHECK-NEXT: abs z0.h, p0/m, z1.h +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svabs_s16_x_2: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: abs z0.h, p0/z, z1.h +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.abs.nxv8i16( undef, %pg, %x) + ret %0 +} + +define @test_svabs_s16_z( %pg, double %z0, %x) { +; CHECK-LABEL: test_svabs_s16_z: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: mov z0.h, #0 // =0x0 +; CHECK-NEXT: abs z0.h, p0/m, z1.h +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svabs_s16_z: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: abs z0.h, p0/z, z1.h +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.abs.nxv8i16( zeroinitializer, %pg, %x) + ret %0 +} + +define @test_svabs_s32_x_1( %pg, %x) { +; CHECK-LABEL: test_svabs_s32_x_1: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: abs z0.s, p0/m, z0.s +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svabs_s32_x_1: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: abs z0.s, p0/z, z0.s +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.abs.nxv4i32( undef, %pg, %x) + ret %0 +} + +define @test_svabs_s32_x_2( %pg, double %z0, %x) { +; CHECK-LABEL: test_svabs_s32_x_2: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: movprfx z0, z1 +; CHECK-NEXT: abs z0.s, p0/m, z1.s +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svabs_s32_x_2: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: abs z0.s, p0/z, z1.s +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.abs.nxv4i32( undef, %pg, %x) + ret %0 +} + +define @test_svabs_s32_z( %pg, double %z0, %x) { +; CHECK-LABEL: test_svabs_s32_z: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: mov z0.s, #0 // =0x0 +; CHECK-NEXT: abs z0.s, p0/m, z1.s +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svabs_s32_z: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: abs z0.s, p0/z, z1.s +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.abs.nxv4i32( zeroinitializer, %pg, %x) + ret %0 +} + +define @test_svabs_s64_x_1( %pg, %x) { +; CHECK-LABEL: test_svabs_s64_x_1: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: abs z0.d, p0/m, z0.d +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svabs_s64_x_1: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: abs z0.d, p0/z, z0.d +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.abs.nxv2i64( undef, %pg, %x) + ret %0 +} + +define @test_svabs_s64_x_2( %pg, double %z0, %x) { +; CHECK-LABEL: test_svabs_s64_x_2: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: movprfx z0, z1 +; CHECK-NEXT: abs z0.d, p0/m, z1.d +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svabs_s64_x_2: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: abs z0.d, p0/z, z1.d +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.abs.nxv2i64( undef, %pg, %x) + ret %0 +} + +define @test_svabs_s64_z( %pg, double %z0, %x) { +; CHECK-LABEL: test_svabs_s64_z: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: mov z0.d, #0 // =0x0 +; CHECK-NEXT: abs z0.d, p0/m, z1.d +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svabs_s64_z: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: abs z0.d, p0/z, z1.d +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.abs.nxv2i64( zeroinitializer, %pg, %x) + ret %0 +} + +define @test_svneg_f64_x_1( %pg, %x) { +; CHECK-LABEL: test_svneg_f64_x_1: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: fneg z0.d, p0/m, z0.d +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svneg_f64_x_1: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: fneg z0.d, p0/z, z0.d +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.fneg.nxv2f64( undef, %pg, %x) + ret %0 +} + +define @test_svneg_f64_x_2( %pg, double %z0, %x) { +; CHECK-LABEL: test_svneg_f64_x_2: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: movprfx z0, z1 +; CHECK-NEXT: fneg z0.d, p0/m, z1.d +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svneg_f64_x_2: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: fneg z0.d, p0/z, z1.d +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.fneg.nxv2f64( undef, %pg, %x) + ret %0 +} + +define @test_svneg_f64_z( %pg, double %z0, %x) { +; CHECK-LABEL: test_svneg_f64_z: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: mov z0.d, #0 // =0x0 +; CHECK-NEXT: fneg z0.d, p0/m, z1.d +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svneg_f64_z: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: fneg z0.d, p0/z, z1.d +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.fneg.nxv2f64( zeroinitializer, %pg, %x) + ret %0 +} + +define @test_svneg_f32_x_1( %pg, %x) { +; CHECK-LABEL: test_svneg_f32_x_1: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: fneg z0.s, p0/m, z0.s +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svneg_f32_x_1: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: fneg z0.s, p0/z, z0.s +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.fneg.nxv4f32( undef, %pg, %x) + ret %0 +} + +define @test_svneg_f32_x_2( %pg, double %z0, %x) { +; CHECK-LABEL: test_svneg_f32_x_2: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: movprfx z0, z1 +; CHECK-NEXT: fneg z0.s, p0/m, z1.s +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svneg_f32_x_2: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: fneg z0.s, p0/z, z1.s +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.fneg.nxv4f32( undef, %pg, %x) + ret %0 +} + +define @test_svneg_f32_z( %pg, double %z0, %x) { +; CHECK-LABEL: test_svneg_f32_z: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: mov z0.s, #0 // =0x0 +; CHECK-NEXT: fneg z0.s, p0/m, z1.s +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svneg_f32_z: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: fneg z0.s, p0/z, z1.s +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.fneg.nxv4f32( zeroinitializer, %pg, %x) + ret %0 +} + +define @test_svneg_f16_x_1( %pg, %x) { +; CHECK-LABEL: test_svneg_f16_x_1: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: fneg z0.h, p0/m, z0.h +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svneg_f16_x_1: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: fneg z0.h, p0/z, z0.h +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.fneg.nxv8f16( undef, %pg, %x) + ret %0 +} + +define @test_svneg_f16_x_2( %pg, double %z0, %x) { +; CHECK-LABEL: test_svneg_f16_x_2: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: movprfx z0, z1 +; CHECK-NEXT: fneg z0.h, p0/m, z1.h +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svneg_f16_x_2: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: fneg z0.h, p0/z, z1.h +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.fneg.nxv8f16( undef, %pg, %x) + ret %0 +} + +define @test_svneg_f16_z( %pg, double %z0, %x) { +; CHECK-LABEL: test_svneg_f16_z: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: mov z0.h, #0 // =0x0 +; CHECK-NEXT: fneg z0.h, p0/m, z1.h +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svneg_f16_z: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: fneg z0.h, p0/z, z1.h +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.fneg.nxv8f16( zeroinitializer, %pg, %x) + ret %0 +} + +define @test_svneg_s8_x_1( %pg, %x) { +; CHECK-LABEL: test_svneg_s8_x_1: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: neg z0.b, p0/m, z0.b +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svneg_s8_x_1: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: neg z0.b, p0/z, z0.b +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.neg.nxv16i8( undef, %pg, %x) + ret %0 +} + +define @test_svneg_s8_x_2( %pg, double %z0, %x) { +; CHECK-LABEL: test_svneg_s8_x_2: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: movprfx z0, z1 +; CHECK-NEXT: neg z0.b, p0/m, z1.b +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svneg_s8_x_2: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: neg z0.b, p0/z, z1.b +; CHECK-2p2-NEXT: ret +entry: + %1 = tail call @llvm.aarch64.sve.neg.nxv16i8( undef, %pg, %x) + ret %1 +} + +define @test_svneg_s8_z( %pg, double %z0, %x) { +; CHECK-LABEL: test_svneg_s8_z: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: mov z0.b, #0 // =0x0 +; CHECK-NEXT: neg z0.b, p0/m, z1.b +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svneg_s8_z: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: neg z0.b, p0/z, z1.b +; CHECK-2p2-NEXT: ret +entry: + %1 = tail call @llvm.aarch64.sve.neg.nxv16i8( zeroinitializer, %pg, %x) + ret %1 +} + +define @test_svneg_s16_x_1( %pg, %x) { +; CHECK-LABEL: test_svneg_s16_x_1: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: neg z0.h, p0/m, z0.h +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svneg_s16_x_1: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: neg z0.h, p0/z, z0.h +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.neg.nxv8i16( undef, %pg, %x) + ret %0 +} + +define @test_svneg_s16_x_2( %pg, double %z0, %x) { +; CHECK-LABEL: test_svneg_s16_x_2: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: movprfx z0, z1 +; CHECK-NEXT: neg z0.h, p0/m, z1.h +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svneg_s16_x_2: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: neg z0.h, p0/z, z1.h +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.neg.nxv8i16( undef, %pg, %x) + ret %0 +} + +define @test_svneg_s16_z( %pg, double %z0, %x) { +; CHECK-LABEL: test_svneg_s16_z: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: mov z0.h, #0 // =0x0 +; CHECK-NEXT: neg z0.h, p0/m, z1.h +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svneg_s16_z: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: neg z0.h, p0/z, z1.h +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.neg.nxv8i16( zeroinitializer, %pg, %x) + ret %0 +} + +define @test_svneg_s32_x_1( %pg, %x) { +; CHECK-LABEL: test_svneg_s32_x_1: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: neg z0.s, p0/m, z0.s +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svneg_s32_x_1: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: neg z0.s, p0/z, z0.s +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.neg.nxv4i32( undef, %pg, %x) + ret %0 +} + +define @test_svneg_s32_x_2( %pg, double %z0, %x) { +; CHECK-LABEL: test_svneg_s32_x_2: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: movprfx z0, z1 +; CHECK-NEXT: neg z0.s, p0/m, z1.s +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svneg_s32_x_2: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: neg z0.s, p0/z, z1.s +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.neg.nxv4i32( undef, %pg, %x) + ret %0 +} + +define @test_svneg_s32_z( %pg, double %z0, %x) { +; CHECK-LABEL: test_svneg_s32_z: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: mov z0.s, #0 // =0x0 +; CHECK-NEXT: neg z0.s, p0/m, z1.s +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svneg_s32_z: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: neg z0.s, p0/z, z1.s +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.neg.nxv4i32( zeroinitializer, %pg, %x) + ret %0 +} + +define @test_svneg_s64_x_1( %pg, %x) { +; CHECK-LABEL: test_svneg_s64_x_1: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: neg z0.d, p0/m, z0.d +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svneg_s64_x_1: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: neg z0.d, p0/z, z0.d +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.neg.nxv2i64( undef, %pg, %x) + ret %0 +} + +define @test_svneg_s64_x_2( %pg, double %z0, %x) { +; CHECK-LABEL: test_svneg_s64_x_2: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: movprfx z0, z1 +; CHECK-NEXT: neg z0.d, p0/m, z1.d +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svneg_s64_x_2: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: neg z0.d, p0/z, z1.d +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.neg.nxv2i64( undef, %pg, %x) + ret %0 +} + +define @test_svneg_s64_z( %pg, double %z0, %x) { +; CHECK-LABEL: test_svneg_s64_z: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: mov z0.d, #0 // =0x0 +; CHECK-NEXT: neg z0.d, p0/m, z1.d +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svneg_s64_z: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: neg z0.d, p0/z, z1.d +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.neg.nxv2i64( zeroinitializer, %pg, %x) + ret %0 +} diff --git a/llvm/test/CodeGen/AArch64/zeroing-forms-fcvt-bfcvt.ll b/llvm/test/CodeGen/AArch64/zeroing-forms-fcvt-bfcvt.ll new file mode 100644 index 0000000000000..cf9ac49ca7b23 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/zeroing-forms-fcvt-bfcvt.ll @@ -0,0 +1,330 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 +; RUN: llc -mattr=+sve,+bf16 < %s | FileCheck %s +; RUN: llc -mattr=+sve2p2,+bf16 < %s | FileCheck %s -check-prefix CHECK-2p2 + +; RUN: llc -mattr=+sme,+bf16 -force-streaming < %s | FileCheck %s +; RUN: llc -mattr=+sme2p2,+bf16 -force-streaming < %s | FileCheck %s -check-prefix CHECK-2p2 + +target triple = "aarch64-linux" + +define @test_svcvt_f16_f32_x_1( %pg, %x) { +; CHECK-LABEL: test_svcvt_f16_f32_x_1: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: fcvt z0.h, p0/m, z0.s +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svcvt_f16_f32_x_1: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: fcvt z0.h, p0/z, z0.s +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.fcvt.f16f32( undef, %pg, %x) + ret %0 +} + +define @test_svcvt_f16_f32_x_2( %pg, double %z0, %x) { +; CHECK-LABEL: test_svcvt_f16_f32_x_2: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: fcvt z0.h, p0/m, z1.s +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svcvt_f16_f32_x_2: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: fcvt z0.h, p0/z, z1.s +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.fcvt.f16f32( undef, %pg, %x) + ret %0 +} + +define @test_svcvt_f16_f32_z( %pg, double %z0, %x) { +; CHECK-LABEL: test_svcvt_f16_f32_z: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: mov z0.h, #0 // =0x0 +; CHECK-NEXT: fcvt z0.h, p0/m, z1.s +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svcvt_f16_f32_z: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: fcvt z0.h, p0/z, z1.s +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.fcvt.f16f32( zeroinitializer, %pg, %x) + ret %0 +} + +define @test_svcvt_bf16_f32_x_1( %pg, %x) { +; CHECK-LABEL: test_svcvt_bf16_f32_x_1: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: bfcvt z0.h, p0/m, z0.s +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svcvt_bf16_f32_x_1: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: bfcvt z0.h, p0/z, z0.s +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.fcvt.bf16f32.v2( undef, %pg, %x) + ret %0 +} + +define @test_svcvt_bf16_f32_x_2( %pg, double %z0, %x) { +; CHECK-LABEL: test_svcvt_bf16_f32_x_2: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: bfcvt z0.h, p0/m, z1.s +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svcvt_bf16_f32_x_2: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: bfcvt z0.h, p0/z, z1.s +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.fcvt.bf16f32.v2( undef, %pg, %x) + ret %0 +} + +define @test_svcvt_bf16_f32_z( %pg, double %z0, %x) { +; CHECK-LABEL: test_svcvt_bf16_f32_z: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: mov z0.h, #0 // =0x0 +; CHECK-NEXT: bfcvt z0.h, p0/m, z1.s +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svcvt_bf16_f32_z: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: bfcvt z0.h, p0/z, z1.s +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.fcvt.bf16f32.v2( zeroinitializer, %pg, %x) + ret %0 +} + +define @test_svcvt_f16_f64_x_1( %pg, %x) { +; CHECK-LABEL: test_svcvt_f16_f64_x_1: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: fcvt z0.h, p0/m, z0.d +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svcvt_f16_f64_x_1: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: fcvt z0.h, p0/z, z0.d +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.fcvt.f16f64( undef, %pg, %x) + ret %0 +} + +define @test_svcvt_f16_f64_x_2( %pg, double %z0, %x) { +; CHECK-LABEL: test_svcvt_f16_f64_x_2: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: fcvt z0.h, p0/m, z1.d +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svcvt_f16_f64_x_2: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: fcvt z0.h, p0/z, z1.d +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.fcvt.f16f64( undef, %pg, %x) + ret %0 +} + +define @test_svcvt_f16_f64_z( %pg, double %z0, %x) { +; CHECK-LABEL: test_svcvt_f16_f64_z: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: mov z0.h, #0 // =0x0 +; CHECK-NEXT: fcvt z0.h, p0/m, z1.d +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svcvt_f16_f64_z: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: fcvt z0.h, p0/z, z1.d +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.fcvt.f16f64( zeroinitializer, %pg, %x) + ret %0 +} + +define @test_svcvt_f32_f64_x_1( %pg, %x) { +; CHECK-LABEL: test_svcvt_f32_f64_x_1: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: fcvt z0.s, p0/m, z0.d +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svcvt_f32_f64_x_1: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: fcvt z0.s, p0/z, z0.d +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.fcvt.f32f64( undef, %pg, %x) + ret %0 +} + +define @test_svcvt_f32_f64_x_2( %pg, double %z0, %x) { +; CHECK-LABEL: test_svcvt_f32_f64_x_2: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: fcvt z0.s, p0/m, z1.d +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svcvt_f32_f64_x_2: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: fcvt z0.s, p0/z, z1.d +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.fcvt.f32f64( undef, %pg, %x) + ret %0 +} + +define @test_svcvt_f32_f64_z( %pg, double %z0, %x) { +; CHECK-LABEL: test_svcvt_f32_f64_z: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: mov z0.s, #0 // =0x0 +; CHECK-NEXT: fcvt z0.s, p0/m, z1.d +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svcvt_f32_f64_z: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: fcvt z0.s, p0/z, z1.d +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.fcvt.f32f64( zeroinitializer, %pg, %x) + ret %0 +} + +define @test_svcvt_f32_f16_x_1( %pg, %x) { +; CHECK-LABEL: test_svcvt_f32_f16_x_1: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: fcvt z0.s, p0/m, z0.h +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svcvt_f32_f16_x_1: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: fcvt z0.s, p0/z, z0.h +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.fcvt.f32f16( undef, %pg, %x) + ret %0 +} + +define @test_svcvt_f32_f16_x_2( %pg, double %z0, %x) { +; CHECK-LABEL: test_svcvt_f32_f16_x_2: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: fcvt z0.s, p0/m, z1.h +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svcvt_f32_f16_x_2: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: fcvt z0.s, p0/z, z1.h +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.fcvt.f32f16( undef, %pg, %x) + ret %0 +} + +define @test_svcvt_f32_f16_z( %pg, double %z0, %x) { +; CHECK-LABEL: test_svcvt_f32_f16_z: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: mov z0.s, #0 // =0x0 +; CHECK-NEXT: fcvt z0.s, p0/m, z1.h +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svcvt_f32_f16_z: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: fcvt z0.s, p0/z, z1.h +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.fcvt.f32f16( zeroinitializer, %pg, %x) + ret %0 +} + +define @test_svcvt_f64_f16_x_1( %pg, %x) { +; CHECK-LABEL: test_svcvt_f64_f16_x_1: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: fcvt z0.d, p0/m, z0.h +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svcvt_f64_f16_x_1: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: fcvt z0.d, p0/z, z0.h +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.fcvt.f64f16( undef, %pg, %x) + ret %0 +} + +define @test_svcvt_f64_f16_x_2( %pg, double %z0, %x) { +; CHECK-LABEL: test_svcvt_f64_f16_x_2: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: fcvt z0.d, p0/m, z1.h +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svcvt_f64_f16_x_2: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: fcvt z0.d, p0/z, z1.h +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.fcvt.f64f16( undef, %pg, %x) + ret %0 +} + +define @test_svcvt_f64_f16_z( %pg, double %z0, %x) { +; CHECK-LABEL: test_svcvt_f64_f16_z: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: mov z0.d, #0 // =0x0 +; CHECK-NEXT: fcvt z0.d, p0/m, z1.h +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svcvt_f64_f16_z: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: fcvt z0.d, p0/z, z1.h +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.fcvt.f64f16( zeroinitializer, %pg, %x) + ret %0 +} + +define @test_svcvt_f64_f32_x_1( %pg, %x) { +; CHECK-LABEL: test_svcvt_f64_f32_x_1: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: fcvt z0.d, p0/m, z0.s +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svcvt_f64_f32_x_1: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: fcvt z0.d, p0/z, z0.s +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.fcvt.f64f32( undef, %pg, %x) + ret %0 +} + +define @test_svcvt_f64_f32_x_2( %pg, double %z0, %x) { +; CHECK-LABEL: test_svcvt_f64_f32_x_2: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: fcvt z0.d, p0/m, z1.s +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svcvt_f64_f32_x_2: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: fcvt z0.d, p0/z, z1.s +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.fcvt.f64f32( undef, %pg, %x) + ret %0 +} + +define @test_svcvt_f64_f32_z( %pg, double %z0, %x) { +; CHECK-LABEL: test_svcvt_f64_f32_z: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: mov z0.d, #0 // =0x0 +; CHECK-NEXT: fcvt z0.d, p0/m, z1.s +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svcvt_f64_f32_z: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: fcvt z0.d, p0/z, z1.s +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.fcvt.f64f32( zeroinitializer, %pg, %x) + ret %0 +} diff --git a/llvm/test/CodeGen/AArch64/zeroing-forms-fcvtlt-fcvtx.ll b/llvm/test/CodeGen/AArch64/zeroing-forms-fcvtlt-fcvtx.ll new file mode 100644 index 0000000000000..d2a948ce60f4a --- /dev/null +++ b/llvm/test/CodeGen/AArch64/zeroing-forms-fcvtlt-fcvtx.ll @@ -0,0 +1,147 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 +; RUN: llc -mattr=+sve2 < %s | FileCheck %s +; RUN: llc -mattr=+sve2p2 < %s | FileCheck %s -check-prefix CHECK-2p2 + +; RUN: llc -mattr=+sme2 -force-streaming < %s | FileCheck %s +; RUN: llc -mattr=+sme2p2 -force-streaming < %s | FileCheck %s -check-prefix CHECK-2p2 + +target triple = "aarch64-linux" + +define @test_svcvtlt_f32_f16_x_1( %pg, %x) { +; CHECK-LABEL: test_svcvtlt_f32_f16_x_1: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: fcvtlt z0.s, p0/m, z0.h +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svcvtlt_f32_f16_x_1: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: fcvtlt z0.s, p0/z, z0.h +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.fcvtlt.f32f16( undef, %pg, %x) + ret %0 +} + +define @test_svcvtlt_f32_f16_x_2( %pg, double %z0, %x) { +; CHECK-LABEL: test_svcvtlt_f32_f16_x_2: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: fcvtlt z0.s, p0/m, z1.h +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svcvtlt_f32_f16_x_2: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: fcvtlt z0.s, p0/z, z1.h +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.fcvtlt.f32f16( undef, %pg, %x) + ret %0 +} + +define @test_svcvtlt_f32_f16_z( %pg, double %z0, %x) { +; CHECK-LABEL: test_svcvtlt_f32_f16_z: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: mov z0.s, #0 // =0x0 +; CHECK-NEXT: fcvtlt z0.s, p0/m, z1.h +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svcvtlt_f32_f16_z: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: fcvtlt z0.s, p0/z, z1.h +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.fcvtlt.f32f16( zeroinitializer, %pg, %x) + ret %0 +} + +define @test_svcvtlt_f64_f32_x_1( %pg, %x) { +; CHECK-LABEL: test_svcvtlt_f64_f32_x_1: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: fcvtlt z0.d, p0/m, z0.s +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svcvtlt_f64_f32_x_1: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: fcvtlt z0.d, p0/z, z0.s +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.fcvtlt.f64f32( undef, %pg, %x) + ret %0 +} + +define @test_svcvtlt_f64_f32_x_2( %pg, double %z0, %x) { +; CHECK-LABEL: test_svcvtlt_f64_f32_x_2: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: fcvtlt z0.d, p0/m, z1.s +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svcvtlt_f64_f32_x_2: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: fcvtlt z0.d, p0/z, z1.s +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.fcvtlt.f64f32( undef, %pg, %x) + ret %0 +} + +define @test_svcvtlt_f64_f32_z( %pg, double %z0, %x) { +; CHECK-LABEL: test_svcvtlt_f64_f32_z: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: mov z0.d, #0 // =0x0 +; CHECK-NEXT: fcvtlt z0.d, p0/m, z1.s +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svcvtlt_f64_f32_z: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: fcvtlt z0.d, p0/z, z1.s +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.fcvtlt.f64f32( zeroinitializer, %pg, %x) + ret %0 +} + +define @test_svcvtx_f32_f64_x_1( %pg, %x) { +; CHECK-LABEL: test_svcvtx_f32_f64_x_1: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: fcvtx z0.s, p0/m, z0.d +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svcvtx_f32_f64_x_1: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: fcvtx z0.s, p0/z, z0.d +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.fcvtx.f32f64( undef, %pg, %x) + ret %0 +} + +define @test_svcvtx_f32_f64_x_2( %pg, %x) { +; CHECK-LABEL: test_svcvtx_f32_f64_x_2: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: fcvtx z0.s, p0/m, z0.d +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svcvtx_f32_f64_x_2: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: fcvtx z0.s, p0/z, z0.d +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.fcvtx.f32f64( undef, %pg, %x) + ret %0 +} + +define @test_svcvtx_f32_f64_z( %pg, %x) { +; CHECK-LABEL: test_svcvtx_f32_f64_z: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: mov z1.s, #0 // =0x0 +; CHECK-NEXT: fcvtx z1.s, p0/m, z0.d +; CHECK-NEXT: mov z0.d, z1.d +; CHECK-NEXT: ret +; +; CHECK-2p2-LABEL: test_svcvtx_f32_f64_z: +; CHECK-2p2: // %bb.0: // %entry +; CHECK-2p2-NEXT: fcvtx z0.s, p0/z, z0.d +; CHECK-2p2-NEXT: ret +entry: + %0 = tail call @llvm.aarch64.sve.fcvtx.f32f64( zeroinitializer, %pg, %x) + ret %0 +}