Index: llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td =================================================================== --- llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td +++ llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td @@ -160,9 +160,10 @@ defm FMAX_ZPmI : sve_fp_2op_i_p_zds<0b110, "fmax", sve_fpimm_zero_one>; defm FMIN_ZPmI : sve_fp_2op_i_p_zds<0b111, "fmin", sve_fpimm_zero_one>; - defm FADD_ZPmZ : sve_fp_2op_p_zds<0b0000, "fadd", int_aarch64_sve_fadd>; - defm FSUB_ZPmZ : sve_fp_2op_p_zds<0b0001, "fsub", int_aarch64_sve_fsub>; - defm FMUL_ZPmZ : sve_fp_2op_p_zds<0b0010, "fmul", int_aarch64_sve_fmul>; + defm FADD_ZPmZ : sve_fp_2op_p_zds_pred<0b0000, "fadd", fadd, int_aarch64_sve_fadd>; + defm FSUB_ZPmZ : sve_fp_2op_p_zds_pred<0b0001, "fsub", fsub, int_aarch64_sve_fsub>; + defm FMUL_ZPmZ : sve_fp_2op_p_zds_pred<0b0010, "fmul", fmul, int_aarch64_sve_fmul>; + defm FDIV_ZPmZ : sve_fp_2op_p_zds_pred<0b1101, "fdiv", fdiv, int_aarch64_sve_fdiv>; defm FSUBR_ZPmZ : sve_fp_2op_p_zds<0b0011, "fsubr", int_aarch64_sve_fsubr>; defm FMAXNM_ZPmZ : sve_fp_2op_p_zds<0b0100, "fmaxnm", int_aarch64_sve_fmaxnm>; defm FMINNM_ZPmZ : sve_fp_2op_p_zds<0b0101, "fminnm", int_aarch64_sve_fminnm>; @@ -172,7 +173,6 @@ defm FSCALE_ZPmZ : sve_fp_2op_p_zds_fscale<0b1001, "fscale", int_aarch64_sve_fscale>; defm FMULX_ZPmZ : sve_fp_2op_p_zds<0b1010, "fmulx", int_aarch64_sve_fmulx>; defm FDIVR_ZPmZ : sve_fp_2op_p_zds<0b1100, "fdivr", int_aarch64_sve_fdivr>; - defm FDIV_ZPmZ : sve_fp_2op_p_zds<0b1101, "fdiv", int_aarch64_sve_fdiv>; defm FADD_ZZZ : sve_fp_3op_u_zd<0b000, "fadd", fadd>; defm FSUB_ZZZ : sve_fp_3op_u_zd<0b001, "fsub", fsub>; Index: llvm/lib/Target/AArch64/SVEInstrFormats.td =================================================================== --- llvm/lib/Target/AArch64/SVEInstrFormats.td +++ llvm/lib/Target/AArch64/SVEInstrFormats.td @@ -303,6 +303,11 @@ : Pat<(vtd (op vt1:$Op1, vt2:$Op2, vt3:$Op3)), (inst $Op1, $Op2, $Op3)>; +class SVE_3_Op_Sel_Pat +: Pat<(vselect vt1:$Op1, (vtd (op vt2:$Op2, vt3:$Op3)), vtd:$Op2), + (inst $Op1, $Op2, $Op3)>; + class SVE_4_Op_Pat @@ -1276,6 +1281,15 @@ def : SVE_3_Op_Pat(NAME # _D)>; } +multiclass sve_fp_2op_p_zds_pred opc, string asm, + SDPatternOperator op, SDPatternOperator intr> { + defm NAME : sve_fp_2op_p_zds; + + def : SVE_3_Op_Sel_Pat(NAME # _H)>; + def : SVE_3_Op_Sel_Pat(NAME # _S)>; + def : SVE_3_Op_Sel_Pat(NAME # _D)>; +} + multiclass sve_fp_2op_p_zds_fscale opc, string asm, SDPatternOperator op> { def _H : sve_fp_2op_p_zds<0b01, opc, asm, ZPR16>; Index: llvm/test/CodeGen/AArch64/sve-fp-pred.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/AArch64/sve-fp-pred.ll @@ -0,0 +1,134 @@ +; RUN: llc -mtriple=aarch64-linux-gnu -mattr=+sve < %s | FileCheck %s + +define @fadd_h( %p, + %a, + %b) { +; CHECK-LABEL: fadd_h: +; CHECK: fadd z0.h, p0/m, z0.h, z1.h +; CHECK-NEXT: ret + %add = fadd %a, %b + %res = select %p, %add, %a + ret %res +} + +define @fadd_s( %p, + %a, + %b) { +; CHECK-LABEL: fadd_s: +; CHECK: fadd z0.s, p0/m, z0.s, z1.s +; CHECK-NEXT: ret + %add = fadd %a, %b + %res = select %p, %add, %a + ret %res +} + +define @fadd_d( %p, + %a, + %b) { +; CHECK-LABEL: fadd_d: +; CHECK: fadd z0.d, p0/m, z0.d, z1.d +; CHECK-NEXT: ret + %add = fadd %a, %b + %res = select %p, %add, %a + ret %res +} + +define @fsub_h( %p, + %a, + %b) { +; CHECK-LABEL: fsub_h: +; CHECK: fsub z0.h, p0/m, z0.h, z1.h +; CHECK-NEXT: ret + %sub = fsub %a, %b + %res = select %p, %sub, %a + ret %res +} + +define @fsub_s( %p, + %a, + %b) { +; CHECK-LABEL: fsub_s: +; CHECK: fsub z0.s, p0/m, z0.s, z1.s +; CHECK-NEXT: ret + %sub = fsub %a, %b + %res = select %p, %sub, %a + ret %res +} + +define @fsub_d( %p, + %a, + %b) { +; CHECK-LABEL: fsub_d: +; CHECK: fsub z0.d, p0/m, z0.d, z1.d +; CHECK-NEXT: ret + %sub = fsub %a, %b + %res = select %p, %sub, %a + ret %res +} + +define @fmul_h( %p, + %a, + %b) { +; CHECK-LABEL: fmul_h: +; CHECK: fmul z0.h, p0/m, z0.h, z1.h +; CHECK-NEXT: ret + %mul = fmul %a, %b + %res = select %p, %mul, %a + ret %res +} + +define @fmul_s( %p, + %a, + %b) { +; CHECK-LABEL: fmul_s: +; CHECK: fmul z0.s, p0/m, z0.s, z1.s +; CHECK-NEXT: ret + %mul = fmul %a, %b + %res = select %p, %mul, %a + ret %res +} + +define @fmul_d( %p, + %a, + %b) { +; CHECK-LABEL: fmul_d: +; CHECK: fmul z0.d, p0/m, z0.d, z1.d +; CHECK-NEXT: ret + %mul = fmul %a, %b + %res = select %p, %mul, %a + ret %res +} + +define @fdiv_h( %p, + %a, + %b) { +; CHECK-LABEL: fdiv_h: +; CHECK: fdiv z0.h, p0/m, z0.h, z1.h +; CHECK-NEXT: ret + %div = fdiv %a, %b + %res = select %p, %div, %a + ret %res +} + +define @fdiv_s( %p, + %a, + %b) { +; CHECK-LABEL: fdiv_s: +; CHECK: fdiv z0.s, p0/m, z0.s, z1.s +; CHECK-NEXT: ret + %div = fdiv %a, %b + %res = select %p, %div, %a + ret %res +} + +define @fdiv_d( %p, + %a, + %b) { +; CHECK-LABEL: fdiv_d: +; CHECK: fdiv z0.d, p0/m, z0.d, z1.d +; CHECK-NEXT: ret + %div = fdiv %a, %b + %res = select %p, %div, %a + ret %res +} +