summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIgor Breger <igor.breger@intel.com>2017-04-12 12:54:54 +0000
committerIgor Breger <igor.breger@intel.com>2017-04-12 12:54:54 +0000
commit3b97ea39e76af6edfcf38075c75ff8d87e989d84 (patch)
treefbe162a023b1d2bee45859678b5479b98c39452c
parentda74ed42dadbbf62644fb8fe0ff1e7885c7b2a04 (diff)
downloadbcm5719-llvm-3b97ea39e76af6edfcf38075c75ff8d87e989d84.tar.gz
bcm5719-llvm-3b97ea39e76af6edfcf38075c75ff8d87e989d84.zip
[GlobalIsel][X86] support G_CONSTANT selection.
Summary: [GlobalISel][X86] support G_CONSTANT selection. Add regbank select tests. Reviewers: zvi, guyblank Reviewed By: guyblank Subscribers: llvm-commits, dberris, rovka, kristof.beyls Differential Revision: https://reviews.llvm.org/D31974 llvm-svn: 300057
-rw-r--r--llvm/lib/Target/X86/X86InstructionSelector.cpp53
-rw-r--r--llvm/test/CodeGen/X86/GlobalISel/X86-regbankselect.mir27
-rw-r--r--llvm/test/CodeGen/X86/GlobalISel/constant.ll54
-rw-r--r--llvm/test/CodeGen/X86/GlobalISel/select-constant.mir143
4 files changed, 276 insertions, 1 deletions
diff --git a/llvm/lib/Target/X86/X86InstructionSelector.cpp b/llvm/lib/Target/X86/X86InstructionSelector.cpp
index d5a1a133f70..6cc5e8b6359 100644
--- a/llvm/lib/Target/X86/X86InstructionSelector.cpp
+++ b/llvm/lib/Target/X86/X86InstructionSelector.cpp
@@ -18,13 +18,13 @@
#include "X86RegisterInfo.h"
#include "X86Subtarget.h"
#include "X86TargetMachine.h"
+#include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
-#include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
#include "llvm/IR/Type.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
@@ -65,6 +65,8 @@ private:
MachineFunction &MF) const;
bool selectFrameIndex(MachineInstr &I, MachineRegisterInfo &MRI,
MachineFunction &MF) const;
+ bool selectConstant(MachineInstr &I, MachineRegisterInfo &MRI,
+ MachineFunction &MF) const;
const X86Subtarget &STI;
const X86InstrInfo &TII;
@@ -203,6 +205,8 @@ bool X86InstructionSelector::select(MachineInstr &I) const {
return true;
if (selectFrameIndex(I, MRI, MF))
return true;
+ if (selectConstant(I, MRI, MF))
+ return true;
return selectImpl(I);
}
@@ -458,6 +462,53 @@ bool X86InstructionSelector::selectFrameIndex(MachineInstr &I,
return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
}
+bool X86InstructionSelector::selectConstant(MachineInstr &I,
+ MachineRegisterInfo &MRI,
+ MachineFunction &MF) const {
+ if (I.getOpcode() != TargetOpcode::G_CONSTANT)
+ return false;
+
+ const unsigned DefReg = I.getOperand(0).getReg();
+ LLT Ty = MRI.getType(DefReg);
+
+ assert(Ty.isScalar() && "invalid element type.");
+
+ uint64_t Val = 0;
+ if (I.getOperand(1).isCImm()) {
+ Val = I.getOperand(1).getCImm()->getZExtValue();
+ I.getOperand(1).ChangeToImmediate(Val);
+ } else if (I.getOperand(1).isImm()) {
+ Val = I.getOperand(1).getImm();
+ } else
+ llvm_unreachable("Unsupported operand type.");
+
+ unsigned NewOpc;
+ switch (Ty.getSizeInBits()) {
+ case 8:
+ NewOpc = X86::MOV8ri;
+ break;
+ case 16:
+ NewOpc = X86::MOV16ri;
+ break;
+ case 32:
+ NewOpc = X86::MOV32ri;
+ break;
+ case 64: {
+ // TODO: in case isUInt<32>(Val), X86::MOV32ri can be used
+ if (isInt<32>(Val))
+ NewOpc = X86::MOV64ri32;
+ else
+ NewOpc = X86::MOV64ri;
+ break;
+ }
+ default:
+ llvm_unreachable("Can't select G_CONSTANT, unsupported type.");
+ }
+
+ I.setDesc(TII.get(NewOpc));
+ return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
+}
+
InstructionSelector *
llvm::createX86InstructionSelector(X86Subtarget &Subtarget,
X86RegisterBankInfo &RBI) {
diff --git a/llvm/test/CodeGen/X86/GlobalISel/X86-regbankselect.mir b/llvm/test/CodeGen/X86/GlobalISel/X86-regbankselect.mir
index e9a0957845a..c4e5fb2d05f 100644
--- a/llvm/test/CodeGen/X86/GlobalISel/X86-regbankselect.mir
+++ b/llvm/test/CodeGen/X86/GlobalISel/X86-regbankselect.mir
@@ -102,6 +102,10 @@
ret double* %p1
}
+ define void @constInt_check() {
+ ret void
+ }
+
...
---
name: test_add_i8
@@ -604,4 +608,27 @@ body: |
RET 0, implicit %rax
...
+---
+name: constInt_check
+alignment: 4
+legalized: true
+# CHECK-LABEL: name: constInt_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(s8) = G_CONSTANT i8 8
+ %1(s16) = G_CONSTANT i16 16
+ %2(s32) = G_CONSTANT i32 32
+ %3(s64) = G_CONSTANT i64 64
+ RET 0
+...
diff --git a/llvm/test/CodeGen/X86/GlobalISel/constant.ll b/llvm/test/CodeGen/X86/GlobalISel/constant.ll
new file mode 100644
index 00000000000..cab043a51f0
--- /dev/null
+++ b/llvm/test/CodeGen/X86/GlobalISel/constant.ll
@@ -0,0 +1,54 @@
+; 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=ALL --check-prefix=X64
+
+define i8 @const_i8() {
+; ALL-LABEL: const_i8:
+; ALL: # BB#0:
+; ALL-NEXT: movb $2, %al
+; ALL-NEXT: retq
+ ret i8 2
+}
+
+define i16 @const_i16() {
+; ALL-LABEL: const_i16:
+; ALL: # BB#0:
+; ALL-NEXT: movw $3, %ax
+; ALL-NEXT: retq
+ ret i16 3
+}
+
+define i32 @const_i32() {
+; ALL-LABEL: const_i32:
+; ALL: # BB#0:
+; ALL-NEXT: movl $4, %eax
+; ALL-NEXT: retq
+ ret i32 4
+}
+
+define i64 @const_i64() {
+; ALL-LABEL: const_i64:
+; ALL: # BB#0:
+; ALL-NEXT: movabsq $68719476720, %rax # imm = 0xFFFFFFFF0
+; ALL-NEXT: retq
+ ret i64 68719476720
+}
+
+;i64 value fit into u32
+define i64 @const_i64_u32() {
+; ALL-LABEL: const_i64_u32:
+; ALL: # BB#0:
+; ALL-NEXT: movq $1879048192, %rax # imm = 0x70000000
+; ALL-NEXT: retq
+ ret i64 1879048192
+}
+
+;i64 value fit into i32
+define i64 @const_i64_i32() {
+; ALL-LABEL: const_i64_i32:
+; ALL: # BB#0:
+; ALL-NEXT: movq $-1, %rax
+; ALL-NEXT: retq
+ ret i64 -1
+}
+
+
diff --git a/llvm/test/CodeGen/X86/GlobalISel/select-constant.mir b/llvm/test/CodeGen/X86/GlobalISel/select-constant.mir
new file mode 100644
index 00000000000..f6b97b578b9
--- /dev/null
+++ b/llvm/test/CodeGen/X86/GlobalISel/select-constant.mir
@@ -0,0 +1,143 @@
+# RUN: llc -mtriple=x86_64-linux-gnu -global-isel -run-pass=instruction-select %s -o - | FileCheck %s --check-prefix=CHECK
+
+--- |
+ define i8 @const_i8() {
+ ret i8 2
+ }
+
+ define i16 @const_i16() {
+ ret i16 3
+ }
+
+ define i32 @const_i32() {
+ ret i32 4
+ }
+
+ define i64 @const_i64() {
+ ret i64 68719476720
+ }
+
+ define i64 @const_i64_u32() {
+ ret i64 1879048192
+ }
+
+ define i64 @const_i64_i32() {
+ ret i64 -1
+ }
+
+...
+---
+name: const_i8
+legalized: true
+regBankSelected: true
+selected: false
+# CHECK-LABEL: name: const_i8
+# CHECK: registers:
+# CHECK-NEXT: - { id: 0, class: gr8 }
+registers:
+ - { id: 0, class: gpr }
+# CHECK: body:
+# CHECK: %0 = MOV8ri 2
+body: |
+ bb.1 (%ir-block.0):
+ %0(s8) = G_CONSTANT i8 2
+ %al = COPY %0(s8)
+ RET 0, implicit %al
+
+...
+---
+name: const_i16
+legalized: true
+regBankSelected: true
+selected: false
+# CHECK-LABEL: name: const_i16
+# CHECK: registers:
+# CHECK-NEXT: - { id: 0, class: gr16 }
+registers:
+ - { id: 0, class: gpr }
+# CHECK: body:
+# CHECK: %0 = MOV16ri 3
+body: |
+ bb.1 (%ir-block.0):
+ %0(s16) = G_CONSTANT i16 3
+ %ax = COPY %0(s16)
+ RET 0, implicit %ax
+
+...
+---
+name: const_i32
+legalized: true
+regBankSelected: true
+selected: false
+# CHECK-LABEL: name: const_i32
+# CHECK: registers:
+# CHECK-NEXT: - { id: 0, class: gr32 }
+registers:
+ - { id: 0, class: gpr }
+# CHECK: body:
+# CHECK: %0 = MOV32ri 4
+body: |
+ bb.1 (%ir-block.0):
+ %0(s32) = G_CONSTANT i32 4
+ %eax = COPY %0(s32)
+ RET 0, implicit %eax
+
+...
+---
+name: const_i64
+legalized: true
+regBankSelected: true
+selected: false
+# CHECK-LABEL: name: const_i64
+# CHECK: registers:
+# CHECK-NEXT: - { id: 0, class: gr64 }
+registers:
+ - { id: 0, class: gpr }
+# CHECK: body:
+# CHECK: %0 = MOV64ri 68719476720
+body: |
+ bb.1 (%ir-block.0):
+ %0(s64) = G_CONSTANT i64 68719476720
+ %rax = COPY %0(s64)
+ RET 0, implicit %rax
+
+...
+---
+name: const_i64_u32
+alignment: 4
+legalized: true
+regBankSelected: true
+selected: false
+# CHECK-LABEL: name: const_i64_u32
+# CHECK: registers:
+# CHECK-NEXT: - { id: 0, class: gr64 }
+registers:
+ - { id: 0, class: gpr }
+# CHECK: body:
+# CHECK: %0 = MOV64ri32 1879048192
+body: |
+ bb.1 (%ir-block.0):
+ %0(s64) = G_CONSTANT i64 1879048192
+ %rax = COPY %0(s64)
+ RET 0, implicit %rax
+
+...
+---
+name: const_i64_i32
+legalized: true
+regBankSelected: true
+selected: false
+# CHECK-LABEL: name: const_i64_i32
+# CHECK: registers:
+# CHECK-NEXT: - { id: 0, class: gr64 }
+registers:
+ - { id: 0, class: gpr }
+# CHECK: body:
+# CHECK: %0 = MOV64ri32 -1
+body: |
+ bb.1 (%ir-block.0):
+ %0(s64) = G_CONSTANT i64 -1
+ %rax = COPY %0(s64)
+ RET 0, implicit %rax
+
+...
OpenPOWER on IntegriCloud