From ea3c2beccb11462984324eca67a3e095ada322ae Mon Sep 17 00:00:00 2001 From: Igor Breger Date: Fri, 7 Apr 2017 14:41:59 +0000 Subject: [PATCH] [GlobalISel] implement narrowing for G_CONSTANT. Summary: [GlobalISel] implement narrowing for G_CONSTANT. Reviewers: bogner, zvi, t.p.northover Reviewed By: t.p.northover Subscribers: llvm-commits, dberris, rovka, kristof.beyls Differential Revision: https://reviews.llvm.org/D31744 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@299772 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/GlobalISel/LegalizerHelper.cpp | 20 ++++++++++++ lib/Target/X86/X86LegalizerInfo.cpp | 16 ++++++++++ test/CodeGen/X86/GlobalISel/legalize-const.mir | 43 ++++++++++++++++++++++++++ 3 files changed, 79 insertions(+) create mode 100644 test/CodeGen/X86/GlobalISel/legalize-const.mir diff --git a/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/lib/CodeGen/GlobalISel/LegalizerHelper.cpp index e47269595f1..17b7e294b6b 100644 --- a/lib/CodeGen/GlobalISel/LegalizerHelper.cpp +++ b/lib/CodeGen/GlobalISel/LegalizerHelper.cpp @@ -274,6 +274,26 @@ LegalizerHelper::LegalizeResult LegalizerHelper::narrowScalar(MachineInstr &MI, MI.eraseFromParent(); return Legalized; } + case TargetOpcode::G_CONSTANT: { + unsigned NarrowSize = NarrowTy.getSizeInBits(); + int NumParts = + MRI.getType(MI.getOperand(0).getReg()).getSizeInBits() / NarrowSize; + const APInt &Cst = MI.getOperand(1).getCImm()->getValue(); + LLVMContext &Ctx = MIRBuilder.getMF().getFunction()->getContext(); + + SmallVector DstRegs; + for (int i = 0; i < NumParts; ++i) { + unsigned DstReg = MRI.createGenericVirtualRegister(NarrowTy); + ConstantInt *CI = + ConstantInt::get(Ctx, Cst.lshr(NarrowSize * i).trunc(NarrowSize)); + MIRBuilder.buildConstant(DstReg, *CI); + DstRegs.push_back(DstReg); + } + unsigned DstReg = MI.getOperand(0).getReg(); + MIRBuilder.buildMerge(DstReg, DstRegs); + MI.eraseFromParent(); + return Legalized; + } } } diff --git a/lib/Target/X86/X86LegalizerInfo.cpp b/lib/Target/X86/X86LegalizerInfo.cpp index 3ab80c4f20c..c2dc762fec5 100644 --- a/lib/Target/X86/X86LegalizerInfo.cpp +++ b/lib/Target/X86/X86LegalizerInfo.cpp @@ -44,9 +44,11 @@ void X86LegalizerInfo::setLegalizerInfo32bit() { return; const LLT p0 = LLT::pointer(0, 32); + const LLT s1 = LLT::scalar(1); const LLT s8 = LLT::scalar(8); const LLT s16 = LLT::scalar(16); const LLT s32 = LLT::scalar(32); + const LLT s64 = LLT::scalar(64); for (unsigned BinOp : {G_ADD, G_SUB}) for (auto Ty : {s8, s16, s32}) @@ -62,6 +64,13 @@ void X86LegalizerInfo::setLegalizerInfo32bit() { // Pointer-handling setAction({G_FRAME_INDEX, p0}, Legal); + + // Constants + for (auto Ty : {s8, s16, s32, p0}) + setAction({TargetOpcode::G_CONSTANT, Ty}, Legal); + + setAction({TargetOpcode::G_CONSTANT, s1}, WidenScalar); + setAction({TargetOpcode::G_CONSTANT, s64}, NarrowScalar); } void X86LegalizerInfo::setLegalizerInfo64bit() { @@ -70,6 +79,7 @@ void X86LegalizerInfo::setLegalizerInfo64bit() { return; const LLT p0 = LLT::pointer(0, TM.getPointerSize() * 8); + const LLT s1 = LLT::scalar(1); const LLT s8 = LLT::scalar(8); const LLT s16 = LLT::scalar(16); const LLT s32 = LLT::scalar(32); @@ -89,6 +99,12 @@ void X86LegalizerInfo::setLegalizerInfo64bit() { // Pointer-handling setAction({G_FRAME_INDEX, p0}, Legal); + + // Constants + for (auto Ty : {s8, s16, s32, s64, p0}) + setAction({TargetOpcode::G_CONSTANT, Ty}, Legal); + + setAction({TargetOpcode::G_CONSTANT, s1}, WidenScalar); } void X86LegalizerInfo::setLegalizerInfoSSE1() { diff --git a/test/CodeGen/X86/GlobalISel/legalize-const.mir b/test/CodeGen/X86/GlobalISel/legalize-const.mir new file mode 100644 index 00000000000..612d33a77fc --- /dev/null +++ b/test/CodeGen/X86/GlobalISel/legalize-const.mir @@ -0,0 +1,43 @@ +# 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 @constInt_check() { + ret void + } + +... +--- +name: constInt_check +# ALL-LABEL: name: constInt_check +registers: + - { id: 0, class: _ } + - { id: 1, class: _ } + - { id: 2, class: _ } + - { id: 3, class: _ } + - { id: 4, class: _ } +body: | + bb.1 (%ir-block.0): + ; ALL: %5(s8) = G_CONSTANT i8 -1 + ; ALL: %0(s1) = G_TRUNC %5(s8) + %0(s1) = G_CONSTANT i1 1 + + ; ALL: %1(s8) = G_CONSTANT i8 8 + %1(s8) = G_CONSTANT i8 8 + + ; ALL: %2(s16) = G_CONSTANT i16 16 + %2(s16) = G_CONSTANT i16 16 + + ; ALL: %3(s32) = G_CONSTANT i32 32 + %3(s32) = G_CONSTANT i32 32 + + ; X64: %4(s64) = G_CONSTANT i64 64 + + ; X32: %6(s32) = G_CONSTANT i32 64 + ; X32: %7(s32) = G_CONSTANT i32 0 + ; X32: %4(s64) = G_MERGE_VALUES %6(s32), %7(s32) + %4(s64) = G_CONSTANT i64 64 + + RET 0 +... + -- 2.11.0