Skip to content

Commit bd418ec

Browse files
committed
DAG: Consider __sincos_stret when deciding to form fsincos
ARM and X86 were changing their legality rules based on libcall availability. We already directly check the libcall in the legalization for the regular sincos case. It's cleaner to check this as part of the combine; this avoids depending on what should be program state in the future in the TargetLowering constructor.
1 parent 1c837ec commit bd418ec

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
@@ -428,6 +428,11 @@ RTLIB::Libcall RTLIB::getSINCOSPI(EVT RetVT) {
428428
SINCOSPI_F128, SINCOSPI_PPCF128);
429429
}
430430

431+
RTLIB::Libcall RTLIB::getSINCOS_STRET(EVT RetVT) {
432+
return getFPLibCall(RetVT, SINCOS_STRET_F32, SINCOS_STRET_F64,
433+
UNKNOWN_LIBCALL, UNKNOWN_LIBCALL, UNKNOWN_LIBCALL);
434+
}
435+
431436
RTLIB::Libcall RTLIB::getMODF(EVT RetVT) {
432437
return getFPLibCall(RetVT, MODF_F32, MODF_F64, MODF_F80, MODF_F128,
433438
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)