From e353fb8d83b1608e9ea428d09c5e497b2b8b233e Mon Sep 17 00:00:00 2001 From: Igor Breger Date: Wed, 12 Apr 2017 12:54:54 +0000 Subject: [PATCH] [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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@300057 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/X86/X86InstructionSelector.cpp | 53 ++++++- .../X86/GlobalISel/X86-regbankselect.mir | 27 ++++ test/CodeGen/X86/GlobalISel/constant.ll | 54 +++++++ .../X86/GlobalISel/select-constant.mir | 143 ++++++++++++++++++ 4 files changed, 276 insertions(+), 1 deletion(-) create mode 100644 test/CodeGen/X86/GlobalISel/constant.ll create mode 100644 test/CodeGen/X86/GlobalISel/select-constant.mir diff --git a/lib/Target/X86/X86InstructionSelector.cpp b/lib/Target/X86/X86InstructionSelector.cpp index d5a1a133f70..6cc5e8b6359 100644 --- a/lib/Target/X86/X86InstructionSelector.cpp +++ b/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/test/CodeGen/X86/GlobalISel/X86-regbankselect.mir b/test/CodeGen/X86/GlobalISel/X86-regbankselect.mir index e9a0957845a..c4e5fb2d05f 100644 --- a/test/CodeGen/X86/GlobalISel/X86-regbankselect.mir +++ b/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/test/CodeGen/X86/GlobalISel/constant.ll b/test/CodeGen/X86/GlobalISel/constant.ll new file mode 100644 index 00000000000..cab043a51f0 --- /dev/null +++ b/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/test/CodeGen/X86/GlobalISel/select-constant.mir b/test/CodeGen/X86/GlobalISel/select-constant.mir new file mode 100644 index 00000000000..f6b97b578b9 --- /dev/null +++ b/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 + +... -- 2.40.0