[llvm] r294442 - [ARM] GlobalISel: Add FPR reg bank

Ahmed Bougacha via llvm-commits llvm-commits at lists.llvm.org
Thu Feb 9 08:13:28 PST 2017


On Wed, Feb 8, 2017 at 11:58 PM, Diana Picus <diana.picus at linaro.org> wrote:
> On 9 February 2017 at 04:00, Ahmed Bougacha <ahmed.bougacha at gmail.com> wrote:
>> On Wed, Feb 8, 2017 at 5:23 AM, Diana Picus via llvm-commits
>> <llvm-commits at lists.llvm.org> wrote:
>>> Author: rovka
>>> Date: Wed Feb  8 07:23:04 2017
>>> New Revision: 294442
>>>
>>> URL: http://llvm.org/viewvc/llvm-project?rev=294442&view=rev
>>> Log:
>>> [ARM] GlobalISel: Add FPR reg bank
>>>
>>> Add a register bank for floating point values and select simple instructions
>>> using them (add, copies from GPR).
>>>
>>> This assumes that the hardware can cope with a single precision add (VADDS)
>>> instruction, so the legalizer will treat G_FADD as legal and the instruction
>>> selector will refuse to select if the hardware doesn't support it. In the future
>>> we'll want to be more careful about this, and legalize to libcalls if we have to
>>> use soft float.
>>>
>>> Modified:
>>>     llvm/trunk/lib/Target/ARM/ARMInstructionSelector.cpp
>>>     llvm/trunk/lib/Target/ARM/ARMLegalizerInfo.cpp
>>>     llvm/trunk/lib/Target/ARM/ARMRegisterBankInfo.cpp
>>>     llvm/trunk/lib/Target/ARM/ARMRegisterBanks.td
>>>     llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-instruction-select.mir
>>>     llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-legalizer.mir
>>>     llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-regbankselect.mir
>>>
>>> Modified: llvm/trunk/lib/Target/ARM/ARMInstructionSelector.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstructionSelector.cpp?rev=294442&r1=294441&r2=294442&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/lib/Target/ARM/ARMInstructionSelector.cpp (original)
>>> +++ llvm/trunk/lib/Target/ARM/ARMInstructionSelector.cpp Wed Feb  8 07:23:04 2017
>>> @@ -54,9 +54,17 @@ static bool selectCopy(MachineInstr &I,
>>>             DstSize <= SrcSize)) &&
>>>           "Copy with different width?!");
>>>
>>> -  assert(RegBank->getID() == ARM::GPRRegBankID && "Unsupported reg bank");
>>> +  assert((RegBank->getID() == ARM::GPRRegBankID ||
>>> +          RegBank->getID() == ARM::FPRRegBankID) &&
>>> +         "Unsupported reg bank");
>>> +
>>>    const TargetRegisterClass *RC = &ARM::GPRRegClass;
>>>
>>> +  if (RegBank->getID() == ARM::FPRRegBankID) {
>>> +    assert(DstSize == 32 && "Only 32-bit FP values are supported");
>>> +    RC = &ARM::SPRRegClass;
>>> +  }
>>> +
>>>    // No need to constrain SrcReg. It will get constrained when
>>>    // we hit another of its uses or its defs.
>>>    // Copies do not have constraints.
>>> @@ -177,6 +185,13 @@ bool ARMInstructionSelector::select(Mach
>>>      I.setDesc(TII.get(ARM::ADDrr));
>>>      MIB.add(predOps(ARMCC::AL)).add(condCodeOp());
>>>      break;
>>> +  case G_FADD:
>>> +    if (!TII.getSubtarget().hasVFP2() ||
>>> +        TII.getSubtarget().useNEONForSinglePrecisionFP())
>>> +      return false;
>>> +    I.setDesc(TII.get(ARM::VADDS));
>>> +    MIB.add(predOps(ARMCC::AL));
>>> +    break;
>>>    case G_FRAME_INDEX:
>>>      // Add 0 to the given frame index and hope it will eventually be folded into
>>>      // the user(s).
>>>
>>> Modified: llvm/trunk/lib/Target/ARM/ARMLegalizerInfo.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMLegalizerInfo.cpp?rev=294442&r1=294441&r2=294442&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/lib/Target/ARM/ARMLegalizerInfo.cpp (original)
>>> +++ llvm/trunk/lib/Target/ARM/ARMLegalizerInfo.cpp Wed Feb  8 07:23:04 2017
>>> @@ -48,5 +48,9 @@ ARMLegalizerInfo::ARMLegalizerInfo() {
>>>        setAction({Op, 1, Ty}, Legal);
>>>    }
>>>
>>> +  // FIXME: This is a bit sloppy, but for now we'll just rely on the instruction
>>> +  // selector to complain if it doesn't support floating point.
>>> +  setAction({G_FADD, s32}, Legal);
>>> +
>>>    computeTables();
>>>  }
>>>
>>> Modified: llvm/trunk/lib/Target/ARM/ARMRegisterBankInfo.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMRegisterBankInfo.cpp?rev=294442&r1=294441&r2=294442&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/lib/Target/ARM/ARMRegisterBankInfo.cpp (original)
>>> +++ llvm/trunk/lib/Target/ARM/ARMRegisterBankInfo.cpp Wed Feb  8 07:23:04 2017
>>> @@ -33,9 +33,11 @@ using namespace llvm;
>>>  namespace llvm {
>>>  namespace ARM {
>>>  RegisterBankInfo::PartialMapping GPRPartialMapping{0, 32, GPRRegBank};
>>> +RegisterBankInfo::PartialMapping FPRPartialMapping{0, 32, FPRRegBank};
>>>
>>>  RegisterBankInfo::ValueMapping ValueMappings[] = {
>>> -    {&GPRPartialMapping, 1}, {&GPRPartialMapping, 1}, {&GPRPartialMapping, 1}};
>>> +    {&GPRPartialMapping, 1}, {&GPRPartialMapping, 1}, {&GPRPartialMapping, 1},
>>> +    {&FPRPartialMapping, 1}, {&FPRPartialMapping, 1}, {&FPRPartialMapping, 1}};
>>>  } // end namespace arm
>>>  } // end namespace llvm
>>>
>>> @@ -82,6 +84,9 @@ const RegisterBank &ARMRegisterBankInfo:
>>>    case GPRnopcRegClassID:
>>>    case tGPR_and_tcGPRRegClassID:
>>>      return getRegBank(ARM::GPRRegBankID);
>>> +  case SPR_8RegClassID:
>>> +  case SPRRegClassID:
>>> +    return getRegBank(ARM::FPRRegBankID);
>>>    default:
>>>      llvm_unreachable("Unsupported register kind");
>>>    }
>>> @@ -115,6 +120,9 @@ ARMRegisterBankInfo::getInstrMapping(con
>>>      // the real world we would use different mappings.
>>>      OperandsMapping = &ARM::ValueMappings[0];
>>>      break;
>>> +  case G_FADD:
>>> +    OperandsMapping = &ARM::ValueMappings[3];
>>> +    break;
>>>    case G_FRAME_INDEX:
>>>      OperandsMapping = getOperandsMapping({&ARM::ValueMappings[0], nullptr});
>>>      break;
>>>
>>> Modified: llvm/trunk/lib/Target/ARM/ARMRegisterBanks.td
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMRegisterBanks.td?rev=294442&r1=294441&r2=294442&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/lib/Target/ARM/ARMRegisterBanks.td (original)
>>> +++ llvm/trunk/lib/Target/ARM/ARMRegisterBanks.td Wed Feb  8 07:23:04 2017
>>> @@ -11,3 +11,4 @@
>>>  //===----------------------------------------------------------------------===//
>>>
>>>  def GPRRegBank : RegisterBank<"GPRB", [GPR, GPRwithAPSR]>;
>>> +def FPRRegBank : RegisterBank<"FPRB", [SPR]>;
>>>
>>> Modified: llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-instruction-select.mir
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-instruction-select.mir?rev=294442&r1=294441&r2=294442&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-instruction-select.mir (original)
>>> +++ llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-instruction-select.mir Wed Feb  8 07:23:04 2017
>>> @@ -9,7 +9,11 @@
>>>    define void @test_add_s16() { ret void }
>>>    define void @test_add_s32() { ret void }
>>>
>>> +  define void @test_fadd_s32() #0 { ret void }
>>> +
>>>    define void @test_load_from_stack() { ret void }
>>> +
>>> +  attributes #0 = { "target-features"="+vfp2" }
>>>  ...
>>>  ---
>>>  name:            test_zext_s1
>>> @@ -217,6 +221,39 @@ body:             |
>>>      ; CHECK: BX_RET 14, _, implicit %r0
>>>  ...
>>>  ---
>>> +name:            test_fadd_s32
>>> +# CHECK-LABEL: name: test_fadd_s32
>>> +legalized:       true
>>> +regBankSelected: true
>>> +selected:        false
>>> +# CHECK: selected: true
>>> +registers:
>>> +  - { id: 0, class: fprb }
>>> +  - { id: 1, class: fprb }
>>> +  - { id: 2, class: fprb }
>>
>> FWIW: you can avoid writing the registers list and instead declare the
>> bank in the vreg definition:
>>
>>   %0:fprb(s32)
>>
>
> Hm, interesting, if that's the preferred style then maybe we should
> get the MIR writer to use it too.

Huh, I hadn't thought about that.  That sounds like a good idea!

Until then, I guess it's just another way of condensing MIR to its
essence;  I find it still quite painful to write.

-Ahmed

> Diana
>
>> -Ahmed
>>
>>> +# CHECK: id: 0, class: spr
>>> +# CHECK: id: 1, class: spr
>>> +# CHECK: id: 2, class: spr
>>> +body:             |
>>> +  bb.0:
>>> +    liveins: %s0, %s1
>>> +
>>> +    %0(s32) = COPY %s0
>>> +    ; CHECK: [[VREGX:%[0-9]+]] = COPY %s0
>>> +
>>> +    %1(s32) = COPY %s1
>>> +    ; CHECK: [[VREGY:%[0-9]+]] = COPY %s1
>>> +
>>> +    %2(s32) = G_FADD %0, %1
>>> +    ; CHECK: [[VREGSUM:%[0-9]+]] = VADDS [[VREGX]], [[VREGY]], 14, _
>>> +
>>> +    %s0 = COPY %2(s32)
>>> +    ; CHECK: %s0 = COPY [[VREGSUM]]
>>> +
>>> +    BX_RET 14, _, implicit %s0
>>> +    ; CHECK: BX_RET 14, _, implicit %s0
>>> +...
>>> +---
>>>  name:            test_load_from_stack
>>>  # CHECK-LABEL: name: test_load_from_stack
>>>  legalized:       true
>>>
>>> Modified: llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-legalizer.mir
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-legalizer.mir?rev=294442&r1=294441&r2=294442&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-legalizer.mir (original)
>>> +++ llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-legalizer.mir Wed Feb  8 07:23:04 2017
>>> @@ -9,6 +9,8 @@
>>>
>>>    define void @test_load_from_stack() { ret void }
>>>    define void @test_legal_loads() { ret void }
>>> +
>>> +  define void @test_fadd_s32() { ret void }
>>>  ...
>>>  ---
>>>  name:            test_sext_s8
>>> @@ -190,3 +192,28 @@ body:             |
>>>      %5(p0)  = G_LOAD %0(p0)
>>>      BX_RET 14, _
>>>  ...
>>> +---
>>> +name:            test_fadd_s32
>>> +# CHECK-LABEL: name: test_fadd_s32
>>> +legalized:       false
>>> +# CHECK: legalized: true
>>> +regBankSelected: false
>>> +selected:        false
>>> +tracksRegLiveness: true
>>> +registers:
>>> +  - { id: 0, class: _ }
>>> +  - { id: 1, class: _ }
>>> +  - { id: 2, class: _ }
>>> +body:             |
>>> +  bb.0:
>>> +    liveins: %r0, %r1
>>> +
>>> +    %0(s32) = COPY %r0
>>> +    %1(s32) = COPY %r1
>>> +    %2(s32) = G_FADD %0, %1
>>> +    ; G_FADD with s32 is legal, so we should find it unchanged in the output
>>> +    ; CHECK: {{%[0-9]+}}(s32) = G_FADD {{%[0-9]+, %[0-9]+}}
>>> +    %r0 = COPY %2(s32)
>>> +    BX_RET 14, _, implicit %r0
>>> +
>>> +...
>>>
>>> Modified: llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-regbankselect.mir
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-regbankselect.mir?rev=294442&r1=294441&r2=294442&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-regbankselect.mir (original)
>>> +++ llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-regbankselect.mir Wed Feb  8 07:23:04 2017
>>> @@ -6,6 +6,8 @@
>>>    define void @test_add_s1() { ret void }
>>>
>>>    define void @test_loads() { ret void }
>>> +
>>> +  define void @test_fadd_s32() { ret void }
>>>  ...
>>>  ---
>>>  name:            test_add_s32
>>> @@ -144,3 +146,29 @@ body:             |
>>>      BX_RET 14, _, implicit %r0
>>>
>>>  ...
>>> +---
>>> +name:            test_fadd_s32
>>> +# CHECK-LABEL: name: test_fadd_s32
>>> +legalized:       true
>>> +regBankSelected: false
>>> +selected:        false
>>> +# CHECK: registers:
>>> +# CHECK: - { id: 0, class: fprb }
>>> +# CHECK: - { id: 1, class: fprb }
>>> +# CHECK: - { id: 2, class: fprb }
>>> +
>>> +registers:
>>> +  - { id: 0, class: _ }
>>> +  - { id: 1, class: _ }
>>> +  - { id: 2, class: _ }
>>> +body:             |
>>> +  bb.0:
>>> +    liveins: %r0, %r1
>>> +
>>> +    %0(s32) = COPY %s0
>>> +    %1(s32) = COPY %s1
>>> +    %2(s32) = G_FADD %0, %1
>>> +    %s0 = COPY %2(s32)
>>> +    BX_RET 14, _, implicit %r0
>>> +
>>> +...
>>>
>>>
>>> _______________________________________________
>>> llvm-commits mailing list
>>> llvm-commits at lists.llvm.org
>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits


More information about the llvm-commits mailing list