@@ -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
599767define 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