[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