[llvm] r295295 - [ARM] GlobalISel: Lower double precision FP args

Diana Picus via llvm-commits llvm-commits at lists.llvm.org
Thu Feb 16 00:10:38 PST 2017


Hi,

This also adds a hook for handling custom VAs, so please have a look
and let me know if the interface for that looks fishy.

Thanks,
Diana

On 16 February 2017 at 08:53, Diana Picus via llvm-commits
<llvm-commits at lists.llvm.org> wrote:
> Author: rovka
> Date: Thu Feb 16 01:53:07 2017
> New Revision: 295295
>
> URL: http://llvm.org/viewvc/llvm-project?rev=295295&view=rev
> Log:
> [ARM] GlobalISel: Lower double precision FP args
>
> For the hard float calling convention, we just use the D registers.
>
> For the soft-fp calling convention, we use the R registers and move values
> to/from the D registers by means of G_SEQUENCE/G_EXTRACT. While doing so, we
> make sure to honor the endianness of the target, since the CCAssignFn doesn't do
> that for us.
>
> For pure soft float targets, we still bail out because we don't support the
> libcalls yet.
>
> Modified:
>     llvm/trunk/include/llvm/CodeGen/GlobalISel/CallLowering.h
>     llvm/trunk/lib/CodeGen/GlobalISel/CallLowering.cpp
>     llvm/trunk/lib/Target/ARM/ARMCallLowering.cpp
>     llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-irtranslator.ll
>
> Modified: llvm/trunk/include/llvm/CodeGen/GlobalISel/CallLowering.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/GlobalISel/CallLowering.h?rev=295295&r1=295294&r2=295295&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/CodeGen/GlobalISel/CallLowering.h (original)
> +++ llvm/trunk/include/llvm/CodeGen/GlobalISel/CallLowering.h Thu Feb 16 01:53:07 2017
> @@ -70,6 +70,17 @@ public:
>                                        uint64_t Size, MachinePointerInfo &MPO,
>                                        CCValAssign &VA) = 0;
>
> +    /// Handle custom values, which may be passed into one or more of \p VAs.
> +    /// \return The number of \p VAs that have been assigned after the first
> +    ///         one, and which should therefore be skipped from further
> +    ///         processing.
> +    virtual unsigned assignCustomValue(const ArgInfo &Arg,
> +                                       ArrayRef<CCValAssign> VAs) {
> +      // This is not a pure virtual method because not all targets need to worry
> +      // about custom values.
> +      llvm_unreachable("Custom values not supported");
> +    }
> +
>      unsigned extendRegister(unsigned ValReg, CCValAssign &VA);
>
>      virtual bool assignArg(unsigned ValNo, MVT ValVT, MVT LocVT,
>
> Modified: llvm/trunk/lib/CodeGen/GlobalISel/CallLowering.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/GlobalISel/CallLowering.cpp?rev=295295&r1=295294&r2=295295&view=diff
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/GlobalISel/CallLowering.cpp (original)
> +++ llvm/trunk/lib/CodeGen/GlobalISel/CallLowering.cpp Thu Feb 16 01:53:07 2017
> @@ -132,8 +132,16 @@ bool CallLowering::handleAssignments(Mac
>        return false;
>    }
>
> -  for (unsigned i = 0, e = Args.size(); i != e; ++i) {
> -    CCValAssign &VA = ArgLocs[i];
> +  for (unsigned i = 0, e = Args.size(), j = 0; i != e; ++i, ++j) {
> +    assert(j < ArgLocs.size() && "Skipped too many arg locs");
> +
> +    CCValAssign &VA = ArgLocs[j];
> +    assert(VA.getValNo() == i && "Location doesn't correspond to current arg");
> +
> +    if (VA.needsCustom()) {
> +      j += Handler.assignCustomValue(Args[i], makeArrayRef(ArgLocs).slice(j));
> +      continue;
> +    }
>
>      if (VA.isRegLoc())
>        Handler.assignValueToReg(Args[i].Reg, VA.getLocReg(), VA);
>
> Modified: llvm/trunk/lib/Target/ARM/ARMCallLowering.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMCallLowering.cpp?rev=295295&r1=295294&r2=295295&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/ARM/ARMCallLowering.cpp (original)
> +++ llvm/trunk/lib/Target/ARM/ARMCallLowering.cpp Thu Feb 16 01:53:07 2017
> @@ -39,6 +39,11 @@ static bool isSupportedType(const DataLa
>      return false;
>
>    unsigned VTSize = VT.getSimpleVT().getSizeInBits();
> +
> +  if (VTSize == 64)
> +    // FIXME: Support i64 too
> +    return VT.isFloatingPoint();
> +
>    return VTSize == 1 || VTSize == 8 || VTSize == 16 || VTSize == 32;
>  }
>
> @@ -58,8 +63,8 @@ struct FuncReturnHandler : public CallLo
>      assert(VA.isRegLoc() && "Value shouldn't be assigned to reg");
>      assert(VA.getLocReg() == PhysReg && "Assigning to the wrong reg?");
>
> -    assert(VA.getValVT().getSizeInBits() <= 32 && "Unsupported value size");
> -    assert(VA.getLocVT().getSizeInBits() == 32 && "Unsupported location size");
> +    assert(VA.getValVT().getSizeInBits() <= 64 && "Unsupported value size");
> +    assert(VA.getLocVT().getSizeInBits() <= 64 && "Unsupported location size");
>
>      unsigned ExtReg = extendRegister(ValVReg, VA);
>      MIRBuilder.buildCopy(PhysReg, ExtReg);
> @@ -71,6 +76,37 @@ struct FuncReturnHandler : public CallLo
>      llvm_unreachable("Don't know how to assign a value to an address yet");
>    }
>
> +  unsigned assignCustomValue(const CallLowering::ArgInfo &Arg,
> +                             ArrayRef<CCValAssign> VAs) override {
> +    CCValAssign VA = VAs[0];
> +    assert(VA.needsCustom() && "Value doesn't need custom handling");
> +    assert(VA.getValVT() == MVT::f64 && "Unsupported type");
> +
> +    CCValAssign NextVA = VAs[1];
> +    assert(NextVA.needsCustom() && "Value doesn't need custom handling");
> +    assert(NextVA.getValVT() == MVT::f64 && "Unsupported type");
> +
> +    assert(VA.getValNo() == NextVA.getValNo() &&
> +           "Values belong to different arguments");
> +
> +    assert(VA.isRegLoc() && "Value should be in reg");
> +    assert(NextVA.isRegLoc() && "Value should be in reg");
> +
> +    unsigned NewRegs[] = {MRI.createGenericVirtualRegister(LLT::scalar(32)),
> +                          MRI.createGenericVirtualRegister(LLT::scalar(32))};
> +
> +    MIRBuilder.buildExtract(NewRegs, {0, 32}, Arg.Reg);
> +
> +    bool IsLittle = MIRBuilder.getMF().getSubtarget<ARMSubtarget>().isLittle();
> +    if (!IsLittle)
> +      std::swap(NewRegs[0], NewRegs[1]);
> +
> +    assignValueToReg(NewRegs[0], VA.getLocReg(), VA);
> +    assignValueToReg(NewRegs[1], NextVA.getLocReg(), NextVA);
> +
> +    return 1;
> +  }
> +
>    MachineInstrBuilder &MIB;
>  };
>  } // End anonymous namespace.
> @@ -144,7 +180,8 @@ struct FormalArgHandler : public CallLow
>
>    unsigned getStackAddress(uint64_t Size, int64_t Offset,
>                             MachinePointerInfo &MPO) override {
> -    assert((Size == 1 || Size == 2 || Size == 4) && "Unsupported size");
> +    assert((Size == 1 || Size == 2 || Size == 4 || Size == 8) &&
> +           "Unsupported size");
>
>      auto &MFI = MIRBuilder.getMF().getFrameInfo();
>
> @@ -160,7 +197,8 @@ struct FormalArgHandler : public CallLow
>
>    void assignValueToAddress(unsigned ValVReg, unsigned Addr, uint64_t Size,
>                              MachinePointerInfo &MPO, CCValAssign &VA) override {
> -    assert((Size == 1 || Size == 2 || Size == 4) && "Unsupported size");
> +    assert((Size == 1 || Size == 2 || Size == 4 || Size == 8) &&
> +           "Unsupported size");
>
>      if (VA.getLocInfo() == CCValAssign::SExt ||
>          VA.getLocInfo() == CCValAssign::ZExt) {
> @@ -181,13 +219,44 @@ struct FormalArgHandler : public CallLow
>      assert(VA.isRegLoc() && "Value shouldn't be assigned to reg");
>      assert(VA.getLocReg() == PhysReg && "Assigning to the wrong reg?");
>
> -    assert(VA.getValVT().getSizeInBits() <= 32 && "Unsupported value size");
> -    assert(VA.getLocVT().getSizeInBits() == 32 && "Unsupported location size");
> +    assert(VA.getValVT().getSizeInBits() <= 64 && "Unsupported value size");
> +    assert(VA.getLocVT().getSizeInBits() <= 64 && "Unsupported location size");
>
>      // The caller should handle all necesary extensions.
>      MIRBuilder.getMBB().addLiveIn(PhysReg);
>      MIRBuilder.buildCopy(ValVReg, PhysReg);
>    }
> +
> +  unsigned assignCustomValue(const llvm::ARMCallLowering::ArgInfo &Arg,
> +                             ArrayRef<CCValAssign> VAs) override {
> +    CCValAssign VA = VAs[0];
> +    assert(VA.needsCustom() && "Value doesn't need custom handling");
> +    assert(VA.getValVT() == MVT::f64 && "Unsupported type");
> +
> +    CCValAssign NextVA = VAs[1];
> +    assert(NextVA.needsCustom() && "Value doesn't need custom handling");
> +    assert(NextVA.getValVT() == MVT::f64 && "Unsupported type");
> +
> +    assert(VA.getValNo() == NextVA.getValNo() &&
> +           "Values belong to different arguments");
> +
> +    assert(VA.isRegLoc() && "Value should be in reg");
> +    assert(NextVA.isRegLoc() && "Value should be in reg");
> +
> +    unsigned NewRegs[] = {MRI.createGenericVirtualRegister(LLT::scalar(32)),
> +                          MRI.createGenericVirtualRegister(LLT::scalar(32))};
> +
> +    assignValueToReg(NewRegs[0], VA.getLocReg(), VA);
> +    assignValueToReg(NewRegs[1], NextVA.getLocReg(), NextVA);
> +
> +    bool IsLittle = MIRBuilder.getMF().getSubtarget<ARMSubtarget>().isLittle();
> +    if (!IsLittle)
> +      std::swap(NewRegs[0], NewRegs[1]);
> +
> +    MIRBuilder.buildSequence(Arg.Reg, NewRegs, {0, 32});
> +
> +    return 1;
> +  }
>  };
>  } // End anonymous namespace
>
>
> Modified: llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-irtranslator.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-irtranslator.ll?rev=295295&r1=295294&r2=295295&view=diff
> ==============================================================================
> --- llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-irtranslator.ll (original)
> +++ llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-irtranslator.ll Thu Feb 16 01:53:07 2017
> @@ -1,4 +1,5 @@
> -; RUN: llc -mtriple arm-unknown -mattr=+vfp2 -global-isel -stop-after=irtranslator %s -o - | FileCheck %s
> +; RUN: llc -mtriple arm-unknown -mattr=+vfp2 -global-isel -stop-after=irtranslator %s -o - | FileCheck %s -check-prefix=CHECK -check-prefix=LITTLE
> +; RUN: llc -mtriple armeb-unknown -mattr=+vfp2 -global-isel -stop-after=irtranslator %s -o - | FileCheck %s -check-prefix=CHECK -check-prefix=BIG
>
>  define void @test_void_return() {
>  ; CHECK-LABEL: name: test_void_return
> @@ -220,3 +221,117 @@ entry:
>    ret float %v
>  }
>
> +define arm_aapcs_vfpcc double @test_double_vfpcc(double %p0, double %p1, double %p2,
> +                                                 double %p3, double %p4, double %p5,
> +                                                 double %reasonable,
> +                                                 double %parameters,
> +                                                 double %q0, double %q1) {
> +; CHECK-LABEL: name: test_double_vfpcc
> +; CHECK: fixedStack:
> +; CHECK-DAG: id: [[Q0:[0-9]+]]{{.*}}offset: 0{{.*}}size: 8
> +; CHECK-DAG: id: [[Q1:[0-9]+]]{{.*}}offset: 8{{.*}}size: 8
> +; CHECK: liveins: %d0, %d1, %d2, %d3, %d4, %d5, %d6, %d7
> +; CHECK: [[VREGP1:%[0-9]+]](s64) = COPY %d1
> +; CHECK: [[FIQ1:%[0-9]+]](p0) = G_FRAME_INDEX %fixed-stack.[[Q1]]
> +; CHECK: [[VREGQ1:%[0-9]+]](s64) = G_LOAD [[FIQ1]](p0)
> +; CHECK: [[VREGV:%[0-9]+]](s64) = G_FADD [[VREGP1]], [[VREGQ1]]
> +; CHECK: %d0 = COPY [[VREGV]]
> +; CHECK: BX_RET 14, _, implicit %d0
> +entry:
> +  %v = fadd double %p1, %q1
> +  ret double %v
> +}
> +
> +define arm_aapcscc double @test_double_aapcscc(double %p0, double %p1, double %p2,
> +                                               double %p3, double %p4, double %p5) {
> +; CHECK-LABEL: name: test_double_aapcscc
> +; CHECK: fixedStack:
> +; CHECK-DAG: id: [[P2:[0-9]+]]{{.*}}offset: 0{{.*}}size: 8
> +; CHECK-DAG: id: [[P3:[0-9]+]]{{.*}}offset: 8{{.*}}size: 8
> +; CHECK-DAG: id: [[P4:[0-9]+]]{{.*}}offset: 16{{.*}}size: 8
> +; CHECK-DAG: id: [[P5:[0-9]+]]{{.*}}offset: 24{{.*}}size: 8
> +; CHECK: liveins: %r0, %r1, %r2, %r3
> +; CHECK-DAG: [[VREGP1LO:%[0-9]+]](s32) = COPY %r2
> +; CHECK-DAG: [[VREGP1HI:%[0-9]+]](s32) = COPY %r3
> +; LITTLE: [[VREGP1:%[0-9]+]](s64) = G_SEQUENCE [[VREGP1LO]](s32), 0, [[VREGP1HI]](s32), 32
> +; BIG: [[VREGP1:%[0-9]+]](s64) = G_SEQUENCE [[VREGP1HI]](s32), 0, [[VREGP1LO]](s32), 32
> +; CHECK: [[FIP5:%[0-9]+]](p0) = G_FRAME_INDEX %fixed-stack.[[P5]]
> +; CHECK: [[VREGP5:%[0-9]+]](s64) = G_LOAD [[FIP5]](p0)
> +; CHECK: [[VREGV:%[0-9]+]](s64) = G_FADD [[VREGP1]], [[VREGP5]]
> +; LITTLE: [[VREGVLO:%[0-9]+]](s32), [[VREGVHI:%[0-9]+]](s32) = G_EXTRACT [[VREGV]](s64), 0, 32
> +; BIG: [[VREGVHI:%[0-9]+]](s32), [[VREGVLO:%[0-9]+]](s32) = G_EXTRACT [[VREGV]](s64), 0, 32
> +; CHECK-DAG: %r0 = COPY [[VREGVLO]]
> +; CHECK-DAG: %r1 = COPY [[VREGVHI]]
> +; CHECK: BX_RET 14, _, implicit %r0, implicit %r1
> +entry:
> +  %v = fadd double %p1, %p5
> +  ret double %v
> +}
> +
> +define arm_aapcs_vfpcc double @test_double_gap_vfpcc(double %p0, float %filler,
> +                                                     double %p1, double %p2,
> +                                                     double %p3, double %p4,
> +                                                     double %reasonable,
> +                                                     double %parameters,
> +                                                     double %q0, double %q1) {
> +; CHECK-LABEL: name: test_double_gap_vfpcc
> +; CHECK: fixedStack:
> +; CHECK-DAG: id: [[Q0:[0-9]+]]{{.*}}offset: 0{{.*}}size: 8
> +; CHECK-DAG: id: [[Q1:[0-9]+]]{{.*}}offset: 8{{.*}}size: 8
> +; CHECK: liveins: %d0, %d2, %d3, %d4, %d5, %d6, %d7, %s2
> +; CHECK: [[VREGP1:%[0-9]+]](s64) = COPY %d2
> +; CHECK: [[FIQ1:%[0-9]+]](p0) = G_FRAME_INDEX %fixed-stack.[[Q1]]
> +; CHECK: [[VREGQ1:%[0-9]+]](s64) = G_LOAD [[FIQ1]](p0)
> +; CHECK: [[VREGV:%[0-9]+]](s64) = G_FADD [[VREGP1]], [[VREGQ1]]
> +; CHECK: %d0 = COPY [[VREGV]]
> +; CHECK: BX_RET 14, _, implicit %d0
> +entry:
> +  %v = fadd double %p1, %q1
> +  ret double %v
> +}
> +
> +define arm_aapcscc double @test_double_gap_aapcscc(float %filler, double %p0,
> +                                                   double %p1) {
> +; CHECK-LABEL: name: test_double_gap_aapcscc
> +; CHECK: fixedStack:
> +; CHECK-DAG: id: [[P1:[0-9]+]]{{.*}}offset: 0{{.*}}size: 8
> +; CHECK: liveins: %r0, %r2, %r3
> +; CHECK-DAG: [[VREGP0LO:%[0-9]+]](s32) = COPY %r2
> +; CHECK-DAG: [[VREGP0HI:%[0-9]+]](s32) = COPY %r3
> +; LITTLE: [[VREGP0:%[0-9]+]](s64) = G_SEQUENCE [[VREGP0LO]](s32), 0, [[VREGP0HI]](s32), 32
> +; BIG: [[VREGP0:%[0-9]+]](s64) = G_SEQUENCE [[VREGP0HI]](s32), 0, [[VREGP0LO]](s32), 32
> +; CHECK: [[FIP1:%[0-9]+]](p0) = G_FRAME_INDEX %fixed-stack.[[P1]]
> +; CHECK: [[VREGP1:%[0-9]+]](s64) = G_LOAD [[FIP1]](p0)
> +; CHECK: [[VREGV:%[0-9]+]](s64) = G_FADD [[VREGP0]], [[VREGP1]]
> +; LITTLE: [[VREGVLO:%[0-9]+]](s32), [[VREGVHI:%[0-9]+]](s32) = G_EXTRACT [[VREGV]](s64), 0, 32
> +; BIG: [[VREGVHI:%[0-9]+]](s32), [[VREGVLO:%[0-9]+]](s32) = G_EXTRACT [[VREGV]](s64), 0, 32
> +; CHECK-DAG: %r0 = COPY [[VREGVLO]]
> +; CHECK-DAG: %r1 = COPY [[VREGVHI]]
> +; CHECK: BX_RET 14, _, implicit %r0, implicit %r1
> +entry:
> +  %v = fadd double %p0, %p1
> +  ret double %v
> +}
> +
> +define arm_aapcscc double @test_double_gap2_aapcscc(double %p0, float %filler,
> +                                                    double %p1) {
> +; CHECK-LABEL: name: test_double_gap2_aapcscc
> +; CHECK: fixedStack:
> +; CHECK-DAG: id: [[P1:[0-9]+]]{{.*}}offset: 0{{.*}}size: 8
> +; CHECK: liveins: %r0, %r1, %r2
> +; CHECK-DAG: [[VREGP0LO:%[0-9]+]](s32) = COPY %r0
> +; CHECK-DAG: [[VREGP0HI:%[0-9]+]](s32) = COPY %r1
> +; LITTLE: [[VREGP0:%[0-9]+]](s64) = G_SEQUENCE [[VREGP0LO]](s32), 0, [[VREGP0HI]](s32), 32
> +; BIG: [[VREGP0:%[0-9]+]](s64) = G_SEQUENCE [[VREGP0HI]](s32), 0, [[VREGP0LO]](s32), 32
> +; CHECK: [[FIP1:%[0-9]+]](p0) = G_FRAME_INDEX %fixed-stack.[[P1]]
> +; CHECK: [[VREGP1:%[0-9]+]](s64) = G_LOAD [[FIP1]](p0)
> +; CHECK: [[VREGV:%[0-9]+]](s64) = G_FADD [[VREGP0]], [[VREGP1]]
> +; LITTLE: [[VREGVLO:%[0-9]+]](s32), [[VREGVHI:%[0-9]+]](s32) = G_EXTRACT [[VREGV]](s64), 0, 32
> +; BIG: [[VREGVHI:%[0-9]+]](s32), [[VREGVLO:%[0-9]+]](s32) = G_EXTRACT [[VREGV]](s64), 0, 32
> +; CHECK-DAG: %r0 = COPY [[VREGVLO]]
> +; CHECK-DAG: %r1 = COPY [[VREGVHI]]
> +; CHECK: BX_RET 14, _, implicit %r0, implicit %r1
> +entry:
> +  %v = fadd double %p0, %p1
> +  ret double %v
> +}
>
>
> _______________________________________________
> 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