[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