Skip to content

Commit 28e9a28

Browse files
authored
DAG: Consider __sincos_stret when deciding to form fsincos (#165169)
1 parent 3172970 commit 28e9a28

File tree

5 files changed

+40
-30
lines changed

5 files changed

+40
-30
lines changed

llvm/include/llvm/CodeGen/RuntimeLibcallUtil.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,10 @@ LLVM_ABI Libcall getSINCOS(EVT RetVT);
8484
/// UNKNOWN_LIBCALL if there is none.
8585
LLVM_ABI Libcall getSINCOSPI(EVT RetVT);
8686

87+
/// Return the SINCOS_STRET_ value for the given types, or UNKNOWN_LIBCALL if
88+
/// there is none.
89+
LLVM_ABI Libcall getSINCOS_STRET(EVT RetVT);
90+
8791
/// getMODF - Return the MODF_* value for the given types, or
8892
/// UNKNOWN_LIBCALL if there is none.
8993
LLVM_ABI Libcall getMODF(EVT RetVT);

llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2400,10 +2400,11 @@ SelectionDAGLegalize::ExpandDivRemLibCall(SDNode *Node,
24002400
Results.push_back(Rem);
24012401
}
24022402

2403-
/// Return true if sincos libcall is available.
2403+
/// Return true if sincos or __sincos_stret libcall is available.
24042404
static bool isSinCosLibcallAvailable(SDNode *Node, const TargetLowering &TLI) {
2405-
RTLIB::Libcall LC = RTLIB::getSINCOS(Node->getSimpleValueType(0).SimpleTy);
2406-
return TLI.getLibcallName(LC) != nullptr;
2405+
MVT::SimpleValueType VT = Node->getSimpleValueType(0).SimpleTy;
2406+
return TLI.getLibcallImpl(RTLIB::getSINCOS(VT)) != RTLIB::Unsupported ||
2407+
TLI.getLibcallImpl(RTLIB::getSINCOS_STRET(VT)) != RTLIB::Unsupported;
24072408
}
24082409

24092410
/// Only issue sincos libcall if both sin and cos are needed.
@@ -3752,9 +3753,9 @@ bool SelectionDAGLegalize::ExpandNode(SDNode *Node) {
37523753
EVT VT = Node->getValueType(0);
37533754
// Turn fsin / fcos into ISD::FSINCOS node if there are a pair of fsin /
37543755
// fcos which share the same operand and both are used.
3755-
if ((TLI.isOperationLegalOrCustom(ISD::FSINCOS, VT) ||
3756-
isSinCosLibcallAvailable(Node, TLI))
3757-
&& useSinCos(Node)) {
3756+
if ((TLI.isOperationLegal(ISD::FSINCOS, VT) ||
3757+
isSinCosLibcallAvailable(Node, TLI)) &&
3758+
useSinCos(Node)) {
37583759
SDVTList VTs = DAG.getVTList(VT, VT);
37593760
Tmp1 = DAG.getNode(ISD::FSINCOS, dl, VTs, Node->getOperand(0));
37603761
if (Node->getOpcode() == ISD::FCOS)

llvm/lib/CodeGen/TargetLoweringBase.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,11 @@ RTLIB::Libcall RTLIB::getSINCOSPI(EVT RetVT) {
434434
SINCOSPI_F128, SINCOSPI_PPCF128);
435435
}
436436

437+
RTLIB::Libcall RTLIB::getSINCOS_STRET(EVT RetVT) {
438+
return getFPLibCall(RetVT, SINCOS_STRET_F32, SINCOS_STRET_F64,
439+
UNKNOWN_LIBCALL, UNKNOWN_LIBCALL, UNKNOWN_LIBCALL);
440+
}
441+
437442
RTLIB::Libcall RTLIB::getMODF(EVT RetVT) {
438443
return getFPLibCall(RetVT, MODF_F32, MODF_F64, MODF_F80, MODF_F128,
439444
MODF_PPCF128);

llvm/lib/Target/ARM/ARMISelLowering.cpp

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1298,12 +1298,8 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM_,
12981298
setOperationAction(ISD::STRICT_FSETCCS, MVT::f64, Custom);
12991299
}
13001300

1301-
// Use __sincos_stret if available.
1302-
if (getLibcallName(RTLIB::SINCOS_STRET_F32) != nullptr &&
1303-
getLibcallName(RTLIB::SINCOS_STRET_F64) != nullptr) {
1304-
setOperationAction(ISD::FSINCOS, MVT::f64, Custom);
1305-
setOperationAction(ISD::FSINCOS, MVT::f32, Custom);
1306-
}
1301+
setOperationAction(ISD::FSINCOS, MVT::f64, Custom);
1302+
setOperationAction(ISD::FSINCOS, MVT::f32, Custom);
13071303

13081304
// FP-ARMv8 implements a lot of rounding-like FP operations.
13091305
if (Subtarget->hasFPARMv8Base()) {
@@ -9835,13 +9831,18 @@ static SDValue LowerUADDSUBO_CARRY(SDValue Op, SelectionDAG &DAG) {
98359831
}
98369832

98379833
SDValue ARMTargetLowering::LowerFSINCOS(SDValue Op, SelectionDAG &DAG) const {
9838-
assert(Subtarget->isTargetDarwin());
9839-
98409834
// For iOS, we want to call an alternative entry point: __sincos_stret,
98419835
// return values are passed via sret.
98429836
SDLoc dl(Op);
98439837
SDValue Arg = Op.getOperand(0);
98449838
EVT ArgVT = Arg.getValueType();
9839+
RTLIB::Libcall LC = RTLIB::getSINCOS_STRET(ArgVT);
9840+
RTLIB::LibcallImpl SincosStret = getLibcallImpl(LC);
9841+
if (SincosStret == RTLIB::Unsupported)
9842+
return SDValue();
9843+
9844+
assert(Subtarget->isTargetDarwin());
9845+
98459846
Type *ArgTy = ArgVT.getTypeForEVT(*DAG.getContext());
98469847
auto PtrVT = getPointerTy(DAG.getDataLayout());
98479848

@@ -9871,11 +9872,9 @@ SDValue ARMTargetLowering::LowerFSINCOS(SDValue Op, SelectionDAG &DAG) const {
98719872

98729873
Args.emplace_back(Arg, ArgTy);
98739874

9874-
RTLIB::Libcall LC =
9875-
(ArgVT == MVT::f64) ? RTLIB::SINCOS_STRET_F64 : RTLIB::SINCOS_STRET_F32;
9876-
const char *LibcallName = getLibcallName(LC);
9877-
CallingConv::ID CC = getLibcallCallingConv(LC);
9878-
SDValue Callee = DAG.getExternalSymbol(LibcallName, getPointerTy(DL));
9875+
StringRef LibcallName = getLibcallImplName(SincosStret);
9876+
CallingConv::ID CC = getLibcallImplCallingConv(SincosStret);
9877+
SDValue Callee = DAG.getExternalSymbol(LibcallName.data(), getPointerTy(DL));
98799878

98809879
TargetLowering::CallLoweringInfo CLI(DAG);
98819880
CLI.setDebugLoc(dl)

llvm/lib/Target/X86/X86ISelLowering.cpp

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2572,11 +2572,8 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
25722572
}
25732573

25742574
// Combine sin / cos into _sincos_stret if it is available.
2575-
if (getLibcallName(RTLIB::SINCOS_STRET_F32) != nullptr &&
2576-
getLibcallName(RTLIB::SINCOS_STRET_F64) != nullptr) {
2577-
setOperationAction(ISD::FSINCOS, MVT::f64, Custom);
2578-
setOperationAction(ISD::FSINCOS, MVT::f32, Custom);
2579-
}
2575+
setOperationAction(ISD::FSINCOS, MVT::f64, Custom);
2576+
setOperationAction(ISD::FSINCOS, MVT::f32, Custom);
25802577

25812578
if (Subtarget.isTargetWin64()) {
25822579
setOperationAction(ISD::SDIV, MVT::i128, Custom);
@@ -33067,26 +33064,30 @@ static SDValue LowerADDSUBO_CARRY(SDValue Op, SelectionDAG &DAG) {
3306733064

3306833065
static SDValue LowerFSINCOS(SDValue Op, const X86Subtarget &Subtarget,
3306933066
SelectionDAG &DAG) {
33067+
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
33068+
SDValue Arg = Op.getOperand(0);
33069+
EVT ArgVT = Arg.getValueType();
33070+
bool isF64 = ArgVT == MVT::f64;
33071+
33072+
RTLIB::Libcall LC = isF64 ? RTLIB::SINCOS_STRET_F64 : RTLIB::SINCOS_STRET_F32;
33073+
const char *LibcallName = TLI.getLibcallName(LC);
33074+
if (!LibcallName)
33075+
return SDValue();
33076+
3307033077
assert(Subtarget.isTargetDarwin() && Subtarget.is64Bit());
3307133078

3307233079
// For MacOSX, we want to call an alternative entry point: __sincos_stret,
3307333080
// which returns the values as { float, float } (in XMM0) or
3307433081
// { double, double } (which is returned in XMM0, XMM1).
3307533082
SDLoc dl(Op);
33076-
SDValue Arg = Op.getOperand(0);
33077-
EVT ArgVT = Arg.getValueType();
3307833083
Type *ArgTy = ArgVT.getTypeForEVT(*DAG.getContext());
3307933084

3308033085
TargetLowering::ArgListTy Args;
3308133086
Args.emplace_back(Arg, ArgTy);
3308233087

33083-
bool isF64 = ArgVT == MVT::f64;
3308433088
// Only optimize x86_64 for now. i386 is a bit messy. For f32,
3308533089
// the small struct {f32, f32} is returned in (eax, edx). For f64,
3308633090
// the results are returned via SRet in memory.
33087-
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
33088-
RTLIB::Libcall LC = isF64 ? RTLIB::SINCOS_STRET_F64 : RTLIB::SINCOS_STRET_F32;
33089-
const char *LibcallName = TLI.getLibcallName(LC);
3309033091
SDValue Callee =
3309133092
DAG.getExternalSymbol(LibcallName, TLI.getPointerTy(DAG.getDataLayout()));
3309233093

0 commit comments

Comments
 (0)