Skip to content

Commit 65011f9

Browse files
committed
DAG: Fall back to separate sin and cos when softening sincos
Fix asserting in the error case.
1 parent a95c091 commit 65011f9

File tree

6 files changed

+288
-18
lines changed

6 files changed

+288
-18
lines changed

llvm/include/llvm/CodeGen/RuntimeLibcallUtil.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,14 @@ LLVM_ABI Libcall getLDEXP(EVT RetVT);
6868
/// UNKNOWN_LIBCALL if there is none.
6969
LLVM_ABI Libcall getFREXP(EVT RetVT);
7070

71+
/// Return the SIN_* value for the given types, or UNKNOWN_LIBCALL if there is
72+
/// none.
73+
LLVM_ABI Libcall getSIN(EVT RetVT);
74+
75+
/// Return the COS_* value for the given types, or UNKNOWN_LIBCALL if there is
76+
/// none.
77+
LLVM_ABI Libcall getCOS(EVT RetVT);
78+
7179
/// getSINCOS - Return the SINCOS_* value for the given types, or
7280
/// UNKNOWN_LIBCALL if there is none.
7381
LLVM_ABI Libcall getSINCOS(EVT RetVT);

llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -794,7 +794,7 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FFREXP(SDNode *N) {
794794
return ReturnVal;
795795
}
796796

797-
SDValue DAGTypeLegalizer::SoftenFloatRes_UnaryWithTwoFPResults(
797+
bool DAGTypeLegalizer::SoftenFloatRes_UnaryWithTwoFPResults(
798798
SDNode *N, RTLIB::Libcall LC, std::optional<unsigned> CallRetResNo) {
799799
assert(!N->isStrictFPOpcode() && "strictfp not implemented");
800800
EVT VT = N->getValueType(0);
@@ -803,7 +803,7 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_UnaryWithTwoFPResults(
803803
"expected both return values to have the same type");
804804

805805
if (!TLI.getLibcallName(LC))
806-
return SDValue();
806+
return false;
807807

808808
EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
809809

@@ -849,17 +849,46 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_UnaryWithTwoFPResults(
849849
SetSoftenedFloat(SDValue(N, ResNum), CreateStackLoad(SlackSlot));
850850
}
851851

852-
return SDValue();
852+
return true;
853853
}
854854

855855
SDValue DAGTypeLegalizer::SoftenFloatRes_FSINCOS(SDNode *N) {
856-
return SoftenFloatRes_UnaryWithTwoFPResults(
857-
N, RTLIB::getSINCOS(N->getValueType(0)));
856+
EVT VT = N->getValueType(0);
857+
if (SoftenFloatRes_UnaryWithTwoFPResults(N, RTLIB::getSINCOS(VT)))
858+
return SDValue();
859+
860+
// Fall back on softening the separate sin and cos calls if available.
861+
RTLIB::Libcall SinLC = RTLIB::getSIN(VT);
862+
RTLIB::Libcall CosLC = RTLIB::getCOS(VT);
863+
864+
SDValue SoftSin, SoftCos;
865+
if (!TLI.getLibcallName(SinLC) || !TLI.getLibcallName(CosLC)) {
866+
DAG.getContext()->emitError("do not know how to soften fsincos");
867+
868+
EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
869+
SoftSin = SoftCos = DAG.getPOISON(NVT);
870+
} else {
871+
SoftSin = SoftenFloatRes_Unary(N, SinLC);
872+
SoftCos = SoftenFloatRes_Unary(N, CosLC);
873+
}
874+
875+
SetSoftenedFloat(SDValue(N, 0), SoftSin);
876+
SetSoftenedFloat(SDValue(N, 1), SoftCos);
877+
return SDValue();
858878
}
859879

860880
SDValue DAGTypeLegalizer::SoftenFloatRes_FMODF(SDNode *N) {
861-
return SoftenFloatRes_UnaryWithTwoFPResults(
862-
N, RTLIB::getMODF(N->getValueType(0)), /*CallRetResNo=*/0);
881+
EVT VT = N->getValueType(0);
882+
if (SoftenFloatRes_UnaryWithTwoFPResults(N, RTLIB::getMODF(VT),
883+
/*CallRetResNo=*/0))
884+
return SDValue();
885+
886+
EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
887+
DAG.getContext()->emitError("do not know how to soften fmodf");
888+
SDValue Poison = DAG.getPOISON(NVT);
889+
SetSoftenedFloat(SDValue(N, 0), Poison);
890+
SetSoftenedFloat(SDValue(N, 1), Poison);
891+
return SDValue();
863892
}
864893

865894
SDValue DAGTypeLegalizer::SoftenFloatRes_FREM(SDNode *N) {

llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -564,7 +564,7 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer {
564564
// Convert Float Results to Integer.
565565
void SoftenFloatResult(SDNode *N, unsigned ResNo);
566566
SDValue SoftenFloatRes_Unary(SDNode *N, RTLIB::Libcall LC);
567-
SDValue SoftenFloatRes_UnaryWithTwoFPResults(
567+
bool SoftenFloatRes_UnaryWithTwoFPResults(
568568
SDNode *N, RTLIB::Libcall LC, std::optional<unsigned> CallRetResNo = {});
569569
SDValue SoftenFloatRes_Binary(SDNode *N, RTLIB::Libcall LC);
570570
SDValue SoftenFloatRes_MERGE_VALUES(SDNode *N, unsigned ResNo);

llvm/lib/CodeGen/TargetLoweringBase.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,14 @@ RTLIB::Libcall RTLIB::getFREXP(EVT RetVT) {
410410
FREXP_PPCF128);
411411
}
412412

413+
RTLIB::Libcall RTLIB::getSIN(EVT RetVT) {
414+
return getFPLibCall(RetVT, SIN_F32, SIN_F64, SIN_F80, SIN_F128, SIN_PPCF128);
415+
}
416+
417+
RTLIB::Libcall RTLIB::getCOS(EVT RetVT) {
418+
return getFPLibCall(RetVT, COS_F32, COS_F64, COS_F80, COS_F128, COS_PPCF128);
419+
}
420+
413421
RTLIB::Libcall RTLIB::getSINCOS(EVT RetVT) {
414422
return getFPLibCall(RetVT, SINCOS_F32, SINCOS_F64, SINCOS_F80, SINCOS_F128,
415423
SINCOS_PPCF128);
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
; RUN: not llc -mtriple=avr -filetype=null %s 2>&1 | FileCheck %s
2+
3+
; CHECK: error: do not know how to soften fsincos
4+
define { double, double } @test_sincos_f64(double %a) #0 {
5+
%result = call { double, double } @llvm.sincos.f64(double %a)
6+
ret { double, double } %result
7+
}
8+
9+
attributes #0 = { nounwind }

llvm/test/CodeGen/WebAssembly/llvm.sincos.ll

Lines changed: 226 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -485,16 +485,232 @@ define { <2 x double>, <2 x double> } @test_sincos_v2f64(<2 x double> %a) #0 {
485485
ret { <2 x double>, <2 x double> } %result
486486
}
487487

488-
; ; FIXME: Asserts
489-
; define { fp128, fp128 } @test_sincos_f128(fp128 %a) #0 {
490-
; %result = call { fp128, fp128 } @llvm.sincos.f128(fp128 %a)
491-
; ret { fp128, fp128 } %result
492-
; }
488+
define { fp128, fp128 } @test_sincos_f128(fp128 %a) #0 {
489+
; WASM32-LABEL: test_sincos_f128:
490+
; WASM32: .functype test_sincos_f128 (i32, i64, i64) -> ()
491+
; WASM32-NEXT: .local i32
492+
; WASM32-NEXT: # %bb.0:
493+
; WASM32-NEXT: global.get __stack_pointer
494+
; WASM32-NEXT: i32.const 32
495+
; WASM32-NEXT: i32.sub
496+
; WASM32-NEXT: local.tee 3
497+
; WASM32-NEXT: global.set __stack_pointer
498+
; WASM32-NEXT: local.get 3
499+
; WASM32-NEXT: local.get 1
500+
; WASM32-NEXT: local.get 2
501+
; WASM32-NEXT: call cosl
502+
; WASM32-NEXT: local.get 3
503+
; WASM32-NEXT: i32.const 16
504+
; WASM32-NEXT: i32.add
505+
; WASM32-NEXT: local.get 1
506+
; WASM32-NEXT: local.get 2
507+
; WASM32-NEXT: call sinl
508+
; WASM32-NEXT: local.get 0
509+
; WASM32-NEXT: local.get 3
510+
; WASM32-NEXT: i64.load 8
511+
; WASM32-NEXT: i64.store 24
512+
; WASM32-NEXT: local.get 0
513+
; WASM32-NEXT: local.get 3
514+
; WASM32-NEXT: i64.load 0
515+
; WASM32-NEXT: i64.store 16
516+
; WASM32-NEXT: local.get 0
517+
; WASM32-NEXT: local.get 3
518+
; WASM32-NEXT: i64.load 24
519+
; WASM32-NEXT: i64.store 8
520+
; WASM32-NEXT: local.get 0
521+
; WASM32-NEXT: local.get 3
522+
; WASM32-NEXT: i64.load 16
523+
; WASM32-NEXT: i64.store 0
524+
; WASM32-NEXT: local.get 3
525+
; WASM32-NEXT: i32.const 32
526+
; WASM32-NEXT: i32.add
527+
; WASM32-NEXT: global.set __stack_pointer
528+
; WASM32-NEXT: # fallthrough-return
529+
;
530+
; WASM64-LABEL: test_sincos_f128:
531+
; WASM64: .functype test_sincos_f128 (i64, i64, i64) -> ()
532+
; WASM64-NEXT: .local i64
533+
; WASM64-NEXT: # %bb.0:
534+
; WASM64-NEXT: global.get __stack_pointer
535+
; WASM64-NEXT: i64.const 32
536+
; WASM64-NEXT: i64.sub
537+
; WASM64-NEXT: local.tee 3
538+
; WASM64-NEXT: global.set __stack_pointer
539+
; WASM64-NEXT: local.get 3
540+
; WASM64-NEXT: local.get 1
541+
; WASM64-NEXT: local.get 2
542+
; WASM64-NEXT: call cosl
543+
; WASM64-NEXT: local.get 3
544+
; WASM64-NEXT: i64.const 16
545+
; WASM64-NEXT: i64.add
546+
; WASM64-NEXT: local.get 1
547+
; WASM64-NEXT: local.get 2
548+
; WASM64-NEXT: call sinl
549+
; WASM64-NEXT: local.get 0
550+
; WASM64-NEXT: local.get 3
551+
; WASM64-NEXT: i64.load 8
552+
; WASM64-NEXT: i64.store 24
553+
; WASM64-NEXT: local.get 0
554+
; WASM64-NEXT: local.get 3
555+
; WASM64-NEXT: i64.load 0
556+
; WASM64-NEXT: i64.store 16
557+
; WASM64-NEXT: local.get 0
558+
; WASM64-NEXT: local.get 3
559+
; WASM64-NEXT: i64.load 24
560+
; WASM64-NEXT: i64.store 8
561+
; WASM64-NEXT: local.get 0
562+
; WASM64-NEXT: local.get 3
563+
; WASM64-NEXT: i64.load 16
564+
; WASM64-NEXT: i64.store 0
565+
; WASM64-NEXT: local.get 3
566+
; WASM64-NEXT: i64.const 32
567+
; WASM64-NEXT: i64.add
568+
; WASM64-NEXT: global.set __stack_pointer
569+
; WASM64-NEXT: # fallthrough-return
570+
%result = call { fp128, fp128 } @llvm.sincos.f128(fp128 %a)
571+
ret { fp128, fp128 } %result
572+
}
493573

494-
; ; FIXME: Asserts
495-
; define { <2 x fp128>, <2 x fp128> } @test_sincos_v2f128(<2 x fp128> %a) #0 {
496-
; %result = call { <2 x fp128>, <2 x fp128> } @llvm.sincos.v2f128(<2 x fp128> %a)
497-
; ret { <2 x fp128>, <2 x fp128> } %result
498-
; }
574+
define { <2 x fp128>, <2 x fp128> } @test_sincos_v2f128(<2 x fp128> %a) #0 {
575+
; WASM32-LABEL: test_sincos_v2f128:
576+
; WASM32: .functype test_sincos_v2f128 (i32, i64, i64, i64, i64) -> ()
577+
; WASM32-NEXT: .local i32
578+
; WASM32-NEXT: # %bb.0:
579+
; WASM32-NEXT: global.get __stack_pointer
580+
; WASM32-NEXT: i32.const 64
581+
; WASM32-NEXT: i32.sub
582+
; WASM32-NEXT: local.tee 5
583+
; WASM32-NEXT: global.set __stack_pointer
584+
; WASM32-NEXT: local.get 5
585+
; WASM32-NEXT: i32.const 32
586+
; WASM32-NEXT: i32.add
587+
; WASM32-NEXT: local.get 3
588+
; WASM32-NEXT: local.get 4
589+
; WASM32-NEXT: call cosl
590+
; WASM32-NEXT: local.get 5
591+
; WASM32-NEXT: local.get 1
592+
; WASM32-NEXT: local.get 2
593+
; WASM32-NEXT: call cosl
594+
; WASM32-NEXT: local.get 5
595+
; WASM32-NEXT: i32.const 48
596+
; WASM32-NEXT: i32.add
597+
; WASM32-NEXT: local.get 3
598+
; WASM32-NEXT: local.get 4
599+
; WASM32-NEXT: call sinl
600+
; WASM32-NEXT: local.get 5
601+
; WASM32-NEXT: i32.const 16
602+
; WASM32-NEXT: i32.add
603+
; WASM32-NEXT: local.get 1
604+
; WASM32-NEXT: local.get 2
605+
; WASM32-NEXT: call sinl
606+
; WASM32-NEXT: local.get 0
607+
; WASM32-NEXT: local.get 5
608+
; WASM32-NEXT: i64.load 40
609+
; WASM32-NEXT: i64.store 56
610+
; WASM32-NEXT: local.get 0
611+
; WASM32-NEXT: local.get 5
612+
; WASM32-NEXT: i64.load 32
613+
; WASM32-NEXT: i64.store 48
614+
; WASM32-NEXT: local.get 0
615+
; WASM32-NEXT: local.get 5
616+
; WASM32-NEXT: i64.load 8
617+
; WASM32-NEXT: i64.store 40
618+
; WASM32-NEXT: local.get 0
619+
; WASM32-NEXT: local.get 5
620+
; WASM32-NEXT: i64.load 0
621+
; WASM32-NEXT: i64.store 32
622+
; WASM32-NEXT: local.get 0
623+
; WASM32-NEXT: local.get 5
624+
; WASM32-NEXT: i64.load 56
625+
; WASM32-NEXT: i64.store 24
626+
; WASM32-NEXT: local.get 0
627+
; WASM32-NEXT: local.get 5
628+
; WASM32-NEXT: i64.load 48
629+
; WASM32-NEXT: i64.store 16
630+
; WASM32-NEXT: local.get 0
631+
; WASM32-NEXT: local.get 5
632+
; WASM32-NEXT: i64.load 24
633+
; WASM32-NEXT: i64.store 8
634+
; WASM32-NEXT: local.get 0
635+
; WASM32-NEXT: local.get 5
636+
; WASM32-NEXT: i64.load 16
637+
; WASM32-NEXT: i64.store 0
638+
; WASM32-NEXT: local.get 5
639+
; WASM32-NEXT: i32.const 64
640+
; WASM32-NEXT: i32.add
641+
; WASM32-NEXT: global.set __stack_pointer
642+
; WASM32-NEXT: # fallthrough-return
643+
;
644+
; WASM64-LABEL: test_sincos_v2f128:
645+
; WASM64: .functype test_sincos_v2f128 (i64, i64, i64, i64, i64) -> ()
646+
; WASM64-NEXT: .local i64
647+
; WASM64-NEXT: # %bb.0:
648+
; WASM64-NEXT: global.get __stack_pointer
649+
; WASM64-NEXT: i64.const 64
650+
; WASM64-NEXT: i64.sub
651+
; WASM64-NEXT: local.tee 5
652+
; WASM64-NEXT: global.set __stack_pointer
653+
; WASM64-NEXT: local.get 5
654+
; WASM64-NEXT: i64.const 32
655+
; WASM64-NEXT: i64.add
656+
; WASM64-NEXT: local.get 3
657+
; WASM64-NEXT: local.get 4
658+
; WASM64-NEXT: call cosl
659+
; WASM64-NEXT: local.get 5
660+
; WASM64-NEXT: local.get 1
661+
; WASM64-NEXT: local.get 2
662+
; WASM64-NEXT: call cosl
663+
; WASM64-NEXT: local.get 5
664+
; WASM64-NEXT: i64.const 48
665+
; WASM64-NEXT: i64.add
666+
; WASM64-NEXT: local.get 3
667+
; WASM64-NEXT: local.get 4
668+
; WASM64-NEXT: call sinl
669+
; WASM64-NEXT: local.get 5
670+
; WASM64-NEXT: i64.const 16
671+
; WASM64-NEXT: i64.add
672+
; WASM64-NEXT: local.get 1
673+
; WASM64-NEXT: local.get 2
674+
; WASM64-NEXT: call sinl
675+
; WASM64-NEXT: local.get 0
676+
; WASM64-NEXT: local.get 5
677+
; WASM64-NEXT: i64.load 40
678+
; WASM64-NEXT: i64.store 56
679+
; WASM64-NEXT: local.get 0
680+
; WASM64-NEXT: local.get 5
681+
; WASM64-NEXT: i64.load 32
682+
; WASM64-NEXT: i64.store 48
683+
; WASM64-NEXT: local.get 0
684+
; WASM64-NEXT: local.get 5
685+
; WASM64-NEXT: i64.load 8
686+
; WASM64-NEXT: i64.store 40
687+
; WASM64-NEXT: local.get 0
688+
; WASM64-NEXT: local.get 5
689+
; WASM64-NEXT: i64.load 0
690+
; WASM64-NEXT: i64.store 32
691+
; WASM64-NEXT: local.get 0
692+
; WASM64-NEXT: local.get 5
693+
; WASM64-NEXT: i64.load 56
694+
; WASM64-NEXT: i64.store 24
695+
; WASM64-NEXT: local.get 0
696+
; WASM64-NEXT: local.get 5
697+
; WASM64-NEXT: i64.load 48
698+
; WASM64-NEXT: i64.store 16
699+
; WASM64-NEXT: local.get 0
700+
; WASM64-NEXT: local.get 5
701+
; WASM64-NEXT: i64.load 24
702+
; WASM64-NEXT: i64.store 8
703+
; WASM64-NEXT: local.get 0
704+
; WASM64-NEXT: local.get 5
705+
; WASM64-NEXT: i64.load 16
706+
; WASM64-NEXT: i64.store 0
707+
; WASM64-NEXT: local.get 5
708+
; WASM64-NEXT: i64.const 64
709+
; WASM64-NEXT: i64.add
710+
; WASM64-NEXT: global.set __stack_pointer
711+
; WASM64-NEXT: # fallthrough-return
712+
%result = call { <2 x fp128>, <2 x fp128> } @llvm.sincos.v2f128(<2 x fp128> %a)
713+
ret { <2 x fp128>, <2 x fp128> } %result
714+
}
499715

500716
attributes #0 = { nounwind }

0 commit comments

Comments
 (0)