From 657bfd330204a748d5b5f9bca4fd50199f913240 Mon Sep 17 00:00:00 2001 From: Diana Picus Date: Thu, 11 May 2017 08:28:31 +0000 Subject: [PATCH] [ARM][GlobalISel] Support for G_ANYEXT G_ANYEXT can be introduced by the legalizer when widening scalars. Add support for it in the register bank info (same mapping as everything else) and in the instruction selector. When selecting it, we treat it as a COPY, just like G_TRUNC. On this occasion we get rid of some assertions in selectCopy so we can reuse it. This shouldn't be a problem at the moment since we're not supporting any complicated cases (e.g. FPR, different register banks). We might want to separate the paths when we do. llvm-svn: 302778 --- .../lib/Target/ARM/ARMInstructionSelector.cpp | 13 ++--- llvm/lib/Target/ARM/ARMRegisterBankInfo.cpp | 1 + .../ARM/GlobalISel/arm-instruction-select.mir | 54 +++++++++++++++++++ .../ARM/GlobalISel/arm-regbankselect.mir | 45 ++++++++++++++++ 4 files changed, 103 insertions(+), 10 deletions(-) diff --git a/llvm/lib/Target/ARM/ARMInstructionSelector.cpp b/llvm/lib/Target/ARM/ARMInstructionSelector.cpp index 2d6bad95d7cd..8c680cdf9b47 100644 --- a/llvm/lib/Target/ARM/ARMInstructionSelector.cpp +++ b/llvm/lib/Target/ARM/ARMInstructionSelector.cpp @@ -101,14 +101,6 @@ static bool selectCopy(MachineInstr &I, const TargetInstrInfo &TII, assert(RegBank && "Can't get reg bank for virtual register"); const unsigned DstSize = MRI.getType(DstReg).getSizeInBits(); - (void)DstSize; - unsigned SrcReg = I.getOperand(1).getReg(); - const unsigned SrcSize = RBI.getSizeInBits(SrcReg, MRI, TRI); - (void)SrcSize; - // We use copies for trunc, so it's ok for the size of the destination to be - // smaller (the higher bits will just be undefined). - assert(DstSize <= SrcSize && "Copy with different width?!"); - assert((RegBank->getID() == ARM::GPRRegBankID || RegBank->getID() == ARM::FPRRegBankID) && "Unsupported reg bank"); @@ -330,6 +322,7 @@ bool ARMInstructionSelector::select(MachineInstr &I) const { } break; } + case G_ANYEXT: case G_TRUNC: { // The high bits are undefined, so there's nothing special to do, just // treat it as a copy. @@ -340,12 +333,12 @@ bool ARMInstructionSelector::select(MachineInstr &I) const { const auto &DstRegBank = *RBI.getRegBank(DstReg, MRI, TRI); if (SrcRegBank.getID() != DstRegBank.getID()) { - DEBUG(dbgs() << "G_TRUNC operands on different register banks\n"); + DEBUG(dbgs() << "G_TRUNC/G_ANYEXT operands on different register banks\n"); return false; } if (SrcRegBank.getID() != ARM::GPRRegBankID) { - DEBUG(dbgs() << "G_TRUNC on non-GPR not supported yet\n"); + DEBUG(dbgs() << "G_TRUNC/G_ANYEXT on non-GPR not supported yet\n"); return false; } diff --git a/llvm/lib/Target/ARM/ARMRegisterBankInfo.cpp b/llvm/lib/Target/ARM/ARMRegisterBankInfo.cpp index 13a32211f88c..a20997c95cd9 100644 --- a/llvm/lib/Target/ARM/ARMRegisterBankInfo.cpp +++ b/llvm/lib/Target/ARM/ARMRegisterBankInfo.cpp @@ -225,6 +225,7 @@ ARMRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { case G_UDIV: case G_SEXT: case G_ZEXT: + case G_ANYEXT: case G_TRUNC: case G_GEP: // FIXME: We're abusing the fact that everything lives in a GPR for now; in diff --git a/llvm/test/CodeGen/ARM/GlobalISel/arm-instruction-select.mir b/llvm/test/CodeGen/ARM/GlobalISel/arm-instruction-select.mir index 83ab2659ef4a..a4c5477e5439 100644 --- a/llvm/test/CodeGen/ARM/GlobalISel/arm-instruction-select.mir +++ b/llvm/test/CodeGen/ARM/GlobalISel/arm-instruction-select.mir @@ -4,6 +4,8 @@ define void @test_sext_s1() { ret void } define void @test_sext_s8() { ret void } define void @test_zext_s16() { ret void } + define void @test_anyext_s8() { ret void } + define void @test_anyext_s16() { ret void } define void @test_trunc_s32_16() { ret void } @@ -149,6 +151,58 @@ body: | ; CHECK: BX_RET 14, _, implicit %r0 ... --- +name: test_anyext_s8 +# CHECK-LABEL: name: test_anyext_s8 +legalized: true +regBankSelected: true +selected: false +# CHECK: selected: true +registers: + - { id: 0, class: gprb } + - { id: 1, class: gprb } +body: | + bb.0: + liveins: %r0 + + %0(s8) = COPY %r0 + ; CHECK: [[VREGX:%[0-9]+]] = COPY %r0 + + %1(s32) = G_ANYEXT %0(s8) + ; CHECK: [[VREGEXT:%[0-9]+]] = COPY [[VREGX]] + + %r0 = COPY %1(s32) + ; CHECK: %r0 = COPY [[VREGEXT]] + + BX_RET 14, _, implicit %r0 + ; CHECK: BX_RET 14, _, implicit %r0 +... +--- +name: test_anyext_s16 +# CHECK-LABEL: name: test_anyext_s16 +legalized: true +regBankSelected: true +selected: false +# CHECK: selected: true +registers: + - { id: 0, class: gprb } + - { id: 1, class: gprb } +body: | + bb.0: + liveins: %r0 + + %0(s16) = COPY %r0 + ; CHECK: [[VREGX:%[0-9]+]] = COPY %r0 + + %1(s32) = G_ANYEXT %0(s16) + ; CHECK: [[VREGEXT:%[0-9]+]] = COPY [[VREGX]] + + %r0 = COPY %1(s32) + ; CHECK: %r0 = COPY [[VREGEXT]] + + BX_RET 14, _, implicit %r0 + ; CHECK: BX_RET 14, _, implicit %r0 +... +--- name: test_trunc_s32_16 # CHECK-LABEL: name: test_trunc_s32_16 legalized: true diff --git a/llvm/test/CodeGen/ARM/GlobalISel/arm-regbankselect.mir b/llvm/test/CodeGen/ARM/GlobalISel/arm-regbankselect.mir index 4e94fb4e3481..b887487cc3f6 100644 --- a/llvm/test/CodeGen/ARM/GlobalISel/arm-regbankselect.mir +++ b/llvm/test/CodeGen/ARM/GlobalISel/arm-regbankselect.mir @@ -25,6 +25,9 @@ define void @test_constants() { ret void } + define void @test_anyext_s8_32() { ret void } + define void @test_anyext_s16_32() { ret void } + define void @test_trunc_s32_16() { ret void } define void @test_fadd_s32() #0 { ret void } @@ -500,6 +503,48 @@ body: | BX_RET 14, _, implicit %r0 ... --- +name: test_anyext_s8_32 +# CHECK-LABEL: name: test_anyext_s8_32 +legalized: true +regBankSelected: false +selected: false +# CHECK: registers: +# CHECK: - { id: 0, class: gprb } +# CHECK: - { id: 1, class: gprb } +registers: + - { id: 0, class: _ } + - { id: 1, class: _ } +body: | + bb.0: + liveins: %r0 + + %0(s8) = COPY %r0 + %1(s32) = G_ANYEXT %0(s8) + %r0 = COPY %1(s32) + BX_RET 14, _, implicit %r0 +... +--- +name: test_anyext_s16_32 +# CHECK-LABEL: name: test_anyext_s16_32 +legalized: true +regBankSelected: false +selected: false +# CHECK: registers: +# CHECK: - { id: 0, class: gprb } +# CHECK: - { id: 1, class: gprb } +registers: + - { id: 0, class: _ } + - { id: 1, class: _ } +body: | + bb.0: + liveins: %r0 + + %0(s16) = COPY %r0 + %1(s32) = G_ANYEXT %0(s16) + %r0 = COPY %1(s32) + BX_RET 14, _, implicit %r0 +... +--- name: test_trunc_s32_16 # CHECK-LABEL: name: test_trunc_s32_16 legalized: true