forked from OSchip/llvm-project
[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
This commit is contained in:
parent
da74ed42da
commit
3b97ea39e7
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
||||
...
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
@ -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
|
||||
|
||||
...
|
Loading…
Reference in New Issue