Skip to content

Commit 248eb92

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

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
@@ -378,16 +378,232 @@ define { <2 x double>, <2 x double> } @test_sincos_v2f64(<2 x double> %a) #0 {
378378
ret { <2 x double>, <2 x double> } %result
379379
}
380380

381-
; ; FIXME: Asserts
382-
; define { fp128, fp128 } @test_sincos_f128(fp128 %a) #0 {
383-
; %result = call { fp128, fp128 } @llvm.sincos.f128(fp128 %a)
384-
; ret { fp128, fp128 } %result
385-
; }
381+
define { fp128, fp128 } @test_sincos_f128(fp128 %a) #0 {
382+
; WASM32-LABEL: test_sincos_f128:
383+
; WASM32: .functype test_sincos_f128 (i32, i64, i64) -> ()
384+
; WASM32-NEXT: .local i32
385+
; WASM32-NEXT: # %bb.0:
386+
; WASM32-NEXT: global.get __stack_pointer
387+
; WASM32-NEXT: i32.const 32
388+
; WASM32-NEXT: i32.sub
389+
; WASM32-NEXT: local.tee 3
390+
; WASM32-NEXT: global.set __stack_pointer
391+
; WASM32-NEXT: local.get 3
392+
; WASM32-NEXT: local.get 1
393+
; WASM32-NEXT: local.get 2
394+
; WASM32-NEXT: call cosl
395+
; WASM32-NEXT: local.get 3
396+
; WASM32-NEXT: i32.const 16
397+
; WASM32-NEXT: i32.add
398+
; WASM32-NEXT: local.get 1
399+
; WASM32-NEXT: local.get 2
400+
; WASM32-NEXT: call sinl
401+
; WASM32-NEXT: local.get 0
402+
; WASM32-NEXT: local.get 3
403+
; WASM32-NEXT: i64.load 8
404+
; WASM32-NEXT: i64.store 24
405+
; WASM32-NEXT: local.get 0
406+
; WASM32-NEXT: local.get 3
407+
; WASM32-NEXT: i64.load 0
408+
; WASM32-NEXT: i64.store 16
409+
; WASM32-NEXT: local.get 0
410+
; WASM32-NEXT: local.get 3
411+
; WASM32-NEXT: i64.load 24
412+
; WASM32-NEXT: i64.store 8
413+
; WASM32-NEXT: local.get 0
414+
; WASM32-NEXT: local.get 3
415+
; WASM32-NEXT: i64.load 16
416+
; WASM32-NEXT: i64.store 0
417+
; WASM32-NEXT: local.get 3
418+
; WASM32-NEXT: i32.const 32
419+
; WASM32-NEXT: i32.add
420+
; WASM32-NEXT: global.set __stack_pointer
421+
; WASM32-NEXT: # fallthrough-return
422+
;
423+
; WASM64-LABEL: test_sincos_f128:
424+
; WASM64: .functype test_sincos_f128 (i64, i64, i64) -> ()
425+
; WASM64-NEXT: .local i64
426+
; WASM64-NEXT: # %bb.0:
427+
; WASM64-NEXT: global.get __stack_pointer
428+
; WASM64-NEXT: i64.const 32
429+
; WASM64-NEXT: i64.sub
430+
; WASM64-NEXT: local.tee 3
431+
; WASM64-NEXT: global.set __stack_pointer
432+
; WASM64-NEXT: local.get 3
433+
; WASM64-NEXT: local.get 1
434+
; WASM64-NEXT: local.get 2
435+
; WASM64-NEXT: call cosl
436+
; WASM64-NEXT: local.get 3
437+
; WASM64-NEXT: i64.const 16
438+
; WASM64-NEXT: i64.add
439+
; WASM64-NEXT: local.get 1
440+
; WASM64-NEXT: local.get 2
441+
; WASM64-NEXT: call sinl
442+
; WASM64-NEXT: local.get 0
443+
; WASM64-NEXT: local.get 3
444+
; WASM64-NEXT: i64.load 8
445+
; WASM64-NEXT: i64.store 24
446+
; WASM64-NEXT: local.get 0
447+
; WASM64-NEXT: local.get 3
448+
; WASM64-NEXT: i64.load 0
449+
; WASM64-NEXT: i64.store 16
450+
; WASM64-NEXT: local.get 0
451+
; WASM64-NEXT: local.get 3
452+
; WASM64-NEXT: i64.load 24
453+
; WASM64-NEXT: i64.store 8
454+
; WASM64-NEXT: local.get 0
455+
; WASM64-NEXT: local.get 3
456+
; WASM64-NEXT: i64.load 16
457+
; WASM64-NEXT: i64.store 0
458+
; WASM64-NEXT: local.get 3
459+
; WASM64-NEXT: i64.const 32
460+
; WASM64-NEXT: i64.add
461+
; WASM64-NEXT: global.set __stack_pointer
462+
; WASM64-NEXT: # fallthrough-return
463+
%result = call { fp128, fp128 } @llvm.sincos.f128(fp128 %a)
464+
ret { fp128, fp128 } %result
465+
}
386466

387-
; ; FIXME: Asserts
388-
; define { <2 x fp128>, <2 x fp128> } @test_sincos_v2f128(<2 x fp128> %a) #0 {
389-
; %result = call { <2 x fp128>, <2 x fp128> } @llvm.sincos.v2f128(<2 x fp128> %a)
390-
; ret { <2 x fp128>, <2 x fp128> } %result
391-
; }
467+
define { <2 x fp128>, <2 x fp128> } @test_sincos_v2f128(<2 x fp128> %a) #0 {
468+
; WASM32-LABEL: test_sincos_v2f128:
469+
; WASM32: .functype test_sincos_v2f128 (i32, i64, i64, i64, i64) -> ()
470+
; WASM32-NEXT: .local i32
471+
; WASM32-NEXT: # %bb.0:
472+
; WASM32-NEXT: global.get __stack_pointer
473+
; WASM32-NEXT: i32.const 64
474+
; WASM32-NEXT: i32.sub
475+
; WASM32-NEXT: local.tee 5
476+
; WASM32-NEXT: global.set __stack_pointer
477+
; WASM32-NEXT: local.get 5
478+
; WASM32-NEXT: i32.const 32
479+
; WASM32-NEXT: i32.add
480+
; WASM32-NEXT: local.get 3
481+
; WASM32-NEXT: local.get 4
482+
; WASM32-NEXT: call cosl
483+
; WASM32-NEXT: local.get 5
484+
; WASM32-NEXT: local.get 1
485+
; WASM32-NEXT: local.get 2
486+
; WASM32-NEXT: call cosl
487+
; WASM32-NEXT: local.get 5
488+
; WASM32-NEXT: i32.const 48
489+
; WASM32-NEXT: i32.add
490+
; WASM32-NEXT: local.get 3
491+
; WASM32-NEXT: local.get 4
492+
; WASM32-NEXT: call sinl
493+
; WASM32-NEXT: local.get 5
494+
; WASM32-NEXT: i32.const 16
495+
; WASM32-NEXT: i32.add
496+
; WASM32-NEXT: local.get 1
497+
; WASM32-NEXT: local.get 2
498+
; WASM32-NEXT: call sinl
499+
; WASM32-NEXT: local.get 0
500+
; WASM32-NEXT: local.get 5
501+
; WASM32-NEXT: i64.load 40
502+
; WASM32-NEXT: i64.store 56
503+
; WASM32-NEXT: local.get 0
504+
; WASM32-NEXT: local.get 5
505+
; WASM32-NEXT: i64.load 32
506+
; WASM32-NEXT: i64.store 48
507+
; WASM32-NEXT: local.get 0
508+
; WASM32-NEXT: local.get 5
509+
; WASM32-NEXT: i64.load 8
510+
; WASM32-NEXT: i64.store 40
511+
; WASM32-NEXT: local.get 0
512+
; WASM32-NEXT: local.get 5
513+
; WASM32-NEXT: i64.load 0
514+
; WASM32-NEXT: i64.store 32
515+
; WASM32-NEXT: local.get 0
516+
; WASM32-NEXT: local.get 5
517+
; WASM32-NEXT: i64.load 56
518+
; WASM32-NEXT: i64.store 24
519+
; WASM32-NEXT: local.get 0
520+
; WASM32-NEXT: local.get 5
521+
; WASM32-NEXT: i64.load 48
522+
; WASM32-NEXT: i64.store 16
523+
; WASM32-NEXT: local.get 0
524+
; WASM32-NEXT: local.get 5
525+
; WASM32-NEXT: i64.load 24
526+
; WASM32-NEXT: i64.store 8
527+
; WASM32-NEXT: local.get 0
528+
; WASM32-NEXT: local.get 5
529+
; WASM32-NEXT: i64.load 16
530+
; WASM32-NEXT: i64.store 0
531+
; WASM32-NEXT: local.get 5
532+
; WASM32-NEXT: i32.const 64
533+
; WASM32-NEXT: i32.add
534+
; WASM32-NEXT: global.set __stack_pointer
535+
; WASM32-NEXT: # fallthrough-return
536+
;
537+
; WASM64-LABEL: test_sincos_v2f128:
538+
; WASM64: .functype test_sincos_v2f128 (i64, i64, i64, i64, i64) -> ()
539+
; WASM64-NEXT: .local i64
540+
; WASM64-NEXT: # %bb.0:
541+
; WASM64-NEXT: global.get __stack_pointer
542+
; WASM64-NEXT: i64.const 64
543+
; WASM64-NEXT: i64.sub
544+
; WASM64-NEXT: local.tee 5
545+
; WASM64-NEXT: global.set __stack_pointer
546+
; WASM64-NEXT: local.get 5
547+
; WASM64-NEXT: i64.const 32
548+
; WASM64-NEXT: i64.add
549+
; WASM64-NEXT: local.get 3
550+
; WASM64-NEXT: local.get 4
551+
; WASM64-NEXT: call cosl
552+
; WASM64-NEXT: local.get 5
553+
; WASM64-NEXT: local.get 1
554+
; WASM64-NEXT: local.get 2
555+
; WASM64-NEXT: call cosl
556+
; WASM64-NEXT: local.get 5
557+
; WASM64-NEXT: i64.const 48
558+
; WASM64-NEXT: i64.add
559+
; WASM64-NEXT: local.get 3
560+
; WASM64-NEXT: local.get 4
561+
; WASM64-NEXT: call sinl
562+
; WASM64-NEXT: local.get 5
563+
; WASM64-NEXT: i64.const 16
564+
; WASM64-NEXT: i64.add
565+
; WASM64-NEXT: local.get 1
566+
; WASM64-NEXT: local.get 2
567+
; WASM64-NEXT: call sinl
568+
; WASM64-NEXT: local.get 0
569+
; WASM64-NEXT: local.get 5
570+
; WASM64-NEXT: i64.load 40
571+
; WASM64-NEXT: i64.store 56
572+
; WASM64-NEXT: local.get 0
573+
; WASM64-NEXT: local.get 5
574+
; WASM64-NEXT: i64.load 32
575+
; WASM64-NEXT: i64.store 48
576+
; WASM64-NEXT: local.get 0
577+
; WASM64-NEXT: local.get 5
578+
; WASM64-NEXT: i64.load 8
579+
; WASM64-NEXT: i64.store 40
580+
; WASM64-NEXT: local.get 0
581+
; WASM64-NEXT: local.get 5
582+
; WASM64-NEXT: i64.load 0
583+
; WASM64-NEXT: i64.store 32
584+
; WASM64-NEXT: local.get 0
585+
; WASM64-NEXT: local.get 5
586+
; WASM64-NEXT: i64.load 56
587+
; WASM64-NEXT: i64.store 24
588+
; WASM64-NEXT: local.get 0
589+
; WASM64-NEXT: local.get 5
590+
; WASM64-NEXT: i64.load 48
591+
; WASM64-NEXT: i64.store 16
592+
; WASM64-NEXT: local.get 0
593+
; WASM64-NEXT: local.get 5
594+
; WASM64-NEXT: i64.load 24
595+
; WASM64-NEXT: i64.store 8
596+
; WASM64-NEXT: local.get 0
597+
; WASM64-NEXT: local.get 5
598+
; WASM64-NEXT: i64.load 16
599+
; WASM64-NEXT: i64.store 0
600+
; WASM64-NEXT: local.get 5
601+
; WASM64-NEXT: i64.const 64
602+
; WASM64-NEXT: i64.add
603+
; WASM64-NEXT: global.set __stack_pointer
604+
; WASM64-NEXT: # fallthrough-return
605+
%result = call { <2 x fp128>, <2 x fp128> } @llvm.sincos.v2f128(<2 x fp128> %a)
606+
ret { <2 x fp128>, <2 x fp128> } %result
607+
}
392608

393609
attributes #0 = { nounwind }

0 commit comments

Comments
 (0)