llvm.org GIT mirror llvm / 3a6b7d3
__sincosf_stret returns sinf / cosf in bits 0:31 and 32:63 of xmm0, not in xmm0 / xmm1. rdar://13599493 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179141 91177308-0d34-0410-b5e6-96231b3b80d8 Evan Cheng 7 years ago
2 changed file(s) with 22 addition(s) and 6 deletion(s). Raw diff Collapse all Expand all
1231812318 assert(Subtarget->isTargetDarwin() && Subtarget->is64Bit());
1231912319
1232012320 // For MacOSX, we want to call an alternative entry point: __sincos_stret,
12321 // which returns the values in two XMM registers.
12321 // which returns the values as { float, float } (in XMM0) or
12322 // { double, double } (which is returned in XMM0, XMM1).
1232212323 DebugLoc dl = Op.getDebugLoc();
1232312324 SDValue Arg = Op.getOperand(0);
1232412325 EVT ArgVT = Arg.getValueType();
1233312334 Entry.isZExt = false;
1233412335 Args.push_back(Entry);
1233512336
12337 bool isF64 = ArgVT == MVT::f64;
1233612338 // Only optimize x86_64 for now. i386 is a bit messy. For f32,
1233712339 // the small struct {f32, f32} is returned in (eax, edx). For f64,
1233812340 // the results are returned via SRet in memory.
12339 const char *LibcallName = (ArgVT == MVT::f64)
12340 ? "__sincos_stret" : "__sincosf_stret";
12341 const char *LibcallName = isF64 ? "__sincos_stret" : "__sincosf_stret";
1234112342 SDValue Callee = DAG.getExternalSymbol(LibcallName, getPointerTy());
1234212343
12343 StructType *RetTy = StructType::get(ArgTy, ArgTy, NULL);
12344 Type *RetTy = isF64
12345 ? (Type*)StructType::get(ArgTy, ArgTy, NULL)
12346 : (Type*)VectorType::get(ArgTy, 4);
1234412347 TargetLowering::
1234512348 CallLoweringInfo CLI(DAG.getEntryNode(), RetTy,
1234612349 false, false, false, false, 0,
1234812351 /*doesNotRet=*/false, /*isReturnValueUsed*/true,
1234912352 Callee, Args, DAG, dl);
1235012353 std::pair CallResult = LowerCallTo(CLI);
12351 return CallResult.first;
12354
12355 if (isF64)
12356 // Returned in xmm0 and xmm1.
12357 return CallResult.first;
12358
12359 // Returned in bits 0:31 and 32:64 xmm0.
12360 SDValue SinVal = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, ArgVT,
12361 CallResult.first, DAG.getIntPtrConstant(0));
12362 SDValue CosVal = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, ArgVT,
12363 CallResult.first, DAG.getIntPtrConstant(1));
12364 SDVTList Tys = DAG.getVTList(ArgVT, ArgVT);
12365 return DAG.getNode(ISD::MERGE_VALUES, dl, Tys, SinVal, CosVal);
1235212366 }
1235312367
1235412368 /// LowerOperation - Provide custom lowering hooks for some operations.
33
44 ; Combine sin / cos into a single call.
55 ; rdar://13087969
6 ; rdar://13599493
67
78 define float @test1(float %x) nounwind {
89 entry:
1314
1415 ; OSX_SINCOS: test1:
1516 ; OSX_SINCOS: callq ___sincosf_stret
16 ; OSX_SINCOS: addss %xmm1, %xmm0
17 ; OSX_SINCOS: pshufd $1, %xmm0, %xmm1
18 ; OSX_SINCOS: addss %xmm0, %xmm1
1719
1820 ; OSX_NOOPT: test1
1921 ; OSX_NOOPT: callq _cosf