Index: lib/CodeGen/GlobalISel/LegalizerHelper.cpp =================================================================== --- lib/CodeGen/GlobalISel/LegalizerHelper.cpp +++ lib/CodeGen/GlobalISel/LegalizerHelper.cpp @@ -274,6 +274,26 @@ 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; + } } } Index: lib/Target/X86/X86LegalizerInfo.cpp =================================================================== --- lib/Target/X86/X86LegalizerInfo.cpp +++ lib/Target/X86/X86LegalizerInfo.cpp @@ -44,9 +44,11 @@ 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 @@ // 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 @@ 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 @@ // 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() { Index: test/CodeGen/X86/GlobalISel/legalize-const.mir =================================================================== --- /dev/null +++ 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 +... +