[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