diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td index 5c9a25f224926..7614f6215b803 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 564fb33758ad5..fb0eb7a80c6d7 100644 --- a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td @@ -675,6 +675,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)), @@ -4321,16 +4329,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 4bdf327e0d3fc..faaaca3f28d75 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)), @@ -606,8 +611,6 @@ class SVE_4_Op_Imm_Pat; -def SVEDup0Undef : ComplexPattern; - let AddedComplexity = 1 in { class SVE_3_Op_Pat_SelZero @@ -4820,23 +4823,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 +4948,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 +4976,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 +}