[llvm] r313478 - [GlobalISel][X86] G_FCONSTANT support.
Igor Breger via llvm-commits
llvm-commits at lists.llvm.org
Sun Sep 17 01:08:13 PDT 2017
Author: ibreger
Date: Sun Sep 17 01:08:13 2017
New Revision: 313478
URL: http://llvm.org/viewvc/llvm-project?rev=313478&view=rev
Log:
[GlobalISel][X86] G_FCONSTANT support.
Summary: G_FCONSTANT support, port the implementation from X86FastIsel.
Reviewers: zvi, delena, guyblank
Reviewed By: delena
Subscribers: rovka, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D37734
Added:
llvm/trunk/test/CodeGen/X86/GlobalISel/fconstant.ll
llvm/trunk/test/CodeGen/X86/GlobalISel/select-fconstant.mir
Modified:
llvm/trunk/lib/Target/X86/X86InstructionSelector.cpp
llvm/trunk/lib/Target/X86/X86LegalizerInfo.cpp
llvm/trunk/lib/Target/X86/X86RegisterBankInfo.cpp
llvm/trunk/test/CodeGen/X86/GlobalISel/legalize-constant.mir
llvm/trunk/test/CodeGen/X86/GlobalISel/regbankselect-X86_64.mir
Modified: llvm/trunk/lib/Target/X86/X86InstructionSelector.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstructionSelector.cpp?rev=313478&r1=313477&r2=313478&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86InstructionSelector.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86InstructionSelector.cpp Sun Sep 17 01:08:13 2017
@@ -21,6 +21,7 @@
#include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
#include "llvm/CodeGen/GlobalISel/Utils.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
@@ -55,7 +56,7 @@ private:
bool selectImpl(MachineInstr &I) const;
// TODO: remove after supported by Tablegen-erated instruction selection.
- unsigned getLoadStoreOp(LLT &Ty, const RegisterBank &RB, unsigned Opc,
+ unsigned getLoadStoreOp(const LLT &Ty, const RegisterBank &RB, unsigned Opc,
uint64_t Alignment) const;
bool selectLoadStoreOp(MachineInstr &I, MachineRegisterInfo &MRI,
@@ -87,6 +88,8 @@ private:
MachineFunction &MF) const;
bool selectCondBranch(MachineInstr &I, MachineRegisterInfo &MRI,
MachineFunction &MF) const;
+ bool materializeFP(MachineInstr &I, MachineRegisterInfo &MRI,
+ MachineFunction &MF) const;
bool selectImplicitDefOrPHI(MachineInstr &I, MachineRegisterInfo &MRI) const;
// emit insert subreg instruction and insert it before MachineInstr &I
@@ -336,13 +339,16 @@ bool X86InstructionSelector::select(Mach
return true;
if (selectCondBranch(I, MRI, MF))
return true;
+ if (materializeFP(I, MRI, MF))
+ return true;
if (selectImplicitDefOrPHI(I, MRI))
return true;
return false;
}
-unsigned X86InstructionSelector::getLoadStoreOp(LLT &Ty, const RegisterBank &RB,
+unsigned X86InstructionSelector::getLoadStoreOp(const LLT &Ty,
+ const RegisterBank &RB,
unsigned Opc,
uint64_t Alignment) const {
bool Isload = (Opc == TargetOpcode::G_LOAD);
@@ -740,11 +746,11 @@ bool X86InstructionSelector::selectAnyex
const RegisterBank &DstRB = *RBI.getRegBank(DstReg, MRI, TRI);
const RegisterBank &SrcRB = *RBI.getRegBank(SrcReg, MRI, TRI);
- assert (DstRB.getID() == SrcRB.getID() &&
- "G_ANYEXT input/output on different banks\n");
+ assert(DstRB.getID() == SrcRB.getID() &&
+ "G_ANYEXT input/output on different banks\n");
- assert (DstTy.getSizeInBits() > SrcTy.getSizeInBits() &&
- "G_ANYEXT incorrect operand size");
+ assert(DstTy.getSizeInBits() > SrcTy.getSizeInBits() &&
+ "G_ANYEXT incorrect operand size");
if (DstRB.getID() != X86::GPRRegBankID)
return false;
@@ -1182,6 +1188,73 @@ bool X86InstructionSelector::selectCondB
I.eraseFromParent();
return true;
}
+
+bool X86InstructionSelector::materializeFP(MachineInstr &I,
+ MachineRegisterInfo &MRI,
+ MachineFunction &MF) const {
+ if (I.getOpcode() != TargetOpcode::G_FCONSTANT)
+ return false;
+
+ // Can't handle alternate code models yet.
+ CodeModel::Model CM = TM.getCodeModel();
+ if (CM != CodeModel::Small && CM != CodeModel::Large)
+ return false;
+
+ const unsigned DstReg = I.getOperand(0).getReg();
+ const LLT DstTy = MRI.getType(DstReg);
+ const RegisterBank &RegBank = *RBI.getRegBank(DstReg, MRI, TRI);
+ unsigned Align = DstTy.getSizeInBits();
+ const DebugLoc &DbgLoc = I.getDebugLoc();
+
+ unsigned Opc = getLoadStoreOp(DstTy, RegBank, TargetOpcode::G_LOAD, Align);
+
+ // Create the load from the constant pool.
+ const ConstantFP *CFP = I.getOperand(1).getFPImm();
+ unsigned CPI = MF.getConstantPool()->getConstantPoolIndex(CFP, Align);
+ MachineInstr *LoadInst = nullptr;
+ unsigned char OpFlag = STI.classifyLocalReference(nullptr);
+
+ if (CM == CodeModel::Large && STI.is64Bit()) {
+ // Under X86-64 non-small code model, GV (and friends) are 64-bits, so
+ // they cannot be folded into immediate fields.
+
+ unsigned AddrReg = MRI.createVirtualRegister(&X86::GR64RegClass);
+ BuildMI(*I.getParent(), I, DbgLoc, TII.get(X86::MOV64ri), AddrReg)
+ .addConstantPoolIndex(CPI, 0, OpFlag);
+
+ MachineMemOperand *MMO = MF.getMachineMemOperand(
+ MachinePointerInfo::getConstantPool(MF), MachineMemOperand::MOLoad,
+ MF.getDataLayout().getPointerSize(), Align);
+
+ LoadInst =
+ addDirectMem(BuildMI(*I.getParent(), I, DbgLoc, TII.get(Opc), DstReg),
+ AddrReg)
+ .addMemOperand(MMO);
+
+ } else if(CM == CodeModel::Small || !STI.is64Bit()){
+ // Handle the case when globals fit in our immediate field.
+ // This is true for X86-32 always and X86-64 when in -mcmodel=small mode.
+
+ // x86-32 PIC requires a PIC base register for constant pools.
+ unsigned PICBase = 0;
+ if (OpFlag == X86II::MO_PIC_BASE_OFFSET || OpFlag == X86II::MO_GOTOFF) {
+ // PICBase can be allocated by TII.getGlobalBaseReg(&MF).
+ // In DAGISEL the code that initialize it generated by the CGBR pass.
+ return false; // TODO support the mode.
+ }
+ else if (STI.is64Bit() && TM.getCodeModel() == CodeModel::Small)
+ PICBase = X86::RIP;
+
+ LoadInst = addConstantPoolReference(
+ BuildMI(*I.getParent(), I, DbgLoc, TII.get(Opc), DstReg), CPI, PICBase,
+ OpFlag);
+ } else
+ return false;
+
+ constrainSelectedInstRegOperands(*LoadInst, TII, TRI, RBI);
+ I.eraseFromParent();
+ return true;
+}
bool X86InstructionSelector::selectImplicitDefOrPHI(
MachineInstr &I, MachineRegisterInfo &MRI) const {
Modified: llvm/trunk/lib/Target/X86/X86LegalizerInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86LegalizerInfo.cpp?rev=313478&r1=313477&r2=313478&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86LegalizerInfo.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86LegalizerInfo.cpp Sun Sep 17 01:08:13 2017
@@ -164,6 +164,9 @@ void X86LegalizerInfo::setLegalizerInfoS
for (unsigned MemOp : {G_LOAD, G_STORE})
for (auto Ty : {v4s32, v2s64})
setAction({MemOp, Ty}, Legal);
+
+ // Constants
+ setAction({TargetOpcode::G_FCONSTANT, s32}, Legal);
}
void X86LegalizerInfo::setLegalizerInfoSSE2() {
@@ -189,6 +192,9 @@ void X86LegalizerInfo::setLegalizerInfoS
setAction({G_FPEXT, s64}, Legal);
setAction({G_FPEXT, 1, s32}, Legal);
+
+ // Constants
+ setAction({TargetOpcode::G_FCONSTANT, s64}, Legal);
}
void X86LegalizerInfo::setLegalizerInfoSSE41() {
Modified: llvm/trunk/lib/Target/X86/X86RegisterBankInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86RegisterBankInfo.cpp?rev=313478&r1=313477&r2=313478&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86RegisterBankInfo.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86RegisterBankInfo.cpp Sun Sep 17 01:08:13 2017
@@ -186,6 +186,7 @@ X86RegisterBankInfo::getInstrMapping(con
switch (Opc) {
case TargetOpcode::G_FPEXT:
+ case TargetOpcode::G_FCONSTANT:
// Instruction having only floating-point operands (all scalars in VECRReg)
getInstrPartialMappingIdxs(MI, MRI, /* isFP */ true, OpRegBankIdx);
break;
Added: llvm/trunk/test/CodeGen/X86/GlobalISel/fconstant.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/GlobalISel/fconstant.ll?rev=313478&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/GlobalISel/fconstant.ll (added)
+++ llvm/trunk/test/CodeGen/X86/GlobalISel/fconstant.ll Sun Sep 17 01:08:13 2017
@@ -0,0 +1,40 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=x86_64-linux-gnu -mattr=+sse2 -global-isel -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=CHECK64 --check-prefix=CHECK_SMALL --check-prefix=CHECK_SMALL64 --check-prefix=CHECK_NOPIC64
+; RUN: llc -mtriple=x86_64-linux-gnu -mattr=+sse2 -global-isel -code-model=large -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=CHECK64 --check-prefix=CHECK_LARGE --check-prefix=CHECK_LARGE64
+; RUN: llc -mtriple=i386-linux-gnu -mattr=+sse2 -global-isel -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=CHECK32 --check-prefix=CHECK_SMALL --check-prefix=CHECK_SMALL32
+; RUN: llc -mtriple=i386-linux-gnu -mattr=+sse2 -global-isel -code-model=large -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=CHECK32 --check-prefix=CHECK_LARGE --check-prefix=CHECK_LARGE32
+; RUN: llc -mtriple=x86_64-linux-gnu -mattr=+sse2 -global-isel -relocation-model=pic -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=CHECK64 --check-prefix=CHECK_SMALL --check-prefix=CHECK_SMALL64 --check-prefix=CHECK_PIC64
+
+define void @test_float(float* %a , float %b) {
+; CHECK_SMALL64-LABEL: test_float:
+; CHECK_SMALL64: # BB#0: # %entry
+; CHECK_SMALL64-NEXT: movss .LCPI0_0(%rip), %xmm1 # xmm1 = mem[0],zero,zero,zero
+; CHECK_SMALL64-NEXT: addss %xmm0, %xmm1
+; CHECK_SMALL64-NEXT: movd %xmm1, %eax
+; CHECK_SMALL64-NEXT: movl %eax, (%rdi)
+; CHECK_SMALL64-NEXT: retq
+;
+; CHECK_LARGE64-LABEL: test_float:
+; CHECK_LARGE64: # BB#0: # %entry
+; CHECK_LARGE64-NEXT: movabsq $.LCPI0_0, %rax
+; CHECK_LARGE64-NEXT: addss (%rax), %xmm0
+; CHECK_LARGE64-NEXT: movd %xmm0, %eax
+; CHECK_LARGE64-NEXT: movl %eax, (%rdi)
+; CHECK_LARGE64-NEXT: retq
+;
+; CHECK32-LABEL: test_float:
+; CHECK32: # BB#0: # %entry
+; CHECK32-NEXT: movl 4(%esp), %eax
+; CHECK32-NEXT: movl 8(%esp), %ecx
+; CHECK32-NEXT: movss .LCPI0_0, %xmm0 # xmm0 = mem[0],zero,zero,zero
+; CHECK32-NEXT: movd %ecx, %xmm1
+; CHECK32-NEXT: addss %xmm0, %xmm1
+; CHECK32-NEXT: movd %xmm1, %ecx
+; CHECK32-NEXT: movl %ecx, (%eax)
+; CHECK32-NEXT: retl
+entry:
+ %aa = fadd float 5.500000e+00, %b
+ store float %aa, float* %a
+ ret void
+}
+
Modified: llvm/trunk/test/CodeGen/X86/GlobalISel/legalize-constant.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/GlobalISel/legalize-constant.mir?rev=313478&r1=313477&r2=313478&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/GlobalISel/legalize-constant.mir (original)
+++ llvm/trunk/test/CodeGen/X86/GlobalISel/legalize-constant.mir Sun Sep 17 01:08:13 2017
@@ -1,15 +1,14 @@
-# RUN: llc -mtriple=i386-linux-gnu -global-isel -run-pass=legalizer %s -o - | FileCheck %s --check-prefix=ALL --check-prefix=X32
-# RUN: llc -mtriple=x86_64-linux-gnu -global-isel -run-pass=legalizer %s -o - | FileCheck %s --check-prefix=ALL --check-prefix=X64
+# RUN: llc -mtriple=i386-linux-gnu -mattr=+sse2 -global-isel -run-pass=legalizer %s -o - | FileCheck %s --check-prefix=ALL --check-prefix=X32
+# RUN: llc -mtriple=x86_64-linux-gnu -global-isel -run-pass=legalizer %s -o - | FileCheck %s --check-prefix=ALL --check-prefix=X64
--- |
- define void @constInt_check() {
- ret void
- }
+ define void @test_constant() { ret void }
+ define void @test_fconstant() { ret void }
...
---
-name: constInt_check
-# ALL-LABEL: name: constInt_check
+name: test_constant
+# ALL-LABEL: name: test_constant
registers:
- { id: 0, class: _ }
- { id: 1, class: _ }
@@ -40,4 +39,18 @@ body: |
RET 0
...
+---
+name: test_fconstant
+# ALL-LABEL: name: test_fconstant
+registers:
+ - { id: 0, class: _ }
+ - { id: 1, class: _ }
+body: |
+ bb.0:
+ ; ALL: %0(s32) = G_FCONSTANT float 1.000000e+00
+ ; ALL: %1(s64) = G_FCONSTANT double 2.000000e+00
+
+ %0(s32) = G_FCONSTANT float 1.0
+ %1(s64) = G_FCONSTANT double 2.0
+...
Modified: llvm/trunk/test/CodeGen/X86/GlobalISel/regbankselect-X86_64.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/GlobalISel/regbankselect-X86_64.mir?rev=313478&r1=313477&r2=313478&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/GlobalISel/regbankselect-X86_64.mir (original)
+++ llvm/trunk/test/CodeGen/X86/GlobalISel/regbankselect-X86_64.mir Sun Sep 17 01:08:13 2017
@@ -236,6 +236,10 @@
%conv = fpext float %a to double
ret double %conv
}
+
+ define void @test_fconstant() {
+ ret void
+ }
...
---
@@ -1411,4 +1415,19 @@ body: |
RET 0, implicit %xmm0
...
+---
+name: test_fconstant
+# ALL-LABEL: name: test_fconstant
+legalized: true
+# CHECK: registers:
+# CHECK-NEXT: - { id: 0, class: vecr, preferred-register: '' }
+# CHECK-NEXT: - { id: 1, class: vecr, preferred-register: '' }
+registers:
+ - { id: 0, class: _ }
+ - { id: 1, class: _ }
+body: |
+ bb.0:
+ %0(s32) = G_FCONSTANT float 1.0
+ %1(s64) = G_FCONSTANT double 2.0
+...
Added: llvm/trunk/test/CodeGen/X86/GlobalISel/select-fconstant.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/GlobalISel/select-fconstant.mir?rev=313478&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/GlobalISel/select-fconstant.mir (added)
+++ llvm/trunk/test/CodeGen/X86/GlobalISel/select-fconstant.mir Sun Sep 17 01:08:13 2017
@@ -0,0 +1,94 @@
+#RUN: llc -mtriple=x86_64-linux-gnu -mattr=+sse2 -global-isel -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=CHECK64 --check-prefix=CHECK_SMALL --check-prefix=CHECK_SMALL64 --check-prefix=CHECK_NOPIC64
+#RUN: llc -mtriple=x86_64-linux-gnu -mattr=+sse2 -global-isel -code-model=large -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=CHECK64 --check-prefix=CHECK_LARGE --check-prefix=CHECK_LARGE64
+#RUN: llc -mtriple=i386-linux-gnu -mattr=+sse2 -global-isel -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=CHECK32 --check-prefix=CHECK_SMALL --check-prefix=CHECK_SMALL32
+#RUN: llc -mtriple=i386-linux-gnu -mattr=+sse2 -global-isel -code-model=large -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=CHECK32 --check-prefix=CHECK_LARGE --check-prefix=CHECK_LARGE32
+#RUN: llc -mtriple=x86_64-linux-gnu -mattr=+sse2 -global-isel -relocation-model=pic -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=CHECK64 --check-prefix=CHECK_SMALL --check-prefix=CHECK_SMALL64 --check-prefix=CHECK_PIC64
+
+--- |
+ define float @test_float() {
+ entry:
+ ret float 5.500000e+00
+ }
+
+ define double @test_double() {
+ entry:
+ ret double 5.500000e+00
+ }
+---
+name: test_float
+# CHECK64-LABEL: name: test_float
+#
+# CHECK32-LABEL: name: test_float
+alignment: 4
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+# CHECK_SMALL64: registers:
+# CHECK_SMALL64-NEXT: - { id: 0, class: fr32, preferred-register: '' }
+#
+# CHECK_LARGE64: registers:
+# CHECK_LARGE64-NEXT: - { id: 0, class: fr32, preferred-register: '' }
+# CHECK_LARGE64-NEXT: - { id: 1, class: gr64, preferred-register: '' }
+#
+# CHECK32: registers:
+# CHECK32-NEXT: - { id: 0, class: fr32, preferred-register: '' }
+registers:
+ - { id: 0, class: vecr, preferred-register: '' }
+# CHECK_SMALL64: %0 = MOVSSrm %rip, 1, _, %const.0, _
+# CHECK_SMALL64-NEXT: %xmm0 = COPY %0
+# CHECK_SMALL64-NEXT: RET 0, implicit %xmm0
+#
+# CHECK_LARGE64: %1 = MOV64ri %const.0
+# CHECK_LARGE64-NEXT: %0 = MOVSSrm %1, 1, _, 0, _ :: (load 8 from constant-pool, align 32)
+# CHECK_LARGE64-NEXT: %xmm0 = COPY %0
+# CHECK_LARGE64-NEXT: RET 0, implicit %xmm0
+#
+# CHECK32: %0 = MOVSSrm _, 1, _, %const.0, _
+# CHECK32-NEXT: %xmm0 = COPY %0
+# CHECK32-NEXT: RET 0, implicit %xmm0
+body: |
+ bb.1.entry:
+ %0(s32) = G_FCONSTANT float 5.500000e+00
+ %xmm0 = COPY %0(s32)
+ RET 0, implicit %xmm0
+
+...
+---
+name: test_double
+# CHECK64-LABEL: name: test_double
+#
+# CHECK32-LABEL: name: test_double
+alignment: 4
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+# CHECK_SMALL64: registers:
+# CHECK_SMALL64-NEXT: - { id: 0, class: fr64, preferred-register: '' }
+#
+# CHECK_LARGE64: registers:
+# CHECK_LARGE64-NEXT: - { id: 0, class: fr64, preferred-register: '' }
+# CHECK_LARGE64-NEXT: - { id: 1, class: gr64, preferred-register: '' }
+#
+# CHECK32: registers:
+# CHECK32-NEXT: - { id: 0, class: fr64, preferred-register: '' }
+registers:
+ - { id: 0, class: vecr, preferred-register: '' }
+# CHECK_SMALL64: %0 = MOVSDrm %rip, 1, _, %const.0, _
+# CHECK_SMALL64-NEXT: %xmm0 = COPY %0
+# CHECK_SMALL64-NEXT: RET 0, implicit %xmm0
+#
+# CHECK_LARGE64: %1 = MOV64ri %const.0
+# CHECK_LARGE64-NEXT: %0 = MOVSDrm %1, 1, _, 0, _ :: (load 8 from constant-pool, align 64)
+# CHECK_LARGE64-NEXT: %xmm0 = COPY %0
+# CHECK_LARGE64-NEXT: RET 0, implicit %xmm0
+#
+# CHECK32: %0 = MOVSDrm _, 1, _, %const.0, _
+# CHECK32-NEXT: %xmm0 = COPY %0
+# CHECK32-NEXT: RET 0, implicit %xmm0
+body: |
+ bb.1.entry:
+ %0(s64) = G_FCONSTANT double 5.500000e+00
+ %xmm0 = COPY %0(s64)
+ RET 0, implicit %xmm0
+
+...
More information about the llvm-commits
mailing list