[llvm] [IR] Add `llvm.sincos` intrinsic (PR #109825)

Simon Pilgrim via llvm-commits llvm-commits at lists.llvm.org
Mon Oct 28 08:02:20 PDT 2024


================
@@ -774,6 +775,45 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FFREXP(SDNode *N) {
   return ReturnVal;
 }
 
+SDValue DAGTypeLegalizer::SoftenFloatRes_FSINCOS(SDNode *N) {
+  assert(!N->isStrictFPOpcode() && "strictfp not implemented for fsincos");
+  EVT VT = N->getValueType(0);
+  RTLIB::Libcall LC = RTLIB::getFSINCOS(VT);
+
+  if (!TLI.getLibcallName(LC))
+    return SDValue();
+
+  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
+  SDValue StackSlotSin = DAG.CreateStackTemporary(NVT);
+  SDValue StackSlotCos = DAG.CreateStackTemporary(NVT);
+
+  SDLoc DL(N);
+
+  TargetLowering::MakeLibCallOptions CallOptions;
+  std::array Ops{GetSoftenedFloat(N->getOperand(0)), StackSlotSin,
+                 StackSlotCos};
+  std::array OpsVT{VT, StackSlotSin.getValueType(),
+                   StackSlotCos.getValueType()};
+
+  // TODO: setTypeListBeforeSoften can't properly express multiple return types,
+  // but since both returns have the same type for sincos it should be okay.
+  CallOptions.setTypeListBeforeSoften({OpsVT}, VT, true);
+
+  auto [ReturnVal, Chain] = TLI.makeLibCall(DAG, LC, NVT, Ops, CallOptions, DL,
+                                            /*Chain=*/SDValue());
+  unsigned ResNo = 0;
+  for (SDValue OutPtr : {StackSlotSin, StackSlotCos}) {
----------------
RKSimon wrote:

It might be cleaner to do this with a lambda:
```
auto CreateStackLoad = [&](SDValue StackSlot) {
  int FrameIdx = cast<FrameIndexSDNode>(OutPtr)->getIndex();
  auto PtrInfo = MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), FrameIdx);
  return DAG.getLoad(NVT, DL, Chain, OutPtr, PtrInfo);
};
SetSoftenedFloat(SDValue(N, 0), CreateStackLoad(StackSlotSin));
SetSoftenedFloat(SDValue(N, 1), CreateStackLoad(StackSlotCos));
```

https://github.com/llvm/llvm-project/pull/109825


More information about the llvm-commits mailing list