[llvm] [X86][GlobalISel] Enable SINCOS with libcall mapping (PR #142438)

via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 3 05:38:32 PDT 2025


https://github.com/JaydeepChauhan14 updated https://github.com/llvm/llvm-project/pull/142438

>From 50557e60b708fe652c0747c90e925f52ad56ba4a Mon Sep 17 00:00:00 2001
From: Chauhan Jaydeep Ashwinbhai <chauhan.jaydeep.ashwinbhai at intel.com>
Date: Mon, 2 Jun 2025 10:23:28 -0700
Subject: [PATCH 1/2] [X86][GlobalISel] Enable SINCOS with libcall mapping

---
 .../llvm/CodeGen/GlobalISel/LegalizerHelper.h |   5 +
 .../CodeGen/GlobalISel/LegalizerHelper.cpp    |  66 ++++++
 .../lib/Target/X86/GISel/X86LegalizerInfo.cpp |   3 +-
 .../CodeGen/X86/GlobalISel/llvm.sincos.mir    | 189 ++++++++++++++++++
 llvm/test/CodeGen/X86/llvm.sincos.ll          |  92 ++++++++-
 5 files changed, 352 insertions(+), 3 deletions(-)
 create mode 100644 llvm/test/CodeGen/X86/GlobalISel/llvm.sincos.mir

diff --git a/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h b/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
index 4106be4c81cea..1ff89873fdac1 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
@@ -295,6 +295,11 @@ class LegalizerHelper {
   getNeutralElementForVecReduce(unsigned Opcode, MachineIRBuilder &MIRBuilder,
                                 LLT Ty);
 
+  LegalizeResult simpleLibcallSinCos(MachineInstr &MI,
+                                     MachineIRBuilder &MIRBuilder,
+                                     unsigned Size, Type *OpType,
+                                     LostDebugLocObserver &LocObserver);
+
 public:
   /// Return the alignment to use for a stack temporary object with the given
   /// type.
diff --git a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
index 7b18a98d7f3ca..f802464048530 100644
--- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
@@ -469,6 +469,8 @@ static RTLIB::Libcall getRTLibDesc(unsigned Opcode, unsigned Size) {
     RTLIBCASE(COSH_F);
   case TargetOpcode::G_FTANH:
     RTLIBCASE(TANH_F);
+  case TargetOpcode::G_FSINCOS:
+    RTLIBCASE(SINCOS_F);
   case TargetOpcode::G_FLOG10:
     RTLIBCASE(LOG10_F);
   case TargetOpcode::G_FLOG:
@@ -648,6 +650,57 @@ simpleLibcall(MachineInstr &MI, MachineIRBuilder &MIRBuilder, unsigned Size,
                        LocObserver, &MI);
 }
 
+LegalizerHelper::LegalizeResult LegalizerHelper::simpleLibcallSinCos(
+    MachineInstr &MI, MachineIRBuilder &MIRBuilder, unsigned Size, Type *OpType,
+    LostDebugLocObserver &LocObserver) {
+  MachineFunction &MF = *MI.getMF();
+  MachineRegisterInfo &MRI = MF.getRegInfo();
+
+  Register DstSin = MI.getOperand(0).getReg();
+  Register DstCos = MI.getOperand(1).getReg();
+  Register Src = MI.getOperand(2).getReg();
+  LLT DstTy = MRI.getType(DstSin);
+  LLT SrcTy = MRI.getType(Src);
+
+  assert((SrcTy.getSizeInBits() == 32 || SrcTy.getSizeInBits() == 64 ||
+          SrcTy.getSizeInBits() == 80) &&
+         "Unexpected source type for SINCOS.");
+
+  int MemSize = DstTy.getSizeInBytes();
+  Align Alignment = getStackTemporaryAlignment(DstTy);
+  const DataLayout &DL = MIRBuilder.getDataLayout();
+  unsigned AddrSpace = DL.getAllocaAddrSpace();
+  MachinePointerInfo PtrInfo;
+
+  Register StackPtrSin =
+      createStackTemporary(TypeSize::getFixed(MemSize), Alignment, PtrInfo)
+          .getReg(0);
+  Register StackPtrCos =
+      createStackTemporary(TypeSize::getFixed(MemSize), Alignment, PtrInfo)
+          .getReg(0);
+
+  auto &Ctx = MF.getFunction().getContext();
+  if (LegalizerHelper::LegalizeResult::Legalized !=
+      createLibcall(MIRBuilder, getRTLibDesc(MI.getOpcode(), Size),
+                    {{0}, Type::getVoidTy(Ctx), 0},
+                    {{Src, OpType, 0},
+                     {StackPtrSin, PointerType::get(Ctx, AddrSpace), 1},
+                     {StackPtrCos, PointerType::get(Ctx, AddrSpace), 2}},
+                    LocObserver, &MI)) {
+    return LegalizerHelper::UnableToLegalize;
+  }
+
+  MachineMemOperand *LoadMMOSin = MF.getMachineMemOperand(
+      PtrInfo, MachineMemOperand::MOLoad, MemSize, Alignment);
+  MachineMemOperand *LoadMMOCos = MF.getMachineMemOperand(
+      PtrInfo, MachineMemOperand::MOLoad, MemSize, Alignment);
+
+  MIRBuilder.buildLoad(DstSin, StackPtrSin, *LoadMMOSin);
+  MIRBuilder.buildLoad(DstCos, StackPtrCos, *LoadMMOCos);
+
+  return LegalizerHelper::Legalized;
+}
+
 LegalizerHelper::LegalizeResult
 llvm::createMemLibcall(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
                        MachineInstr &MI, LostDebugLocObserver &LocObserver) {
@@ -1271,6 +1324,19 @@ LegalizerHelper::libcall(MachineInstr &MI, LostDebugLocObserver &LocObserver) {
       return Status;
     break;
   }
+  case TargetOpcode::G_FSINCOS: {
+    LLT LLTy = MRI.getType(MI.getOperand(0).getReg());
+    unsigned Size = LLTy.getSizeInBits();
+    Type *HLTy = getFloatTypeForLLT(Ctx, LLTy);
+    if (!HLTy || (Size != 32 && Size != 64 && Size != 80 && Size != 128)) {
+      LLVM_DEBUG(dbgs() << "No libcall available for type " << LLTy << ".\n");
+      return UnableToLegalize;
+    }
+    auto Status = simpleLibcallSinCos(MI, MIRBuilder, Size, HLTy, LocObserver);
+    if (Status != Legalized)
+      return Status;
+    break;
+  }
   case TargetOpcode::G_LROUND:
   case TargetOpcode::G_LLROUND:
   case TargetOpcode::G_INTRINSIC_LRINT:
diff --git a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp
index 11dd05c584983..fbac4b7bd6163 100644
--- a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp
+++ b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp
@@ -102,7 +102,8 @@ X86LegalizerInfo::X86LegalizerInfo(const X86Subtarget &STI,
   getActionDefinitionsBuilder({G_LROUND, G_LLROUND, G_FCOS,  G_FCOSH,  G_FACOS,
                                G_FSIN,   G_FSINH,   G_FASIN, G_FTAN,   G_FTANH,
                                G_FATAN,  G_FATAN2,  G_FPOW,  G_FEXP,   G_FEXP2,
-                               G_FEXP10, G_FLOG,    G_FLOG2, G_FLOG10, G_FPOWI})
+                               G_FEXP10, G_FLOG,    G_FLOG2, G_FLOG10, G_FPOWI,
+                               G_FSINCOS})
       .libcall();
 
   getActionDefinitionsBuilder(G_FSQRT)
diff --git a/llvm/test/CodeGen/X86/GlobalISel/llvm.sincos.mir b/llvm/test/CodeGen/X86/GlobalISel/llvm.sincos.mir
new file mode 100644
index 0000000000000..f8ce9ea8be650
--- /dev/null
+++ b/llvm/test/CodeGen/X86/GlobalISel/llvm.sincos.mir
@@ -0,0 +1,189 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5
+# RUN: llc -mtriple=i686-linux-gnu -run-pass=regbankselect,instruction-select %s -o - | FileCheck %s --check-prefixes GISEL-I686
+
+---
+name:            test_sincos_f32
+alignment:       16
+legalized:       true
+fixedStack:
+  - { id: 0, type: default, offset: 0, size: 4, alignment: 16, stack-id: default,
+      isImmutable: true, isAliased: false, callee-saved-register: '', callee-saved-restored: true,
+      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+stack:
+  - { id: 0, name: '', type: default, offset: 0, size: 4, alignment: 4,
+      stack-id: default, callee-saved-register: '', callee-saved-restored: true,
+      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+  - { id: 1, name: '', type: default, offset: 0, size: 4, alignment: 4,
+      stack-id: default, callee-saved-register: '', callee-saved-restored: true,
+      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+body:             |
+  bb.1:
+    ; GISEL-I686-LABEL: name: test_sincos_f32
+    ; GISEL-I686: [[MOV32rm:%[0-9]+]]:gr32 = MOV32rm %fixed-stack.0, 1, $noreg, 0, $noreg :: (invariant load (s32) from %fixed-stack.0, align 16)
+    ; GISEL-I686-NEXT: [[LEA32r:%[0-9]+]]:gr32 = LEA32r %stack.0, 1, $noreg, 0, $noreg
+    ; GISEL-I686-NEXT: [[LEA32r1:%[0-9]+]]:gr32 = LEA32r %stack.1, 1, $noreg, 0, $noreg
+    ; GISEL-I686-NEXT: ADJCALLSTACKDOWN32 12, 0, 0, implicit-def $esp, implicit-def $eflags, implicit-def $ssp, implicit $esp, implicit $ssp
+    ; GISEL-I686-NEXT: [[COPY:%[0-9]+]]:gr32 = COPY $esp
+    ; GISEL-I686-NEXT: MOV32mr [[COPY]], 1, $noreg, 0, $noreg, [[MOV32rm]] :: (store (s32) into stack, align 1)
+    ; GISEL-I686-NEXT: [[COPY1:%[0-9]+]]:gr32 = COPY $esp
+    ; GISEL-I686-NEXT: MOV32mr [[COPY1]], 1, $noreg, 4, $noreg, [[LEA32r]] :: (store (s32) into stack + 4, align 1)
+    ; GISEL-I686-NEXT: [[COPY2:%[0-9]+]]:gr32 = COPY $esp
+    ; GISEL-I686-NEXT: MOV32mr [[COPY2]], 1, $noreg, 8, $noreg, [[LEA32r1]] :: (store (s32) into stack + 8, align 1)
+    ; GISEL-I686-NEXT: CALLpcrel32 &sincosf, csr_32, implicit $esp, implicit $ssp
+    ; GISEL-I686-NEXT: ADJCALLSTACKUP32 12, 0, implicit-def $esp, implicit-def $eflags, implicit-def $ssp, implicit $esp, implicit $ssp
+    ; GISEL-I686-NEXT: [[LD_Fp32m:%[0-9]+]]:rfp32 = nofpexcept LD_Fp32m %stack.0, 1, $noreg, 0, $noreg, implicit-def dead $fpsw, implicit $fpcw :: (load (s32) from %stack.0)
+    ; GISEL-I686-NEXT: [[LD_Fp32m1:%[0-9]+]]:rfp32 = nofpexcept LD_Fp32m %stack.1, 1, $noreg, 0, $noreg, implicit-def dead $fpsw, implicit $fpcw :: (load (s32) from %stack.1)
+    ; GISEL-I686-NEXT: $fp0 = COPY [[LD_Fp32m]]
+    ; GISEL-I686-NEXT: $fp1 = COPY [[LD_Fp32m1]]
+    ; GISEL-I686-NEXT: RET 0, implicit $fp0, implicit $fp1
+    %1:_(p0) = G_FRAME_INDEX %fixed-stack.0
+    %0:_(s32) = G_LOAD %1(p0) :: (invariant load (s32) from %fixed-stack.0, align 16)
+    %4:_(p0) = G_FRAME_INDEX %stack.0
+    %5:_(p0) = G_FRAME_INDEX %stack.1
+    ADJCALLSTACKDOWN32 12, 0, 0, implicit-def $esp, implicit-def $eflags, implicit-def $ssp, implicit $esp, implicit $ssp
+    %6:_(p0) = COPY $esp
+    %7:_(s32) = G_CONSTANT i32 0
+    %8:_(p0) = G_PTR_ADD %6, %7(s32)
+    G_STORE %0(s32), %8(p0) :: (store (s32) into stack, align 1)
+    %9:_(p0) = COPY $esp
+    %10:_(s32) = G_CONSTANT i32 4
+    %11:_(p0) = G_PTR_ADD %9, %10(s32)
+    G_STORE %4(p0), %11(p0) :: (store (s32) into stack + 4, align 1)
+    %12:_(p0) = COPY $esp
+    %13:_(s32) = G_CONSTANT i32 8
+    %14:_(p0) = G_PTR_ADD %12, %13(s32)
+    G_STORE %5(p0), %14(p0) :: (store (s32) into stack + 8, align 1)
+    CALLpcrel32 &sincosf, csr_32, implicit $esp, implicit $ssp
+    ADJCALLSTACKUP32 12, 0, implicit-def $esp, implicit-def $eflags, implicit-def $ssp, implicit $esp, implicit $ssp
+    %2:_(s32) = G_LOAD %4(p0) :: (load (s32) from %stack.0)
+    %3:_(s32) = G_LOAD %5(p0) :: (load (s32) from %stack.1)
+    $fp0 = COPY %2(s32)
+    $fp1 = COPY %3(s32)
+    RET 0, implicit $fp0, implicit $fp1
+...
+---
+name:            test_sincos_f64
+alignment:       16
+legalized:       true
+fixedStack:
+  - { id: 0, type: default, offset: 0, size: 8, alignment: 16, stack-id: default,
+      isImmutable: true, isAliased: false, callee-saved-register: '', callee-saved-restored: true,
+      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+stack:
+  - { id: 0, name: '', type: default, offset: 0, size: 8, alignment: 8,
+      stack-id: default, callee-saved-register: '', callee-saved-restored: true,
+      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+  - { id: 1, name: '', type: default, offset: 0, size: 8, alignment: 8,
+      stack-id: default, callee-saved-register: '', callee-saved-restored: true,
+      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+body:             |
+  bb.1:
+    ; GISEL-I686-LABEL: name: test_sincos_f64
+    ; GISEL-I686: [[LEA32r:%[0-9]+]]:gr32 = LEA32r %fixed-stack.0, 1, $noreg, 0, $noreg
+    ; GISEL-I686-NEXT: [[MOV32rm:%[0-9]+]]:gr32 = MOV32rm %fixed-stack.0, 1, $noreg, 0, $noreg :: (invariant load (s32) from %fixed-stack.0, align 16)
+    ; GISEL-I686-NEXT: [[MOV32rm1:%[0-9]+]]:gr32 = MOV32rm [[LEA32r]], 1, $noreg, 4, $noreg :: (invariant load (s32) from %fixed-stack.0 + 4, basealign 16)
+    ; GISEL-I686-NEXT: [[LEA32r1:%[0-9]+]]:gr32 = LEA32r %stack.0, 1, $noreg, 0, $noreg
+    ; GISEL-I686-NEXT: [[LEA32r2:%[0-9]+]]:gr32 = LEA32r %stack.1, 1, $noreg, 0, $noreg
+    ; GISEL-I686-NEXT: ADJCALLSTACKDOWN32 16, 0, 0, implicit-def $esp, implicit-def $eflags, implicit-def $ssp, implicit $esp, implicit $ssp
+    ; GISEL-I686-NEXT: [[COPY:%[0-9]+]]:gr32 = COPY $esp
+    ; GISEL-I686-NEXT: [[MOV32r0_:%[0-9]+]]:gr32_nosp = MOV32r0 implicit-def dead $eflags
+    ; GISEL-I686-NEXT: [[LEA32r3:%[0-9]+]]:gr32 = LEA32r [[COPY]], 1, [[MOV32r0_]], 0, $noreg
+    ; GISEL-I686-NEXT: MOV32mr [[COPY]], 1, $noreg, 0, $noreg, [[MOV32rm]] :: (store (s32) into stack, align 1)
+    ; GISEL-I686-NEXT: MOV32mr [[LEA32r3]], 1, $noreg, 4, $noreg, [[MOV32rm1]] :: (store (s32) into stack + 4, align 1)
+    ; GISEL-I686-NEXT: [[COPY1:%[0-9]+]]:gr32 = COPY $esp
+    ; GISEL-I686-NEXT: MOV32mr [[COPY1]], 1, $noreg, 8, $noreg, [[LEA32r1]] :: (store (s32) into stack + 8, align 1)
+    ; GISEL-I686-NEXT: [[COPY2:%[0-9]+]]:gr32 = COPY $esp
+    ; GISEL-I686-NEXT: MOV32mr [[COPY2]], 1, $noreg, 12, $noreg, [[LEA32r2]] :: (store (s32) into stack + 12, align 1)
+    ; GISEL-I686-NEXT: CALLpcrel32 &sincos, csr_32, implicit $esp, implicit $ssp
+    ; GISEL-I686-NEXT: ADJCALLSTACKUP32 16, 0, implicit-def $esp, implicit-def $eflags, implicit-def $ssp, implicit $esp, implicit $ssp
+    ; GISEL-I686-NEXT: $fp0 = IMPLICIT_DEF
+    ; GISEL-I686-NEXT: $fp1 = IMPLICIT_DEF
+    ; GISEL-I686-NEXT: RET 0, implicit $fp0, implicit $fp1
+    %1:_(p0) = G_FRAME_INDEX %fixed-stack.0
+    %25:_(s32) = G_LOAD %1(p0) :: (invariant load (s32) from %fixed-stack.0, align 16)
+    %17:_(s32) = G_CONSTANT i32 4
+    %26:_(p0) = G_PTR_ADD %1, %17(s32)
+    %27:_(s32) = G_LOAD %26(p0) :: (invariant load (s32) from %fixed-stack.0 + 4, basealign 16)
+    %4:_(p0) = G_FRAME_INDEX %stack.0
+    %5:_(p0) = G_FRAME_INDEX %stack.1
+    ADJCALLSTACKDOWN32 16, 0, 0, implicit-def $esp, implicit-def $eflags, implicit-def $ssp, implicit $esp, implicit $ssp
+    %6:_(p0) = COPY $esp
+    %7:_(s32) = G_CONSTANT i32 0
+    %8:_(p0) = G_PTR_ADD %6, %7(s32)
+    G_STORE %25(s32), %8(p0) :: (store (s32) into stack, align 1)
+    %24:_(p0) = G_PTR_ADD %8, %17(s32)
+    G_STORE %27(s32), %24(p0) :: (store (s32) into stack + 4, align 1)
+    %9:_(p0) = COPY $esp
+    %10:_(s32) = G_CONSTANT i32 8
+    %11:_(p0) = G_PTR_ADD %9, %10(s32)
+    G_STORE %4(p0), %11(p0) :: (store (s32) into stack + 8, align 1)
+    %12:_(p0) = COPY $esp
+    %13:_(s32) = G_CONSTANT i32 12
+    %14:_(p0) = G_PTR_ADD %12, %13(s32)
+    G_STORE %5(p0), %14(p0) :: (store (s32) into stack + 12, align 1)
+    CALLpcrel32 &sincos, csr_32, implicit $esp, implicit $ssp
+    ADJCALLSTACKUP32 16, 0, implicit-def $esp, implicit-def $eflags, implicit-def $ssp, implicit $esp, implicit $ssp
+    $fp0 = IMPLICIT_DEF
+    $fp1 = IMPLICIT_DEF
+    RET 0, implicit $fp0, implicit $fp1
+...
+---
+name:            test_sincos_f80
+alignment:       16
+legalized:       true
+fixedStack:
+  - { id: 0, type: default, offset: 0, size: 10, alignment: 16, stack-id: default,
+      isImmutable: true, isAliased: false, callee-saved-register: '', callee-saved-restored: true,
+      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+stack:
+  - { id: 0, name: '', type: default, offset: 0, size: 10, alignment: 16,
+      stack-id: default, callee-saved-register: '', callee-saved-restored: true,
+      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+  - { id: 1, name: '', type: default, offset: 0, size: 10, alignment: 16,
+      stack-id: default, callee-saved-register: '', callee-saved-restored: true,
+      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+body:             |
+  bb.1:
+    ; GISEL-I686-LABEL: name: test_sincos_f80
+    ; GISEL-I686: [[LD_Fp80m:%[0-9]+]]:rfp80 = nofpexcept LD_Fp80m %fixed-stack.0, 1, $noreg, 0, $noreg, implicit-def dead $fpsw, implicit $fpcw :: (invariant load (s80) from %fixed-stack.0, align 16)
+    ; GISEL-I686-NEXT: [[LEA32r:%[0-9]+]]:gr32 = LEA32r %stack.0, 1, $noreg, 0, $noreg
+    ; GISEL-I686-NEXT: [[LEA32r1:%[0-9]+]]:gr32 = LEA32r %stack.1, 1, $noreg, 0, $noreg
+    ; GISEL-I686-NEXT: ADJCALLSTACKDOWN32 20, 0, 0, implicit-def $esp, implicit-def $eflags, implicit-def $ssp, implicit $esp, implicit $ssp
+    ; GISEL-I686-NEXT: [[COPY:%[0-9]+]]:gr32 = COPY $esp
+    ; GISEL-I686-NEXT: nofpexcept ST_FpP80m [[COPY]], 1, $noreg, 0, $noreg, [[LD_Fp80m]], implicit-def dead $fpsw, implicit $fpcw :: (store (s80) into stack, align 1)
+    ; GISEL-I686-NEXT: [[COPY1:%[0-9]+]]:gr32 = COPY $esp
+    ; GISEL-I686-NEXT: MOV32mr [[COPY1]], 1, $noreg, 12, $noreg, [[LEA32r]] :: (store (s32) into stack + 12, align 1)
+    ; GISEL-I686-NEXT: [[COPY2:%[0-9]+]]:gr32 = COPY $esp
+    ; GISEL-I686-NEXT: MOV32mr [[COPY2]], 1, $noreg, 16, $noreg, [[LEA32r1]] :: (store (s32) into stack + 16, align 1)
+    ; GISEL-I686-NEXT: CALLpcrel32 &sincosl, csr_32, implicit $esp, implicit $ssp
+    ; GISEL-I686-NEXT: ADJCALLSTACKUP32 20, 0, implicit-def $esp, implicit-def $eflags, implicit-def $ssp, implicit $esp, implicit $ssp
+    ; GISEL-I686-NEXT: [[LD_Fp80m1:%[0-9]+]]:rfp80 = nofpexcept LD_Fp80m %stack.0, 1, $noreg, 0, $noreg, implicit-def dead $fpsw, implicit $fpcw :: (load (s80) from %stack.0, align 16)
+    ; GISEL-I686-NEXT: [[LD_Fp80m2:%[0-9]+]]:rfp80 = nofpexcept LD_Fp80m %stack.1, 1, $noreg, 0, $noreg, implicit-def dead $fpsw, implicit $fpcw :: (load (s80) from %stack.1, align 16)
+    ; GISEL-I686-NEXT: $fp0 = COPY [[LD_Fp80m1]]
+    ; GISEL-I686-NEXT: $fp1 = COPY [[LD_Fp80m2]]
+    ; GISEL-I686-NEXT: RET 0, implicit $fp0, implicit $fp1
+    %1:_(p0) = G_FRAME_INDEX %fixed-stack.0
+    %0:_(s80) = G_LOAD %1(p0) :: (invariant load (s80) from %fixed-stack.0, align 16)
+    %4:_(p0) = G_FRAME_INDEX %stack.0
+    %5:_(p0) = G_FRAME_INDEX %stack.1
+    ADJCALLSTACKDOWN32 20, 0, 0, implicit-def $esp, implicit-def $eflags, implicit-def $ssp, implicit $esp, implicit $ssp
+    %6:_(p0) = COPY $esp
+    %7:_(s32) = G_CONSTANT i32 0
+    %8:_(p0) = G_PTR_ADD %6, %7(s32)
+    G_STORE %0(s80), %8(p0) :: (store (s80) into stack, align 1)
+    %9:_(p0) = COPY $esp
+    %10:_(s32) = G_CONSTANT i32 12
+    %11:_(p0) = G_PTR_ADD %9, %10(s32)
+    G_STORE %4(p0), %11(p0) :: (store (s32) into stack + 12, align 1)
+    %12:_(p0) = COPY $esp
+    %13:_(s32) = G_CONSTANT i32 16
+    %14:_(p0) = G_PTR_ADD %12, %13(s32)
+    G_STORE %5(p0), %14(p0) :: (store (s32) into stack + 16, align 1)
+    CALLpcrel32 &sincosl, csr_32, implicit $esp, implicit $ssp
+    ADJCALLSTACKUP32 20, 0, implicit-def $esp, implicit-def $eflags, implicit-def $ssp, implicit $esp, implicit $ssp
+    %2:_(s80) = G_LOAD %4(p0) :: (load (s80) from %stack.0, align 16)
+    %3:_(s80) = G_LOAD %5(p0) :: (load (s80) from %stack.1, align 16)
+    $fp0 = COPY %2(s80)
+    $fp1 = COPY %3(s80)
+    RET 0, implicit $fp0, implicit $fp1
+...
diff --git a/llvm/test/CodeGen/X86/llvm.sincos.ll b/llvm/test/CodeGen/X86/llvm.sincos.ll
index 5734729a2c507..065710f91457b 100644
--- a/llvm/test/CodeGen/X86/llvm.sincos.ll
+++ b/llvm/test/CodeGen/X86/llvm.sincos.ll
@@ -3,8 +3,9 @@
 ; RUN: llc < %s -mtriple=x86_64-linux-gnu -fast-isel  | FileCheck %s --check-prefixes=X64,FASTISEL-X64
 ; RUN: llc < %s -mtriple=i686-linux-gnu -global-isel=0 -fast-isel=0  | FileCheck %s --check-prefixes=X86,SDAG-X86
 ; RUN: llc < %s -mtriple=x86_64-linux-gnu -global-isel=0 -fast-isel=0  | FileCheck %s --check-prefixes=X64,SDAG-X64
-; RUN: llc < %s -mtriple=i686-linux-gnu -global-isel=1 -global-isel-abort=2 | FileCheck %s --check-prefixes=X86,GISEL-X86
-; RUN: llc < %s -mtriple=x86_64-linux-gnu -global-isel=1 -global-isel-abort=2 | FileCheck %s --check-prefixes=X64,GISEL-X64
+; TODO: The below RUN line will fails GISEL selection and will fallback to DAG selection due to lack of support for loads/stores in i686 mode, support is expected soon enough, for this reason the llvm/test/CodeGen/X86/GlobalISel/llvm.sincos.mir test is added for now because of the lack of support for i686 in GlobalISel.
+; RUN: llc < %s -mtriple=i686-linux-gnu -global-isel=1 -global-isel-abort=2 | FileCheck %s --check-prefixes=GISEL-X86
+; RUN: llc < %s -mtriple=x86_64-linux-gnu -global-isel=1 -global-isel-abort=1 | FileCheck %s --check-prefixes=GISEL-X64
 
 define { float, float } @test_sincos_f32(float %Val) nounwind {
 ; X86-LABEL: test_sincos_f32:
@@ -32,6 +33,35 @@ define { float, float } @test_sincos_f32(float %Val) nounwind {
 ; X64-NEXT:    movss {{.*#+}} xmm1 = mem[0],zero,zero,zero
 ; X64-NEXT:    popq %rax
 ; X64-NEXT:    retq
+;
+; GISEL-X86-LABEL: test_sincos_f32:
+; GISEL-X86:       # %bb.0:
+; GISEL-X86-NEXT:    subl $28, %esp
+; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; GISEL-X86-NEXT:    leal {{[0-9]+}}(%esp), %ecx
+; GISEL-X86-NEXT:    leal {{[0-9]+}}(%esp), %edx
+; GISEL-X86-NEXT:    movl %eax, (%esp)
+; GISEL-X86-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
+; GISEL-X86-NEXT:    movl %edx, {{[0-9]+}}(%esp)
+; GISEL-X86-NEXT:    calll sincosf
+; GISEL-X86-NEXT:    flds {{[0-9]+}}(%esp)
+; GISEL-X86-NEXT:    flds {{[0-9]+}}(%esp)
+; GISEL-X86-NEXT:    fxch %st(1)
+; GISEL-X86-NEXT:    addl $28, %esp
+; GISEL-X86-NEXT:    retl
+;
+; GISEL-X64-LABEL: test_sincos_f32:
+; GISEL-X64:       # %bb.0:
+; GISEL-X64-NEXT:    pushq %rax
+; GISEL-X64-NEXT:    leaq {{[0-9]+}}(%rsp), %rdi
+; GISEL-X64-NEXT:    movq %rsp, %rsi
+; GISEL-X64-NEXT:    callq sincosf
+; GISEL-X64-NEXT:    movl {{[0-9]+}}(%rsp), %eax
+; GISEL-X64-NEXT:    movl (%rsp), %ecx
+; GISEL-X64-NEXT:    movd %eax, %xmm0
+; GISEL-X64-NEXT:    movd %ecx, %xmm1
+; GISEL-X64-NEXT:    popq %rax
+; GISEL-X64-NEXT:    retq
   %res = call { float, float } @llvm.sincos.f32(float %Val)
   ret { float, float } %res
 }
@@ -62,6 +92,34 @@ define { double, double } @test_sincos_f64(double %Val) nounwind  {
 ; X64-NEXT:    movsd {{.*#+}} xmm1 = mem[0],zero
 ; X64-NEXT:    addq $24, %rsp
 ; X64-NEXT:    retq
+;
+; GISEL-X86-LABEL: test_sincos_f64:
+; GISEL-X86:       # %bb.0:
+; GISEL-X86-NEXT:    subl $44, %esp
+; GISEL-X86-NEXT:    fldl {{[0-9]+}}(%esp)
+; GISEL-X86-NEXT:    leal {{[0-9]+}}(%esp), %eax
+; GISEL-X86-NEXT:    movl %eax, {{[0-9]+}}(%esp)
+; GISEL-X86-NEXT:    leal {{[0-9]+}}(%esp), %eax
+; GISEL-X86-NEXT:    movl %eax, {{[0-9]+}}(%esp)
+; GISEL-X86-NEXT:    fstpl (%esp)
+; GISEL-X86-NEXT:    calll sincos
+; GISEL-X86-NEXT:    fldl {{[0-9]+}}(%esp)
+; GISEL-X86-NEXT:    fldl {{[0-9]+}}(%esp)
+; GISEL-X86-NEXT:    addl $44, %esp
+; GISEL-X86-NEXT:    retl
+;
+; GISEL-X64-LABEL: test_sincos_f64:
+; GISEL-X64:       # %bb.0:
+; GISEL-X64-NEXT:    subq $24, %rsp
+; GISEL-X64-NEXT:    leaq {{[0-9]+}}(%rsp), %rdi
+; GISEL-X64-NEXT:    leaq {{[0-9]+}}(%rsp), %rsi
+; GISEL-X64-NEXT:    callq sincos
+; GISEL-X64-NEXT:    movq {{[0-9]+}}(%rsp), %rax
+; GISEL-X64-NEXT:    movq {{[0-9]+}}(%rsp), %rcx
+; GISEL-X64-NEXT:    movq %rax, %xmm0
+; GISEL-X64-NEXT:    movq %rcx, %xmm1
+; GISEL-X64-NEXT:    addq $24, %rsp
+; GISEL-X64-NEXT:    retq
   %res = call { double, double } @llvm.sincos.f64(double %Val)
   ret { double, double } %res
 }
@@ -94,6 +152,36 @@ define { x86_fp80, x86_fp80 } @test_sincos_f80(x86_fp80 %Val) nounwind {
 ; X64-NEXT:    fldt {{[0-9]+}}(%rsp)
 ; X64-NEXT:    addq $56, %rsp
 ; X64-NEXT:    retq
+;
+; GISEL-X86-LABEL: test_sincos_f80:
+; GISEL-X86:       # %bb.0:
+; GISEL-X86-NEXT:    subl $60, %esp
+; GISEL-X86-NEXT:    fldt {{[0-9]+}}(%esp)
+; GISEL-X86-NEXT:    leal {{[0-9]+}}(%esp), %eax
+; GISEL-X86-NEXT:    leal {{[0-9]+}}(%esp), %ecx
+; GISEL-X86-NEXT:    fstpt (%esp)
+; GISEL-X86-NEXT:    movl %eax, {{[0-9]+}}(%esp)
+; GISEL-X86-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
+; GISEL-X86-NEXT:    calll sincosl
+; GISEL-X86-NEXT:    fldt {{[0-9]+}}(%esp)
+; GISEL-X86-NEXT:    fldt {{[0-9]+}}(%esp)
+; GISEL-X86-NEXT:    fxch %st(1)
+; GISEL-X86-NEXT:    addl $60, %esp
+; GISEL-X86-NEXT:    retl
+;
+; GISEL-X64-LABEL: test_sincos_f80:
+; GISEL-X64:       # %bb.0:
+; GISEL-X64-NEXT:    subq $56, %rsp
+; GISEL-X64-NEXT:    fldt {{[0-9]+}}(%rsp)
+; GISEL-X64-NEXT:    leaq {{[0-9]+}}(%rsp), %rdi
+; GISEL-X64-NEXT:    leaq {{[0-9]+}}(%rsp), %rsi
+; GISEL-X64-NEXT:    fstpt (%rsp)
+; GISEL-X64-NEXT:    callq sincosl
+; GISEL-X64-NEXT:    fldt {{[0-9]+}}(%rsp)
+; GISEL-X64-NEXT:    fldt {{[0-9]+}}(%rsp)
+; GISEL-X64-NEXT:    fxch %st(1)
+; GISEL-X64-NEXT:    addq $56, %rsp
+; GISEL-X64-NEXT:    retq
   %res = call { x86_fp80, x86_fp80 } @llvm.sincos.f80(x86_fp80 %Val)
   ret { x86_fp80, x86_fp80 } %res
 }

>From 7c476cc5936880aa4293807a7df7a37b5e845ed3 Mon Sep 17 00:00:00 2001
From: Chauhan Jaydeep Ashwinbhai <chauhan.jaydeep.ashwinbhai at intel.com>
Date: Tue, 3 Jun 2025 05:35:42 -0700
Subject: [PATCH 2/2] Fixed formatting issue

---
 llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp
index fbac4b7bd6163..f2078d50d0232 100644
--- a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp
+++ b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp
@@ -99,11 +99,10 @@ X86LegalizerInfo::X86LegalizerInfo(const X86Subtarget &STI,
       .widenScalarToNextPow2(0, /*Min=*/8)
       .clampScalar(0, s8, sMaxScalar);
 
-  getActionDefinitionsBuilder({G_LROUND, G_LLROUND, G_FCOS,  G_FCOSH,  G_FACOS,
-                               G_FSIN,   G_FSINH,   G_FASIN, G_FTAN,   G_FTANH,
-                               G_FATAN,  G_FATAN2,  G_FPOW,  G_FEXP,   G_FEXP2,
-                               G_FEXP10, G_FLOG,    G_FLOG2, G_FLOG10, G_FPOWI,
-                               G_FSINCOS})
+  getActionDefinitionsBuilder(
+      {G_LROUND, G_LLROUND, G_FCOS,  G_FCOSH, G_FACOS,  G_FSIN,  G_FSINH,
+       G_FASIN,  G_FTAN,    G_FTANH, G_FATAN, G_FATAN2, G_FPOW,  G_FEXP,
+       G_FEXP2,  G_FEXP10,  G_FLOG,  G_FLOG2, G_FLOG10, G_FPOWI, G_FSINCOS})
       .libcall();
 
   getActionDefinitionsBuilder(G_FSQRT)



More information about the llvm-commits mailing list