diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoD.td b/llvm/lib/Target/RISCV/RISCVInstrInfoD.td --- a/llvm/lib/Target/RISCV/RISCVInstrInfoD.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoD.td @@ -233,15 +233,15 @@ class PatFpr64Fpr64 : Pat<(OpNode FPR64:$rs1, FPR64:$rs2), (Inst $rs1, $rs2)>; -class PatFpr64Fpr64DynFrm - : Pat<(OpNode FPR64:$rs1, FPR64:$rs2), (Inst $rs1, $rs2, 0b111)>; +class PatFpr64Fpr64DefFrm + : Pat<(OpNode FPR64:$rs1, FPR64:$rs2), (Inst $rs1, $rs2, 0b000)>; let Predicates = [HasStdExtD] in { /// Float conversion operations // f64 -> f32, f32 -> f64 -def : Pat<(fpround FPR64:$rs1), (FCVT_S_D FPR64:$rs1, 0b111)>; +def : Pat<(fpround FPR64:$rs1), (FCVT_S_D FPR64:$rs1, 0b000)>; def : Pat<(fpextend FPR32:$rs1), (FCVT_D_S FPR32:$rs1)>; // [u]int<->double conversion patterns must be gated on IsRV32 or IsRV64, so @@ -249,12 +249,12 @@ /// Float arithmetic operations -def : PatFpr64Fpr64DynFrm; -def : PatFpr64Fpr64DynFrm; -def : PatFpr64Fpr64DynFrm; -def : PatFpr64Fpr64DynFrm; +def : PatFpr64Fpr64DefFrm; +def : PatFpr64Fpr64DefFrm; +def : PatFpr64Fpr64DefFrm; +def : PatFpr64Fpr64DefFrm; -def : Pat<(fsqrt FPR64:$rs1), (FSQRT_D FPR64:$rs1, 0b111)>; +def : Pat<(fsqrt FPR64:$rs1), (FSQRT_D FPR64:$rs1, 0b000)>; def : Pat<(fneg FPR64:$rs1), (FSGNJN_D $rs1, $rs1)>; def : Pat<(fabs FPR64:$rs1), (FSGNJX_D $rs1, $rs1)>; @@ -263,23 +263,23 @@ def : Pat<(fcopysign FPR64:$rs1, (fneg FPR64:$rs2)), (FSGNJN_D $rs1, $rs2)>; def : Pat<(fcopysign FPR64:$rs1, FPR32:$rs2), (FSGNJ_D $rs1, (FCVT_D_S $rs2))>; def : Pat<(fcopysign FPR32:$rs1, FPR64:$rs2), (FSGNJ_S $rs1, (FCVT_S_D $rs2, - 0b111))>; + 0b000))>; // fmadd: rs1 * rs2 + rs3 def : Pat<(fma FPR64:$rs1, FPR64:$rs2, FPR64:$rs3), - (FMADD_D $rs1, $rs2, $rs3, 0b111)>; + (FMADD_D $rs1, $rs2, $rs3, 0b000)>; // fmsub: rs1 * rs2 - rs3 def : Pat<(fma FPR64:$rs1, FPR64:$rs2, (fneg FPR64:$rs3)), - (FMSUB_D FPR64:$rs1, FPR64:$rs2, FPR64:$rs3, 0b111)>; + (FMSUB_D FPR64:$rs1, FPR64:$rs2, FPR64:$rs3, 0b000)>; // fnmsub: -rs1 * rs2 + rs3 def : Pat<(fma (fneg FPR64:$rs1), FPR64:$rs2, FPR64:$rs3), - (FNMSUB_D FPR64:$rs1, FPR64:$rs2, FPR64:$rs3, 0b111)>; + (FNMSUB_D FPR64:$rs1, FPR64:$rs2, FPR64:$rs3, 0b000)>; // fnmadd: -rs1 * rs2 - rs3 def : Pat<(fma (fneg FPR64:$rs1), FPR64:$rs2, (fneg FPR64:$rs3)), - (FNMADD_D FPR64:$rs1, FPR64:$rs2, FPR64:$rs3, 0b111)>; + (FNMADD_D FPR64:$rs1, FPR64:$rs2, FPR64:$rs3, 0b000)>; // The RISC-V 2.2 user-level ISA spec defines fmin and fmax as returning the // canonical NaN when giving a signaling NaN. This doesn't match the LLVM @@ -362,7 +362,7 @@ def : Pat<(fp_to_sint FPR64:$rs1), (FCVT_L_D FPR64:$rs1, 0b001)>; def : Pat<(fp_to_uint FPR64:$rs1), (FCVT_LU_D FPR64:$rs1, 0b001)>; -// [u]int64->fp. Match GCC and default to using dynamic rounding mode. -def : Pat<(sint_to_fp GPR:$rs1), (FCVT_D_L GPR:$rs1, 0b111)>; -def : Pat<(uint_to_fp GPR:$rs1), (FCVT_D_LU GPR:$rs1, 0b111)>; +// [u]int64->fp. Match GCC and default to using rounding mode to nearest even. +def : Pat<(sint_to_fp GPR:$rs1), (FCVT_D_L GPR:$rs1, 0b000)>; +def : Pat<(uint_to_fp GPR:$rs1), (FCVT_D_LU GPR:$rs1, 0b000)>; } // Predicates = [HasStdExtD, IsRV64] diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoF.td b/llvm/lib/Target/RISCV/RISCVInstrInfoF.td --- a/llvm/lib/Target/RISCV/RISCVInstrInfoF.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoF.td @@ -293,8 +293,8 @@ class PatFpr32Fpr32 : Pat<(OpNode FPR32:$rs1, FPR32:$rs2), (Inst $rs1, $rs2)>; -class PatFpr32Fpr32DynFrm - : Pat<(OpNode FPR32:$rs1, FPR32:$rs2), (Inst $rs1, $rs2, 0b111)>; +class PatFpr32Fpr32DefFrm + : Pat<(OpNode FPR32:$rs1, FPR32:$rs2), (Inst $rs1, $rs2, 0b000)>; let Predicates = [HasStdExtF] in { @@ -308,12 +308,12 @@ /// Float arithmetic operations -def : PatFpr32Fpr32DynFrm; -def : PatFpr32Fpr32DynFrm; -def : PatFpr32Fpr32DynFrm; -def : PatFpr32Fpr32DynFrm; +def : PatFpr32Fpr32DefFrm; +def : PatFpr32Fpr32DefFrm; +def : PatFpr32Fpr32DefFrm; +def : PatFpr32Fpr32DefFrm; -def : Pat<(fsqrt FPR32:$rs1), (FSQRT_S FPR32:$rs1, 0b111)>; +def : Pat<(fsqrt FPR32:$rs1), (FSQRT_S FPR32:$rs1, 0b000)>; def : Pat<(fneg FPR32:$rs1), (FSGNJN_S $rs1, $rs1)>; def : Pat<(fabs FPR32:$rs1), (FSGNJX_S $rs1, $rs1)>; @@ -323,19 +323,19 @@ // fmadd: rs1 * rs2 + rs3 def : Pat<(fma FPR32:$rs1, FPR32:$rs2, FPR32:$rs3), - (FMADD_S $rs1, $rs2, $rs3, 0b111)>; + (FMADD_S $rs1, $rs2, $rs3, 0b000)>; // fmsub: rs1 * rs2 - rs3 def : Pat<(fma FPR32:$rs1, FPR32:$rs2, (fneg FPR32:$rs3)), - (FMSUB_S FPR32:$rs1, FPR32:$rs2, FPR32:$rs3, 0b111)>; + (FMSUB_S FPR32:$rs1, FPR32:$rs2, FPR32:$rs3, 0b000)>; // fnmsub: -rs1 * rs2 + rs3 def : Pat<(fma (fneg FPR32:$rs1), FPR32:$rs2, FPR32:$rs3), - (FNMSUB_S FPR32:$rs1, FPR32:$rs2, FPR32:$rs3, 0b111)>; + (FNMSUB_S FPR32:$rs1, FPR32:$rs2, FPR32:$rs3, 0b000)>; // fnmadd: -rs1 * rs2 - rs3 def : Pat<(fma (fneg FPR32:$rs1), FPR32:$rs2, (fneg FPR32:$rs3)), - (FNMADD_S FPR32:$rs1, FPR32:$rs2, FPR32:$rs3, 0b111)>; + (FNMADD_S FPR32:$rs1, FPR32:$rs2, FPR32:$rs3, 0b000)>; // The RISC-V 2.2 user-level ISA spec defines fmin and fmax as returning the // canonical NaN when given a signaling NaN. This doesn't match the LLVM @@ -376,9 +376,9 @@ def : Pat<(fp_to_sint FPR32:$rs1), (FCVT_W_S $rs1, 0b001)>; def : Pat<(fp_to_uint FPR32:$rs1), (FCVT_WU_S $rs1, 0b001)>; -// [u]int->float. Match GCC and default to using dynamic rounding mode. -def : Pat<(sint_to_fp GPR:$rs1), (FCVT_S_W $rs1, 0b111)>; -def : Pat<(uint_to_fp GPR:$rs1), (FCVT_S_WU $rs1, 0b111)>; +// [u]int->float. Match GCC and default to using rounding mode to nearest even. +def : Pat<(sint_to_fp GPR:$rs1), (FCVT_S_W $rs1, 0b000)>; +def : Pat<(uint_to_fp GPR:$rs1), (FCVT_S_WU $rs1, 0b000)>; } // Predicates = [HasStdExtF, IsRV32] let Predicates = [HasStdExtF, IsRV64] in { @@ -399,9 +399,9 @@ def : Pat<(fp_to_sint FPR32:$rs1), (FCVT_L_S $rs1, 0b001)>; def : Pat<(fp_to_uint FPR32:$rs1), (FCVT_LU_S $rs1, 0b001)>; -// [u]int->fp. Match GCC and default to using dynamic rounding mode. -def : Pat<(sint_to_fp (sexti32 GPR:$rs1)), (FCVT_S_W $rs1, 0b111)>; -def : Pat<(uint_to_fp (zexti32 GPR:$rs1)), (FCVT_S_WU $rs1, 0b111)>; -def : Pat<(sint_to_fp GPR:$rs1), (FCVT_S_L $rs1, 0b111)>; -def : Pat<(uint_to_fp GPR:$rs1), (FCVT_S_LU $rs1, 0b111)>; +// [u]int->fp. Match GCC and default to using rounding mode to nearest even. +def : Pat<(sint_to_fp (sexti32 GPR:$rs1)), (FCVT_S_W $rs1, 0b000)>; +def : Pat<(uint_to_fp (zexti32 GPR:$rs1)), (FCVT_S_WU $rs1, 0b000)>; +def : Pat<(sint_to_fp GPR:$rs1), (FCVT_S_L $rs1, 0b000)>; +def : Pat<(uint_to_fp GPR:$rs1), (FCVT_S_LU $rs1, 0b000)>; } // Predicates = [HasStdExtF, IsRV64] diff --git a/llvm/test/CodeGen/RISCV/double-arith.ll b/llvm/test/CodeGen/RISCV/double-arith.ll --- a/llvm/test/CodeGen/RISCV/double-arith.ll +++ b/llvm/test/CodeGen/RISCV/double-arith.ll @@ -3,6 +3,9 @@ ; RUN: | FileCheck -check-prefix=RV32IFD %s ; RUN: llc -mtriple=riscv64 -mattr=+d -verify-machineinstrs < %s \ ; RUN: | FileCheck -check-prefix=RV64IFD %s +; RUN: llc -mtriple=riscv32 -mattr=+d -filetype=obj < %s \ +; RUN: | llvm-objdump -d --triple=riscv32 --mattr=+d - \ +; RUN: | FileCheck -check-prefix=RV32IFDIS %s ; These tests are each targeted at a particular RISC-V FPU instruction. Most ; other files in this folder exercise LLVM IR instructions that don't directly @@ -32,6 +35,9 @@ ; RV64IFD-NEXT: fadd.d ft0, ft1, ft0 ; RV64IFD-NEXT: fmv.x.d a0, ft0 ; RV64IFD-NEXT: ret + +; RV32IFDIS-LABEL: : +; RV32IFDIS: fadd.d ft0, ft1, ft0, rne %1 = fadd double %a, %b ret double %1 } @@ -60,6 +66,9 @@ ; RV64IFD-NEXT: fsub.d ft0, ft1, ft0 ; RV64IFD-NEXT: fmv.x.d a0, ft0 ; RV64IFD-NEXT: ret + +; RV32IFDIS-LABEL: : +; RV32IFDIS: fsub.d ft0, ft1, ft0, rne %1 = fsub double %a, %b ret double %1 } @@ -88,6 +97,9 @@ ; RV64IFD-NEXT: fmul.d ft0, ft1, ft0 ; RV64IFD-NEXT: fmv.x.d a0, ft0 ; RV64IFD-NEXT: ret + +; RV32IFDIS-LABEL: : +; RV32IFDIS: fmul.d ft0, ft1, ft0, rne %1 = fmul double %a, %b ret double %1 } @@ -116,6 +128,9 @@ ; RV64IFD-NEXT: fdiv.d ft0, ft1, ft0 ; RV64IFD-NEXT: fmv.x.d a0, ft0 ; RV64IFD-NEXT: ret + +; RV32IFDIS-LABEL: : +; RV32IFDIS: fdiv.d ft0, ft1, ft0, rne %1 = fdiv double %a, %b ret double %1 } @@ -142,6 +157,9 @@ ; RV64IFD-NEXT: fsqrt.d ft0, ft0 ; RV64IFD-NEXT: fmv.x.d a0, ft0 ; RV64IFD-NEXT: ret + +; RV32IFDIS-LABEL: : +; RV32IFDIS: fsqrt.d ft0, ft0, rne %1 = call double @llvm.sqrt.f64(double %a) ret double %1 } @@ -198,6 +216,9 @@ ; RV64IFD-NEXT: fneg.d ft1, ft0 ; RV64IFD-NEXT: feq.d a0, ft0, ft1 ; RV64IFD-NEXT: ret + +; RV32IFDIS-LABEL: : +; RV32IFDIS: fadd.d ft0, ft0, ft0, rne %1 = fadd double %a, %a %2 = fneg double %1 %3 = fcmp oeq double %1, %2 @@ -272,6 +293,9 @@ ; RV64IFD-NEXT: fadd.d ft0, ft1, ft0 ; RV64IFD-NEXT: fmv.x.d a0, ft0 ; RV64IFD-NEXT: ret + +; RV32IFDIS-LABEL: : +; RV32IFDIS: fadd.d ft0, ft1, ft0, rne %1 = fadd double %a, %b %2 = call double @llvm.fabs.f64(double %1) %3 = fadd double %2, %1 @@ -443,6 +467,9 @@ ; RV64IFD-NEXT: fmadd.d ft0, ft2, ft1, ft0 ; RV64IFD-NEXT: fmv.x.d a0, ft0 ; RV64IFD-NEXT: ret + +; RV32IFDIS-LABEL: : +; RV32IFDIS: fmadd.d ft0, ft2, ft1, ft0, rne %1 = call double @llvm.fma.f64(double %a, double %b, double %c) ret double %1 } @@ -479,6 +506,9 @@ ; RV64IFD-NEXT: fmsub.d ft0, ft1, ft0, ft2 ; RV64IFD-NEXT: fmv.x.d a0, ft0 ; RV64IFD-NEXT: ret + +; RV32IFDIS-LABEL: : +; RV32IFDIS: fmsub.d ft0, ft1, ft0, ft2, rne %c_ = fadd double 0.0, %c ; avoid negation using xor %negc = fsub double -0.0, %c_ %1 = call double @llvm.fma.f64(double %a, double %b, double %negc) @@ -519,6 +549,11 @@ ; RV64IFD-NEXT: fnmadd.d ft0, ft2, ft0, ft1 ; RV64IFD-NEXT: fmv.x.d a0, ft0 ; RV64IFD-NEXT: ret + +; RV32IFDIS-LABEL: : +; RV32IFDIS: fadd.d ft2, ft2, ft3, rne +; RV32IFDIS: fadd.d ft1, ft1, ft3, rne +; RV32IFDIS: fnmadd.d ft0, ft2, ft0, ft1, rne %a_ = fadd double 0.0, %a %c_ = fadd double 0.0, %c %nega = fsub double -0.0, %a_ @@ -561,6 +596,11 @@ ; RV64IFD-NEXT: fnmadd.d ft0, ft2, ft0, ft1 ; RV64IFD-NEXT: fmv.x.d a0, ft0 ; RV64IFD-NEXT: ret + +; RV32IFDIS-LABEL: : +; RV32IFDIS: fadd.d ft2, ft2, ft3, rne +; RV32IFDIS: fadd.d ft1, ft1, ft3, rne +; RV32IFDIS: fnmadd.d ft0, ft2, ft0, ft1, rne %b_ = fadd double 0.0, %b %c_ = fadd double 0.0, %c %negb = fsub double -0.0, %b_ @@ -601,6 +641,10 @@ ; RV64IFD-NEXT: fnmsub.d ft0, ft2, ft1, ft0 ; RV64IFD-NEXT: fmv.x.d a0, ft0 ; RV64IFD-NEXT: ret + +; RV32IFDIS-LABEL: : +; RV32IFDIS: fadd.d ft2, ft2, ft3, rne +; RV32IFDIS: fnmsub.d ft0, ft2, ft1, ft0, rne %a_ = fadd double 0.0, %a %nega = fsub double -0.0, %a_ %1 = call double @llvm.fma.f64(double %nega, double %b, double %c) @@ -639,6 +683,10 @@ ; RV64IFD-NEXT: fnmsub.d ft0, ft2, ft1, ft0 ; RV64IFD-NEXT: fmv.x.d a0, ft0 ; RV64IFD-NEXT: ret + +; RV32IFDIS-LABEL: : +; RV32IFDIS: fadd.d ft2, ft2, ft3, rne +; RV32IFDIS: fnmsub.d ft0, ft2, ft1, ft0, rne %b_ = fadd double 0.0, %b %negb = fsub double -0.0, %b_ %1 = call double @llvm.fma.f64(double %a, double %negb, double %c) @@ -673,6 +721,9 @@ ; RV64IFD-NEXT: fmadd.d ft0, ft2, ft1, ft0 ; RV64IFD-NEXT: fmv.x.d a0, ft0 ; RV64IFD-NEXT: ret + +; RV32IFDIS-LABEL: : +; RV32IFDIS: fmadd.d ft0, ft2, ft1, ft0, rne %1 = fmul contract double %a, %b %2 = fadd contract double %1, %c ret double %2 @@ -710,6 +761,10 @@ ; RV64IFD-NEXT: fmsub.d ft0, ft1, ft0, ft2 ; RV64IFD-NEXT: fmv.x.d a0, ft0 ; RV64IFD-NEXT: ret + +; RV32IFDIS-LABEL: : +; RV32IFDIS: fadd.d ft2, ft2, ft3, rne +; RV32IFDIS: fmsub.d ft0, ft1, ft0, ft2, rne %c_ = fadd double 0.0, %c ; avoid negation using xor %1 = fmul contract double %a, %b %2 = fsub contract double %1, %c_ @@ -752,6 +807,12 @@ ; RV64IFD-NEXT: fnmadd.d ft0, ft2, ft1, ft0 ; RV64IFD-NEXT: fmv.x.d a0, ft0 ; RV64IFD-NEXT: ret + +; RV32IFDIS-LABEL: : +; RV32IFDIS: fadd.d ft2, ft2, ft3, rne +; RV32IFDIS: fadd.d ft1, ft1, ft3, rne +; RV32IFDIS: fadd.d ft0, ft0, ft3, rne +; RV32IFDIS: fnmadd.d ft0, ft2, ft1, ft0, rne %a_ = fadd double 0.0, %a ; avoid negation using xor %b_ = fadd double 0.0, %b ; avoid negation using xor %c_ = fadd double 0.0, %c ; avoid negation using xor @@ -795,6 +856,11 @@ ; RV64IFD-NEXT: fnmsub.d ft0, ft2, ft1, ft0 ; RV64IFD-NEXT: fmv.x.d a0, ft0 ; RV64IFD-NEXT: ret + +; RV32IFDIS-LABEL: : +; RV32IFDIS: fadd.d ft2, ft2, ft3, rne +; RV32IFDIS: fadd.d ft1, ft1, ft3, rne +; RV32IFDIS: fnmsub.d ft0, ft2, ft1, ft0, rne %a_ = fadd double 0.0, %a ; avoid negation using xor %b_ = fadd double 0.0, %b ; avoid negation using xor %1 = fmul contract double %a_, %b_ diff --git a/llvm/test/CodeGen/RISCV/float-arith.ll b/llvm/test/CodeGen/RISCV/float-arith.ll --- a/llvm/test/CodeGen/RISCV/float-arith.ll +++ b/llvm/test/CodeGen/RISCV/float-arith.ll @@ -3,6 +3,9 @@ ; RUN: | FileCheck -check-prefix=RV32IF %s ; RUN: llc -mtriple=riscv64 -mattr=+f -verify-machineinstrs < %s \ ; RUN: | FileCheck -check-prefix=RV64IF %s +; RUN: llc -mtriple=riscv32 -mattr=+f -filetype=obj < %s \ +; RUN: | llvm-objdump -d --triple=riscv32 --mattr=+f - \ +; RUN: | FileCheck -check-prefix=RV32IFDIS %s ; These tests are each targeted at a particular RISC-V FPU instruction. Most ; other files in this folder exercise LLVM IR instructions that don't directly @@ -24,6 +27,9 @@ ; RV64IF-NEXT: fadd.s ft0, ft1, ft0 ; RV64IF-NEXT: fmv.x.w a0, ft0 ; RV64IF-NEXT: ret + +; RV32IFDIS-LABEL: : +; RV32IFDIS: fadd.s ft0, ft1, ft0, rne %1 = fadd float %a, %b ret float %1 } @@ -44,6 +50,9 @@ ; RV64IF-NEXT: fsub.s ft0, ft1, ft0 ; RV64IF-NEXT: fmv.x.w a0, ft0 ; RV64IF-NEXT: ret + +; RV32IFDIS-LABEL: : +; RV32IFDIS: fsub.s ft0, ft1, ft0, rne %1 = fsub float %a, %b ret float %1 } @@ -64,6 +73,9 @@ ; RV64IF-NEXT: fmul.s ft0, ft1, ft0 ; RV64IF-NEXT: fmv.x.w a0, ft0 ; RV64IF-NEXT: ret + +; RV32IFDIS-LABEL: : +; RV32IFDIS: fmul.s ft0, ft1, ft0, rne %1 = fmul float %a, %b ret float %1 } @@ -84,6 +96,9 @@ ; RV64IF-NEXT: fdiv.s ft0, ft1, ft0 ; RV64IF-NEXT: fmv.x.w a0, ft0 ; RV64IF-NEXT: ret + +; RV32IFDIS-LABEL: : +; RV32IFDIS: fdiv.s ft0, ft1, ft0, rne %1 = fdiv float %a, %b ret float %1 } @@ -104,6 +119,9 @@ ; RV64IF-NEXT: fsqrt.s ft0, ft0 ; RV64IF-NEXT: fmv.x.w a0, ft0 ; RV64IF-NEXT: ret + +; RV32IFDIS-LABEL: : +; RV32IFDIS: fsqrt.s ft0, ft0, rne %1 = call float @llvm.sqrt.f32(float %a) ret float %1 } @@ -175,6 +193,9 @@ ; RV64IF-NEXT: fsgnjn.s ft0, ft1, ft0 ; RV64IF-NEXT: fmv.x.w a0, ft0 ; RV64IF-NEXT: ret + +; RV32IFDIS-LABEL: : +; RV32IFDIS: fadd.s ft0, ft1, ft0, rne %1 = fadd float %a, %b %2 = fneg float %1 %3 = call float @llvm.copysign.f32(float %a, float %2) @@ -205,6 +226,10 @@ ; RV64IF-NEXT: fadd.s ft0, ft1, ft0 ; RV64IF-NEXT: fmv.x.w a0, ft0 ; RV64IF-NEXT: ret + +; RV32IFDIS-LABEL: : +; RV32IFDIS: fadd.s ft0, ft1, ft0, rne +; RV32IFDIS: fadd.s ft0, ft1, ft0, rne %1 = fadd float %a, %b %2 = call float @llvm.fabs.f32(float %1) %3 = fadd float %2, %1 @@ -332,6 +357,9 @@ ; RV64IF-NEXT: fmadd.s ft0, ft2, ft1, ft0 ; RV64IF-NEXT: fmv.x.w a0, ft0 ; RV64IF-NEXT: ret + +; RV32IFDIS-LABEL: : +; RV32IFDIS: fmadd.s ft0, ft2, ft1, ft0, rne %1 = call float @llvm.fma.f32(float %a, float %b, float %c) ret float %1 } @@ -358,6 +386,10 @@ ; RV64IF-NEXT: fmsub.s ft0, ft1, ft0, ft2 ; RV64IF-NEXT: fmv.x.w a0, ft0 ; RV64IF-NEXT: ret + +; RV32IFDIS-LABEL: : +; RV32IFDIS: fadd.s ft2, ft2, ft3, rne +; RV32IFDIS: fmsub.s ft0, ft1, ft0, ft2, rne %c_ = fadd float 0.0, %c ; avoid negation using xor %negc = fsub float -0.0, %c_ %1 = call float @llvm.fma.f32(float %a, float %b, float %negc) @@ -388,6 +420,11 @@ ; RV64IF-NEXT: fnmadd.s ft0, ft2, ft0, ft1 ; RV64IF-NEXT: fmv.x.w a0, ft0 ; RV64IF-NEXT: ret + +; RV32IFDIS-LABEL: : +; RV32IFDIS: fadd.s ft2, ft2, ft3, rne +; RV32IFDIS: fadd.s ft1, ft1, ft3, rne +; RV32IFDIS: fnmadd.s ft0, ft2, ft0, ft1, rne %a_ = fadd float 0.0, %a %c_ = fadd float 0.0, %c %nega = fsub float -0.0, %a_ @@ -420,6 +457,11 @@ ; RV64IF-NEXT: fnmadd.s ft0, ft2, ft0, ft1 ; RV64IF-NEXT: fmv.x.w a0, ft0 ; RV64IF-NEXT: ret + +; RV32IFDIS-LABEL: : +; RV32IFDIS: fadd.s ft2, ft2, ft3, rne +; RV32IFDIS: fadd.s ft1, ft1, ft3, rne +; RV32IFDIS: fnmadd.s ft0, ft2, ft0, ft1, rne %b_ = fadd float 0.0, %b %c_ = fadd float 0.0, %c %negb = fsub float -0.0, %b_ @@ -450,6 +492,10 @@ ; RV64IF-NEXT: fnmsub.s ft0, ft2, ft1, ft0 ; RV64IF-NEXT: fmv.x.w a0, ft0 ; RV64IF-NEXT: ret + +; RV32IFDIS-LABEL: : +; RV32IFDIS: fadd.s ft2, ft2, ft3, rne +; RV32IFDIS: fnmsub.s ft0, ft2, ft1, ft0, rne %a_ = fadd float 0.0, %a %nega = fsub float -0.0, %a_ %1 = call float @llvm.fma.f32(float %nega, float %b, float %c) @@ -478,6 +524,10 @@ ; RV64IF-NEXT: fnmsub.s ft0, ft2, ft1, ft0 ; RV64IF-NEXT: fmv.x.w a0, ft0 ; RV64IF-NEXT: ret + +; RV32IFDIS-LABEL: : +; RV32IFDIS: fadd.s ft2, ft2, ft3, rne +; RV32IFDIS: fnmsub.s ft0, ft2, ft1, ft0, rne %b_ = fadd float 0.0, %b %negb = fsub float -0.0, %b_ %1 = call float @llvm.fma.f32(float %a, float %negb, float %c) @@ -502,6 +552,9 @@ ; RV64IF-NEXT: fmadd.s ft0, ft2, ft1, ft0 ; RV64IF-NEXT: fmv.x.w a0, ft0 ; RV64IF-NEXT: ret + +; RV32IFDIS-LABEL: : +; RV32IFDIS: fmadd.s ft0, ft2, ft1, ft0, rne %1 = fmul contract float %a, %b %2 = fadd contract float %1, %c ret float %2 @@ -529,6 +582,10 @@ ; RV64IF-NEXT: fmsub.s ft0, ft1, ft0, ft2 ; RV64IF-NEXT: fmv.x.w a0, ft0 ; RV64IF-NEXT: ret + +; RV32IFDIS-LABEL: : +; RV32IFDIS: fadd.s ft2, ft2, ft3, rne +; RV32IFDIS: fmsub.s ft0, ft1, ft0, ft2, rne %c_ = fadd float 0.0, %c ; avoid negation using xor %1 = fmul contract float %a, %b %2 = fsub contract float %1, %c_ @@ -561,6 +618,12 @@ ; RV64IF-NEXT: fnmadd.s ft0, ft2, ft1, ft0 ; RV64IF-NEXT: fmv.x.w a0, ft0 ; RV64IF-NEXT: ret + +; RV32IFDIS-LABEL: : +; RV32IFDIS: fadd.s ft2, ft2, ft3, rne +; RV32IFDIS: fadd.s ft1, ft1, ft3, rne +; RV32IFDIS: fadd.s ft0, ft0, ft3, rne +; RV32IFDIS: fnmadd.s ft0, ft2, ft1, ft0, rne %a_ = fadd float 0.0, %a ; avoid negation using xor %b_ = fadd float 0.0, %b ; avoid negation using xor %c_ = fadd float 0.0, %c ; avoid negation using xor @@ -594,6 +657,11 @@ ; RV64IF-NEXT: fnmsub.s ft0, ft2, ft1, ft0 ; RV64IF-NEXT: fmv.x.w a0, ft0 ; RV64IF-NEXT: ret + +; RV32IFDIS-LABEL: : +; RV32IFDIS: fadd.s ft2, ft2, ft3, rne +; RV32IFDIS: fadd.s ft1, ft1, ft3, rne +; RV32IFDIS: fnmsub.s ft0, ft2, ft1, ft0, rne %a_ = fadd float 0.0, %a ; avoid negation using xor %b_ = fadd float 0.0, %b ; avoid negation using xor %1 = fmul contract float %a_, %b_