[X86][GlobalISel] Enable SINCOS with libcall mapping (#142438)
This commit is contained in:
parent
a0ce3e691c
commit
c3c923c8d6
@ -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.
|
||||
|
@ -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:
|
||||
|
@ -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)
|
||||
|
189
llvm/test/CodeGen/X86/GlobalISel/llvm.sincos.mir
Normal file
189
llvm/test/CodeGen/X86/GlobalISel/llvm.sincos.mir
Normal 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
|
||||
...
|
@ -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
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user