From 1415d66424772a8147b6f5218ae2065335f0b2d0 Mon Sep 17 00:00:00 2001 From: Pawan Nirpal Date: Fri, 25 Apr 2025 20:02:05 +0200 Subject: [PATCH 01/10] [X86][GlobalISel] - Legalize And Select of G_FPTOSI/G_SITOFP in X87 mode --- .../X86/GISel/X86InstructionSelector.cpp | 13 +- .../lib/Target/X86/GISel/X86LegalizerInfo.cpp | 92 ++++- llvm/lib/Target/X86/GISel/X86LegalizerInfo.h | 6 + .../Target/X86/GISel/X86RegisterBankInfo.cpp | 12 + llvm/lib/Target/X86/X86InstrFragments.td | 28 +- llvm/lib/Target/X86/X86InstrGISel.td | 31 ++ llvm/lib/Target/X86/X86InstrInfo.td | 5 + .../X86/GlobalISel/isel-fp64-to-sint-x86.mir | 136 ++++++++ .../X86/GlobalISel/isel-sint-to-fp64-x86.mir | 152 ++++++++ llvm/test/CodeGen/X86/isel-fp-to-sint-x87.ll | 330 ++++++++++++------ llvm/test/CodeGen/X86/isel-sint-to-fp-x87.ll | 253 ++++++++++---- 11 files changed, 866 insertions(+), 192 deletions(-) create mode 100644 llvm/lib/Target/X86/X86InstrGISel.td create mode 100644 llvm/test/CodeGen/X86/GlobalISel/isel-fp64-to-sint-x86.mir create mode 100644 llvm/test/CodeGen/X86/GlobalISel/isel-sint-to-fp64-x86.mir diff --git a/llvm/lib/Target/X86/GISel/X86InstructionSelector.cpp b/llvm/lib/Target/X86/GISel/X86InstructionSelector.cpp index ea08f71b8af4a..f409ec0c921fd 100644 --- a/llvm/lib/Target/X86/GISel/X86InstructionSelector.cpp +++ b/llvm/lib/Target/X86/GISel/X86InstructionSelector.cpp @@ -77,6 +77,8 @@ class X86InstructionSelector : public InstructionSelector { unsigned getPtrLoadStoreOp(const LLT &Ty, const RegisterBank &RB, unsigned Opc) const; + bool checkMemoryOpSize(const MachineInstr &MI, unsigned NumBytes) const; + bool selectLoadStoreOp(MachineInstr &I, MachineRegisterInfo &MRI, MachineFunction &MF) const; bool selectFrameIndexOrGep(MachineInstr &I, MachineRegisterInfo &MRI, @@ -355,6 +357,15 @@ bool X86InstructionSelector::selectCopy(MachineInstr &I, return true; } +bool X86InstructionSelector::checkMemoryOpSize(const MachineInstr &MI, + unsigned NumBytes) const { + if (!MI.mayLoadOrStore()) + return false; + assert(MI.hasOneMemOperand() && + "Expected load/store to have only one mem op!"); + return (*MI.memoperands_begin())->getSize() == NumBytes; +} + bool X86InstructionSelector::select(MachineInstr &I) { assert(I.getParent() && "Instruction should be in a basic block!"); assert(I.getParent()->getParent() && "Instruction should be in a function!"); @@ -364,7 +375,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) diff --git a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp index f008cb1bea839..84e95cc40b9e8 100644 --- a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp +++ b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp @@ -17,6 +17,7 @@ #include "llvm/CodeGen/GlobalISel/LegalizerHelper.h" #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" #include "llvm/CodeGen/MachineConstantPool.h" +#include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/TargetOpcodes.h" #include "llvm/CodeGen/ValueTypes.h" #include "llvm/IR/DerivedTypes.h" @@ -498,7 +499,16 @@ X86LegalizerInfo::X86LegalizerInfo(const X86Subtarget &STI, (typePairInSet(0, 1, {{s64, s32}})(Query) || (Is64Bit && typePairInSet(0, 1, {{s64, s64}})(Query)))); }) - .clampScalar(1, s32, sMaxScalar) + .customIf([=](const LegalityQuery &Query) -> bool { + if (!UseX87) + return false; + if ((typeIs(0, s32)(Query) && HasSSE1) || + (typeIs(0, s64)(Query) && HasSSE2)) + return false; + return typeInSet(0, {s32, s64, s80})(Query) && + typeInSet(1, {s16, s32, s64})(Query); + }) + .clampScalar(1, (UseX87 && !HasSSE1) ? s16 : s32, sMaxScalar) .widenScalarToNextPow2(1) .clampScalar(0, s32, HasSSE2 ? s64 : s32) .widenScalarToNextPow2(0); @@ -512,9 +522,18 @@ X86LegalizerInfo::X86LegalizerInfo(const X86Subtarget &STI, (typePairInSet(0, 1, {{s32, s64}})(Query) || (Is64Bit && typePairInSet(0, 1, {{s64, s64}})(Query)))); }) - .clampScalar(1, s32, HasSSE2 ? s64 : s32) + .customIf([=](const LegalityQuery &Query) -> bool { + if (!UseX87) + return false; + if ((typeIs(1, s32)(Query) && HasSSE1) || + (typeIs(1, s64)(Query) && HasSSE2)) + return false; + return typeInSet(0, {s16, s32, s64})(Query) && + typeInSet(1, {s32, s64, s80})(Query); + }) + .clampScalar(0, (UseX87 && !HasSSE1) ? s16 : s32, sMaxScalar) .widenScalarToNextPow2(0) - .clampScalar(0, s32, sMaxScalar) + .clampScalar(1, s32, HasSSE2 ? s64 : s32) .widenScalarToNextPow2(1); // For G_UITOFP and G_FPTOUI without AVX512, we have to custom legalize types @@ -671,10 +690,77 @@ 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."); + + const LLT p0 = LLT::pointer(0, MF.getTarget().getPointerSizeInBits(0)); + int MemSize = SrcTy.getSizeInBytes(); + int StackSlot = + MF.getFrameInfo().CreateStackObject(MemSize, Align(MemSize), false); + + auto SlotPointer = MIRBuilder.buildFrameIndex(p0, StackSlot); + MachinePointerInfo PtrInfo = MachinePointerInfo::getFixedStack(MF, StackSlot); + 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; + const LLT p0 = LLT::pointer(0, MF.getTarget().getPointerSizeInBits(0)); + auto [Dst, DstTy, Src, SrcTy] = MI.getFirst2RegLLTs(); + + unsigned MemSize = DstTy.getSizeInBytes(); + int StackSlot = + MF.getFrameInfo().CreateStackObject(MemSize, Align(MemSize), false); + + auto SlotPointer = MIRBuilder.buildFrameIndex(p0, StackSlot); + + MachinePointerInfo PtrInfo = MachinePointerInfo::getFixedStack(MF, StackSlot); + 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 { diff --git a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.h b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.h index 54f776456397b..1ba82674ed4c6 100644 --- a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.h +++ b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.h @@ -48,6 +48,12 @@ class X86LegalizerInfo : public LegalizerInfo { 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 diff --git a/llvm/lib/Target/X86/GISel/X86RegisterBankInfo.cpp b/llvm/lib/Target/X86/GISel/X86RegisterBankInfo.cpp index 0baca81494694..74fe5fcaab6cc 100644 --- a/llvm/lib/Target/X86/GISel/X86RegisterBankInfo.cpp +++ b/llvm/lib/Target/X86/GISel/X86RegisterBankInfo.cpp @@ -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: diff --git a/llvm/lib/Target/X86/X86InstrFragments.td b/llvm/lib/Target/X86/X86InstrFragments.td index f9d70d1bb5d85..00af5b1f50733 100644 --- a/llvm/lib/Target/X86/X86InstrFragments.td +++ b/llvm/lib/Target/X86/X86InstrFragments.td @@ -841,13 +841,21 @@ def X86fldf80 : PatFrag<(ops node:$ptr), (X86fld node:$ptr), [{ def X86fild16 : PatFrag<(ops node:$ptr), (X86fild node:$ptr), [{ return cast(N)->getMemoryVT() == MVT::i16; -}]>; +}]> { + let GISelPredicateCode = [{ return checkMemoryOpSize(MI, 2); }]; +} + def X86fild32 : PatFrag<(ops node:$ptr), (X86fild node:$ptr), [{ return cast(N)->getMemoryVT() == MVT::i32; -}]>; +}]> { + let GISelPredicateCode = [{ return checkMemoryOpSize(MI, 4); }]; +} + def X86fild64 : PatFrag<(ops node:$ptr), (X86fild node:$ptr), [{ return cast(N)->getMemoryVT() == MVT::i64; -}]>; +}]> { + let GISelPredicateCode = [{ return checkMemoryOpSize(MI, 8); }]; +} def X86fist32 : PatFrag<(ops node:$val, node:$ptr), (X86fist node:$val, node:$ptr), [{ @@ -862,15 +870,23 @@ 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(N)->getMemoryVT() == MVT::i16; -}]>; +}]> { + let GISelPredicateCode = [{ return checkMemoryOpSize(MI, 2); }]; +} + def X86fp_to_i32mem : PatFrag<(ops node:$val, node:$ptr), (X86fp_to_mem node:$val, node:$ptr), [{ return cast(N)->getMemoryVT() == MVT::i32; -}]>; +}]> { + let GISelPredicateCode = [{ return checkMemoryOpSize(MI, 4); }]; +} + def X86fp_to_i64mem : PatFrag<(ops node:$val, node:$ptr), (X86fp_to_mem node:$val, node:$ptr), [{ return cast(N)->getMemoryVT() == MVT::i64; -}]>; +}]> { + let GISelPredicateCode = [{ return checkMemoryOpSize(MI, 8); }]; +} //===----------------------------------------------------------------------===// // FPStack pattern fragments diff --git a/llvm/lib/Target/X86/X86InstrGISel.td b/llvm/lib/Target/X86/X86InstrGISel.td new file mode 100644 index 0000000000000..7f5d92f43b0bb --- /dev/null +++ b/llvm/lib/Target/X86/X86InstrGISel.td @@ -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; +def : GINodeEquiv; \ No newline at end of file diff --git a/llvm/lib/Target/X86/X86InstrInfo.td b/llvm/lib/Target/X86/X86InstrInfo.td index e75d6743f9273..7f6c5614847e3 100644 --- a/llvm/lib/Target/X86/X86InstrInfo.td +++ b/llvm/lib/Target/X86/X86InstrInfo.td @@ -37,6 +37,11 @@ include "X86InstrFormats.td" // include "X86InstrUtils.td" +//===----------------------------------------------------------------------===// +// Global ISel +// +include "X86InstrGISel.td" + //===----------------------------------------------------------------------===// // Subsystems. //===----------------------------------------------------------------------===// diff --git a/llvm/test/CodeGen/X86/GlobalISel/isel-fp64-to-sint-x86.mir b/llvm/test/CodeGen/X86/GlobalISel/isel-fp64-to-sint-x86.mir new file mode 100644 index 0000000000000..3e1af9d836aec --- /dev/null +++ b/llvm/test/CodeGen/X86/GlobalISel/isel-fp64-to-sint-x86.mir @@ -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 diff --git a/llvm/test/CodeGen/X86/GlobalISel/isel-sint-to-fp64-x86.mir b/llvm/test/CodeGen/X86/GlobalISel/isel-sint-to-fp64-x86.mir new file mode 100644 index 0000000000000..b6b2bd610fa3b --- /dev/null +++ b/llvm/test/CodeGen/X86/GlobalISel/isel-sint-to-fp64-x86.mir @@ -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 diff --git a/llvm/test/CodeGen/X86/isel-fp-to-sint-x87.ll b/llvm/test/CodeGen/X86/isel-fp-to-sint-x87.ll index b0400dff1d3d4..1421b9cc4c146 100644 --- a/llvm/test/CodeGen/X86/isel-fp-to-sint-x87.ll +++ b/llvm/test/CodeGen/X86/isel-fp-to-sint-x87.ll @@ -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 @@ -218,25 +280,46 @@ define i64 @test_float_to_int64(float %input) nounwind { ; X64-NEXT: movq -{{[0-9]+}}(%rsp), %rax ; X64-NEXT: retq ; -; X86-LABEL: test_float_to_int64: -; X86: # %bb.0: # %entry -; X86-NEXT: pushl %ebp -; X86-NEXT: movl %esp, %ebp -; X86-NEXT: andl $-8, %esp -; X86-NEXT: subl $16, %esp -; X86-NEXT: flds 8(%ebp) -; 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: fistpll {{[0-9]+}}(%esp) -; X86-NEXT: fldcw {{[0-9]+}}(%esp) -; X86-NEXT: movl {{[0-9]+}}(%esp), %eax -; X86-NEXT: movl {{[0-9]+}}(%esp), %edx -; X86-NEXT: movl %ebp, %esp -; X86-NEXT: popl %ebp -; X86-NEXT: retl +; SDAG-X86-LABEL: test_float_to_int64: +; SDAG-X86: # %bb.0: # %entry +; SDAG-X86-NEXT: pushl %ebp +; SDAG-X86-NEXT: movl %esp, %ebp +; SDAG-X86-NEXT: andl $-8, %esp +; SDAG-X86-NEXT: subl $16, %esp +; SDAG-X86-NEXT: flds 8(%ebp) +; 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: fistpll {{[0-9]+}}(%esp) +; SDAG-X86-NEXT: fldcw {{[0-9]+}}(%esp) +; SDAG-X86-NEXT: movl {{[0-9]+}}(%esp), %eax +; SDAG-X86-NEXT: movl {{[0-9]+}}(%esp), %edx +; SDAG-X86-NEXT: movl %ebp, %esp +; SDAG-X86-NEXT: popl %ebp +; SDAG-X86-NEXT: retl +; +; GISEL-X86-LABEL: test_float_to_int64: +; GISEL-X86: # %bb.0: # %entry +; GISEL-X86-NEXT: pushl %ebp +; GISEL-X86-NEXT: movl %esp, %ebp +; GISEL-X86-NEXT: andl $-8, %esp +; GISEL-X86-NEXT: subl $16, %esp +; GISEL-X86-NEXT: flds 8(%ebp) +; GISEL-X86-NEXT: leal {{[0-9]+}}(%esp), %ecx +; 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: fistpll {{[0-9]+}}(%esp) +; GISEL-X86-NEXT: fldcw {{[0-9]+}}(%esp) +; GISEL-X86-NEXT: movl {{[0-9]+}}(%esp), %eax +; GISEL-X86-NEXT: movl 4(%ecx), %edx +; GISEL-X86-NEXT: movl %ebp, %esp +; GISEL-X86-NEXT: popl %ebp +; GISEL-X86-NEXT: retl entry: %conv = fptosi float %input to i64 ret i64 %conv @@ -256,43 +339,78 @@ define i64 @test_longdouble_to_int64(x86_fp80 %input) nounwind { ; X64-NEXT: movq -{{[0-9]+}}(%rsp), %rax ; X64-NEXT: retq ; -; X86-LABEL: test_longdouble_to_int64: -; X86: # %bb.0: # %entry -; X86-NEXT: pushl %ebp -; X86-NEXT: movl %esp, %ebp -; X86-NEXT: andl $-8, %esp -; X86-NEXT: subl $16, %esp -; X86-NEXT: fldt 8(%ebp) -; 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: fistpll {{[0-9]+}}(%esp) -; X86-NEXT: fldcw {{[0-9]+}}(%esp) -; X86-NEXT: movl {{[0-9]+}}(%esp), %eax -; X86-NEXT: movl {{[0-9]+}}(%esp), %edx -; X86-NEXT: movl %ebp, %esp -; X86-NEXT: popl %ebp -; X86-NEXT: retl +; SDAG-X86-LABEL: test_longdouble_to_int64: +; SDAG-X86: # %bb.0: # %entry +; SDAG-X86-NEXT: pushl %ebp +; SDAG-X86-NEXT: movl %esp, %ebp +; SDAG-X86-NEXT: andl $-8, %esp +; SDAG-X86-NEXT: subl $16, %esp +; SDAG-X86-NEXT: fldt 8(%ebp) +; 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: fistpll {{[0-9]+}}(%esp) +; SDAG-X86-NEXT: fldcw {{[0-9]+}}(%esp) +; SDAG-X86-NEXT: movl {{[0-9]+}}(%esp), %eax +; SDAG-X86-NEXT: movl {{[0-9]+}}(%esp), %edx +; SDAG-X86-NEXT: movl %ebp, %esp +; SDAG-X86-NEXT: popl %ebp +; SDAG-X86-NEXT: retl +; +; GISEL-X86-LABEL: test_longdouble_to_int64: +; GISEL-X86: # %bb.0: # %entry +; GISEL-X86-NEXT: pushl %ebp +; GISEL-X86-NEXT: movl %esp, %ebp +; GISEL-X86-NEXT: andl $-8, %esp +; GISEL-X86-NEXT: subl $16, %esp +; GISEL-X86-NEXT: fldt 8(%ebp) +; GISEL-X86-NEXT: leal {{[0-9]+}}(%esp), %ecx +; 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: fistpll {{[0-9]+}}(%esp) +; GISEL-X86-NEXT: fldcw {{[0-9]+}}(%esp) +; GISEL-X86-NEXT: movl {{[0-9]+}}(%esp), %eax +; GISEL-X86-NEXT: movl 4(%ecx), %edx +; GISEL-X86-NEXT: movl %ebp, %esp +; GISEL-X86-NEXT: popl %ebp +; GISEL-X86-NEXT: retl entry: %conv = fptosi x86_fp80 %input to i64 ret i64 %conv } 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 +534,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: {{.*}} + diff --git a/llvm/test/CodeGen/X86/isel-sint-to-fp-x87.ll b/llvm/test/CodeGen/X86/isel-sint-to-fp-x87.ll index 6e8461598d5e8..68eee6c0162db 100644 --- a/llvm/test/CodeGen/X86/isel-sint-to-fp-x87.ll +++ b/llvm/test/CodeGen/X86/isel-sint-to-fp-x87.ll @@ -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 @@ -87,12 +133,32 @@ define void @test_int64_to_float(i64 %x, ptr %p) nounwind { ; X64-NEXT: fstps (%rsi) ; X64-NEXT: retq ; -; X86-LABEL: test_int64_to_float: -; X86: # %bb.0: # %entry -; X86-NEXT: movl {{[0-9]+}}(%esp), %eax -; X86-NEXT: fildll {{[0-9]+}}(%esp) -; X86-NEXT: fstps (%eax) -; X86-NEXT: retl +; SDAG-X86-LABEL: test_int64_to_float: +; SDAG-X86: # %bb.0: # %entry +; SDAG-X86-NEXT: movl {{[0-9]+}}(%esp), %eax +; SDAG-X86-NEXT: fildll {{[0-9]+}}(%esp) +; SDAG-X86-NEXT: fstps (%eax) +; SDAG-X86-NEXT: retl +; +; GISEL-X86-LABEL: test_int64_to_float: +; GISEL-X86: # %bb.0: # %entry +; GISEL-X86-NEXT: pushl %ebp +; GISEL-X86-NEXT: movl %esp, %ebp +; GISEL-X86-NEXT: pushl %esi +; GISEL-X86-NEXT: andl $-8, %esp +; GISEL-X86-NEXT: subl $16, %esp +; GISEL-X86-NEXT: movl 8(%ebp), %eax +; GISEL-X86-NEXT: movl 12(%ebp), %ecx +; GISEL-X86-NEXT: movl 16(%ebp), %edx +; GISEL-X86-NEXT: movl %esp, %esi +; GISEL-X86-NEXT: movl %eax, (%esp) +; GISEL-X86-NEXT: movl %ecx, 4(%esi) +; GISEL-X86-NEXT: fildll (%esp) +; GISEL-X86-NEXT: fstps (%edx) +; GISEL-X86-NEXT: leal -4(%ebp), %esp +; GISEL-X86-NEXT: popl %esi +; GISEL-X86-NEXT: popl %ebp +; GISEL-X86-NEXT: retl entry: %conv = sitofp i64 %x to float store float %conv, ptr %p, align 4 @@ -100,21 +166,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 } @@ -164,23 +249,48 @@ define x86_fp80 @test_int64_to_longdouble(i64 %a, ptr %p) nounwind { ; X64-NEXT: fildll -{{[0-9]+}}(%rsp) ; X64-NEXT: retq ; -; X86-LABEL: test_int64_to_longdouble: -; X86: # %bb.0: -; X86-NEXT: fildll {{[0-9]+}}(%esp) -; X86-NEXT: retl +; SDAG-X86-LABEL: test_int64_to_longdouble: +; SDAG-X86: # %bb.0: +; SDAG-X86-NEXT: fildll {{[0-9]+}}(%esp) +; SDAG-X86-NEXT: retl +; +; GISEL-X86-LABEL: test_int64_to_longdouble: +; GISEL-X86: # %bb.0: +; GISEL-X86-NEXT: pushl %ebp +; GISEL-X86-NEXT: movl %esp, %ebp +; GISEL-X86-NEXT: andl $-8, %esp +; GISEL-X86-NEXT: subl $8, %esp +; GISEL-X86-NEXT: movl 8(%ebp), %eax +; GISEL-X86-NEXT: movl 12(%ebp), %ecx +; GISEL-X86-NEXT: movl %esp, %edx +; GISEL-X86-NEXT: movl %eax, (%esp) +; GISEL-X86-NEXT: movl %ecx, 4(%edx) +; GISEL-X86-NEXT: fildll (%esp) +; GISEL-X86-NEXT: movl %ebp, %esp +; GISEL-X86-NEXT: popl %ebp +; GISEL-X86-NEXT: retl %conv = sitofp i64 %a to x86_fp80 ret x86_fp80 %conv } 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 +375,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: {{.*}} From 2dcb0579fc3a862445499d9855b4e2564e2f2fef Mon Sep 17 00:00:00 2001 From: Pawan Nirpal Date: Tue, 13 May 2025 12:14:55 +0200 Subject: [PATCH 02/10] addressing cmts --- .../X86/GISel/X86InstructionSelector.cpp | 8 +- .../lib/Target/X86/GISel/X86LegalizerInfo.cpp | 83 ++++++++----------- llvm/lib/Target/X86/X86InstrFragments.td | 12 +-- 3 files changed, 43 insertions(+), 60 deletions(-) diff --git a/llvm/lib/Target/X86/GISel/X86InstructionSelector.cpp b/llvm/lib/Target/X86/GISel/X86InstructionSelector.cpp index f409ec0c921fd..7ff6f2aac5a30 100644 --- a/llvm/lib/Target/X86/GISel/X86InstructionSelector.cpp +++ b/llvm/lib/Target/X86/GISel/X86InstructionSelector.cpp @@ -77,7 +77,7 @@ class X86InstructionSelector : public InstructionSelector { unsigned getPtrLoadStoreOp(const LLT &Ty, const RegisterBank &RB, unsigned Opc) const; - bool checkMemoryOpSize(const MachineInstr &MI, unsigned NumBytes) const; + bool checkMemoryOpSize(const MachineInstr &MI, LLT Sz) const; bool selectLoadStoreOp(MachineInstr &I, MachineRegisterInfo &MRI, MachineFunction &MF) const; @@ -358,12 +358,10 @@ bool X86InstructionSelector::selectCopy(MachineInstr &I, } bool X86InstructionSelector::checkMemoryOpSize(const MachineInstr &MI, - unsigned NumBytes) const { - if (!MI.mayLoadOrStore()) - return false; + LLT Sz) const { assert(MI.hasOneMemOperand() && "Expected load/store to have only one mem op!"); - return (*MI.memoperands_begin())->getSize() == NumBytes; + return (*MI.memoperands_begin())->getMemoryType() == Sz; } bool X86InstructionSelector::select(MachineInstr &I) { diff --git a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp index 84e95cc40b9e8..9cf6a87c9eda4 100644 --- a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp +++ b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp @@ -491,46 +491,38 @@ 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)))); - }) - .customIf([=](const LegalityQuery &Query) -> bool { - if (!UseX87) - return false; - if ((typeIs(0, s32)(Query) && HasSSE1) || - (typeIs(0, s64)(Query) && HasSSE2)) - return false; - return typeInSet(0, {s32, s64, s80})(Query) && - typeInSet(1, {s16, s32, s64})(Query); - }) + .legalFor(HasSSE1, {s32, s32}) + .legalFor(HasSSE1 && Is64Bit, {s32, s64}) + .legalFor(HasSSE2, {s64, s32}) + .legalFor(HasSSE2 && Is64Bit, {s64, s64}) + .customFor(UseX87, {{s32, s16}, + {s32, s32}, + {s32, s64}, + {s64, s16}, + {s64, s32}, + {s64, s64}, + {s80, s16}, + {s80, s32}, + {s80, s64}}) .clampScalar(1, (UseX87 && !HasSSE1) ? s16 : s32, sMaxScalar) .widenScalarToNextPow2(1) .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)))); - }) - .customIf([=](const LegalityQuery &Query) -> bool { - if (!UseX87) - return false; - if ((typeIs(1, s32)(Query) && HasSSE1) || - (typeIs(1, s64)(Query) && HasSSE2)) - return false; - return typeInSet(0, {s16, s32, s64})(Query) && - typeInSet(1, {s32, s64, s80})(Query); - }) + .legalFor(HasSSE1, {s32, s32}) + .legalFor(HasSSE1 && Is64Bit, {s64, s32}) + .legalFor(HasSSE2, {s32, s64}) + .legalFor(HasSSE2 && Is64Bit, {s64, s64}) + .customFor(UseX87, {{s16, s32}, + {s16, s64}, + {s16, s80}, + {s32, s32}, + {s32, s64}, + {s32, s80}, + {s64, s32}, + {s64, s64}, + {s64, s80}}) .clampScalar(0, (UseX87 && !HasSSE1) ? s16 : s32, sMaxScalar) .widenScalarToNextPow2(0) .clampScalar(1, s32, HasSSE2 ? s64 : s32) @@ -709,13 +701,10 @@ bool X86LegalizerInfo::legalizeSITOFP(MachineInstr &MI, SrcTy.getSizeInBits() == 64) && "Unexpected source type for SITOFP in X87 mode."); - const LLT p0 = LLT::pointer(0, MF.getTarget().getPointerSizeInBits(0)); - int MemSize = SrcTy.getSizeInBytes(); - int StackSlot = - MF.getFrameInfo().CreateStackObject(MemSize, Align(MemSize), false); - - auto SlotPointer = MIRBuilder.buildFrameIndex(p0, StackSlot); - MachinePointerInfo PtrInfo = MachinePointerInfo::getFixedStack(MF, StackSlot); + 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)); @@ -738,16 +727,12 @@ bool X86LegalizerInfo::legalizeFPTOSI(MachineInstr &MI, LegalizerHelper &Helper) const { MachineFunction &MF = *MI.getMF(); MachineIRBuilder &MIRBuilder = Helper.MIRBuilder; - const LLT p0 = LLT::pointer(0, MF.getTarget().getPointerSizeInBits(0)); auto [Dst, DstTy, Src, SrcTy] = MI.getFirst2RegLLTs(); - unsigned MemSize = DstTy.getSizeInBytes(); - int StackSlot = - MF.getFrameInfo().CreateStackObject(MemSize, Align(MemSize), false); - - auto SlotPointer = MIRBuilder.buildFrameIndex(p0, StackSlot); - - MachinePointerInfo PtrInfo = MachinePointerInfo::getFixedStack(MF, StackSlot); + 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)); diff --git a/llvm/lib/Target/X86/X86InstrFragments.td b/llvm/lib/Target/X86/X86InstrFragments.td index 00af5b1f50733..c7210b5e695a1 100644 --- a/llvm/lib/Target/X86/X86InstrFragments.td +++ b/llvm/lib/Target/X86/X86InstrFragments.td @@ -842,19 +842,19 @@ def X86fldf80 : PatFrag<(ops node:$ptr), (X86fld node:$ptr), [{ def X86fild16 : PatFrag<(ops node:$ptr), (X86fild node:$ptr), [{ return cast(N)->getMemoryVT() == MVT::i16; }]> { - let GISelPredicateCode = [{ return checkMemoryOpSize(MI, 2); }]; + let GISelPredicateCode = [{ return checkMemoryOpSize(MI, LLT::scalar(16)); }]; } def X86fild32 : PatFrag<(ops node:$ptr), (X86fild node:$ptr), [{ return cast(N)->getMemoryVT() == MVT::i32; }]> { - let GISelPredicateCode = [{ return checkMemoryOpSize(MI, 4); }]; + let GISelPredicateCode = [{ return checkMemoryOpSize(MI, LLT::scalar(32)); }]; } def X86fild64 : PatFrag<(ops node:$ptr), (X86fild node:$ptr), [{ return cast(N)->getMemoryVT() == MVT::i64; }]> { - let GISelPredicateCode = [{ return checkMemoryOpSize(MI, 8); }]; + let GISelPredicateCode = [{ return checkMemoryOpSize(MI, LLT::scalar(64)); }]; } def X86fist32 : PatFrag<(ops node:$val, node:$ptr), @@ -871,21 +871,21 @@ def X86fp_to_i16mem : PatFrag<(ops node:$val, node:$ptr), (X86fp_to_mem node:$val, node:$ptr), [{ return cast(N)->getMemoryVT() == MVT::i16; }]> { - let GISelPredicateCode = [{ return checkMemoryOpSize(MI, 2); }]; + let GISelPredicateCode = [{ return checkMemoryOpSize(MI, LLT::scalar(16)); }]; } def X86fp_to_i32mem : PatFrag<(ops node:$val, node:$ptr), (X86fp_to_mem node:$val, node:$ptr), [{ return cast(N)->getMemoryVT() == MVT::i32; }]> { - let GISelPredicateCode = [{ return checkMemoryOpSize(MI, 4); }]; + let GISelPredicateCode = [{ return checkMemoryOpSize(MI, LLT::scalar(32)); }]; } def X86fp_to_i64mem : PatFrag<(ops node:$val, node:$ptr), (X86fp_to_mem node:$val, node:$ptr), [{ return cast(N)->getMemoryVT() == MVT::i64; }]> { - let GISelPredicateCode = [{ return checkMemoryOpSize(MI, 8); }]; + let GISelPredicateCode = [{ return checkMemoryOpSize(MI, LLT::scalar(64)); }]; } //===----------------------------------------------------------------------===// From 1ca8ff2471e670c743732f5aaab7c3fe4a13b6f4 Mon Sep 17 00:00:00 2001 From: Pawan Nirpal Date: Wed, 14 May 2025 06:09:58 +0200 Subject: [PATCH 03/10] introduce predicated customForCartesianProduct --- .../llvm/CodeGen/GlobalISel/LegalizerInfo.h | 10 ++++++++++ .../lib/Target/X86/GISel/X86LegalizerInfo.cpp | 20 ++----------------- 2 files changed, 12 insertions(+), 18 deletions(-) diff --git a/llvm/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h b/llvm/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h index 9472aa196f9b4..31e530ee2f6a1 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h @@ -926,6 +926,16 @@ class LegalizeRuleSet { 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 Types0, + std::initializer_list Types1) { + if (!Pred) + return *this; + return actionForCartesianProduct(LegalizeAction::Custom, Types0, Types1); + } + /// Unconditionally custom lower. LegalizeRuleSet &custom() { return customIf(always); diff --git a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp index 9cf6a87c9eda4..172c12388a676 100644 --- a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp +++ b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp @@ -495,15 +495,7 @@ X86LegalizerInfo::X86LegalizerInfo(const X86Subtarget &STI, .legalFor(HasSSE1 && Is64Bit, {s32, s64}) .legalFor(HasSSE2, {s64, s32}) .legalFor(HasSSE2 && Is64Bit, {s64, s64}) - .customFor(UseX87, {{s32, s16}, - {s32, s32}, - {s32, s64}, - {s64, s16}, - {s64, s32}, - {s64, s64}, - {s80, s16}, - {s80, s32}, - {s80, s64}}) + .customForCartesianProduct(UseX87, {s32, s64, s80}, {s16, s32, s64}) .clampScalar(1, (UseX87 && !HasSSE1) ? s16 : s32, sMaxScalar) .widenScalarToNextPow2(1) .clampScalar(0, s32, HasSSE2 ? s64 : s32) @@ -514,15 +506,7 @@ X86LegalizerInfo::X86LegalizerInfo(const X86Subtarget &STI, .legalFor(HasSSE1 && Is64Bit, {s64, s32}) .legalFor(HasSSE2, {s32, s64}) .legalFor(HasSSE2 && Is64Bit, {s64, s64}) - .customFor(UseX87, {{s16, s32}, - {s16, s64}, - {s16, s80}, - {s32, s32}, - {s32, s64}, - {s32, s80}, - {s64, s32}, - {s64, s64}, - {s64, s80}}) + .customForCartesianProduct(UseX87, {s16, s32, s64}, {s32, s64, s80}) .clampScalar(0, (UseX87 && !HasSSE1) ? s16 : s32, sMaxScalar) .widenScalarToNextPow2(0) .clampScalar(1, s32, HasSSE2 ? s64 : s32) From 4d9944d972dd0255c3af9ccbe6b925276162af54 Mon Sep 17 00:00:00 2001 From: Pawan Nirpal Date: Wed, 14 May 2025 06:18:02 +0200 Subject: [PATCH 04/10] braces for legalfor --- llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp index 172c12388a676..da9b61b2d5ee3 100644 --- a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp +++ b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp @@ -491,10 +491,10 @@ X86LegalizerInfo::X86LegalizerInfo(const X86Subtarget &STI, }); getActionDefinitionsBuilder(G_SITOFP) - .legalFor(HasSSE1, {s32, s32}) - .legalFor(HasSSE1 && Is64Bit, {s32, s64}) - .legalFor(HasSSE2, {s64, s32}) - .legalFor(HasSSE2 && Is64Bit, {s64, s64}) + .legalFor(HasSSE1, {{s32, s32}}) + .legalFor(HasSSE1 && Is64Bit, {{s32, s64}}) + .legalFor(HasSSE2, {{s64, s32}}) + .legalFor(HasSSE2 && Is64Bit, {{s64, s64}}) .customForCartesianProduct(UseX87, {s32, s64, s80}, {s16, s32, s64}) .clampScalar(1, (UseX87 && !HasSSE1) ? s16 : s32, sMaxScalar) .widenScalarToNextPow2(1) @@ -502,10 +502,10 @@ X86LegalizerInfo::X86LegalizerInfo(const X86Subtarget &STI, .widenScalarToNextPow2(0); getActionDefinitionsBuilder(G_FPTOSI) - .legalFor(HasSSE1, {s32, s32}) - .legalFor(HasSSE1 && Is64Bit, {s64, s32}) - .legalFor(HasSSE2, {s32, s64}) - .legalFor(HasSSE2 && Is64Bit, {s64, s64}) + .legalFor(HasSSE1, {{s32, s32}}) + .legalFor(HasSSE1 && Is64Bit, {{s64, s32}}) + .legalFor(HasSSE2, {{s32, s64}}) + .legalFor(HasSSE2 && Is64Bit, {{s64, s64}}) .customForCartesianProduct(UseX87, {s16, s32, s64}, {s32, s64, s80}) .clampScalar(0, (UseX87 && !HasSSE1) ? s16 : s32, sMaxScalar) .widenScalarToNextPow2(0) From c62687df1a5cb781ed8a533aae09b9030089f102 Mon Sep 17 00:00:00 2001 From: Pawan Nirpal Date: Wed, 14 May 2025 16:29:03 +0200 Subject: [PATCH 05/10] fix failing tests --- llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp index da9b61b2d5ee3..8ade5675ed665 100644 --- a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp +++ b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp @@ -495,7 +495,8 @@ X86LegalizerInfo::X86LegalizerInfo(const X86Subtarget &STI, .legalFor(HasSSE1 && Is64Bit, {{s32, s64}}) .legalFor(HasSSE2, {{s64, s32}}) .legalFor(HasSSE2 && Is64Bit, {{s64, s64}}) - .customForCartesianProduct(UseX87, {s32, s64, s80}, {s16, s32, s64}) + .customForCartesianProduct(UseX87 && !HasSSE1, {s32, s64, s80}, + {s16, s32, s64}) .clampScalar(1, (UseX87 && !HasSSE1) ? s16 : s32, sMaxScalar) .widenScalarToNextPow2(1) .clampScalar(0, s32, HasSSE2 ? s64 : s32) @@ -506,7 +507,8 @@ X86LegalizerInfo::X86LegalizerInfo(const X86Subtarget &STI, .legalFor(HasSSE1 && Is64Bit, {{s64, s32}}) .legalFor(HasSSE2, {{s32, s64}}) .legalFor(HasSSE2 && Is64Bit, {{s64, s64}}) - .customForCartesianProduct(UseX87, {s16, s32, s64}, {s32, s64, s80}) + .customForCartesianProduct(UseX87 && !HasSSE1, {s16, s32, s64}, + {s32, s64, s80}) .clampScalar(0, (UseX87 && !HasSSE1) ? s16 : s32, sMaxScalar) .widenScalarToNextPow2(0) .clampScalar(1, s32, HasSSE2 ? s64 : s32) From 10bc9bfd2baadc009a986c4355d5229e506716fe Mon Sep 17 00:00:00 2001 From: Pawan Nirpal Date: Wed, 21 May 2025 06:32:39 +0200 Subject: [PATCH 06/10] fix tests --- .../lib/Target/X86/GISel/X86LegalizerInfo.cpp | 6 +- llvm/test/CodeGen/X86/isel-fp-to-sint-x87.ll | 120 ++++++------------ llvm/test/CodeGen/X86/isel-sint-to-fp-x87.ll | 58 ++------- 3 files changed, 52 insertions(+), 132 deletions(-) diff --git a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp index 8ade5675ed665..848059d90a2d3 100644 --- a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp +++ b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp @@ -495,10 +495,9 @@ X86LegalizerInfo::X86LegalizerInfo(const X86Subtarget &STI, .legalFor(HasSSE1 && Is64Bit, {{s32, s64}}) .legalFor(HasSSE2, {{s64, s32}}) .legalFor(HasSSE2 && Is64Bit, {{s64, s64}}) - .customForCartesianProduct(UseX87 && !HasSSE1, {s32, s64, s80}, - {s16, s32, 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); @@ -507,10 +506,9 @@ X86LegalizerInfo::X86LegalizerInfo(const X86Subtarget &STI, .legalFor(HasSSE1 && Is64Bit, {{s64, s32}}) .legalFor(HasSSE2, {{s32, s64}}) .legalFor(HasSSE2 && Is64Bit, {{s64, s64}}) - .customForCartesianProduct(UseX87 && !HasSSE1, {s16, s32, s64}, - {s32, s64, s80}) .clampScalar(0, (UseX87 && !HasSSE1) ? s16 : s32, sMaxScalar) .widenScalarToNextPow2(0) + .customForCartesianProduct(UseX87, {s16, s32, s64}, {s32, s64, s80}) .clampScalar(1, s32, HasSSE2 ? s64 : s32) .widenScalarToNextPow2(1); diff --git a/llvm/test/CodeGen/X86/isel-fp-to-sint-x87.ll b/llvm/test/CodeGen/X86/isel-fp-to-sint-x87.ll index 1421b9cc4c146..49e33141701fb 100644 --- a/llvm/test/CodeGen/X86/isel-fp-to-sint-x87.ll +++ b/llvm/test/CodeGen/X86/isel-fp-to-sint-x87.ll @@ -4,7 +4,7 @@ ; 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=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 +; 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 @@ -280,46 +280,25 @@ define i64 @test_float_to_int64(float %input) nounwind { ; X64-NEXT: movq -{{[0-9]+}}(%rsp), %rax ; X64-NEXT: retq ; -; SDAG-X86-LABEL: test_float_to_int64: -; SDAG-X86: # %bb.0: # %entry -; SDAG-X86-NEXT: pushl %ebp -; SDAG-X86-NEXT: movl %esp, %ebp -; SDAG-X86-NEXT: andl $-8, %esp -; SDAG-X86-NEXT: subl $16, %esp -; SDAG-X86-NEXT: flds 8(%ebp) -; 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: fistpll {{[0-9]+}}(%esp) -; SDAG-X86-NEXT: fldcw {{[0-9]+}}(%esp) -; SDAG-X86-NEXT: movl {{[0-9]+}}(%esp), %eax -; SDAG-X86-NEXT: movl {{[0-9]+}}(%esp), %edx -; SDAG-X86-NEXT: movl %ebp, %esp -; SDAG-X86-NEXT: popl %ebp -; SDAG-X86-NEXT: retl -; -; GISEL-X86-LABEL: test_float_to_int64: -; GISEL-X86: # %bb.0: # %entry -; GISEL-X86-NEXT: pushl %ebp -; GISEL-X86-NEXT: movl %esp, %ebp -; GISEL-X86-NEXT: andl $-8, %esp -; GISEL-X86-NEXT: subl $16, %esp -; GISEL-X86-NEXT: flds 8(%ebp) -; GISEL-X86-NEXT: leal {{[0-9]+}}(%esp), %ecx -; 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: fistpll {{[0-9]+}}(%esp) -; GISEL-X86-NEXT: fldcw {{[0-9]+}}(%esp) -; GISEL-X86-NEXT: movl {{[0-9]+}}(%esp), %eax -; GISEL-X86-NEXT: movl 4(%ecx), %edx -; GISEL-X86-NEXT: movl %ebp, %esp -; GISEL-X86-NEXT: popl %ebp -; GISEL-X86-NEXT: retl +; X86-LABEL: test_float_to_int64: +; X86: # %bb.0: # %entry +; X86-NEXT: pushl %ebp +; X86-NEXT: movl %esp, %ebp +; X86-NEXT: andl $-8, %esp +; X86-NEXT: subl $16, %esp +; X86-NEXT: flds 8(%ebp) +; 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: fistpll {{[0-9]+}}(%esp) +; X86-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-NEXT: movl {{[0-9]+}}(%esp), %eax +; X86-NEXT: movl {{[0-9]+}}(%esp), %edx +; X86-NEXT: movl %ebp, %esp +; X86-NEXT: popl %ebp +; X86-NEXT: retl entry: %conv = fptosi float %input to i64 ret i64 %conv @@ -339,46 +318,25 @@ define i64 @test_longdouble_to_int64(x86_fp80 %input) nounwind { ; X64-NEXT: movq -{{[0-9]+}}(%rsp), %rax ; X64-NEXT: retq ; -; SDAG-X86-LABEL: test_longdouble_to_int64: -; SDAG-X86: # %bb.0: # %entry -; SDAG-X86-NEXT: pushl %ebp -; SDAG-X86-NEXT: movl %esp, %ebp -; SDAG-X86-NEXT: andl $-8, %esp -; SDAG-X86-NEXT: subl $16, %esp -; SDAG-X86-NEXT: fldt 8(%ebp) -; 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: fistpll {{[0-9]+}}(%esp) -; SDAG-X86-NEXT: fldcw {{[0-9]+}}(%esp) -; SDAG-X86-NEXT: movl {{[0-9]+}}(%esp), %eax -; SDAG-X86-NEXT: movl {{[0-9]+}}(%esp), %edx -; SDAG-X86-NEXT: movl %ebp, %esp -; SDAG-X86-NEXT: popl %ebp -; SDAG-X86-NEXT: retl -; -; GISEL-X86-LABEL: test_longdouble_to_int64: -; GISEL-X86: # %bb.0: # %entry -; GISEL-X86-NEXT: pushl %ebp -; GISEL-X86-NEXT: movl %esp, %ebp -; GISEL-X86-NEXT: andl $-8, %esp -; GISEL-X86-NEXT: subl $16, %esp -; GISEL-X86-NEXT: fldt 8(%ebp) -; GISEL-X86-NEXT: leal {{[0-9]+}}(%esp), %ecx -; 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: fistpll {{[0-9]+}}(%esp) -; GISEL-X86-NEXT: fldcw {{[0-9]+}}(%esp) -; GISEL-X86-NEXT: movl {{[0-9]+}}(%esp), %eax -; GISEL-X86-NEXT: movl 4(%ecx), %edx -; GISEL-X86-NEXT: movl %ebp, %esp -; GISEL-X86-NEXT: popl %ebp -; GISEL-X86-NEXT: retl +; X86-LABEL: test_longdouble_to_int64: +; X86: # %bb.0: # %entry +; X86-NEXT: pushl %ebp +; X86-NEXT: movl %esp, %ebp +; X86-NEXT: andl $-8, %esp +; X86-NEXT: subl $16, %esp +; X86-NEXT: fldt 8(%ebp) +; 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: fistpll {{[0-9]+}}(%esp) +; X86-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-NEXT: movl {{[0-9]+}}(%esp), %eax +; X86-NEXT: movl {{[0-9]+}}(%esp), %edx +; X86-NEXT: movl %ebp, %esp +; X86-NEXT: popl %ebp +; X86-NEXT: retl entry: %conv = fptosi x86_fp80 %input to i64 ret i64 %conv diff --git a/llvm/test/CodeGen/X86/isel-sint-to-fp-x87.ll b/llvm/test/CodeGen/X86/isel-sint-to-fp-x87.ll index 68eee6c0162db..98fa3c9541faa 100644 --- a/llvm/test/CodeGen/X86/isel-sint-to-fp-x87.ll +++ b/llvm/test/CodeGen/X86/isel-sint-to-fp-x87.ll @@ -4,7 +4,7 @@ ; 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=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 +; 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 @@ -133,32 +133,12 @@ define void @test_int64_to_float(i64 %x, ptr %p) nounwind { ; X64-NEXT: fstps (%rsi) ; X64-NEXT: retq ; -; SDAG-X86-LABEL: test_int64_to_float: -; SDAG-X86: # %bb.0: # %entry -; SDAG-X86-NEXT: movl {{[0-9]+}}(%esp), %eax -; SDAG-X86-NEXT: fildll {{[0-9]+}}(%esp) -; SDAG-X86-NEXT: fstps (%eax) -; SDAG-X86-NEXT: retl -; -; GISEL-X86-LABEL: test_int64_to_float: -; GISEL-X86: # %bb.0: # %entry -; GISEL-X86-NEXT: pushl %ebp -; GISEL-X86-NEXT: movl %esp, %ebp -; GISEL-X86-NEXT: pushl %esi -; GISEL-X86-NEXT: andl $-8, %esp -; GISEL-X86-NEXT: subl $16, %esp -; GISEL-X86-NEXT: movl 8(%ebp), %eax -; GISEL-X86-NEXT: movl 12(%ebp), %ecx -; GISEL-X86-NEXT: movl 16(%ebp), %edx -; GISEL-X86-NEXT: movl %esp, %esi -; GISEL-X86-NEXT: movl %eax, (%esp) -; GISEL-X86-NEXT: movl %ecx, 4(%esi) -; GISEL-X86-NEXT: fildll (%esp) -; GISEL-X86-NEXT: fstps (%edx) -; GISEL-X86-NEXT: leal -4(%ebp), %esp -; GISEL-X86-NEXT: popl %esi -; GISEL-X86-NEXT: popl %ebp -; GISEL-X86-NEXT: retl +; X86-LABEL: test_int64_to_float: +; X86: # %bb.0: # %entry +; X86-NEXT: movl {{[0-9]+}}(%esp), %eax +; X86-NEXT: fildll {{[0-9]+}}(%esp) +; X86-NEXT: fstps (%eax) +; X86-NEXT: retl entry: %conv = sitofp i64 %x to float store float %conv, ptr %p, align 4 @@ -249,26 +229,10 @@ define x86_fp80 @test_int64_to_longdouble(i64 %a, ptr %p) nounwind { ; X64-NEXT: fildll -{{[0-9]+}}(%rsp) ; X64-NEXT: retq ; -; SDAG-X86-LABEL: test_int64_to_longdouble: -; SDAG-X86: # %bb.0: -; SDAG-X86-NEXT: fildll {{[0-9]+}}(%esp) -; SDAG-X86-NEXT: retl -; -; GISEL-X86-LABEL: test_int64_to_longdouble: -; GISEL-X86: # %bb.0: -; GISEL-X86-NEXT: pushl %ebp -; GISEL-X86-NEXT: movl %esp, %ebp -; GISEL-X86-NEXT: andl $-8, %esp -; GISEL-X86-NEXT: subl $8, %esp -; GISEL-X86-NEXT: movl 8(%ebp), %eax -; GISEL-X86-NEXT: movl 12(%ebp), %ecx -; GISEL-X86-NEXT: movl %esp, %edx -; GISEL-X86-NEXT: movl %eax, (%esp) -; GISEL-X86-NEXT: movl %ecx, 4(%edx) -; GISEL-X86-NEXT: fildll (%esp) -; GISEL-X86-NEXT: movl %ebp, %esp -; GISEL-X86-NEXT: popl %ebp -; GISEL-X86-NEXT: retl +; X86-LABEL: test_int64_to_longdouble: +; X86: # %bb.0: +; X86-NEXT: fildll {{[0-9]+}}(%esp) +; X86-NEXT: retl %conv = sitofp i64 %a to x86_fp80 ret x86_fp80 %conv } From 1e910d3c45a266fa5656836c381880beb7346c9a Mon Sep 17 00:00:00 2001 From: Pawan Nirpal Date: Fri, 23 May 2025 17:41:49 +0530 Subject: [PATCH 07/10] Update llvm/lib/Target/X86/X86InstrGISel.td Co-authored-by: Matt Arsenault --- llvm/lib/Target/X86/X86InstrGISel.td | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/Target/X86/X86InstrGISel.td b/llvm/lib/Target/X86/X86InstrGISel.td index 7f5d92f43b0bb..f4fa33807cd9a 100644 --- a/llvm/lib/Target/X86/X86InstrGISel.td +++ b/llvm/lib/Target/X86/X86InstrGISel.td @@ -28,4 +28,4 @@ def G_FIST : X86GenericInstruction { } def : GINodeEquiv; -def : GINodeEquiv; \ No newline at end of file +def : GINodeEquiv; From c1bb7af297dd231f318f35a54abd978bd0620240 Mon Sep 17 00:00:00 2001 From: Pawan Nirpal Date: Fri, 23 May 2025 14:53:56 +0200 Subject: [PATCH 08/10] use MemoryVT instead of custom c++ predicate --- .../X86/GISel/X86InstructionSelector.cpp | 9 --------- llvm/lib/Target/X86/X86InstrFragments.td | 18 ++++++++++++------ 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/llvm/lib/Target/X86/GISel/X86InstructionSelector.cpp b/llvm/lib/Target/X86/GISel/X86InstructionSelector.cpp index 7ff6f2aac5a30..3090ad313b90d 100644 --- a/llvm/lib/Target/X86/GISel/X86InstructionSelector.cpp +++ b/llvm/lib/Target/X86/GISel/X86InstructionSelector.cpp @@ -77,8 +77,6 @@ class X86InstructionSelector : public InstructionSelector { unsigned getPtrLoadStoreOp(const LLT &Ty, const RegisterBank &RB, unsigned Opc) const; - bool checkMemoryOpSize(const MachineInstr &MI, LLT Sz) const; - bool selectLoadStoreOp(MachineInstr &I, MachineRegisterInfo &MRI, MachineFunction &MF) const; bool selectFrameIndexOrGep(MachineInstr &I, MachineRegisterInfo &MRI, @@ -357,13 +355,6 @@ bool X86InstructionSelector::selectCopy(MachineInstr &I, return true; } -bool X86InstructionSelector::checkMemoryOpSize(const MachineInstr &MI, - LLT Sz) const { - assert(MI.hasOneMemOperand() && - "Expected load/store to have only one mem op!"); - return (*MI.memoperands_begin())->getMemoryType() == Sz; -} - bool X86InstructionSelector::select(MachineInstr &I) { assert(I.getParent() && "Instruction should be in a basic block!"); assert(I.getParent()->getParent() && "Instruction should be in a function!"); diff --git a/llvm/lib/Target/X86/X86InstrFragments.td b/llvm/lib/Target/X86/X86InstrFragments.td index c7210b5e695a1..f3c656f4ef3c2 100644 --- a/llvm/lib/Target/X86/X86InstrFragments.td +++ b/llvm/lib/Target/X86/X86InstrFragments.td @@ -842,19 +842,22 @@ def X86fldf80 : PatFrag<(ops node:$ptr), (X86fld node:$ptr), [{ def X86fild16 : PatFrag<(ops node:$ptr), (X86fild node:$ptr), [{ return cast(N)->getMemoryVT() == MVT::i16; }]> { - let GISelPredicateCode = [{ return checkMemoryOpSize(MI, LLT::scalar(16)); }]; + let IsStore = true; + let MemoryVT = i16; } def X86fild32 : PatFrag<(ops node:$ptr), (X86fild node:$ptr), [{ return cast(N)->getMemoryVT() == MVT::i32; }]> { - let GISelPredicateCode = [{ return checkMemoryOpSize(MI, LLT::scalar(32)); }]; + let IsStore = true; + let MemoryVT = i32; } def X86fild64 : PatFrag<(ops node:$ptr), (X86fild node:$ptr), [{ return cast(N)->getMemoryVT() == MVT::i64; }]> { - let GISelPredicateCode = [{ return checkMemoryOpSize(MI, LLT::scalar(64)); }]; + let IsStore = true; + let MemoryVT = i64; } def X86fist32 : PatFrag<(ops node:$val, node:$ptr), @@ -871,21 +874,24 @@ def X86fp_to_i16mem : PatFrag<(ops node:$val, node:$ptr), (X86fp_to_mem node:$val, node:$ptr), [{ return cast(N)->getMemoryVT() == MVT::i16; }]> { - let GISelPredicateCode = [{ return checkMemoryOpSize(MI, LLT::scalar(16)); }]; + 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(N)->getMemoryVT() == MVT::i32; }]> { - let GISelPredicateCode = [{ return checkMemoryOpSize(MI, LLT::scalar(32)); }]; + 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(N)->getMemoryVT() == MVT::i64; }]> { - let GISelPredicateCode = [{ return checkMemoryOpSize(MI, LLT::scalar(64)); }]; + let IsStore = true; + let MemoryVT = i64; } //===----------------------------------------------------------------------===// From 919c934f292bfaf6a3e8ed3667b1b62982b739c1 Mon Sep 17 00:00:00 2001 From: Pawan Nirpal Date: Fri, 23 May 2025 19:02:51 +0200 Subject: [PATCH 09/10] oops --- llvm/lib/Target/X86/X86InstrFragments.td | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/llvm/lib/Target/X86/X86InstrFragments.td b/llvm/lib/Target/X86/X86InstrFragments.td index f3c656f4ef3c2..b2602429bd8c9 100644 --- a/llvm/lib/Target/X86/X86InstrFragments.td +++ b/llvm/lib/Target/X86/X86InstrFragments.td @@ -842,21 +842,21 @@ def X86fldf80 : PatFrag<(ops node:$ptr), (X86fld node:$ptr), [{ def X86fild16 : PatFrag<(ops node:$ptr), (X86fild node:$ptr), [{ return cast(N)->getMemoryVT() == MVT::i16; }]> { - let IsStore = true; + let IsLoad = true; let MemoryVT = i16; } def X86fild32 : PatFrag<(ops node:$ptr), (X86fild node:$ptr), [{ return cast(N)->getMemoryVT() == MVT::i32; }]> { - let IsStore = true; + let IsLoad = true; let MemoryVT = i32; } def X86fild64 : PatFrag<(ops node:$ptr), (X86fild node:$ptr), [{ return cast(N)->getMemoryVT() == MVT::i64; }]> { - let IsStore = true; + let IsLoad = true; let MemoryVT = i64; } From 9821d76279633db1859eeaa881ee0a52ec2e1512 Mon Sep 17 00:00:00 2001 From: Pawan Nirpal Date: Thu, 29 May 2025 06:05:00 +0200 Subject: [PATCH 10/10] remove redundant include --- llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp index 848059d90a2d3..11dd05c584983 100644 --- a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp +++ b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp @@ -17,7 +17,6 @@ #include "llvm/CodeGen/GlobalISel/LegalizerHelper.h" #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" #include "llvm/CodeGen/MachineConstantPool.h" -#include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/TargetOpcodes.h" #include "llvm/CodeGen/ValueTypes.h" #include "llvm/IR/DerivedTypes.h"