[llvm] r300678 - [GlobalIsel][X86] support G_TRUNC selection.

Igor Breger via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 19 04:34:59 PDT 2017


Author: ibreger
Date: Wed Apr 19 06:34:59 2017
New Revision: 300678

URL: http://llvm.org/viewvc/llvm-project?rev=300678&view=rev
Log:
[GlobalIsel][X86] support G_TRUNC selection.

Summary:
[GlobalIsel][X86] support G_TRUNC selection.
Add regbank-select and legalizer tests. Currently legalization of trunc i64 on 32bit platform not supported.

Reviewers: ab, zvi, rovka

Reviewed By: zvi

Subscribers: dberris, kristof.beyls, llvm-commits

Differential Revision: https://reviews.llvm.org/D32115

Added:
    llvm/trunk/test/CodeGen/X86/GlobalISel/legalize-trunc.mir
    llvm/trunk/test/CodeGen/X86/GlobalISel/select-trunc.mir
    llvm/trunk/test/CodeGen/X86/GlobalISel/trunc.ll
Modified:
    llvm/trunk/lib/Target/X86/X86InstructionSelector.cpp
    llvm/trunk/lib/Target/X86/X86RegisterBankInfo.cpp
    llvm/trunk/test/CodeGen/X86/GlobalISel/X86-regbankselect.mir

Modified: llvm/trunk/lib/Target/X86/X86InstructionSelector.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstructionSelector.cpp?rev=300678&r1=300677&r2=300678&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86InstructionSelector.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86InstructionSelector.cpp Wed Apr 19 06:34:59 2017
@@ -67,6 +67,8 @@ private:
                         MachineFunction &MF) const;
   bool selectConstant(MachineInstr &I, MachineRegisterInfo &MRI,
                       MachineFunction &MF) const;
+  bool selectTrunc(MachineInstr &I, MachineRegisterInfo &MRI,
+                   MachineFunction &MF) const;
 
   const X86Subtarget &STI;
   const X86InstrInfo &TII;
@@ -99,6 +101,10 @@ X86InstructionSelector::X86InstructionSe
 static const TargetRegisterClass *
 getRegClassForTypeOnBank(LLT Ty, const RegisterBank &RB) {
   if (RB.getID() == X86::GPRRegBankID) {
+    if (Ty.getSizeInBits() <= 8)
+      return &X86::GR8RegClass;
+    if (Ty.getSizeInBits() == 16)
+      return &X86::GR16RegClass;
     if (Ty.getSizeInBits() == 32)
       return &X86::GR32RegClass;
     if (Ty.getSizeInBits() == 64)
@@ -207,6 +213,8 @@ bool X86InstructionSelector::select(Mach
     return true;
   if (selectConstant(I, MRI, MF))
     return true;
+  if (selectTrunc(I, MRI, MF))
+    return true;
 
   return selectImpl(I);
 }
@@ -509,6 +517,59 @@ bool X86InstructionSelector::selectConst
   return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
 }
 
+bool X86InstructionSelector::selectTrunc(MachineInstr &I,
+                                         MachineRegisterInfo &MRI,
+                                         MachineFunction &MF) const {
+  if (I.getOpcode() != TargetOpcode::G_TRUNC)
+    return false;
+
+  const unsigned DstReg = I.getOperand(0).getReg();
+  const unsigned SrcReg = I.getOperand(1).getReg();
+
+  const LLT DstTy = MRI.getType(DstReg);
+  const LLT SrcTy = MRI.getType(SrcReg);
+
+  const RegisterBank &DstRB = *RBI.getRegBank(DstReg, MRI, TRI);
+  const RegisterBank &SrcRB = *RBI.getRegBank(SrcReg, MRI, TRI);
+
+  if (DstRB.getID() != SrcRB.getID()) {
+    DEBUG(dbgs() << "G_TRUNC input/output on different banks\n");
+    return false;
+  }
+
+  if (DstRB.getID() != X86::GPRRegBankID)
+    return false;
+
+  const TargetRegisterClass *DstRC = getRegClassForTypeOnBank(DstTy, DstRB);
+  if (!DstRC)
+    return false;
+
+  const TargetRegisterClass *SrcRC = getRegClassForTypeOnBank(SrcTy, SrcRB);
+  if (!SrcRC)
+    return false;
+
+  if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, MRI) ||
+      !RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) {
+    DEBUG(dbgs() << "Failed to constrain G_TRUNC\n");
+    return false;
+  }
+
+  if (DstRC == SrcRC) {
+    // Nothing to be done
+  } else if (DstRC == &X86::GR32RegClass) {
+    I.getOperand(1).setSubReg(X86::sub_32bit);
+  } else if (DstRC == &X86::GR16RegClass) {
+    I.getOperand(1).setSubReg(X86::sub_16bit);
+  } else if (DstRC == &X86::GR8RegClass) {
+    I.getOperand(1).setSubReg(X86::sub_8bit);
+  } else {
+    return false;
+  }
+
+  I.setDesc(TII.get(X86::COPY));
+  return true;
+}
+
 InstructionSelector *
 llvm::createX86InstructionSelector(X86Subtarget &Subtarget,
                                    X86RegisterBankInfo &RBI) {

Modified: llvm/trunk/lib/Target/X86/X86RegisterBankInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86RegisterBankInfo.cpp?rev=300678&r1=300677&r2=300678&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86RegisterBankInfo.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86RegisterBankInfo.cpp Wed Apr 19 06:34:59 2017
@@ -68,6 +68,7 @@ X86GenRegisterBankInfo::PartialMappingId
 X86GenRegisterBankInfo::getPartialMappingIdx(const LLT &Ty, bool isFP) {
   if ((Ty.isScalar() && !isFP) || Ty.isPointer()) {
     switch (Ty.getSizeInBits()) {
+    case 1:
     case 8:
       return PMI_GPR8;
     case 16:

Modified: llvm/trunk/test/CodeGen/X86/GlobalISel/X86-regbankselect.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/GlobalISel/X86-regbankselect.mir?rev=300678&r1=300677&r2=300678&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/GlobalISel/X86-regbankselect.mir (original)
+++ llvm/trunk/test/CodeGen/X86/GlobalISel/X86-regbankselect.mir Wed Apr 19 06:34:59 2017
@@ -106,6 +106,10 @@
     ret void
   }
 
+  define void @trunc_check() {
+    ret void
+  }
+
 ...
 ---
 name:            test_add_i8
@@ -632,3 +636,27 @@ body:             |
     RET 0
 
 ...
+---
+name:            trunc_check
+alignment:       4
+legalized:       true
+# CHECK-LABEL: name:            trunc_check
+# CHECK: registers:
+# CHECK-NEXT:  - { id: 0, class: gpr }
+# CHECK-NEXT:  - { id: 1, class: gpr }
+# CHECK-NEXT:  - { id: 2, class: gpr }
+# CHECK-NEXT:  - { id: 3, class: gpr }
+registers:
+  - { id: 0, class: _ }
+  - { id: 1, class: _ }
+  - { id: 2, class: _ }
+  - { id: 3, class: _ }
+body:             |
+  bb.0 (%ir-block.0):
+    %0(s32) = IMPLICIT_DEF
+    %1(s1) = G_TRUNC %0(s32)
+    %2(s8) = G_TRUNC %0(s32)
+    %3(s16) = G_TRUNC %0(s32)
+    RET 0
+
+...

Added: llvm/trunk/test/CodeGen/X86/GlobalISel/legalize-trunc.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/GlobalISel/legalize-trunc.mir?rev=300678&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/GlobalISel/legalize-trunc.mir (added)
+++ llvm/trunk/test/CodeGen/X86/GlobalISel/legalize-trunc.mir Wed Apr 19 06:34:59 2017
@@ -0,0 +1,31 @@
+# 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
+--- |
+  define void @trunc_check() {
+    ret void
+  }
+
+...
+---
+name:            trunc_check
+# ALL-LABEL: name:            trunc_check
+registers:
+  - { id: 0, class: _ }
+  - { id: 1, class: _ }
+  - { id: 2, class: _ }
+  - { id: 3, class: _ }
+body:             |
+  bb.1 (%ir-block.0):
+    %0(s32) = IMPLICIT_DEF
+    ; ALL: %1(s1)  = G_TRUNC %0(s32)
+    %1(s1)  = G_TRUNC %0(s32)
+
+    ; ALL: %2(s8)  = G_TRUNC %0(s32)
+    %2(s8)  = G_TRUNC %0(s32)
+
+    ; ALL: %3(s16) = G_TRUNC %0(s32)
+    %3(s16) = G_TRUNC %0(s32)
+    RET 0
+
+...
+

Added: llvm/trunk/test/CodeGen/X86/GlobalISel/select-trunc.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/GlobalISel/select-trunc.mir?rev=300678&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/GlobalISel/select-trunc.mir (added)
+++ llvm/trunk/test/CodeGen/X86/GlobalISel/select-trunc.mir Wed Apr 19 06:34:59 2017
@@ -0,0 +1,183 @@
+# RUN: llc -mtriple=x86_64-linux-gnu -global-isel -run-pass=instruction-select %s -o - | FileCheck %s --check-prefix=CHECK
+--- |
+  define i1 @trunc_i32toi1(i32 %a) {
+    %r = trunc i32 %a to i1
+    ret i1 %r
+  }
+
+  define i8 @trunc_i32toi8(i32 %a) {
+    %r = trunc i32 %a to i8
+    ret i8 %r
+  }
+
+  define i16 @trunc_i32toi16(i32 %a) {
+    %r = trunc i32 %a to i16
+    ret i16 %r
+  }
+
+  define i8 @trunc_i64toi8(i64 %a) {
+    %r = trunc i64 %a to i8
+    ret i8 %r
+  }
+
+  define i16 @trunc_i64toi16(i64 %a) {
+    %r = trunc i64 %a to i16
+    ret i16 %r
+  }
+
+  define i32 @trunc_i64toi32(i64 %a) {
+    %r = trunc i64 %a to i32
+    ret i32 %r
+  }
+
+...
+---
+name:            trunc_i32toi1
+alignment:       4
+legalized:       true
+regBankSelected: true
+selected:        false
+# CHECK-LABEL: name:            trunc_i32toi1
+# CHECK: registers:
+# CHECK-NEXT:  - { id: 0, class: gr32 }
+# CHECK-NEXT:  - { id: 1, class: gr8 }
+registers:
+  - { id: 0, class: gpr }
+  - { id: 1, class: gpr }
+# CHECK:  body:
+# CHECK:    %1 = COPY %0.sub_8
+body:             |
+  bb.1 (%ir-block.0):
+    liveins: %edi
+
+    %0(s32) = COPY %edi
+    %1(s1) = G_TRUNC %0(s32)
+    %al = COPY %1(s1)
+    RET 0, implicit %al
+
+...
+---
+name:            trunc_i32toi8
+alignment:       4
+legalized:       true
+regBankSelected: true
+selected:        false
+# CHECK-LABEL: name:            trunc_i32toi8
+# CHECK: registers:
+# CHECK-NEXT:  - { id: 0, class: gr32 }
+# CHECK-NEXT:  - { id: 1, class: gr8 }
+registers:
+  - { id: 0, class: gpr }
+  - { id: 1, class: gpr }
+# CHECK:  body:
+# CHECK:    %1 = COPY %0.sub_8
+body:             |
+  bb.1 (%ir-block.0):
+    liveins: %edi
+
+    %0(s32) = COPY %edi
+    %1(s8) = G_TRUNC %0(s32)
+    %al = COPY %1(s8)
+    RET 0, implicit %al
+
+...
+---
+name:            trunc_i32toi16
+alignment:       4
+legalized:       true
+regBankSelected: true
+selected:        false
+# CHECK-LABEL: name:            trunc_i32toi16
+# CHECK: registers:
+# CHECK-NEXT:  - { id: 0, class: gr32 }
+# CHECK-NEXT:  - { id: 1, class: gr16 }
+registers:
+  - { id: 0, class: gpr }
+  - { id: 1, class: gpr }
+# CHECK:  body:
+# CHECK:    %1 = COPY %0.sub_16
+body:             |
+  bb.1 (%ir-block.0):
+    liveins: %edi
+
+    %0(s32) = COPY %edi
+    %1(s16) = G_TRUNC %0(s32)
+    %ax = COPY %1(s16)
+    RET 0, implicit %ax
+
+...
+---
+name:            trunc_i64toi8
+alignment:       4
+legalized:       true
+regBankSelected: true
+selected:        false
+# CHECK-LABEL: name:            trunc_i64toi8
+# CHECK: registers:
+# CHECK-NEXT:  - { id: 0, class: gr64 }
+# CHECK-NEXT:  - { id: 1, class: gr8 }
+registers:
+  - { id: 0, class: gpr }
+  - { id: 1, class: gpr }
+# CHECK:  body:
+# CHECK:    %1 = COPY %0.sub_8
+body:             |
+  bb.1 (%ir-block.0):
+    liveins: %rdi
+
+    %0(s64) = COPY %rdi
+    %1(s8) = G_TRUNC %0(s64)
+    %al = COPY %1(s8)
+    RET 0, implicit %al
+
+...
+---
+name:            trunc_i64toi16
+alignment:       4
+legalized:       true
+regBankSelected: true
+selected:        false
+# CHECK-LABEL: name:            trunc_i64toi16
+# CHECK: registers:
+# CHECK-NEXT:  - { id: 0, class: gr64 }
+# CHECK-NEXT:  - { id: 1, class: gr16 }
+registers:
+  - { id: 0, class: gpr }
+  - { id: 1, class: gpr }
+# CHECK:  body:
+# CHECK:    %1 = COPY %0.sub_16
+body:             |
+  bb.1 (%ir-block.0):
+    liveins: %rdi
+
+    %0(s64) = COPY %rdi
+    %1(s16) = G_TRUNC %0(s64)
+    %ax = COPY %1(s16)
+    RET 0, implicit %ax
+
+...
+---
+name:            trunc_i64toi32
+alignment:       4
+legalized:       true
+regBankSelected: true
+selected:        false
+# CHECK-LABEL: name:            trunc_i64toi32
+# CHECK: registers:
+# CHECK-NEXT:  - { id: 0, class: gr64 }
+# CHECK-NEXT:  - { id: 1, class: gr32 }
+registers:
+  - { id: 0, class: gpr }
+  - { id: 1, class: gpr }
+# CHECK:  body:
+# CHECK:    %1 = COPY %0.sub_32
+body:             |
+  bb.1 (%ir-block.0):
+    liveins: %rdi
+
+    %0(s64) = COPY %rdi
+    %1(s32) = G_TRUNC %0(s64)
+    %eax = COPY %1(s32)
+    RET 0, implicit %eax
+
+...

Added: llvm/trunk/test/CodeGen/X86/GlobalISel/trunc.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/GlobalISel/trunc.ll?rev=300678&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/GlobalISel/trunc.ll (added)
+++ llvm/trunk/test/CodeGen/X86/GlobalISel/trunc.ll Wed Apr 19 06:34:59 2017
@@ -0,0 +1,57 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=x86_64-linux-gnu -global-isel < %s -o - | FileCheck %s --check-prefix=CHECK
+
+define i1 @trunc_i32toi1(i32 %a) {
+; CHECK-LABEL: trunc_i32toi1:
+; CHECK:       # BB#0:
+; CHECK-NEXT:    movl %edi, %eax
+; CHECK-NEXT:    retq
+  %r = trunc i32 %a to i1
+  ret i1 %r
+}
+
+define i8 @trunc_i32toi8(i32 %a) {
+; CHECK-LABEL: trunc_i32toi8:
+; CHECK:       # BB#0:
+; CHECK-NEXT:    movl %edi, %eax
+; CHECK-NEXT:    retq
+  %r = trunc i32 %a to i8
+  ret i8 %r
+}
+
+define i16 @trunc_i32toi16(i32 %a) {
+; CHECK-LABEL: trunc_i32toi16:
+; CHECK:       # BB#0:
+; CHECK-NEXT:    movl %edi, %eax
+; CHECK-NEXT:    retq
+  %r = trunc i32 %a to i16
+  ret i16 %r
+}
+
+define i8 @trunc_i64toi8(i64 %a) {
+; CHECK-LABEL: trunc_i64toi8:
+; CHECK:       # BB#0:
+; CHECK-NEXT:    movl %edi, %eax
+; CHECK-NEXT:    retq
+  %r = trunc i64 %a to i8
+  ret i8 %r
+}
+
+define i16 @trunc_i64toi16(i64 %a) {
+; CHECK-LABEL: trunc_i64toi16:
+; CHECK:       # BB#0:
+; CHECK-NEXT:    movl %edi, %eax
+; CHECK-NEXT:    retq
+  %r = trunc i64 %a to i16
+  ret i16 %r
+}
+
+define i32 @trunc_i64toi32(i64 %a) {
+; CHECK-LABEL: trunc_i64toi32:
+; CHECK:       # BB#0:
+; CHECK-NEXT:    movl %edi, %eax
+; CHECK-NEXT:    retq
+  %r = trunc i64 %a to i32
+  ret i32 %r
+}
+




More information about the llvm-commits mailing list