@@ -529,6 +529,91 @@ define float @fmsub_s(float %a, float %b, float %c) nounwind {
529529 ret float %1
530530}
531531
532+ define float @fmsub_s_fmul_fneg (float %a , float %b , float %c , float %d ) nounwind {
533+ ; CHECKIFD-LABEL: fmsub_d_fmul_fneg:
534+ ; CHECKIFD: # %bb.0:
535+ ; CHECKIFD-NEXT: fneg.d fa5, fa3
536+ ; CHECKIFD-NEXT: fmul.d fa5, fa2, fa5
537+ ; CHECKIFD-NEXT: fmadd.d fa0, fa0, fa1, fa5
538+ ; CHECKIFD-NEXT: ret
539+ ;
540+ ; RV32IZFINXZDINX-LABEL: fmsub_d_fmul_fneg:
541+ ; RV32IZFINXZDINX: # %bb.0:
542+ ; RV32IZFINXZDINX-NEXT: fneg.d a6, a6
543+ ; RV32IZFINXZDINX-NEXT: fmul.d a4, a4, a6
544+ ; RV32IZFINXZDINX-NEXT: fmadd.d a0, a0, a2, a4
545+ ; RV32IZFINXZDINX-NEXT: ret
546+ ;
547+ ; RV64IZFINXZDINX-LABEL: fmsub_d_fmul_fneg:
548+ ; RV64IZFINXZDINX: # %bb.0:
549+ ; RV64IZFINXZDINX-NEXT: fneg.d a3, a3
550+ ; RV64IZFINXZDINX-NEXT: fmul.d a2, a2, a3
551+ ; RV64IZFINXZDINX-NEXT: fmadd.d a0, a0, a1, a2
552+ ; RV64IZFINXZDINX-NEXT: ret
553+ ;
554+ ; CHECKIF-LABEL: fmsub_s_fmul_fneg:
555+ ; CHECKIF: # %bb.0:
556+ ; CHECKIF-NEXT: fneg.s fa5, fa3
557+ ; CHECKIF-NEXT: fmul.s fa5, fa2, fa5
558+ ; CHECKIF-NEXT: fmadd.s fa0, fa0, fa1, fa5
559+ ; CHECKIF-NEXT: ret
560+ ;
561+ ; CHECKIZFINX-LABEL: fmsub_s_fmul_fneg:
562+ ; CHECKIZFINX: # %bb.0:
563+ ; CHECKIZFINX-NEXT: fneg.s a3, a3
564+ ; CHECKIZFINX-NEXT: fmul.s a2, a2, a3
565+ ; CHECKIZFINX-NEXT: fmadd.s a0, a0, a1, a2
566+ ; CHECKIZFINX-NEXT: ret
567+ ;
568+ ; RV32I-LABEL: fmsub_s_fmul_fneg:
569+ ; RV32I: # %bb.0:
570+ ; RV32I-NEXT: addi sp, sp, -16
571+ ; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
572+ ; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
573+ ; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill
574+ ; RV32I-NEXT: mv s0, a1
575+ ; RV32I-NEXT: mv s1, a0
576+ ; RV32I-NEXT: lui a1, 524288
577+ ; RV32I-NEXT: xor a1, a3, a1
578+ ; RV32I-NEXT: mv a0, a2
579+ ; RV32I-NEXT: call __mulsf3
580+ ; RV32I-NEXT: mv a2, a0
581+ ; RV32I-NEXT: mv a0, s1
582+ ; RV32I-NEXT: mv a1, s0
583+ ; RV32I-NEXT: call fmaf
584+ ; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
585+ ; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
586+ ; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload
587+ ; RV32I-NEXT: addi sp, sp, 16
588+ ; RV32I-NEXT: ret
589+ ;
590+ ; RV64I-LABEL: fmsub_s_fmul_fneg:
591+ ; RV64I: # %bb.0:
592+ ; RV64I-NEXT: addi sp, sp, -32
593+ ; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
594+ ; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
595+ ; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill
596+ ; RV64I-NEXT: mv s0, a1
597+ ; RV64I-NEXT: mv s1, a0
598+ ; RV64I-NEXT: lui a1, 524288
599+ ; RV64I-NEXT: xor a1, a3, a1
600+ ; RV64I-NEXT: mv a0, a2
601+ ; RV64I-NEXT: call __mulsf3
602+ ; RV64I-NEXT: mv a2, a0
603+ ; RV64I-NEXT: mv a0, s1
604+ ; RV64I-NEXT: mv a1, s0
605+ ; RV64I-NEXT: call fmaf
606+ ; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
607+ ; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
608+ ; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload
609+ ; RV64I-NEXT: addi sp, sp, 32
610+ ; RV64I-NEXT: ret
611+ %negd = fneg float %d
612+ %fmul = fmul float %c , %negd
613+ %1 = call float @llvm.fma.f32 (float %a , float %b , float %fmul )
614+ ret float %1
615+ }
616+
532617define float @fnmadd_s (float %a , float %b , float %c ) nounwind {
533618; CHECKIF-LABEL: fnmadd_s:
534619; CHECKIF: # %bb.0:
@@ -738,6 +823,93 @@ define float @fnmadd_s_3(float %a, float %b, float %c) nounwind {
738823 ret float %neg
739824}
740825
826+ define float @fnmadd_s_fmul_fneg (float %a , float %b , float %c , float %d ) nounwind {
827+ ; CHECKIFD-LABEL: fnmadd_d_fmul_fneg:
828+ ; CHECKIFD: # %bb.0:
829+ ; CHECKIFD-NEXT: fneg.d fa5, fa0
830+ ; CHECKIFD-NEXT: fmul.d fa5, fa1, fa5
831+ ; CHECKIFD-NEXT: fmadd.d fa0, fa2, fa3, fa5
832+ ; CHECKIFD-NEXT: ret
833+ ;
834+ ; RV32IZFINXZDINX-LABEL: fnmadd_d_fmul_fneg:
835+ ; RV32IZFINXZDINX: # %bb.0:
836+ ; RV32IZFINXZDINX-NEXT: fneg.d a0, a0
837+ ; RV32IZFINXZDINX-NEXT: fmul.d a0, a2, a0
838+ ; RV32IZFINXZDINX-NEXT: fmadd.d a0, a4, a6, a0
839+ ; RV32IZFINXZDINX-NEXT: ret
840+ ;
841+ ; RV64IZFINXZDINX-LABEL: fnmadd_d_fmul_fneg:
842+ ; RV64IZFINXZDINX: # %bb.0:
843+ ; RV64IZFINXZDINX-NEXT: fneg.d a0, a0
844+ ; RV64IZFINXZDINX-NEXT: fmul.d a0, a1, a0
845+ ; RV64IZFINXZDINX-NEXT: fmadd.d a0, a2, a3, a0
846+ ; RV64IZFINXZDINX-NEXT: ret
847+ ;
848+ ; CHECKIF-LABEL: fnmadd_s_fmul_fneg:
849+ ; CHECKIF: # %bb.0:
850+ ; CHECKIF-NEXT: fneg.s fa5, fa0
851+ ; CHECKIF-NEXT: fmul.s fa5, fa1, fa5
852+ ; CHECKIF-NEXT: fmadd.s fa0, fa2, fa3, fa5
853+ ; CHECKIF-NEXT: ret
854+ ;
855+ ; CHECKIZFINX-LABEL: fnmadd_s_fmul_fneg:
856+ ; CHECKIZFINX: # %bb.0:
857+ ; CHECKIZFINX-NEXT: fneg.s a0, a0
858+ ; CHECKIZFINX-NEXT: fmul.s a0, a1, a0
859+ ; CHECKIZFINX-NEXT: fmadd.s a0, a2, a3, a0
860+ ; CHECKIZFINX-NEXT: ret
861+ ;
862+ ; RV32I-LABEL: fnmadd_s_fmul_fneg:
863+ ; RV32I: # %bb.0:
864+ ; RV32I-NEXT: addi sp, sp, -16
865+ ; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
866+ ; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
867+ ; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill
868+ ; RV32I-NEXT: mv s0, a3
869+ ; RV32I-NEXT: mv s1, a2
870+ ; RV32I-NEXT: mv a2, a1
871+ ; RV32I-NEXT: lui a1, 524288
872+ ; RV32I-NEXT: xor a1, a0, a1
873+ ; RV32I-NEXT: mv a0, a2
874+ ; RV32I-NEXT: call __mulsf3
875+ ; RV32I-NEXT: mv a2, a0
876+ ; RV32I-NEXT: mv a0, s1
877+ ; RV32I-NEXT: mv a1, s0
878+ ; RV32I-NEXT: call fmaf
879+ ; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
880+ ; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
881+ ; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload
882+ ; RV32I-NEXT: addi sp, sp, 16
883+ ; RV32I-NEXT: ret
884+ ;
885+ ; RV64I-LABEL: fnmadd_s_fmul_fneg:
886+ ; RV64I: # %bb.0:
887+ ; RV64I-NEXT: addi sp, sp, -32
888+ ; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
889+ ; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
890+ ; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill
891+ ; RV64I-NEXT: mv s0, a3
892+ ; RV64I-NEXT: mv s1, a2
893+ ; RV64I-NEXT: mv a2, a1
894+ ; RV64I-NEXT: lui a1, 524288
895+ ; RV64I-NEXT: xor a1, a0, a1
896+ ; RV64I-NEXT: mv a0, a2
897+ ; RV64I-NEXT: call __mulsf3
898+ ; RV64I-NEXT: mv a2, a0
899+ ; RV64I-NEXT: mv a0, s1
900+ ; RV64I-NEXT: mv a1, s0
901+ ; RV64I-NEXT: call fmaf
902+ ; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
903+ ; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
904+ ; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload
905+ ; RV64I-NEXT: addi sp, sp, 32
906+ ; RV64I-NEXT: ret
907+ %nega = fneg float %a
908+ %mul = fmul float %b , %nega
909+ %1 = call float @llvm.fma.f32 (float %c , float %d , float %mul )
910+ ret float %1
911+ }
912+
741913define float @fnmadd_nsz (float %a , float %b , float %c ) nounwind {
742914; RV32IF-LABEL: fnmadd_nsz:
743915; RV32IF: # %bb.0:
0 commit comments