diff --git a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td --- a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td @@ -297,6 +297,9 @@ [(AArch64fma_p node:$pred, (AArch64fneg_mt node:$pred, node:$op1, (undef)), node:$op2, node:$op3), (AArch64fma_p node:$pred, node:$op2, (AArch64fneg_mt node:$pred, node:$op1, (undef)), node:$op3)]>; +def AArch64fsubr_p : PatFrag<(ops node:$pg, node:$op1, node:$op2), + (AArch64fsub_p node:$pg, node:$op2, node:$op1)>; + def AArch64fneg_mt_nsz : PatFrag<(ops node:$pred, node:$op, node:$pt), (AArch64fneg_mt node:$pred, node:$op, node:$pt), [{ return N->getFlags().hasNoSignedZeros(); @@ -460,11 +463,11 @@ defm FMINNM_ZPmI : sve_fp_2op_i_p_zds<0b101, "fminnm", "FMINNM_ZPZI", sve_fpimm_zero_one, fpimm0, fpimm_one, int_aarch64_sve_fminnm>; defm FMAX_ZPmI : sve_fp_2op_i_p_zds<0b110, "fmax", "FMAX_ZPZI", sve_fpimm_zero_one, fpimm0, fpimm_one, int_aarch64_sve_fmax>; defm FMIN_ZPmI : sve_fp_2op_i_p_zds<0b111, "fmin", "FMIN_ZPZI", sve_fpimm_zero_one, fpimm0, fpimm_one, int_aarch64_sve_fmin>; - + defm FADD_ZPZI : sve_fp_2op_i_p_zds_hfd; defm FSUB_ZPZI : sve_fp_2op_i_p_zds_hfd; defm FMUL_ZPZI : sve_fp_2op_i_p_zds_hfd; - defm FSUBR_ZPZI : sve_fp_2op_i_p_zds_hfd; + defm FSUBR_ZPZI : sve_fp_2op_i_p_zds_hfd; defm FMAXNM_ZPZI : sve_fp_2op_i_p_zds_hfd; defm FMINNM_ZPZI : sve_fp_2op_i_p_zds_hfd; defm FMAX_ZPZI : sve_fp_2op_i_p_zds_hfd; diff --git a/llvm/test/CodeGen/AArch64/sve-fp-immediates-merging.ll b/llvm/test/CodeGen/AArch64/sve-fp-immediates-merging.ll --- a/llvm/test/CodeGen/AArch64/sve-fp-immediates-merging.ll +++ b/llvm/test/CodeGen/AArch64/sve-fp-immediates-merging.ll @@ -1037,6 +1037,154 @@ ret %out } +; +; FSUBR +; + +define @fsubr_h_immhalf( %a) #0 { +; CHECK-LABEL: fsubr_h_immhalf: +; CHECK: // %bb.0: +; CHECK-NEXT: ptrue p0.h +; CHECK-NEXT: fsubr z0.h, p0/m, z0.h, #0.5 +; CHECK-NEXT: ret + %elt = insertelement undef, half 0.500000e+00, i32 0 + %splat = shufflevector %elt, undef, zeroinitializer + %out = fsub %splat, %a + ret %out +} + +define @fsubr_h_immone( %a) #0 { +; CHECK-LABEL: fsubr_h_immone: +; CHECK: // %bb.0: +; CHECK-NEXT: ptrue p0.h +; CHECK-NEXT: fsubr z0.h, p0/m, z0.h, #1.0 +; CHECK-NEXT: ret + %elt = insertelement undef, half 1.000000e+00, i32 0 + %splat = shufflevector %elt, undef, zeroinitializer + %out = fsub %splat, %a + ret %out +} + +define @fsubr_4h_immhalf( %a) #0 { +; CHECK-LABEL: fsubr_4h_immhalf: +; CHECK: // %bb.0: +; CHECK-NEXT: ptrue p0.s +; CHECK-NEXT: fsubr z0.h, p0/m, z0.h, #0.5 +; CHECK-NEXT: ret + %elt = insertelement undef, half 0.500000e+00, i32 0 + %splat = shufflevector %elt, undef, zeroinitializer + %out = fsub %splat, %a + ret %out +} + +define @fsubr_4h_immone( %a) #0 { +; CHECK-LABEL: fsubr_4h_immone: +; CHECK: // %bb.0: +; CHECK-NEXT: ptrue p0.s +; CHECK-NEXT: fsubr z0.h, p0/m, z0.h, #1.0 +; CHECK-NEXT: ret + %elt = insertelement undef, half 1.000000e+00, i32 0 + %splat = shufflevector %elt, undef, zeroinitializer + %out = fsub %splat, %a + ret %out +} + +define @fsubr_2h_immhalf( %a) #0 { +; CHECK-LABEL: fsubr_2h_immhalf: +; CHECK: // %bb.0: +; CHECK-NEXT: ptrue p0.d +; CHECK-NEXT: fsubr z0.h, p0/m, z0.h, #0.5 +; CHECK-NEXT: ret + %elt = insertelement undef, half 0.500000e+00, i32 0 + %splat = shufflevector %elt, undef, zeroinitializer + %out = fsub %splat, %a + ret %out +} + +define @fsubr_2h_immone( %a) #0 { +; CHECK-LABEL: fsubr_2h_immone: +; CHECK: // %bb.0: +; CHECK-NEXT: ptrue p0.d +; CHECK-NEXT: fsubr z0.h, p0/m, z0.h, #1.0 +; CHECK-NEXT: ret + %elt = insertelement undef, half 1.000000e+00, i32 0 + %splat = shufflevector %elt, undef, zeroinitializer + %out = fsub %splat, %a + ret %out +} + +define @fsubr_s_immhalf( %a) #0 { +; CHECK-LABEL: fsubr_s_immhalf: +; CHECK: // %bb.0: +; CHECK-NEXT: ptrue p0.s +; CHECK-NEXT: fsubr z0.s, p0/m, z0.s, #0.5 +; CHECK-NEXT: ret + %elt = insertelement undef, float 0.500000e+00, i32 0 + %splat = shufflevector %elt, undef, zeroinitializer + %out = fsub %splat, %a + ret %out +} + +define @fsubr_s_immone( %a) #0 { +; CHECK-LABEL: fsubr_s_immone: +; CHECK: // %bb.0: +; CHECK-NEXT: ptrue p0.s +; CHECK-NEXT: fsubr z0.s, p0/m, z0.s, #1.0 +; CHECK-NEXT: ret + %elt = insertelement undef, float 1.000000e+00, i32 0 + %splat = shufflevector %elt, undef, zeroinitializer + %out = fsub %splat, %a + ret %out +} + +define @fsubr_2s_immhalf( %a) #0 { +; CHECK-LABEL: fsubr_2s_immhalf: +; CHECK: // %bb.0: +; CHECK-NEXT: ptrue p0.d +; CHECK-NEXT: fsubr z0.s, p0/m, z0.s, #0.5 +; CHECK-NEXT: ret + %elt = insertelement undef, float 0.500000e+00, i32 0 + %splat = shufflevector %elt, undef, zeroinitializer + %out = fsub %splat, %a + ret %out +} + +define @fsubr_2s_immone( %a) #0 { +; CHECK-LABEL: fsubr_2s_immone: +; CHECK: // %bb.0: +; CHECK-NEXT: ptrue p0.d +; CHECK-NEXT: fsubr z0.s, p0/m, z0.s, #1.0 +; CHECK-NEXT: ret + %elt = insertelement undef, float 1.000000e+00, i32 0 + %splat = shufflevector %elt, undef, zeroinitializer + %out = fsub %splat, %a + ret %out +} + +define @fsubr_d_immhalf( %a) #0 { +; CHECK-LABEL: fsubr_d_immhalf: +; CHECK: // %bb.0: +; CHECK-NEXT: ptrue p0.d +; CHECK-NEXT: fsubr z0.d, p0/m, z0.d, #0.5 +; CHECK-NEXT: ret + %elt = insertelement undef, double 0.500000e+00, i32 0 + %splat = shufflevector %elt, undef, zeroinitializer + %out = fsub %splat, %a + ret %out +} + +define @fsubr_d_immone( %a) #0 { +; CHECK-LABEL: fsubr_d_immone: +; CHECK: // %bb.0: +; CHECK-NEXT: ptrue p0.d +; CHECK-NEXT: fsubr z0.d, p0/m, z0.d, #1.0 +; CHECK-NEXT: ret + %elt = insertelement undef, double 1.000000e+00, i32 0 + %splat = shufflevector %elt, undef, zeroinitializer + %out = fsub %splat, %a + ret %out +} + ;; Arithmetic intrinsic declarations declare @llvm.maximum.nxv8f16(, )