From: Diana Picus Date: Fri, 6 Oct 2017 15:39:16 +0000 (+0000) Subject: [ARM] GlobalISel: Select shifts X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e4864187fd979946bebd56bdc74d3dda4cbe0699;p=llvm [ARM] GlobalISel: Select shifts Unfortunately TableGen doesn't handle this yet: Unable to deduce gMIR opcode to handle Src (which is a leaf). Just add some temporary hand-written code to generate the proper MOVsr. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@315071 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/ARM/ARMInstructionSelector.cpp b/lib/Target/ARM/ARMInstructionSelector.cpp index 00517aeb032..d8cfdd9180e 100644 --- a/lib/Target/ARM/ARMInstructionSelector.cpp +++ b/lib/Target/ARM/ARMInstructionSelector.cpp @@ -59,6 +59,7 @@ private: bool selectGlobal(MachineInstrBuilder &MIB, MachineRegisterInfo &MRI) const; bool selectSelect(MachineInstrBuilder &MIB, MachineRegisterInfo &MRI) const; + bool selectShift(unsigned ShiftOpc, MachineInstrBuilder &MIB) const; // Check if the types match and both operands have the expected size and // register bank. @@ -640,6 +641,14 @@ bool ARMInstructionSelector::selectSelect(MachineInstrBuilder &MIB, return true; } +bool ARMInstructionSelector::selectShift(unsigned ShiftOpc, + MachineInstrBuilder &MIB) const { + MIB->setDesc(TII.get(ARM::MOVsr)); + MIB.addImm(ShiftOpc); + MIB.add(predOps(ARMCC::AL)).add(condCodeOp()); + return constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI); +} + bool ARMInstructionSelector::select(MachineInstr &I) const { assert(I.getParent() && "Instruction should be in a basic block!"); assert(I.getParent()->getParent() && "Instruction should be in a function!"); @@ -766,6 +775,13 @@ bool ARMInstructionSelector::select(MachineInstr &I) const { ARM::FPRRegBankID, Size); return selectCmp(Helper, MIB, MRI); } + case G_LSHR: + return selectShift(ARM_AM::ShiftOpc::lsr, MIB); + case G_ASHR: + return selectShift(ARM_AM::ShiftOpc::asr, MIB); + case G_SHL: { + return selectShift(ARM_AM::ShiftOpc::lsl, MIB); + } case G_GEP: I.setDesc(TII.get(ARM::ADDrr)); MIB.add(predOps(ARMCC::AL)).add(condCodeOp()); diff --git a/test/CodeGen/ARM/GlobalISel/arm-instruction-select.mir b/test/CodeGen/ARM/GlobalISel/arm-instruction-select.mir index 0e3ef479bc3..7d8e58ec7f5 100644 --- a/test/CodeGen/ARM/GlobalISel/arm-instruction-select.mir +++ b/test/CodeGen/ARM/GlobalISel/arm-instruction-select.mir @@ -32,6 +32,10 @@ define void @test_or_s32() { ret void } define void @test_xor_s32() { ret void } + define void @test_lshr_s32() { ret void } + define void @test_ashr_s32() { ret void } + define void @test_shl_s32() { ret void } + define void @test_load_from_stack() { ret void } define void @test_load_f32() #0 { ret void } define void @test_load_f64() #0 { ret void } @@ -891,6 +895,105 @@ body: | ; CHECK: BX_RET 14, _, implicit %r0 ... --- +name: test_lshr_s32 +# CHECK-LABEL: name: test_lshr_s32 +legalized: true +regBankSelected: true +selected: false +# CHECK: selected: true +registers: + - { id: 0, class: gprb } + - { id: 1, class: gprb } + - { id: 2, class: gprb } +# CHECK: id: 0, class: gpr +# CHECK: id: 1, class: gpr +# CHECK: id: 2, class: gpr +body: | + bb.0: + liveins: %r0, %r1 + + %0(s32) = COPY %r0 + ; CHECK: [[VREGX:%[0-9]+]] = COPY %r0 + + %1(s32) = COPY %r1 + ; CHECK: [[VREGY:%[0-9]+]] = COPY %r1 + + %2(s32) = G_LSHR %0, %1 + ; CHECK: [[VREGRES:%[0-9]+]] = MOVsr [[VREGX]], [[VREGY]], 3, 14, _, _ + + %r0 = COPY %2(s32) + ; CHECK: %r0 = COPY [[VREGRES]] + + BX_RET 14, _, implicit %r0 + ; CHECK: BX_RET 14, _, implicit %r0 +... +--- +name: test_ashr_s32 +# CHECK-LABEL: name: test_ashr_s32 +legalized: true +regBankSelected: true +selected: false +# CHECK: selected: true +registers: + - { id: 0, class: gprb } + - { id: 1, class: gprb } + - { id: 2, class: gprb } +# CHECK: id: 0, class: gpr +# CHECK: id: 1, class: gpr +# CHECK: id: 2, class: gpr +body: | + bb.0: + liveins: %r0, %r1 + + %0(s32) = COPY %r0 + ; CHECK: [[VREGX:%[0-9]+]] = COPY %r0 + + %1(s32) = COPY %r1 + ; CHECK: [[VREGY:%[0-9]+]] = COPY %r1 + + %2(s32) = G_ASHR %0, %1 + ; CHECK: [[VREGRES:%[0-9]+]] = MOVsr [[VREGX]], [[VREGY]], 1, 14, _, _ + + %r0 = COPY %2(s32) + ; CHECK: %r0 = COPY [[VREGRES]] + + BX_RET 14, _, implicit %r0 + ; CHECK: BX_RET 14, _, implicit %r0 +... +--- +name: test_shl_s32 +# CHECK-LABEL: name: test_shl_s32 +legalized: true +regBankSelected: true +selected: false +# CHECK: selected: true +registers: + - { id: 0, class: gprb } + - { id: 1, class: gprb } + - { id: 2, class: gprb } +# CHECK: id: 0, class: gpr +# CHECK: id: 1, class: gpr +# CHECK: id: 2, class: gpr +body: | + bb.0: + liveins: %r0, %r1 + + %0(s32) = COPY %r0 + ; CHECK: [[VREGX:%[0-9]+]] = COPY %r0 + + %1(s32) = COPY %r1 + ; CHECK: [[VREGY:%[0-9]+]] = COPY %r1 + + %2(s32) = G_SHL %0, %1 + ; CHECK: [[VREGRES:%[0-9]+]] = MOVsr [[VREGX]], [[VREGY]], 2, 14, _, _ + + %r0 = COPY %2(s32) + ; CHECK: %r0 = COPY [[VREGRES]] + + BX_RET 14, _, implicit %r0 + ; CHECK: BX_RET 14, _, implicit %r0 +... +--- name: test_load_from_stack # CHECK-LABEL: name: test_load_from_stack legalized: true