Skip to content

Commit 5e7e0d6

Browse files
authored
[LoongArch] Fix pattern for FNMSUB_{S/D} instructions (#73742)
``` when a=c=-0.0, b=0.0: -(a * b + (-c)) = -0.0 -a * b + c = 0.0 (fneg (fma a, b (-c))) != (fma (fneg a), b ,c) ``` See https://reviews.llvm.org/D90901 for a similar discussion on X86.
1 parent d0c8d41 commit 5e7e0d6

File tree

4 files changed

+483
-49
lines changed

4 files changed

+483
-49
lines changed

llvm/lib/Target/LoongArch/LoongArchFloat32InstrInfo.td

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -295,8 +295,12 @@ def : Pat<(fneg (fma FPR32:$fj, FPR32:$fk, FPR32:$fa)),
295295
def : Pat<(fma_nsz (fneg FPR32:$fj), FPR32:$fk, (fneg FPR32:$fa)),
296296
(FNMADD_S FPR32:$fj, FPR32:$fk, FPR32:$fa)>;
297297

298-
// fnmsub.s: -fj * fk + fa
299-
def : Pat<(fma (fneg FPR32:$fj), FPR32:$fk, FPR32:$fa),
298+
// fnmsub.s: -(fj * fk - fa)
299+
def : Pat<(fneg (fma FPR32:$fj, FPR32:$fk, (fneg FPR32:$fa))),
300+
(FNMSUB_S FPR32:$fj, FPR32:$fk, FPR32:$fa)>;
301+
302+
// fnmsub.s: -fj * fk + fa (the nsz flag on the FMA)
303+
def : Pat<(fma_nsz (fneg FPR32:$fj), FPR32:$fk, FPR32:$fa),
300304
(FNMSUB_S FPR32:$fj, FPR32:$fk, FPR32:$fa)>;
301305
} // Predicates = [HasBasicF]
302306

llvm/lib/Target/LoongArch/LoongArchFloat64InstrInfo.td

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,11 @@ def : Pat<(fma_nsz (fneg FPR64:$fj), FPR64:$fk, (fneg FPR64:$fa)),
263263
(FNMADD_D FPR64:$fj, FPR64:$fk, FPR64:$fa)>;
264264

265265
// fnmsub.d: -(fj * fk - fa)
266-
def : Pat<(fma (fneg FPR64:$fj), FPR64:$fk, FPR64:$fa),
266+
def : Pat<(fneg (fma FPR64:$fj, FPR64:$fk, (fneg FPR64:$fa))),
267+
(FNMSUB_D FPR64:$fj, FPR64:$fk, FPR64:$fa)>;
268+
269+
// fnmsub.d: -fj * fk + fa (the nsz flag on the FMA)
270+
def : Pat<(fma_nsz (fneg FPR64:$fj), FPR64:$fk, FPR64:$fa),
267271
(FNMSUB_D FPR64:$fj, FPR64:$fk, FPR64:$fa)>;
268272
} // Predicates = [HasBasicD]
269273

llvm/test/CodeGen/LoongArch/double-fma.ll

Lines changed: 236 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -236,13 +236,15 @@ define double @fnmsub_d(double %a, double %b, double %c) nounwind {
236236
; LA32-CONTRACT-ON-LABEL: fnmsub_d:
237237
; LA32-CONTRACT-ON: # %bb.0:
238238
; LA32-CONTRACT-ON-NEXT: fmul.d $fa0, $fa0, $fa1
239-
; LA32-CONTRACT-ON-NEXT: fsub.d $fa0, $fa2, $fa0
239+
; LA32-CONTRACT-ON-NEXT: fsub.d $fa0, $fa0, $fa2
240+
; LA32-CONTRACT-ON-NEXT: fneg.d $fa0, $fa0
240241
; LA32-CONTRACT-ON-NEXT: ret
241242
;
242243
; LA32-CONTRACT-OFF-LABEL: fnmsub_d:
243244
; LA32-CONTRACT-OFF: # %bb.0:
244245
; LA32-CONTRACT-OFF-NEXT: fmul.d $fa0, $fa0, $fa1
245-
; LA32-CONTRACT-OFF-NEXT: fsub.d $fa0, $fa2, $fa0
246+
; LA32-CONTRACT-OFF-NEXT: fsub.d $fa0, $fa0, $fa2
247+
; LA32-CONTRACT-OFF-NEXT: fneg.d $fa0, $fa0
246248
; LA32-CONTRACT-OFF-NEXT: ret
247249
;
248250
; LA64-CONTRACT-FAST-LABEL: fnmsub_d:
@@ -253,12 +255,98 @@ define double @fnmsub_d(double %a, double %b, double %c) nounwind {
253255
; LA64-CONTRACT-ON-LABEL: fnmsub_d:
254256
; LA64-CONTRACT-ON: # %bb.0:
255257
; LA64-CONTRACT-ON-NEXT: fmul.d $fa0, $fa0, $fa1
256-
; LA64-CONTRACT-ON-NEXT: fsub.d $fa0, $fa2, $fa0
258+
; LA64-CONTRACT-ON-NEXT: fsub.d $fa0, $fa0, $fa2
259+
; LA64-CONTRACT-ON-NEXT: fneg.d $fa0, $fa0
257260
; LA64-CONTRACT-ON-NEXT: ret
258261
;
259262
; LA64-CONTRACT-OFF-LABEL: fnmsub_d:
260263
; LA64-CONTRACT-OFF: # %bb.0:
261264
; LA64-CONTRACT-OFF-NEXT: fmul.d $fa0, $fa0, $fa1
265+
; LA64-CONTRACT-OFF-NEXT: fsub.d $fa0, $fa0, $fa2
266+
; LA64-CONTRACT-OFF-NEXT: fneg.d $fa0, $fa0
267+
; LA64-CONTRACT-OFF-NEXT: ret
268+
%negc = fneg double %c
269+
%mul = fmul double %a, %b
270+
%add = fadd double %mul, %negc
271+
%neg = fneg double %add
272+
ret double %neg
273+
}
274+
275+
define double @fnmsub_d_nsz(double %a, double %b, double %c) nounwind {
276+
; LA32-CONTRACT-FAST-LABEL: fnmsub_d_nsz:
277+
; LA32-CONTRACT-FAST: # %bb.0:
278+
; LA32-CONTRACT-FAST-NEXT: fnmsub.d $fa0, $fa0, $fa1, $fa2
279+
; LA32-CONTRACT-FAST-NEXT: ret
280+
;
281+
; LA32-CONTRACT-ON-LABEL: fnmsub_d_nsz:
282+
; LA32-CONTRACT-ON: # %bb.0:
283+
; LA32-CONTRACT-ON-NEXT: fmul.d $fa0, $fa0, $fa1
284+
; LA32-CONTRACT-ON-NEXT: fsub.d $fa0, $fa2, $fa0
285+
; LA32-CONTRACT-ON-NEXT: ret
286+
;
287+
; LA32-CONTRACT-OFF-LABEL: fnmsub_d_nsz:
288+
; LA32-CONTRACT-OFF: # %bb.0:
289+
; LA32-CONTRACT-OFF-NEXT: fmul.d $fa0, $fa0, $fa1
290+
; LA32-CONTRACT-OFF-NEXT: fsub.d $fa0, $fa2, $fa0
291+
; LA32-CONTRACT-OFF-NEXT: ret
292+
;
293+
; LA64-CONTRACT-FAST-LABEL: fnmsub_d_nsz:
294+
; LA64-CONTRACT-FAST: # %bb.0:
295+
; LA64-CONTRACT-FAST-NEXT: fnmsub.d $fa0, $fa0, $fa1, $fa2
296+
; LA64-CONTRACT-FAST-NEXT: ret
297+
;
298+
; LA64-CONTRACT-ON-LABEL: fnmsub_d_nsz:
299+
; LA64-CONTRACT-ON: # %bb.0:
300+
; LA64-CONTRACT-ON-NEXT: fmul.d $fa0, $fa0, $fa1
301+
; LA64-CONTRACT-ON-NEXT: fsub.d $fa0, $fa2, $fa0
302+
; LA64-CONTRACT-ON-NEXT: ret
303+
;
304+
; LA64-CONTRACT-OFF-LABEL: fnmsub_d_nsz:
305+
; LA64-CONTRACT-OFF: # %bb.0:
306+
; LA64-CONTRACT-OFF-NEXT: fmul.d $fa0, $fa0, $fa1
307+
; LA64-CONTRACT-OFF-NEXT: fsub.d $fa0, $fa2, $fa0
308+
; LA64-CONTRACT-OFF-NEXT: ret
309+
%nega = fneg nsz double %a
310+
%mul = fmul nsz double %nega, %b
311+
%add = fadd nsz double %mul, %c
312+
ret double %add
313+
}
314+
315+
;; Check that fnmsub.d is not emitted.
316+
define double @not_fnmsub_d(double %a, double %b, double %c) nounwind {
317+
; LA32-CONTRACT-FAST-LABEL: not_fnmsub_d:
318+
; LA32-CONTRACT-FAST: # %bb.0:
319+
; LA32-CONTRACT-FAST-NEXT: fneg.d $fa0, $fa0
320+
; LA32-CONTRACT-FAST-NEXT: fmadd.d $fa0, $fa0, $fa1, $fa2
321+
; LA32-CONTRACT-FAST-NEXT: ret
322+
;
323+
; LA32-CONTRACT-ON-LABEL: not_fnmsub_d:
324+
; LA32-CONTRACT-ON: # %bb.0:
325+
; LA32-CONTRACT-ON-NEXT: fmul.d $fa0, $fa0, $fa1
326+
; LA32-CONTRACT-ON-NEXT: fsub.d $fa0, $fa2, $fa0
327+
; LA32-CONTRACT-ON-NEXT: ret
328+
;
329+
; LA32-CONTRACT-OFF-LABEL: not_fnmsub_d:
330+
; LA32-CONTRACT-OFF: # %bb.0:
331+
; LA32-CONTRACT-OFF-NEXT: fmul.d $fa0, $fa0, $fa1
332+
; LA32-CONTRACT-OFF-NEXT: fsub.d $fa0, $fa2, $fa0
333+
; LA32-CONTRACT-OFF-NEXT: ret
334+
;
335+
; LA64-CONTRACT-FAST-LABEL: not_fnmsub_d:
336+
; LA64-CONTRACT-FAST: # %bb.0:
337+
; LA64-CONTRACT-FAST-NEXT: fneg.d $fa0, $fa0
338+
; LA64-CONTRACT-FAST-NEXT: fmadd.d $fa0, $fa0, $fa1, $fa2
339+
; LA64-CONTRACT-FAST-NEXT: ret
340+
;
341+
; LA64-CONTRACT-ON-LABEL: not_fnmsub_d:
342+
; LA64-CONTRACT-ON: # %bb.0:
343+
; LA64-CONTRACT-ON-NEXT: fmul.d $fa0, $fa0, $fa1
344+
; LA64-CONTRACT-ON-NEXT: fsub.d $fa0, $fa2, $fa0
345+
; LA64-CONTRACT-ON-NEXT: ret
346+
;
347+
; LA64-CONTRACT-OFF-LABEL: not_fnmsub_d:
348+
; LA64-CONTRACT-OFF: # %bb.0:
349+
; LA64-CONTRACT-OFF-NEXT: fmul.d $fa0, $fa0, $fa1
262350
; LA64-CONTRACT-OFF-NEXT: fsub.d $fa0, $fa2, $fa0
263351
; LA64-CONTRACT-OFF-NEXT: ret
264352
%nega = fneg double %a
@@ -483,6 +571,86 @@ define double @contract_fnmsub_d(double %a, double %b, double %c) nounwind {
483571
; LA64-CONTRACT-OFF-LABEL: contract_fnmsub_d:
484572
; LA64-CONTRACT-OFF: # %bb.0:
485573
; LA64-CONTRACT-OFF-NEXT: fnmsub.d $fa0, $fa0, $fa1, $fa2
574+
; LA64-CONTRACT-OFF-NEXT: ret
575+
%negc = fneg contract double %c
576+
%mul = fmul contract double %a, %b
577+
%add = fadd contract double %mul, %negc
578+
%neg = fneg contract double %add
579+
ret double %neg
580+
}
581+
582+
define double @contract_fnmsub_d_nsz(double %a, double %b, double %c) nounwind {
583+
; LA32-CONTRACT-FAST-LABEL: contract_fnmsub_d_nsz:
584+
; LA32-CONTRACT-FAST: # %bb.0:
585+
; LA32-CONTRACT-FAST-NEXT: fnmsub.d $fa0, $fa0, $fa1, $fa2
586+
; LA32-CONTRACT-FAST-NEXT: ret
587+
;
588+
; LA32-CONTRACT-ON-LABEL: contract_fnmsub_d_nsz:
589+
; LA32-CONTRACT-ON: # %bb.0:
590+
; LA32-CONTRACT-ON-NEXT: fnmsub.d $fa0, $fa0, $fa1, $fa2
591+
; LA32-CONTRACT-ON-NEXT: ret
592+
;
593+
; LA32-CONTRACT-OFF-LABEL: contract_fnmsub_d_nsz:
594+
; LA32-CONTRACT-OFF: # %bb.0:
595+
; LA32-CONTRACT-OFF-NEXT: fnmsub.d $fa0, $fa0, $fa1, $fa2
596+
; LA32-CONTRACT-OFF-NEXT: ret
597+
;
598+
; LA64-CONTRACT-FAST-LABEL: contract_fnmsub_d_nsz:
599+
; LA64-CONTRACT-FAST: # %bb.0:
600+
; LA64-CONTRACT-FAST-NEXT: fnmsub.d $fa0, $fa0, $fa1, $fa2
601+
; LA64-CONTRACT-FAST-NEXT: ret
602+
;
603+
; LA64-CONTRACT-ON-LABEL: contract_fnmsub_d_nsz:
604+
; LA64-CONTRACT-ON: # %bb.0:
605+
; LA64-CONTRACT-ON-NEXT: fnmsub.d $fa0, $fa0, $fa1, $fa2
606+
; LA64-CONTRACT-ON-NEXT: ret
607+
;
608+
; LA64-CONTRACT-OFF-LABEL: contract_fnmsub_d_nsz:
609+
; LA64-CONTRACT-OFF: # %bb.0:
610+
; LA64-CONTRACT-OFF-NEXT: fnmsub.d $fa0, $fa0, $fa1, $fa2
611+
; LA64-CONTRACT-OFF-NEXT: ret
612+
%nega = fneg contract nsz double %a
613+
%mul = fmul contract nsz double %nega, %b
614+
%add = fadd contract nsz double %mul, %c
615+
ret double %add
616+
}
617+
618+
;; Check that fnmsub.d is not emitted.
619+
define double @not_contract_fnmsub_d(double %a, double %b, double %c) nounwind {
620+
; LA32-CONTRACT-FAST-LABEL: not_contract_fnmsub_d:
621+
; LA32-CONTRACT-FAST: # %bb.0:
622+
; LA32-CONTRACT-FAST-NEXT: fneg.d $fa0, $fa0
623+
; LA32-CONTRACT-FAST-NEXT: fmadd.d $fa0, $fa0, $fa1, $fa2
624+
; LA32-CONTRACT-FAST-NEXT: ret
625+
;
626+
; LA32-CONTRACT-ON-LABEL: not_contract_fnmsub_d:
627+
; LA32-CONTRACT-ON: # %bb.0:
628+
; LA32-CONTRACT-ON-NEXT: fneg.d $fa0, $fa0
629+
; LA32-CONTRACT-ON-NEXT: fmadd.d $fa0, $fa0, $fa1, $fa2
630+
; LA32-CONTRACT-ON-NEXT: ret
631+
;
632+
; LA32-CONTRACT-OFF-LABEL: not_contract_fnmsub_d:
633+
; LA32-CONTRACT-OFF: # %bb.0:
634+
; LA32-CONTRACT-OFF-NEXT: fneg.d $fa0, $fa0
635+
; LA32-CONTRACT-OFF-NEXT: fmadd.d $fa0, $fa0, $fa1, $fa2
636+
; LA32-CONTRACT-OFF-NEXT: ret
637+
;
638+
; LA64-CONTRACT-FAST-LABEL: not_contract_fnmsub_d:
639+
; LA64-CONTRACT-FAST: # %bb.0:
640+
; LA64-CONTRACT-FAST-NEXT: fneg.d $fa0, $fa0
641+
; LA64-CONTRACT-FAST-NEXT: fmadd.d $fa0, $fa0, $fa1, $fa2
642+
; LA64-CONTRACT-FAST-NEXT: ret
643+
;
644+
; LA64-CONTRACT-ON-LABEL: not_contract_fnmsub_d:
645+
; LA64-CONTRACT-ON: # %bb.0:
646+
; LA64-CONTRACT-ON-NEXT: fneg.d $fa0, $fa0
647+
; LA64-CONTRACT-ON-NEXT: fmadd.d $fa0, $fa0, $fa1, $fa2
648+
; LA64-CONTRACT-ON-NEXT: ret
649+
;
650+
; LA64-CONTRACT-OFF-LABEL: not_contract_fnmsub_d:
651+
; LA64-CONTRACT-OFF: # %bb.0:
652+
; LA64-CONTRACT-OFF-NEXT: fneg.d $fa0, $fa0
653+
; LA64-CONTRACT-OFF-NEXT: fmadd.d $fa0, $fa0, $fa1, $fa2
486654
; LA64-CONTRACT-OFF-NEXT: ret
487655
%nega = fneg contract double %a
488656
%mul = fmul contract double %nega, %b
@@ -592,8 +760,8 @@ define double @fnmadd_d_intrinsics(double %a, double %b, double %c) nounwind {
592760
; LA64-CONTRACT-OFF-NEXT: fnmadd.d $fa0, $fa0, $fa1, $fa2
593761
; LA64-CONTRACT-OFF-NEXT: ret
594762
%fma = call double @llvm.fma.f64(double %a, double %b, double %c)
595-
%neg = fneg double %fma
596-
ret double %neg
763+
%negfma = fneg double %fma
764+
ret double %negfma
597765
}
598766

599767
define double @fnmadd_d_nsz_intrinsics(double %a, double %b, double %c) nounwind {
@@ -704,44 +872,87 @@ define double @fnmsub_d_intrinsics(double %a, double %b, double %c) nounwind {
704872
; LA64-CONTRACT-OFF-LABEL: fnmsub_d_intrinsics:
705873
; LA64-CONTRACT-OFF: # %bb.0:
706874
; LA64-CONTRACT-OFF-NEXT: fnmsub.d $fa0, $fa0, $fa1, $fa2
875+
; LA64-CONTRACT-OFF-NEXT: ret
876+
%negc = fneg double %c
877+
%fma = call double @llvm.fma.f64(double %a, double %b, double %negc)
878+
%negfma = fneg double %fma
879+
ret double %negfma
880+
}
881+
882+
define double @fnmsub_d_nsz_intrinsics(double %a, double %b, double %c) nounwind {
883+
; LA32-CONTRACT-FAST-LABEL: fnmsub_d_nsz_intrinsics:
884+
; LA32-CONTRACT-FAST: # %bb.0:
885+
; LA32-CONTRACT-FAST-NEXT: fnmsub.d $fa0, $fa0, $fa1, $fa2
886+
; LA32-CONTRACT-FAST-NEXT: ret
887+
;
888+
; LA32-CONTRACT-ON-LABEL: fnmsub_d_nsz_intrinsics:
889+
; LA32-CONTRACT-ON: # %bb.0:
890+
; LA32-CONTRACT-ON-NEXT: fnmsub.d $fa0, $fa0, $fa1, $fa2
891+
; LA32-CONTRACT-ON-NEXT: ret
892+
;
893+
; LA32-CONTRACT-OFF-LABEL: fnmsub_d_nsz_intrinsics:
894+
; LA32-CONTRACT-OFF: # %bb.0:
895+
; LA32-CONTRACT-OFF-NEXT: fnmsub.d $fa0, $fa0, $fa1, $fa2
896+
; LA32-CONTRACT-OFF-NEXT: ret
897+
;
898+
; LA64-CONTRACT-FAST-LABEL: fnmsub_d_nsz_intrinsics:
899+
; LA64-CONTRACT-FAST: # %bb.0:
900+
; LA64-CONTRACT-FAST-NEXT: fnmsub.d $fa0, $fa0, $fa1, $fa2
901+
; LA64-CONTRACT-FAST-NEXT: ret
902+
;
903+
; LA64-CONTRACT-ON-LABEL: fnmsub_d_nsz_intrinsics:
904+
; LA64-CONTRACT-ON: # %bb.0:
905+
; LA64-CONTRACT-ON-NEXT: fnmsub.d $fa0, $fa0, $fa1, $fa2
906+
; LA64-CONTRACT-ON-NEXT: ret
907+
;
908+
; LA64-CONTRACT-OFF-LABEL: fnmsub_d_nsz_intrinsics:
909+
; LA64-CONTRACT-OFF: # %bb.0:
910+
; LA64-CONTRACT-OFF-NEXT: fnmsub.d $fa0, $fa0, $fa1, $fa2
707911
; LA64-CONTRACT-OFF-NEXT: ret
708912
%nega = fneg double %a
709-
%fma = call double @llvm.fma.f64(double %nega, double %b, double %c)
913+
%fma = call nsz double @llvm.fma.f64(double %nega, double %b, double %c)
710914
ret double %fma
711915
}
712916

713-
define double @fnmsub_d_swap_intrinsics(double %a, double %b, double %c) nounwind {
714-
; LA32-CONTRACT-FAST-LABEL: fnmsub_d_swap_intrinsics:
917+
;; Check that fnmsub.d is not emitted.
918+
define double @not_fnmsub_d_intrinsics(double %a, double %b, double %c) nounwind {
919+
; LA32-CONTRACT-FAST-LABEL: not_fnmsub_d_intrinsics:
715920
; LA32-CONTRACT-FAST: # %bb.0:
716-
; LA32-CONTRACT-FAST-NEXT: fnmsub.d $fa0, $fa1, $fa0, $fa2
921+
; LA32-CONTRACT-FAST-NEXT: fneg.d $fa0, $fa0
922+
; LA32-CONTRACT-FAST-NEXT: fmadd.d $fa0, $fa0, $fa1, $fa2
717923
; LA32-CONTRACT-FAST-NEXT: ret
718924
;
719-
; LA32-CONTRACT-ON-LABEL: fnmsub_d_swap_intrinsics:
925+
; LA32-CONTRACT-ON-LABEL: not_fnmsub_d_intrinsics:
720926
; LA32-CONTRACT-ON: # %bb.0:
721-
; LA32-CONTRACT-ON-NEXT: fnmsub.d $fa0, $fa1, $fa0, $fa2
927+
; LA32-CONTRACT-ON-NEXT: fneg.d $fa0, $fa0
928+
; LA32-CONTRACT-ON-NEXT: fmadd.d $fa0, $fa0, $fa1, $fa2
722929
; LA32-CONTRACT-ON-NEXT: ret
723930
;
724-
; LA32-CONTRACT-OFF-LABEL: fnmsub_d_swap_intrinsics:
931+
; LA32-CONTRACT-OFF-LABEL: not_fnmsub_d_intrinsics:
725932
; LA32-CONTRACT-OFF: # %bb.0:
726-
; LA32-CONTRACT-OFF-NEXT: fnmsub.d $fa0, $fa1, $fa0, $fa2
933+
; LA32-CONTRACT-OFF-NEXT: fneg.d $fa0, $fa0
934+
; LA32-CONTRACT-OFF-NEXT: fmadd.d $fa0, $fa0, $fa1, $fa2
727935
; LA32-CONTRACT-OFF-NEXT: ret
728936
;
729-
; LA64-CONTRACT-FAST-LABEL: fnmsub_d_swap_intrinsics:
937+
; LA64-CONTRACT-FAST-LABEL: not_fnmsub_d_intrinsics:
730938
; LA64-CONTRACT-FAST: # %bb.0:
731-
; LA64-CONTRACT-FAST-NEXT: fnmsub.d $fa0, $fa1, $fa0, $fa2
939+
; LA64-CONTRACT-FAST-NEXT: fneg.d $fa0, $fa0
940+
; LA64-CONTRACT-FAST-NEXT: fmadd.d $fa0, $fa0, $fa1, $fa2
732941
; LA64-CONTRACT-FAST-NEXT: ret
733942
;
734-
; LA64-CONTRACT-ON-LABEL: fnmsub_d_swap_intrinsics:
943+
; LA64-CONTRACT-ON-LABEL: not_fnmsub_d_intrinsics:
735944
; LA64-CONTRACT-ON: # %bb.0:
736-
; LA64-CONTRACT-ON-NEXT: fnmsub.d $fa0, $fa1, $fa0, $fa2
945+
; LA64-CONTRACT-ON-NEXT: fneg.d $fa0, $fa0
946+
; LA64-CONTRACT-ON-NEXT: fmadd.d $fa0, $fa0, $fa1, $fa2
737947
; LA64-CONTRACT-ON-NEXT: ret
738948
;
739-
; LA64-CONTRACT-OFF-LABEL: fnmsub_d_swap_intrinsics:
949+
; LA64-CONTRACT-OFF-LABEL: not_fnmsub_d_intrinsics:
740950
; LA64-CONTRACT-OFF: # %bb.0:
741-
; LA64-CONTRACT-OFF-NEXT: fnmsub.d $fa0, $fa1, $fa0, $fa2
951+
; LA64-CONTRACT-OFF-NEXT: fneg.d $fa0, $fa0
952+
; LA64-CONTRACT-OFF-NEXT: fmadd.d $fa0, $fa0, $fa1, $fa2
742953
; LA64-CONTRACT-OFF-NEXT: ret
743-
%negb = fneg double %b
744-
%fma = call double @llvm.fma.f64(double %a, double %negb, double %c)
954+
%nega = fneg double %a
955+
%fma = call double @llvm.fma.f64(double %nega, double %b, double %c)
745956
ret double %fma
746957
}
747958

@@ -882,6 +1093,8 @@ define double @fnmsub_d_contract(double %a, double %b, double %c) nounwind {
8821093
; LA64-CONTRACT-OFF-NEXT: fnmsub.d $fa0, $fa0, $fa1, $fa2
8831094
; LA64-CONTRACT-OFF-NEXT: ret
8841095
%mul = fmul contract double %a, %b
885-
%sub = fsub contract double %c, %mul
886-
ret double %sub
1096+
%negc = fneg contract double %c
1097+
%add = fadd contract double %negc, %mul
1098+
%negadd = fneg contract double %add
1099+
ret double %negadd
8871100
}

0 commit comments

Comments
 (0)