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

This commit is contained in:
JaydeepChauhan14 2025-06-24 23:37:33 -07:00 committed by GitHub
parent a0ce3e691c
commit c3c923c8d6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 348 additions and 6 deletions

View File

@ -295,6 +295,11 @@ private:
getNeutralElementForVecReduce(unsigned Opcode, MachineIRBuilder &MIRBuilder,
LLT Ty);
LegalizeResult emitSincosLibcall(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.

View File

@ -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,54 @@ simpleLibcall(MachineInstr &MI, MachineIRBuilder &MIRBuilder, unsigned Size,
LocObserver, &MI);
}
LegalizerHelper::LegalizeResult LegalizerHelper::emitSincosLibcall(
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);
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();
auto LibcallResult =
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);
if (LibcallResult != LegalizeResult::Legalized)
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);
MI.eraseFromParent();
return LegalizerHelper::Legalized;
}
LegalizerHelper::LegalizeResult
llvm::createMemLibcall(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
MachineInstr &MI, LostDebugLocObserver &LocObserver) {
@ -1275,6 +1325,16 @@ 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;
}
return emitSincosLibcall(MI, MIRBuilder, Size, HLTy, LocObserver);
}
case TargetOpcode::G_LROUND:
case TargetOpcode::G_LLROUND:
case TargetOpcode::G_INTRINSIC_LRINT:

View File

@ -97,10 +97,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})
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)

View File

@ -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
...

View File

@ -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
}