[X86][GlobalISel] - Legalize And Select G_FPTOSI/G_SITOFP in X87 mode (#137377)
Support legalization and selection of G_FPTOSI/G_SITOFP generic opcodes in x87 mode.
This commit is contained in:
@@ -935,6 +935,16 @@ public:
|
||||
Types2);
|
||||
}
|
||||
|
||||
/// The instruction is custom when the predicate is true and type indexes 0
|
||||
/// and 1 are all in their respective lists.
|
||||
LegalizeRuleSet &
|
||||
customForCartesianProduct(bool Pred, std::initializer_list<LLT> Types0,
|
||||
std::initializer_list<LLT> Types1) {
|
||||
if (!Pred)
|
||||
return *this;
|
||||
return actionForCartesianProduct(LegalizeAction::Custom, Types0, Types1);
|
||||
}
|
||||
|
||||
/// Unconditionally custom lower.
|
||||
LegalizeRuleSet &custom() {
|
||||
return customIf(always);
|
||||
|
||||
@@ -364,7 +364,7 @@ bool X86InstructionSelector::select(MachineInstr &I) {
|
||||
MachineRegisterInfo &MRI = MF.getRegInfo();
|
||||
|
||||
unsigned Opcode = I.getOpcode();
|
||||
if (!isPreISelGenericOpcode(Opcode)) {
|
||||
if (!isPreISelGenericOpcode(Opcode) && !I.isPreISelOpcode()) {
|
||||
// Certain non-generic instructions also need some special handling.
|
||||
|
||||
if (Opcode == TargetOpcode::LOAD_STACK_GUARD)
|
||||
|
||||
@@ -490,31 +490,25 @@ X86LegalizerInfo::X86LegalizerInfo(const X86Subtarget &STI,
|
||||
});
|
||||
|
||||
getActionDefinitionsBuilder(G_SITOFP)
|
||||
.legalIf([=](const LegalityQuery &Query) {
|
||||
return (HasSSE1 &&
|
||||
(typePairInSet(0, 1, {{s32, s32}})(Query) ||
|
||||
(Is64Bit && typePairInSet(0, 1, {{s32, s64}})(Query)))) ||
|
||||
(HasSSE2 &&
|
||||
(typePairInSet(0, 1, {{s64, s32}})(Query) ||
|
||||
(Is64Bit && typePairInSet(0, 1, {{s64, s64}})(Query))));
|
||||
})
|
||||
.clampScalar(1, s32, sMaxScalar)
|
||||
.legalFor(HasSSE1, {{s32, s32}})
|
||||
.legalFor(HasSSE1 && Is64Bit, {{s32, s64}})
|
||||
.legalFor(HasSSE2, {{s64, s32}})
|
||||
.legalFor(HasSSE2 && Is64Bit, {{s64, s64}})
|
||||
.clampScalar(1, (UseX87 && !HasSSE1) ? s16 : s32, sMaxScalar)
|
||||
.widenScalarToNextPow2(1)
|
||||
.customForCartesianProduct(UseX87, {s32, s64, s80}, {s16, s32, s64})
|
||||
.clampScalar(0, s32, HasSSE2 ? s64 : s32)
|
||||
.widenScalarToNextPow2(0);
|
||||
|
||||
getActionDefinitionsBuilder(G_FPTOSI)
|
||||
.legalIf([=](const LegalityQuery &Query) {
|
||||
return (HasSSE1 &&
|
||||
(typePairInSet(0, 1, {{s32, s32}})(Query) ||
|
||||
(Is64Bit && typePairInSet(0, 1, {{s64, s32}})(Query)))) ||
|
||||
(HasSSE2 &&
|
||||
(typePairInSet(0, 1, {{s32, s64}})(Query) ||
|
||||
(Is64Bit && typePairInSet(0, 1, {{s64, s64}})(Query))));
|
||||
})
|
||||
.clampScalar(1, s32, HasSSE2 ? s64 : s32)
|
||||
.legalFor(HasSSE1, {{s32, s32}})
|
||||
.legalFor(HasSSE1 && Is64Bit, {{s64, s32}})
|
||||
.legalFor(HasSSE2, {{s32, s64}})
|
||||
.legalFor(HasSSE2 && Is64Bit, {{s64, s64}})
|
||||
.clampScalar(0, (UseX87 && !HasSSE1) ? s16 : s32, sMaxScalar)
|
||||
.widenScalarToNextPow2(0)
|
||||
.clampScalar(0, s32, sMaxScalar)
|
||||
.customForCartesianProduct(UseX87, {s16, s32, s64}, {s32, s64, s80})
|
||||
.clampScalar(1, s32, HasSSE2 ? s64 : s32)
|
||||
.widenScalarToNextPow2(1);
|
||||
|
||||
// For G_UITOFP and G_FPTOUI without AVX512, we have to custom legalize types
|
||||
@@ -671,10 +665,70 @@ bool X86LegalizerInfo::legalizeCustom(LegalizerHelper &Helper, MachineInstr &MI,
|
||||
return legalizeUITOFP(MI, MRI, Helper);
|
||||
case TargetOpcode::G_STORE:
|
||||
return legalizeNarrowingStore(MI, MRI, Helper);
|
||||
case TargetOpcode::G_SITOFP:
|
||||
return legalizeSITOFP(MI, MRI, Helper);
|
||||
case TargetOpcode::G_FPTOSI:
|
||||
return legalizeFPTOSI(MI, MRI, Helper);
|
||||
}
|
||||
llvm_unreachable("expected switch to return");
|
||||
}
|
||||
|
||||
bool X86LegalizerInfo::legalizeSITOFP(MachineInstr &MI,
|
||||
MachineRegisterInfo &MRI,
|
||||
LegalizerHelper &Helper) const {
|
||||
MachineIRBuilder &MIRBuilder = Helper.MIRBuilder;
|
||||
MachineFunction &MF = *MI.getMF();
|
||||
auto [Dst, DstTy, Src, SrcTy] = MI.getFirst2RegLLTs();
|
||||
|
||||
assert((SrcTy.getSizeInBits() == 16 || SrcTy.getSizeInBits() == 32 ||
|
||||
SrcTy.getSizeInBits() == 64) &&
|
||||
"Unexpected source type for SITOFP in X87 mode.");
|
||||
|
||||
TypeSize MemSize = SrcTy.getSizeInBytes();
|
||||
MachinePointerInfo PtrInfo;
|
||||
Align Alignmt = Helper.getStackTemporaryAlignment(SrcTy);
|
||||
auto SlotPointer = Helper.createStackTemporary(MemSize, Alignmt, PtrInfo);
|
||||
MachineMemOperand *StoreMMO = MF.getMachineMemOperand(
|
||||
PtrInfo, MachineMemOperand::MOStore, MemSize, Align(MemSize));
|
||||
|
||||
// Store the integer value on the FPU stack.
|
||||
MIRBuilder.buildStore(Src, SlotPointer, *StoreMMO);
|
||||
|
||||
MachineMemOperand *LoadMMO = MF.getMachineMemOperand(
|
||||
PtrInfo, MachineMemOperand::MOLoad, MemSize, Align(MemSize));
|
||||
MIRBuilder.buildInstr(X86::G_FILD)
|
||||
.addDef(Dst)
|
||||
.addUse(SlotPointer.getReg(0))
|
||||
.addMemOperand(LoadMMO);
|
||||
|
||||
MI.eraseFromParent();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool X86LegalizerInfo::legalizeFPTOSI(MachineInstr &MI,
|
||||
MachineRegisterInfo &MRI,
|
||||
LegalizerHelper &Helper) const {
|
||||
MachineFunction &MF = *MI.getMF();
|
||||
MachineIRBuilder &MIRBuilder = Helper.MIRBuilder;
|
||||
auto [Dst, DstTy, Src, SrcTy] = MI.getFirst2RegLLTs();
|
||||
|
||||
TypeSize MemSize = DstTy.getSizeInBytes();
|
||||
MachinePointerInfo PtrInfo;
|
||||
Align Alignmt = Helper.getStackTemporaryAlignment(DstTy);
|
||||
auto SlotPointer = Helper.createStackTemporary(MemSize, Alignmt, PtrInfo);
|
||||
MachineMemOperand *StoreMMO = MF.getMachineMemOperand(
|
||||
PtrInfo, MachineMemOperand::MOStore, MemSize, Align(MemSize));
|
||||
|
||||
MIRBuilder.buildInstr(X86::G_FIST)
|
||||
.addUse(Src)
|
||||
.addUse(SlotPointer.getReg(0))
|
||||
.addMemOperand(StoreMMO);
|
||||
|
||||
MIRBuilder.buildLoad(Dst, SlotPointer, PtrInfo, Align(MemSize));
|
||||
MI.eraseFromParent();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool X86LegalizerInfo::legalizeBuildVector(MachineInstr &MI,
|
||||
MachineRegisterInfo &MRI,
|
||||
LegalizerHelper &Helper) const {
|
||||
|
||||
@@ -48,6 +48,12 @@ private:
|
||||
|
||||
bool legalizeNarrowingStore(MachineInstr &MI, MachineRegisterInfo &MRI,
|
||||
LegalizerHelper &Helper) const;
|
||||
|
||||
bool legalizeSITOFP(MachineInstr &MI, MachineRegisterInfo &MRI,
|
||||
LegalizerHelper &Helper) const;
|
||||
|
||||
bool legalizeFPTOSI(MachineInstr &MI, MachineRegisterInfo &MRI,
|
||||
LegalizerHelper &Helper) const;
|
||||
};
|
||||
} // namespace llvm
|
||||
#endif
|
||||
|
||||
@@ -111,6 +111,7 @@ bool X86RegisterBankInfo::onlyUsesFP(const MachineInstr &MI,
|
||||
case TargetOpcode::G_FPTOSI:
|
||||
case TargetOpcode::G_FPTOUI:
|
||||
case TargetOpcode::G_FCMP:
|
||||
case X86::G_FIST:
|
||||
case TargetOpcode::G_LROUND:
|
||||
case TargetOpcode::G_LLROUND:
|
||||
case TargetOpcode::G_INTRINSIC_TRUNC:
|
||||
@@ -129,6 +130,7 @@ bool X86RegisterBankInfo::onlyDefinesFP(const MachineInstr &MI,
|
||||
switch (MI.getOpcode()) {
|
||||
case TargetOpcode::G_SITOFP:
|
||||
case TargetOpcode::G_UITOFP:
|
||||
case X86::G_FILD:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
@@ -296,6 +298,16 @@ X86RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
|
||||
// VECRReg)
|
||||
getInstrPartialMappingIdxs(MI, MRI, /* isFP= */ true, OpRegBankIdx);
|
||||
break;
|
||||
case X86::G_FIST:
|
||||
case X86::G_FILD: {
|
||||
auto &Op0 = MI.getOperand(0);
|
||||
auto &Op1 = MI.getOperand(1);
|
||||
const LLT Ty0 = MRI.getType(Op0.getReg());
|
||||
const LLT Ty1 = MRI.getType(Op1.getReg());
|
||||
OpRegBankIdx[0] = getPartialMappingIdx(MI, Ty0, /* isFP= */ true);
|
||||
OpRegBankIdx[1] = getPartialMappingIdx(MI, Ty1, /* isFP= */ false);
|
||||
break;
|
||||
}
|
||||
case TargetOpcode::G_SITOFP:
|
||||
case TargetOpcode::G_FPTOSI:
|
||||
case TargetOpcode::G_UITOFP:
|
||||
|
||||
@@ -844,13 +844,24 @@ def X86fldf80 : PatFrag<(ops node:$ptr), (X86fld node:$ptr), [{
|
||||
|
||||
def X86fild16 : PatFrag<(ops node:$ptr), (X86fild node:$ptr), [{
|
||||
return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i16;
|
||||
}]>;
|
||||
}]> {
|
||||
let IsLoad = true;
|
||||
let MemoryVT = i16;
|
||||
}
|
||||
|
||||
def X86fild32 : PatFrag<(ops node:$ptr), (X86fild node:$ptr), [{
|
||||
return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i32;
|
||||
}]>;
|
||||
}]> {
|
||||
let IsLoad = true;
|
||||
let MemoryVT = i32;
|
||||
}
|
||||
|
||||
def X86fild64 : PatFrag<(ops node:$ptr), (X86fild node:$ptr), [{
|
||||
return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i64;
|
||||
}]>;
|
||||
}]> {
|
||||
let IsLoad = true;
|
||||
let MemoryVT = i64;
|
||||
}
|
||||
|
||||
def X86fist32 : PatFrag<(ops node:$val, node:$ptr),
|
||||
(X86fist node:$val, node:$ptr), [{
|
||||
@@ -865,15 +876,26 @@ def X86fist64 : PatFrag<(ops node:$val, node:$ptr),
|
||||
def X86fp_to_i16mem : PatFrag<(ops node:$val, node:$ptr),
|
||||
(X86fp_to_mem node:$val, node:$ptr), [{
|
||||
return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i16;
|
||||
}]>;
|
||||
}]> {
|
||||
let IsStore = true;
|
||||
let MemoryVT = i16;
|
||||
}
|
||||
|
||||
def X86fp_to_i32mem : PatFrag<(ops node:$val, node:$ptr),
|
||||
(X86fp_to_mem node:$val, node:$ptr), [{
|
||||
return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i32;
|
||||
}]>;
|
||||
}]> {
|
||||
let IsStore = true;
|
||||
let MemoryVT = i32;
|
||||
}
|
||||
|
||||
def X86fp_to_i64mem : PatFrag<(ops node:$val, node:$ptr),
|
||||
(X86fp_to_mem node:$val, node:$ptr), [{
|
||||
return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i64;
|
||||
}]>;
|
||||
}]> {
|
||||
let IsStore = true;
|
||||
let MemoryVT = i64;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// FPStack pattern fragments
|
||||
|
||||
31
llvm/lib/Target/X86/X86InstrGISel.td
Normal file
31
llvm/lib/Target/X86/X86InstrGISel.td
Normal file
@@ -0,0 +1,31 @@
|
||||
//===- X86InstrGISel.td - X86 GISel target specific opcodes -*- tablegen -*===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// X86 GlobalISel target pseudo instruction definitions. This is kept
|
||||
// separately from the other tablegen files for organizational purposes, but
|
||||
// share the same infrastructure.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
class X86GenericInstruction : GenericInstruction { let Namespace = "X86"; }
|
||||
|
||||
def G_FILD : X86GenericInstruction {
|
||||
let OutOperandList = (outs type0:$dst);
|
||||
let InOperandList = (ins ptype1:$src);
|
||||
let hasSideEffects = false;
|
||||
let mayLoad = true;
|
||||
}
|
||||
def G_FIST : X86GenericInstruction {
|
||||
let OutOperandList = (outs);
|
||||
let InOperandList = (ins type0:$src1, ptype1:$src2);
|
||||
let hasSideEffects = false;
|
||||
let mayStore = true;
|
||||
}
|
||||
|
||||
def : GINodeEquiv<G_FILD, X86fild>;
|
||||
def : GINodeEquiv<G_FIST, X86fp_to_mem>;
|
||||
@@ -37,6 +37,11 @@ include "X86InstrFormats.td"
|
||||
//
|
||||
include "X86InstrUtils.td"
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Global ISel
|
||||
//
|
||||
include "X86InstrGISel.td"
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Subsystems.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
136
llvm/test/CodeGen/X86/GlobalISel/isel-fp64-to-sint-x86.mir
Normal file
136
llvm/test/CodeGen/X86/GlobalISel/isel-fp64-to-sint-x86.mir
Normal file
@@ -0,0 +1,136 @@
|
||||
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5
|
||||
# NOTE: This MIR test is required because the support for 64 bit memory ops is missing in X86 mode, Due to distinction between float/int types, support is expected in near future and there is this RFC in place https://discourse.llvm.org/t/rfc-globalisel-adding-fp-type-information-to-llt/83349. Once this support is introduced this test must be dropped and integrated into the LLVM IR tests.
|
||||
# RUN: llc -O2 -mtriple=i686-linux-gnu -mattr=+x87,-sse,-sse2 -run-pass=regbankselect,instruction-select -disable-gisel-legality-check -global-isel -verify-machineinstrs %s -o - | FileCheck %s --check-prefixes GISEL-X86
|
||||
|
||||
---
|
||||
name: test_double_to_int16
|
||||
alignment: 16
|
||||
exposesReturnsTwice: false
|
||||
legalized: true
|
||||
tracksRegLiveness: 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: 2, alignment: 2,
|
||||
stack-id: default, callee-saved-register: '', callee-saved-restored: true,
|
||||
debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
|
||||
|
||||
body: |
|
||||
bb.1.entry:
|
||||
; GISEL-X86-LABEL: name: test_double_to_int16
|
||||
; GISEL-X86: [[DEF:%[0-9]+]]:rfp64 = IMPLICIT_DEF
|
||||
; GISEL-X86-NEXT: FP64_TO_INT16_IN_MEM %stack.0, 1, $noreg, 0, $noreg, [[DEF]], implicit-def dead $eflags :: (store (s16) into %stack.0)
|
||||
; GISEL-X86-NEXT: [[MOV16rm:%[0-9]+]]:gr16 = MOV16rm %stack.0, 1, $noreg, 0, $noreg :: (load (s16) from %stack.0)
|
||||
; GISEL-X86-NEXT: $ax = COPY [[MOV16rm]]
|
||||
; GISEL-X86-NEXT: RET 0, implicit $ax
|
||||
%0:_(s64) = IMPLICIT_DEF
|
||||
%3:_(p0) = G_FRAME_INDEX %stack.0
|
||||
G_FIST %0(s64), %3(p0) :: (store (s16) into %stack.0)
|
||||
%2:_(s16) = G_LOAD %3(p0) :: (load (s16) from %stack.0)
|
||||
$ax = COPY %2(s16)
|
||||
RET 0, implicit $ax
|
||||
...
|
||||
---
|
||||
name: test_double_to_int32
|
||||
alignment: 16
|
||||
exposesReturnsTwice: false
|
||||
legalized: true
|
||||
tracksRegLiveness: 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: 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.entry:
|
||||
; GISEL-X86-LABEL: name: test_double_to_int32
|
||||
; GISEL-X86: [[DEF:%[0-9]+]]:rfp64 = IMPLICIT_DEF
|
||||
; GISEL-X86-NEXT: FP64_TO_INT32_IN_MEM %stack.0, 1, $noreg, 0, $noreg, [[DEF]], implicit-def dead $eflags :: (store (s32) into %stack.0)
|
||||
; GISEL-X86-NEXT: [[MOV32rm:%[0-9]+]]:gr32 = MOV32rm %stack.0, 1, $noreg, 0, $noreg :: (load (s32) from %stack.0)
|
||||
; GISEL-X86-NEXT: $eax = COPY [[MOV32rm]]
|
||||
; GISEL-X86-NEXT: RET 0, implicit $eax
|
||||
%0:_(s64) = IMPLICIT_DEF
|
||||
%3:_(p0) = G_FRAME_INDEX %stack.0
|
||||
G_FIST %0(s64), %3(p0) :: (store (s32) into %stack.0)
|
||||
%2:_(s32) = G_LOAD %3(p0) :: (load (s32) from %stack.0)
|
||||
$eax = COPY %2(s32)
|
||||
RET 0, implicit $eax
|
||||
...
|
||||
---
|
||||
name: test_double_to_int64
|
||||
alignment: 16
|
||||
exposesReturnsTwice: false
|
||||
legalized: true
|
||||
tracksRegLiveness: 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: '' }
|
||||
body: |
|
||||
bb.1.entry:
|
||||
; GISEL-X86-LABEL: name: test_double_to_int64
|
||||
; GISEL-X86: [[DEF:%[0-9]+]]:rfp64 = IMPLICIT_DEF
|
||||
; GISEL-X86-NEXT: [[LEA32r:%[0-9]+]]:gr32 = LEA32r %stack.0, 1, $noreg, 0, $noreg
|
||||
; GISEL-X86-NEXT: FP64_TO_INT64_IN_MEM %stack.0, 1, $noreg, 0, $noreg, [[DEF]], implicit-def dead $eflags :: (store (s64) into %stack.0)
|
||||
; GISEL-X86-NEXT: [[MOV32rm:%[0-9]+]]:gr32 = MOV32rm %stack.0, 1, $noreg, 0, $noreg :: (load (s32) from %stack.0, align 8)
|
||||
; GISEL-X86-NEXT: [[MOV32rm1:%[0-9]+]]:gr32 = MOV32rm [[LEA32r]], 1, $noreg, 4, $noreg :: (load (s32) from %stack.0 + 4, basealign 8)
|
||||
; GISEL-X86-NEXT: $eax = COPY [[MOV32rm]]
|
||||
; GISEL-X86-NEXT: $edx = COPY [[MOV32rm1]]
|
||||
; GISEL-X86-NEXT: RET 0, implicit $eax, implicit $edx
|
||||
%1:_(p0) = G_FRAME_INDEX %fixed-stack.0
|
||||
%10:_(s32) = G_LOAD %1(p0) :: (invariant load (s32) from %fixed-stack.0, align 16)
|
||||
%8:_(s32) = G_CONSTANT i32 4
|
||||
%11:_(p0) = G_PTR_ADD %1, %8(s32)
|
||||
%12:_(s32) = G_LOAD %11(p0) :: (invariant load (s32) from %fixed-stack.0 + 4, basealign 16)
|
||||
%0:_(s64) = IMPLICIT_DEF
|
||||
%5:_(p0) = G_FRAME_INDEX %stack.0
|
||||
G_FIST %0(s64), %5(p0) :: (store (s64) into %stack.0)
|
||||
%6:_(s32) = G_LOAD %5(p0) :: (load (s32) from %stack.0, align 8)
|
||||
%7:_(p0) = G_PTR_ADD %5, %8(s32)
|
||||
%9:_(s32) = G_LOAD %7(p0) :: (load (s32) from %stack.0 + 4, basealign 8)
|
||||
$eax = COPY %6(s32)
|
||||
$edx = COPY %9(s32)
|
||||
RET 0, implicit $eax, implicit $edx
|
||||
...
|
||||
---
|
||||
name: test_double_to_int8
|
||||
alignment: 16
|
||||
exposesReturnsTwice: false
|
||||
legalized: true
|
||||
tracksRegLiveness: 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: 2, alignment: 2,
|
||||
stack-id: default, callee-saved-register: '', callee-saved-restored: true,
|
||||
debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
|
||||
|
||||
body: |
|
||||
bb.1.entry:
|
||||
; GISEL-X86-LABEL: name: test_double_to_int8
|
||||
; GISEL-X86: [[DEF:%[0-9]+]]:rfp64 = IMPLICIT_DEF
|
||||
; GISEL-X86-NEXT: FP64_TO_INT16_IN_MEM %stack.0, 1, $noreg, 0, $noreg, [[DEF]], implicit-def dead $eflags :: (store (s16) into %stack.0)
|
||||
; GISEL-X86-NEXT: [[MOV16rm:%[0-9]+]]:gr16 = MOV16rm %stack.0, 1, $noreg, 0, $noreg :: (load (s16) from %stack.0)
|
||||
; GISEL-X86-NEXT: [[COPY:%[0-9]+]]:gr16_abcd = COPY [[MOV16rm]]
|
||||
; GISEL-X86-NEXT: [[COPY1:%[0-9]+]]:gr8_abcd_l = COPY [[COPY]].sub_8bit
|
||||
; GISEL-X86-NEXT: $al = COPY [[COPY1]]
|
||||
; GISEL-X86-NEXT: RET 0, implicit $al
|
||||
%0:_(s64) = IMPLICIT_DEF
|
||||
%4:_(p0) = G_FRAME_INDEX %stack.0
|
||||
G_FIST %0(s64), %4(p0) :: (store (s16) into %stack.0)
|
||||
%3:_(s16) = G_LOAD %4(p0) :: (load (s16) from %stack.0)
|
||||
%2:_(s8) = G_TRUNC %3(s16)
|
||||
$al = COPY %2(s8)
|
||||
RET 0, implicit $al
|
||||
152
llvm/test/CodeGen/X86/GlobalISel/isel-sint-to-fp64-x86.mir
Normal file
152
llvm/test/CodeGen/X86/GlobalISel/isel-sint-to-fp64-x86.mir
Normal file
@@ -0,0 +1,152 @@
|
||||
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5
|
||||
# NOTE: This MIR test is required because the support for 64 bit memory ops is missing in X86 mode, Due to distinction between float/int types, support is expected in near future and there is this RFC in place https://discourse.llvm.org/t/rfc-globalisel-adding-fp-type-information-to-llt/83349. Once this support is introduced this test must be dropped and integrated into the LLVM IR tests.
|
||||
# RUN: llc -O2 -mtriple=i686-linux-gnu -mattr=+x87,-sse,-sse2 -run-pass=regbankselect,instruction-select -disable-gisel-legality-check -global-isel -verify-machineinstrs %s -o - | FileCheck %s --check-prefixes GISEL-X86
|
||||
|
||||
---
|
||||
name: test_si8tofp64
|
||||
alignment: 16
|
||||
exposesReturnsTwice: false
|
||||
legalized: true
|
||||
tracksRegLiveness: true
|
||||
fixedStack:
|
||||
- { id: 0, type: default, offset: 4, size: 4, alignment: 4, stack-id: default,
|
||||
isImmutable: true, isAliased: false, callee-saved-register: '', callee-saved-restored: true,
|
||||
debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
|
||||
- { id: 1, type: default, offset: 0, size: 1, alignment: 4, 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: 2, alignment: 2,
|
||||
stack-id: default, callee-saved-register: '', callee-saved-restored: true,
|
||||
debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
|
||||
body: |
|
||||
bb.1.entry:
|
||||
; GISEL-X86-LABEL: name: test_si8tofp64
|
||||
; GISEL-X86: [[MOV32rm:%[0-9]+]]:gr32 = MOV32rm %fixed-stack.1, 1, $noreg, 0, $noreg :: (invariant load (p0) from %fixed-stack.1)
|
||||
; GISEL-X86-NEXT: [[DEF:%[0-9]+]]:gr16 = IMPLICIT_DEF
|
||||
; GISEL-X86-NEXT: MOV16mr %stack.0, 1, $noreg, 0, $noreg, [[DEF]] :: (store (s16) into %stack.0)
|
||||
; GISEL-X86-NEXT: [[ILD_Fp16m64_:%[0-9]+]]:rfp64 = ILD_Fp16m64 %stack.0, 1, $noreg, 0, $noreg, implicit-def dead $fpsw, implicit $fpcw :: (load (s16) from %stack.0)
|
||||
; GISEL-X86-NEXT: nofpexcept ST_Fp64m [[MOV32rm]], 1, $noreg, 0, $noreg, [[ILD_Fp16m64_]], implicit-def dead $fpsw, implicit $fpcw :: (store (s64))
|
||||
; GISEL-X86-NEXT: RET 0
|
||||
%4:_(p0) = G_FRAME_INDEX %fixed-stack.0
|
||||
%1:_(p0) = G_LOAD %4(p0) :: (invariant load (p0) from %fixed-stack.0)
|
||||
%6:_(s16) = IMPLICIT_DEF
|
||||
%7:_(p0) = G_FRAME_INDEX %stack.0
|
||||
G_STORE %6(s16), %7(p0) :: (store (s16) into %stack.0)
|
||||
%5:_(s64) = G_FILD %7(p0) :: (load (s16) from %stack.0)
|
||||
G_STORE %5(s64), %1(p0) :: (store (s64))
|
||||
RET 0
|
||||
...
|
||||
---
|
||||
name: test_si16tofp64
|
||||
alignment: 16
|
||||
legalized: true
|
||||
tracksRegLiveness: true
|
||||
fixedStack:
|
||||
- { id: 0, type: default, offset: 4, size: 4, alignment: 4, stack-id: default,
|
||||
isImmutable: true, isAliased: false, callee-saved-register: '', callee-saved-restored: true,
|
||||
debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
|
||||
- { id: 1, type: default, offset: 0, size: 2, alignment: 4, 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: 2, alignment: 2,
|
||||
stack-id: default, callee-saved-register: '', callee-saved-restored: true,
|
||||
debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
|
||||
body: |
|
||||
bb.1.entry:
|
||||
; GISEL-X86-LABEL: name: test_si16tofp64
|
||||
; GISEL-X86: [[DEF:%[0-9]+]]:gr16 = IMPLICIT_DEF
|
||||
; GISEL-X86-NEXT: [[MOV32rm:%[0-9]+]]:gr32 = MOV32rm %fixed-stack.1, 1, $noreg, 0, $noreg :: (invariant load (p0) from %fixed-stack.1)
|
||||
; GISEL-X86-NEXT: MOV16mr %stack.0, 1, $noreg, 0, $noreg, [[DEF]] :: (store (s16) into %stack.0)
|
||||
; GISEL-X86-NEXT: [[ILD_Fp16m64_:%[0-9]+]]:rfp64 = ILD_Fp16m64 %stack.0, 1, $noreg, 0, $noreg, implicit-def dead $fpsw, implicit $fpcw :: (load (s16) from %stack.0)
|
||||
; GISEL-X86-NEXT: nofpexcept ST_Fp64m [[MOV32rm]], 1, $noreg, 0, $noreg, [[ILD_Fp16m64_]], implicit-def dead $fpsw, implicit $fpcw :: (store (s64))
|
||||
; GISEL-X86-NEXT: RET 0
|
||||
%0:_(s16) = IMPLICIT_DEF
|
||||
%4:_(p0) = G_FRAME_INDEX %fixed-stack.0
|
||||
%1:_(p0) = G_LOAD %4(p0) :: (invariant load (p0) from %fixed-stack.0)
|
||||
%6:_(p0) = G_FRAME_INDEX %stack.0
|
||||
G_STORE %0(s16), %6(p0) :: (store (s16) into %stack.0)
|
||||
%5:_(s64) = G_FILD %6(p0):: (load (s16) from %stack.0)
|
||||
G_STORE %5(s64), %1(p0) :: (store (s64))
|
||||
RET 0
|
||||
...
|
||||
---
|
||||
name: test_si32tofp64
|
||||
alignment: 4
|
||||
exposesReturnsTwice: false
|
||||
legalized: true
|
||||
tracksRegLiveness: true
|
||||
fixedStack:
|
||||
- { id: 0, type: default, offset: 4, size: 4, alignment: 4, stack-id: default,
|
||||
isImmutable: true, isAliased: false, callee-saved-register: '', callee-saved-restored: true,
|
||||
debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
|
||||
- { id: 1, type: default, offset: 0, size: 4, alignment: 4, 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: '' }
|
||||
body: |
|
||||
bb.1.entry:
|
||||
; GISEL-X86-LABEL: name: test_si32tofp64
|
||||
; GISEL-X86: [[DEF:%[0-9]+]]:gr32 = IMPLICIT_DEF
|
||||
; GISEL-X86-NEXT: [[MOV32rm:%[0-9]+]]:gr32 = MOV32rm %fixed-stack.1, 1, $noreg, 0, $noreg :: (invariant load (p0) from %fixed-stack.1)
|
||||
; GISEL-X86-NEXT: MOV32mr %stack.0, 1, $noreg, 0, $noreg, [[DEF]] :: (store (s32) into %stack.0)
|
||||
; GISEL-X86-NEXT: [[ILD_Fp32m64_:%[0-9]+]]:rfp64 = ILD_Fp32m64 %stack.0, 1, $noreg, 0, $noreg, implicit-def dead $fpsw, implicit $fpcw :: (load (s32) from %stack.0)
|
||||
; GISEL-X86-NEXT: nofpexcept ST_Fp64m [[MOV32rm]], 1, $noreg, 0, $noreg, [[ILD_Fp32m64_]], implicit-def dead $fpsw, implicit $fpcw :: (store (s64))
|
||||
; GISEL-X86-NEXT: RET 0
|
||||
%0:_(s32) = IMPLICIT_DEF
|
||||
%3:_(p0) = G_FRAME_INDEX %fixed-stack.0
|
||||
%1:_(p0) = G_LOAD %3(p0) :: (invariant load (p0) from %fixed-stack.0)
|
||||
%5:_(p0) = G_FRAME_INDEX %stack.0
|
||||
G_STORE %0(s32), %5(p0) :: (store (s32) into %stack.0)
|
||||
%4:_(s64) = G_FILD %5(p0) :: (load (s32) from %stack.0)
|
||||
G_STORE %4(s64), %1(p0) :: (store (s64))
|
||||
RET 0
|
||||
...
|
||||
---
|
||||
name: test_si64tofp64
|
||||
alignment: 16
|
||||
exposesReturnsTwice: false
|
||||
legalized: true
|
||||
tracksRegLiveness: true
|
||||
fixedStack:
|
||||
- { id: 0, type: default, offset: 8, size: 4, alignment: 8, stack-id: default,
|
||||
isImmutable: true, isAliased: false, callee-saved-register: '', callee-saved-restored: true,
|
||||
debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
|
||||
- { id: 1, type: default, offset: 4, size: 4, alignment: 4, stack-id: default,
|
||||
isImmutable: true, isAliased: false, callee-saved-register: '', callee-saved-restored: true,
|
||||
debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
|
||||
- { id: 2, 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: 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.entry:
|
||||
; GISEL-X86-LABEL: name: test_si64tofp64
|
||||
; GISEL-X86: [[DEF:%[0-9]+]]:gr32 = IMPLICIT_DEF
|
||||
; GISEL-X86-NEXT: [[DEF1:%[0-9]+]]:gr32 = IMPLICIT_DEF
|
||||
; GISEL-X86-NEXT: [[MOV32rm:%[0-9]+]]:gr32 = MOV32rm %fixed-stack.2, 1, $noreg, 0, $noreg :: (invariant load (p0) from %fixed-stack.2, align 8)
|
||||
; GISEL-X86-NEXT: [[LEA32r:%[0-9]+]]:gr32 = LEA32r %stack.0, 1, $noreg, 0, $noreg
|
||||
; GISEL-X86-NEXT: MOV32mr %stack.0, 1, $noreg, 0, $noreg, [[DEF]] :: (store (s32) into %stack.0, align 8)
|
||||
; GISEL-X86-NEXT: MOV32mr [[LEA32r]], 1, $noreg, 4, $noreg, [[DEF1]] :: (store (s32) into %stack.0 + 4, basealign 8)
|
||||
; GISEL-X86-NEXT: [[ILD_Fp64m64_:%[0-9]+]]:rfp64 = ILD_Fp64m64 %stack.0, 1, $noreg, 0, $noreg, implicit-def dead $fpsw, implicit $fpcw :: (load (s64) from %stack.0)
|
||||
; GISEL-X86-NEXT: nofpexcept ST_Fp64m [[MOV32rm]], 1, $noreg, 0, $noreg, [[ILD_Fp64m64_]], implicit-def dead $fpsw, implicit $fpcw :: (store (s64))
|
||||
; GISEL-X86-NEXT: RET 0
|
||||
%2:_(s32) = IMPLICIT_DEF
|
||||
%3:_(s32) = IMPLICIT_DEF
|
||||
%6:_(p0) = G_FRAME_INDEX %fixed-stack.0
|
||||
%1:_(p0) = G_LOAD %6(p0) :: (invariant load (p0) from %fixed-stack.0, align 8)
|
||||
%8:_(p0) = G_FRAME_INDEX %stack.0
|
||||
G_STORE %2(s32), %8(p0) :: (store (s32) into %stack.0, align 8)
|
||||
%12:_(s32) = G_CONSTANT i32 4
|
||||
%11:_(p0) = G_PTR_ADD %8, %12(s32)
|
||||
G_STORE %3(s32), %11(p0) :: (store (s32) into %stack.0 + 4, basealign 8)
|
||||
%7:_(s64) = G_FILD %8(p0) :: (load (s64) from %stack.0)
|
||||
G_STORE %7(s64), %1(p0) :: (store (s64))
|
||||
RET 0
|
||||
@@ -2,71 +2,133 @@
|
||||
; NOTE: Fast Isel is not added because it does not support x87 stores.
|
||||
|
||||
; RUN: llc < %s -mtriple=x86_64-- -mattr=+x87,-sse,-sse2 -global-isel=0 | FileCheck %s --check-prefixes X64,SDAG-X64
|
||||
; RUN: llc < %s -mtriple=x86_64-- -mattr=+x87,-sse,-sse2 -global-isel -global-isel-abort=2 | FileCheck %s --check-prefixes X64,GISEL-X64
|
||||
; RUN: llc < %s -mtriple=x86_64-- -mattr=+x87,-sse,-sse2 -global-isel -global-isel-abort=1 | FileCheck %s --check-prefixes X64,GISEL-X64
|
||||
; RUN: llc < %s -mtriple=i686-- -mattr=+x87,-sse,-sse2 -global-isel=0 | FileCheck %s --check-prefixes X86,SDAG-X86
|
||||
; TODO: The last RUN line fails GISEL for f64/double cases and will fallback to DAG due to lack of support for
|
||||
; loads/stores in X86 mode, support is expected soon enough, for this reason the isel-fp64-to-sint-x86.mir test is added.
|
||||
; RUN: llc < %s -mtriple=i686-- -mattr=+x87,-sse,-sse2 -global-isel -global-isel-abort=2 | FileCheck %s --check-prefixes X86,GISEL-X86
|
||||
|
||||
define i8 @test_float_to_int8(float %input) nounwind {
|
||||
; X64-LABEL: test_float_to_int8:
|
||||
; X64: # %bb.0: # %entry
|
||||
; X64-NEXT: flds {{[0-9]+}}(%rsp)
|
||||
; X64-NEXT: fnstcw -{{[0-9]+}}(%rsp)
|
||||
; X64-NEXT: movzwl -{{[0-9]+}}(%rsp), %eax
|
||||
; X64-NEXT: orl $3072, %eax # imm = 0xC00
|
||||
; X64-NEXT: movw %ax, -{{[0-9]+}}(%rsp)
|
||||
; X64-NEXT: fldcw -{{[0-9]+}}(%rsp)
|
||||
; X64-NEXT: fistps -{{[0-9]+}}(%rsp)
|
||||
; X64-NEXT: fldcw -{{[0-9]+}}(%rsp)
|
||||
; X64-NEXT: movzbl -{{[0-9]+}}(%rsp), %eax
|
||||
; X64-NEXT: retq
|
||||
; SDAG-X64-LABEL: test_float_to_int8:
|
||||
; SDAG-X64: # %bb.0: # %entry
|
||||
; SDAG-X64-NEXT: flds {{[0-9]+}}(%rsp)
|
||||
; SDAG-X64-NEXT: fnstcw -{{[0-9]+}}(%rsp)
|
||||
; SDAG-X64-NEXT: movzwl -{{[0-9]+}}(%rsp), %eax
|
||||
; SDAG-X64-NEXT: orl $3072, %eax # imm = 0xC00
|
||||
; SDAG-X64-NEXT: movw %ax, -{{[0-9]+}}(%rsp)
|
||||
; SDAG-X64-NEXT: fldcw -{{[0-9]+}}(%rsp)
|
||||
; SDAG-X64-NEXT: fistps -{{[0-9]+}}(%rsp)
|
||||
; SDAG-X64-NEXT: fldcw -{{[0-9]+}}(%rsp)
|
||||
; SDAG-X64-NEXT: movzbl -{{[0-9]+}}(%rsp), %eax
|
||||
; SDAG-X64-NEXT: retq
|
||||
;
|
||||
; X86-LABEL: test_float_to_int8:
|
||||
; X86: # %bb.0: # %entry
|
||||
; X86-NEXT: subl $8, %esp
|
||||
; X86-NEXT: flds {{[0-9]+}}(%esp)
|
||||
; X86-NEXT: fnstcw {{[0-9]+}}(%esp)
|
||||
; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax
|
||||
; X86-NEXT: orl $3072, %eax # imm = 0xC00
|
||||
; X86-NEXT: movw %ax, {{[0-9]+}}(%esp)
|
||||
; X86-NEXT: fldcw {{[0-9]+}}(%esp)
|
||||
; X86-NEXT: fistps {{[0-9]+}}(%esp)
|
||||
; X86-NEXT: fldcw {{[0-9]+}}(%esp)
|
||||
; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax
|
||||
; X86-NEXT: addl $8, %esp
|
||||
; X86-NEXT: retl
|
||||
; GISEL-X64-LABEL: test_float_to_int8:
|
||||
; GISEL-X64: # %bb.0: # %entry
|
||||
; GISEL-X64-NEXT: flds {{[0-9]+}}(%rsp)
|
||||
; GISEL-X64-NEXT: fnstcw -{{[0-9]+}}(%rsp)
|
||||
; GISEL-X64-NEXT: movzwl -{{[0-9]+}}(%rsp), %eax
|
||||
; GISEL-X64-NEXT: orl $3072, %eax # imm = 0xC00
|
||||
; GISEL-X64-NEXT: movw %ax, -{{[0-9]+}}(%rsp)
|
||||
; GISEL-X64-NEXT: fldcw -{{[0-9]+}}(%rsp)
|
||||
; GISEL-X64-NEXT: fistps -{{[0-9]+}}(%rsp)
|
||||
; GISEL-X64-NEXT: fldcw -{{[0-9]+}}(%rsp)
|
||||
; GISEL-X64-NEXT: movzwl -{{[0-9]+}}(%rsp), %eax
|
||||
; GISEL-X64-NEXT: # kill: def $al killed $al killed $ax
|
||||
; GISEL-X64-NEXT: retq
|
||||
;
|
||||
; SDAG-X86-LABEL: test_float_to_int8:
|
||||
; SDAG-X86: # %bb.0: # %entry
|
||||
; SDAG-X86-NEXT: subl $8, %esp
|
||||
; SDAG-X86-NEXT: flds {{[0-9]+}}(%esp)
|
||||
; SDAG-X86-NEXT: fnstcw {{[0-9]+}}(%esp)
|
||||
; SDAG-X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax
|
||||
; SDAG-X86-NEXT: orl $3072, %eax # imm = 0xC00
|
||||
; SDAG-X86-NEXT: movw %ax, {{[0-9]+}}(%esp)
|
||||
; SDAG-X86-NEXT: fldcw {{[0-9]+}}(%esp)
|
||||
; SDAG-X86-NEXT: fistps {{[0-9]+}}(%esp)
|
||||
; SDAG-X86-NEXT: fldcw {{[0-9]+}}(%esp)
|
||||
; SDAG-X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax
|
||||
; SDAG-X86-NEXT: addl $8, %esp
|
||||
; SDAG-X86-NEXT: retl
|
||||
;
|
||||
; GISEL-X86-LABEL: test_float_to_int8:
|
||||
; GISEL-X86: # %bb.0: # %entry
|
||||
; GISEL-X86-NEXT: subl $8, %esp
|
||||
; GISEL-X86-NEXT: flds {{[0-9]+}}(%esp)
|
||||
; GISEL-X86-NEXT: fnstcw {{[0-9]+}}(%esp)
|
||||
; GISEL-X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax
|
||||
; GISEL-X86-NEXT: orl $3072, %eax # imm = 0xC00
|
||||
; GISEL-X86-NEXT: movw %ax, {{[0-9]+}}(%esp)
|
||||
; GISEL-X86-NEXT: fldcw {{[0-9]+}}(%esp)
|
||||
; GISEL-X86-NEXT: fistps {{[0-9]+}}(%esp)
|
||||
; GISEL-X86-NEXT: fldcw {{[0-9]+}}(%esp)
|
||||
; GISEL-X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax
|
||||
; GISEL-X86-NEXT: # kill: def $al killed $al killed $ax
|
||||
; GISEL-X86-NEXT: addl $8, %esp
|
||||
; GISEL-X86-NEXT: retl
|
||||
entry:
|
||||
%conv = fptosi float %input to i8
|
||||
ret i8 %conv
|
||||
}
|
||||
|
||||
define i8 @test_longdouble_to_int8(x86_fp80 %input) nounwind {
|
||||
; X64-LABEL: test_longdouble_to_int8:
|
||||
; X64: # %bb.0: # %entry
|
||||
; X64-NEXT: fldt {{[0-9]+}}(%rsp)
|
||||
; X64-NEXT: fnstcw -{{[0-9]+}}(%rsp)
|
||||
; X64-NEXT: movzwl -{{[0-9]+}}(%rsp), %eax
|
||||
; X64-NEXT: orl $3072, %eax # imm = 0xC00
|
||||
; X64-NEXT: movw %ax, -{{[0-9]+}}(%rsp)
|
||||
; X64-NEXT: fldcw -{{[0-9]+}}(%rsp)
|
||||
; X64-NEXT: fistps -{{[0-9]+}}(%rsp)
|
||||
; X64-NEXT: fldcw -{{[0-9]+}}(%rsp)
|
||||
; X64-NEXT: movzbl -{{[0-9]+}}(%rsp), %eax
|
||||
; X64-NEXT: retq
|
||||
; SDAG-X64-LABEL: test_longdouble_to_int8:
|
||||
; SDAG-X64: # %bb.0: # %entry
|
||||
; SDAG-X64-NEXT: fldt {{[0-9]+}}(%rsp)
|
||||
; SDAG-X64-NEXT: fnstcw -{{[0-9]+}}(%rsp)
|
||||
; SDAG-X64-NEXT: movzwl -{{[0-9]+}}(%rsp), %eax
|
||||
; SDAG-X64-NEXT: orl $3072, %eax # imm = 0xC00
|
||||
; SDAG-X64-NEXT: movw %ax, -{{[0-9]+}}(%rsp)
|
||||
; SDAG-X64-NEXT: fldcw -{{[0-9]+}}(%rsp)
|
||||
; SDAG-X64-NEXT: fistps -{{[0-9]+}}(%rsp)
|
||||
; SDAG-X64-NEXT: fldcw -{{[0-9]+}}(%rsp)
|
||||
; SDAG-X64-NEXT: movzbl -{{[0-9]+}}(%rsp), %eax
|
||||
; SDAG-X64-NEXT: retq
|
||||
;
|
||||
; X86-LABEL: test_longdouble_to_int8:
|
||||
; X86: # %bb.0: # %entry
|
||||
; X86-NEXT: subl $8, %esp
|
||||
; X86-NEXT: fldt {{[0-9]+}}(%esp)
|
||||
; X86-NEXT: fnstcw {{[0-9]+}}(%esp)
|
||||
; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax
|
||||
; X86-NEXT: orl $3072, %eax # imm = 0xC00
|
||||
; X86-NEXT: movw %ax, {{[0-9]+}}(%esp)
|
||||
; X86-NEXT: fldcw {{[0-9]+}}(%esp)
|
||||
; X86-NEXT: fistps {{[0-9]+}}(%esp)
|
||||
; X86-NEXT: fldcw {{[0-9]+}}(%esp)
|
||||
; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax
|
||||
; X86-NEXT: addl $8, %esp
|
||||
; X86-NEXT: retl
|
||||
; GISEL-X64-LABEL: test_longdouble_to_int8:
|
||||
; GISEL-X64: # %bb.0: # %entry
|
||||
; GISEL-X64-NEXT: fldt {{[0-9]+}}(%rsp)
|
||||
; GISEL-X64-NEXT: fnstcw -{{[0-9]+}}(%rsp)
|
||||
; GISEL-X64-NEXT: movzwl -{{[0-9]+}}(%rsp), %eax
|
||||
; GISEL-X64-NEXT: orl $3072, %eax # imm = 0xC00
|
||||
; GISEL-X64-NEXT: movw %ax, -{{[0-9]+}}(%rsp)
|
||||
; GISEL-X64-NEXT: fldcw -{{[0-9]+}}(%rsp)
|
||||
; GISEL-X64-NEXT: fistps -{{[0-9]+}}(%rsp)
|
||||
; GISEL-X64-NEXT: fldcw -{{[0-9]+}}(%rsp)
|
||||
; GISEL-X64-NEXT: movzwl -{{[0-9]+}}(%rsp), %eax
|
||||
; GISEL-X64-NEXT: # kill: def $al killed $al killed $ax
|
||||
; GISEL-X64-NEXT: retq
|
||||
;
|
||||
; SDAG-X86-LABEL: test_longdouble_to_int8:
|
||||
; SDAG-X86: # %bb.0: # %entry
|
||||
; SDAG-X86-NEXT: subl $8, %esp
|
||||
; SDAG-X86-NEXT: fldt {{[0-9]+}}(%esp)
|
||||
; SDAG-X86-NEXT: fnstcw {{[0-9]+}}(%esp)
|
||||
; SDAG-X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax
|
||||
; SDAG-X86-NEXT: orl $3072, %eax # imm = 0xC00
|
||||
; SDAG-X86-NEXT: movw %ax, {{[0-9]+}}(%esp)
|
||||
; SDAG-X86-NEXT: fldcw {{[0-9]+}}(%esp)
|
||||
; SDAG-X86-NEXT: fistps {{[0-9]+}}(%esp)
|
||||
; SDAG-X86-NEXT: fldcw {{[0-9]+}}(%esp)
|
||||
; SDAG-X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax
|
||||
; SDAG-X86-NEXT: addl $8, %esp
|
||||
; SDAG-X86-NEXT: retl
|
||||
;
|
||||
; GISEL-X86-LABEL: test_longdouble_to_int8:
|
||||
; GISEL-X86: # %bb.0: # %entry
|
||||
; GISEL-X86-NEXT: subl $8, %esp
|
||||
; GISEL-X86-NEXT: fldt {{[0-9]+}}(%esp)
|
||||
; GISEL-X86-NEXT: fnstcw {{[0-9]+}}(%esp)
|
||||
; GISEL-X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax
|
||||
; GISEL-X86-NEXT: orl $3072, %eax # imm = 0xC00
|
||||
; GISEL-X86-NEXT: movw %ax, {{[0-9]+}}(%esp)
|
||||
; GISEL-X86-NEXT: fldcw {{[0-9]+}}(%esp)
|
||||
; GISEL-X86-NEXT: fistps {{[0-9]+}}(%esp)
|
||||
; GISEL-X86-NEXT: fldcw {{[0-9]+}}(%esp)
|
||||
; GISEL-X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax
|
||||
; GISEL-X86-NEXT: # kill: def $al killed $al killed $ax
|
||||
; GISEL-X86-NEXT: addl $8, %esp
|
||||
; GISEL-X86-NEXT: retl
|
||||
entry:
|
||||
%conv = fptosi x86_fp80 %input to i8
|
||||
ret i8 %conv
|
||||
@@ -281,18 +343,32 @@ entry:
|
||||
}
|
||||
|
||||
define i8 @test_double_to_int8(double %input) nounwind {
|
||||
; X64-LABEL: test_double_to_int8:
|
||||
; X64: # %bb.0: # %entry
|
||||
; X64-NEXT: fldl {{[0-9]+}}(%rsp)
|
||||
; X64-NEXT: fnstcw -{{[0-9]+}}(%rsp)
|
||||
; X64-NEXT: movzwl -{{[0-9]+}}(%rsp), %eax
|
||||
; X64-NEXT: orl $3072, %eax # imm = 0xC00
|
||||
; X64-NEXT: movw %ax, -{{[0-9]+}}(%rsp)
|
||||
; X64-NEXT: fldcw -{{[0-9]+}}(%rsp)
|
||||
; X64-NEXT: fistps -{{[0-9]+}}(%rsp)
|
||||
; X64-NEXT: fldcw -{{[0-9]+}}(%rsp)
|
||||
; X64-NEXT: movzbl -{{[0-9]+}}(%rsp), %eax
|
||||
; X64-NEXT: retq
|
||||
; SDAG-X64-LABEL: test_double_to_int8:
|
||||
; SDAG-X64: # %bb.0: # %entry
|
||||
; SDAG-X64-NEXT: fldl {{[0-9]+}}(%rsp)
|
||||
; SDAG-X64-NEXT: fnstcw -{{[0-9]+}}(%rsp)
|
||||
; SDAG-X64-NEXT: movzwl -{{[0-9]+}}(%rsp), %eax
|
||||
; SDAG-X64-NEXT: orl $3072, %eax # imm = 0xC00
|
||||
; SDAG-X64-NEXT: movw %ax, -{{[0-9]+}}(%rsp)
|
||||
; SDAG-X64-NEXT: fldcw -{{[0-9]+}}(%rsp)
|
||||
; SDAG-X64-NEXT: fistps -{{[0-9]+}}(%rsp)
|
||||
; SDAG-X64-NEXT: fldcw -{{[0-9]+}}(%rsp)
|
||||
; SDAG-X64-NEXT: movzbl -{{[0-9]+}}(%rsp), %eax
|
||||
; SDAG-X64-NEXT: retq
|
||||
;
|
||||
; GISEL-X64-LABEL: test_double_to_int8:
|
||||
; GISEL-X64: # %bb.0: # %entry
|
||||
; GISEL-X64-NEXT: fldl {{[0-9]+}}(%rsp)
|
||||
; GISEL-X64-NEXT: fnstcw -{{[0-9]+}}(%rsp)
|
||||
; GISEL-X64-NEXT: movzwl -{{[0-9]+}}(%rsp), %eax
|
||||
; GISEL-X64-NEXT: orl $3072, %eax # imm = 0xC00
|
||||
; GISEL-X64-NEXT: movw %ax, -{{[0-9]+}}(%rsp)
|
||||
; GISEL-X64-NEXT: fldcw -{{[0-9]+}}(%rsp)
|
||||
; GISEL-X64-NEXT: fistps -{{[0-9]+}}(%rsp)
|
||||
; GISEL-X64-NEXT: fldcw -{{[0-9]+}}(%rsp)
|
||||
; GISEL-X64-NEXT: movzwl -{{[0-9]+}}(%rsp), %eax
|
||||
; GISEL-X64-NEXT: # kill: def $al killed $al killed $ax
|
||||
; GISEL-X64-NEXT: retq
|
||||
;
|
||||
; X86-LABEL: test_double_to_int8:
|
||||
; X86: # %bb.0: # %entry
|
||||
@@ -416,8 +492,4 @@ entry:
|
||||
%conv = fptosi double %input to i64
|
||||
ret i64 %conv
|
||||
}
|
||||
;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
|
||||
; GISEL-X86: {{.*}}
|
||||
; GISEL-X64: {{.*}}
|
||||
; SDAG-X86: {{.*}}
|
||||
; SDAG-X64: {{.*}}
|
||||
|
||||
|
||||
@@ -2,29 +2,53 @@
|
||||
; NOTE: Fast Isel is not added because it does not support x87 stores.
|
||||
|
||||
; RUN: llc < %s -mtriple=x86_64-- -mattr=+x87,-sse,-sse2 -global-isel=0 | FileCheck %s --check-prefixes X64,SDAG-X64
|
||||
; RUN: llc < %s -mtriple=x86_64-- -mattr=+x87,-sse,-sse2 -global-isel -global-isel-abort=2 | FileCheck %s --check-prefixes X64,GISEL-X64
|
||||
; RUN: llc < %s -mtriple=x86_64-- -mattr=+x87,-sse,-sse2 -global-isel -global-isel-abort=1 | FileCheck %s --check-prefixes X64,GISEL-X64
|
||||
; RUN: llc < %s -mtriple=i686-- -mattr=+x87,-sse,-sse2 -global-isel=0 | FileCheck %s --check-prefixes X86,SDAG-X86
|
||||
; TODO: The last RUN line fails GISEL for f64/double cases and will fallback to DAG due to lack of support for
|
||||
; loads/stores in X86 mode, support is expected soon enough, for this reason the isel-sint-to-fp64-x86.mir test is added.
|
||||
; RUN: llc < %s -mtriple=i686-- -mattr=+x87,-sse,-sse2 -global-isel -global-isel-abort=2 | FileCheck %s --check-prefixes X86,GISEL-X86
|
||||
|
||||
define void @test_int8_to_float(i8 %x, ptr %p) nounwind {
|
||||
; X64-LABEL: test_int8_to_float:
|
||||
; X64: # %bb.0: # %entry
|
||||
; X64-NEXT: movsbl %dil, %eax
|
||||
; X64-NEXT: movw %ax, -{{[0-9]+}}(%rsp)
|
||||
; X64-NEXT: filds -{{[0-9]+}}(%rsp)
|
||||
; X64-NEXT: fstps (%rsi)
|
||||
; X64-NEXT: retq
|
||||
; SDAG-X64-LABEL: test_int8_to_float:
|
||||
; SDAG-X64: # %bb.0: # %entry
|
||||
; SDAG-X64-NEXT: movsbl %dil, %eax
|
||||
; SDAG-X64-NEXT: movw %ax, -{{[0-9]+}}(%rsp)
|
||||
; SDAG-X64-NEXT: filds -{{[0-9]+}}(%rsp)
|
||||
; SDAG-X64-NEXT: fstps (%rsi)
|
||||
; SDAG-X64-NEXT: retq
|
||||
;
|
||||
; X86-LABEL: test_int8_to_float:
|
||||
; X86: # %bb.0: # %entry
|
||||
; X86-NEXT: pushl %eax
|
||||
; X86-NEXT: movsbl {{[0-9]+}}(%esp), %eax
|
||||
; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
|
||||
; X86-NEXT: movw %ax, {{[0-9]+}}(%esp)
|
||||
; X86-NEXT: filds {{[0-9]+}}(%esp)
|
||||
; X86-NEXT: fstps (%ecx)
|
||||
; X86-NEXT: popl %eax
|
||||
; X86-NEXT: retl
|
||||
; GISEL-X64-LABEL: test_int8_to_float:
|
||||
; GISEL-X64: # %bb.0: # %entry
|
||||
; GISEL-X64-NEXT: shlw $8, %di
|
||||
; GISEL-X64-NEXT: sarw $8, %di
|
||||
; GISEL-X64-NEXT: movw %di, -{{[0-9]+}}(%rsp)
|
||||
; GISEL-X64-NEXT: filds -{{[0-9]+}}(%rsp)
|
||||
; GISEL-X64-NEXT: fstps (%rsi)
|
||||
; GISEL-X64-NEXT: retq
|
||||
;
|
||||
; SDAG-X86-LABEL: test_int8_to_float:
|
||||
; SDAG-X86: # %bb.0: # %entry
|
||||
; SDAG-X86-NEXT: pushl %eax
|
||||
; SDAG-X86-NEXT: movsbl {{[0-9]+}}(%esp), %eax
|
||||
; SDAG-X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
|
||||
; SDAG-X86-NEXT: movw %ax, {{[0-9]+}}(%esp)
|
||||
; SDAG-X86-NEXT: filds {{[0-9]+}}(%esp)
|
||||
; SDAG-X86-NEXT: fstps (%ecx)
|
||||
; SDAG-X86-NEXT: popl %eax
|
||||
; SDAG-X86-NEXT: retl
|
||||
;
|
||||
; GISEL-X86-LABEL: test_int8_to_float:
|
||||
; GISEL-X86: # %bb.0: # %entry
|
||||
; GISEL-X86-NEXT: pushl %eax
|
||||
; GISEL-X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax
|
||||
; GISEL-X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
|
||||
; GISEL-X86-NEXT: shlw $8, %ax
|
||||
; GISEL-X86-NEXT: sarw $8, %ax
|
||||
; GISEL-X86-NEXT: movw %ax, {{[0-9]+}}(%esp)
|
||||
; GISEL-X86-NEXT: filds {{[0-9]+}}(%esp)
|
||||
; GISEL-X86-NEXT: fstps (%ecx)
|
||||
; GISEL-X86-NEXT: popl %eax
|
||||
; GISEL-X86-NEXT: retl
|
||||
entry:
|
||||
%conv = sitofp i8 %x to float
|
||||
store float %conv, ptr %p, align 4
|
||||
@@ -39,16 +63,27 @@ define void @test_int16_to_float(i16 %x, ptr %p) nounwind {
|
||||
; X64-NEXT: fstps (%rsi)
|
||||
; X64-NEXT: retq
|
||||
;
|
||||
; X86-LABEL: test_int16_to_float:
|
||||
; X86: # %bb.0: # %entry
|
||||
; X86-NEXT: pushl %eax
|
||||
; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
|
||||
; X86-NEXT: movzwl {{[0-9]+}}(%esp), %ecx
|
||||
; X86-NEXT: movw %cx, {{[0-9]+}}(%esp)
|
||||
; X86-NEXT: filds {{[0-9]+}}(%esp)
|
||||
; X86-NEXT: fstps (%eax)
|
||||
; X86-NEXT: popl %eax
|
||||
; X86-NEXT: retl
|
||||
; SDAG-X86-LABEL: test_int16_to_float:
|
||||
; SDAG-X86: # %bb.0: # %entry
|
||||
; SDAG-X86-NEXT: pushl %eax
|
||||
; SDAG-X86-NEXT: movl {{[0-9]+}}(%esp), %eax
|
||||
; SDAG-X86-NEXT: movzwl {{[0-9]+}}(%esp), %ecx
|
||||
; SDAG-X86-NEXT: movw %cx, {{[0-9]+}}(%esp)
|
||||
; SDAG-X86-NEXT: filds {{[0-9]+}}(%esp)
|
||||
; SDAG-X86-NEXT: fstps (%eax)
|
||||
; SDAG-X86-NEXT: popl %eax
|
||||
; SDAG-X86-NEXT: retl
|
||||
;
|
||||
; GISEL-X86-LABEL: test_int16_to_float:
|
||||
; GISEL-X86: # %bb.0: # %entry
|
||||
; GISEL-X86-NEXT: pushl %eax
|
||||
; GISEL-X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax
|
||||
; GISEL-X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
|
||||
; GISEL-X86-NEXT: movw %ax, {{[0-9]+}}(%esp)
|
||||
; GISEL-X86-NEXT: filds {{[0-9]+}}(%esp)
|
||||
; GISEL-X86-NEXT: fstps (%ecx)
|
||||
; GISEL-X86-NEXT: popl %eax
|
||||
; GISEL-X86-NEXT: retl
|
||||
entry:
|
||||
%conv = sitofp i16 %x to float
|
||||
store float %conv, ptr %p, align 4
|
||||
@@ -63,16 +98,27 @@ define void @test_int32_to_float(i32 %x, ptr %p) nounwind {
|
||||
; X64-NEXT: fstps (%rsi)
|
||||
; X64-NEXT: retq
|
||||
;
|
||||
; X86-LABEL: test_int32_to_float:
|
||||
; X86: # %bb.0: # %entry
|
||||
; X86-NEXT: pushl %eax
|
||||
; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
|
||||
; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
|
||||
; X86-NEXT: movl %ecx, (%esp)
|
||||
; X86-NEXT: fildl (%esp)
|
||||
; X86-NEXT: fstps (%eax)
|
||||
; X86-NEXT: popl %eax
|
||||
; X86-NEXT: retl
|
||||
; SDAG-X86-LABEL: test_int32_to_float:
|
||||
; SDAG-X86: # %bb.0: # %entry
|
||||
; SDAG-X86-NEXT: pushl %eax
|
||||
; SDAG-X86-NEXT: movl {{[0-9]+}}(%esp), %eax
|
||||
; SDAG-X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
|
||||
; SDAG-X86-NEXT: movl %ecx, (%esp)
|
||||
; SDAG-X86-NEXT: fildl (%esp)
|
||||
; SDAG-X86-NEXT: fstps (%eax)
|
||||
; SDAG-X86-NEXT: popl %eax
|
||||
; SDAG-X86-NEXT: retl
|
||||
;
|
||||
; GISEL-X86-LABEL: test_int32_to_float:
|
||||
; GISEL-X86: # %bb.0: # %entry
|
||||
; GISEL-X86-NEXT: pushl %eax
|
||||
; GISEL-X86-NEXT: movl {{[0-9]+}}(%esp), %eax
|
||||
; GISEL-X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
|
||||
; GISEL-X86-NEXT: movl %eax, (%esp)
|
||||
; GISEL-X86-NEXT: fildl (%esp)
|
||||
; GISEL-X86-NEXT: fstps (%ecx)
|
||||
; GISEL-X86-NEXT: popl %eax
|
||||
; GISEL-X86-NEXT: retl
|
||||
entry:
|
||||
%conv = sitofp i32 %x to float
|
||||
store float %conv, ptr %p, align 4
|
||||
@@ -100,21 +146,40 @@ entry:
|
||||
}
|
||||
|
||||
define x86_fp80 @test_int8to_longdouble(i8 %a) nounwind {
|
||||
; X64-LABEL: test_int8to_longdouble:
|
||||
; X64: # %bb.0:
|
||||
; X64-NEXT: movsbl %dil, %eax
|
||||
; X64-NEXT: movw %ax, -{{[0-9]+}}(%rsp)
|
||||
; X64-NEXT: filds -{{[0-9]+}}(%rsp)
|
||||
; X64-NEXT: retq
|
||||
; SDAG-X64-LABEL: test_int8to_longdouble:
|
||||
; SDAG-X64: # %bb.0:
|
||||
; SDAG-X64-NEXT: movsbl %dil, %eax
|
||||
; SDAG-X64-NEXT: movw %ax, -{{[0-9]+}}(%rsp)
|
||||
; SDAG-X64-NEXT: filds -{{[0-9]+}}(%rsp)
|
||||
; SDAG-X64-NEXT: retq
|
||||
;
|
||||
; X86-LABEL: test_int8to_longdouble:
|
||||
; X86: # %bb.0:
|
||||
; X86-NEXT: pushl %eax
|
||||
; X86-NEXT: movsbl {{[0-9]+}}(%esp), %eax
|
||||
; X86-NEXT: movw %ax, {{[0-9]+}}(%esp)
|
||||
; X86-NEXT: filds {{[0-9]+}}(%esp)
|
||||
; X86-NEXT: popl %eax
|
||||
; X86-NEXT: retl
|
||||
; GISEL-X64-LABEL: test_int8to_longdouble:
|
||||
; GISEL-X64: # %bb.0:
|
||||
; GISEL-X64-NEXT: shlw $8, %di
|
||||
; GISEL-X64-NEXT: sarw $8, %di
|
||||
; GISEL-X64-NEXT: movw %di, -{{[0-9]+}}(%rsp)
|
||||
; GISEL-X64-NEXT: filds -{{[0-9]+}}(%rsp)
|
||||
; GISEL-X64-NEXT: retq
|
||||
;
|
||||
; SDAG-X86-LABEL: test_int8to_longdouble:
|
||||
; SDAG-X86: # %bb.0:
|
||||
; SDAG-X86-NEXT: pushl %eax
|
||||
; SDAG-X86-NEXT: movsbl {{[0-9]+}}(%esp), %eax
|
||||
; SDAG-X86-NEXT: movw %ax, {{[0-9]+}}(%esp)
|
||||
; SDAG-X86-NEXT: filds {{[0-9]+}}(%esp)
|
||||
; SDAG-X86-NEXT: popl %eax
|
||||
; SDAG-X86-NEXT: retl
|
||||
;
|
||||
; GISEL-X86-LABEL: test_int8to_longdouble:
|
||||
; GISEL-X86: # %bb.0:
|
||||
; GISEL-X86-NEXT: pushl %eax
|
||||
; GISEL-X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax
|
||||
; GISEL-X86-NEXT: shlw $8, %ax
|
||||
; GISEL-X86-NEXT: sarw $8, %ax
|
||||
; GISEL-X86-NEXT: movw %ax, {{[0-9]+}}(%esp)
|
||||
; GISEL-X86-NEXT: filds {{[0-9]+}}(%esp)
|
||||
; GISEL-X86-NEXT: popl %eax
|
||||
; GISEL-X86-NEXT: retl
|
||||
%conv = sitofp i8 %a to x86_fp80
|
||||
ret x86_fp80 %conv
|
||||
}
|
||||
@@ -174,13 +239,22 @@ define x86_fp80 @test_int64_to_longdouble(i64 %a, ptr %p) nounwind {
|
||||
|
||||
|
||||
define void @test_int8to_double(i8 %x, ptr %p) nounwind {
|
||||
; X64-LABEL: test_int8to_double:
|
||||
; X64: # %bb.0: # %entry
|
||||
; X64-NEXT: movsbl %dil, %eax
|
||||
; X64-NEXT: movw %ax, -{{[0-9]+}}(%rsp)
|
||||
; X64-NEXT: filds -{{[0-9]+}}(%rsp)
|
||||
; X64-NEXT: fstpl (%rsi)
|
||||
; X64-NEXT: retq
|
||||
; SDAG-X64-LABEL: test_int8to_double:
|
||||
; SDAG-X64: # %bb.0: # %entry
|
||||
; SDAG-X64-NEXT: movsbl %dil, %eax
|
||||
; SDAG-X64-NEXT: movw %ax, -{{[0-9]+}}(%rsp)
|
||||
; SDAG-X64-NEXT: filds -{{[0-9]+}}(%rsp)
|
||||
; SDAG-X64-NEXT: fstpl (%rsi)
|
||||
; SDAG-X64-NEXT: retq
|
||||
;
|
||||
; GISEL-X64-LABEL: test_int8to_double:
|
||||
; GISEL-X64: # %bb.0: # %entry
|
||||
; GISEL-X64-NEXT: shlw $8, %di
|
||||
; GISEL-X64-NEXT: sarw $8, %di
|
||||
; GISEL-X64-NEXT: movw %di, -{{[0-9]+}}(%rsp)
|
||||
; GISEL-X64-NEXT: filds -{{[0-9]+}}(%rsp)
|
||||
; GISEL-X64-NEXT: fstpl (%rsi)
|
||||
; GISEL-X64-NEXT: retq
|
||||
;
|
||||
; X86-LABEL: test_int8to_double:
|
||||
; X86: # %bb.0: # %entry
|
||||
@@ -265,8 +339,3 @@ entry:
|
||||
store double %conv, ptr %p, align 4
|
||||
ret void
|
||||
}
|
||||
;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
|
||||
; GISEL-X86: {{.*}}
|
||||
; GISEL-X64: {{.*}}
|
||||
; SDAG-X86: {{.*}}
|
||||
; SDAG-X64: {{.*}}
|
||||
|
||||
Reference in New Issue
Block a user