[llvm] r358032 - [GlobalISel][AArch64] Allow CallLowering to handle types which are normally

Yvan Roux via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 12 04:06:52 PDT 2019


Hi Amara,

AArch64 bots are broken since the first 4 patches (r358032-r358035) of
that series were checked-in, logs are available at:
http://lab.llvm.org:8011/builders/clang-cmake-aarch64-quick/builds/18185

Thanks
Yvan

On Tue, 9 Apr 2019 at 23:20, Amara Emerson via llvm-commits
<llvm-commits at lists.llvm.org> wrote:
>
> Author: aemerson
> Date: Tue Apr  9 14:22:33 2019
> New Revision: 358032
>
> URL: http://llvm.org/viewvc/llvm-project?rev=358032&view=rev
> Log:
> [GlobalISel][AArch64] Allow CallLowering to handle types which are normally
> required to be passed as different register types. E.g. <2 x i16> may need to
> be passed as a larger <2 x i32> type, so formal arg lowering needs to be able
> truncate it back. Likewise, when dealing with returns of these types, they need
> to be widened in the appropriate way back.
>
> Differential Revision: https://reviews.llvm.org/D60425
>
> Added:
>     llvm/trunk/test/CodeGen/AArch64/GlobalISel/ret-vec-promote.ll
>     llvm/trunk/test/CodeGen/AArch64/GlobalISel/vec-s16-param.ll
> Modified:
>     llvm/trunk/include/llvm/CodeGen/GlobalISel/CallLowering.h
>     llvm/trunk/lib/CodeGen/GlobalISel/CallLowering.cpp
>     llvm/trunk/lib/Target/AArch64/AArch64CallLowering.cpp
>     llvm/trunk/lib/Target/ARM/ARMCallLowering.cpp
>     llvm/trunk/lib/Target/X86/X86CallLowering.cpp
>     llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-unsupported.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=358032&r1=358031&r2=358032&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/CodeGen/GlobalISel/CallLowering.h (original)
> +++ llvm/trunk/include/llvm/CodeGen/GlobalISel/CallLowering.h Tue Apr  9 14:22:33 2019
> @@ -65,6 +65,10 @@ public:
>
>      virtual ~ValueHandler() = default;
>
> +    /// Returns true if the handler is dealing with formal arguments,
> +    /// not with return values etc.
> +    virtual bool isArgumentHandler() const { return false; }
> +
>      /// Materialize a VReg containing the address of the specified
>      /// stack-based object. This is either based on a FrameIndex or
>      /// direct SP manipulation, depending on the context. \p MPO
>
> Modified: llvm/trunk/lib/CodeGen/GlobalISel/CallLowering.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/GlobalISel/CallLowering.cpp?rev=358032&r1=358031&r2=358032&view=diff
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/GlobalISel/CallLowering.cpp (original)
> +++ llvm/trunk/lib/CodeGen/GlobalISel/CallLowering.cpp Tue Apr  9 14:22:33 2019
> @@ -20,6 +20,8 @@
>  #include "llvm/IR/Instructions.h"
>  #include "llvm/IR/Module.h"
>
> +#define DEBUG_TYPE "call-lowering"
> +
>  using namespace llvm;
>
>  void CallLowering::anchor() {}
> @@ -121,8 +123,15 @@ bool CallLowering::handleAssignments(Mac
>    unsigned NumArgs = Args.size();
>    for (unsigned i = 0; i != NumArgs; ++i) {
>      MVT CurVT = MVT::getVT(Args[i].Ty);
> -    if (Handler.assignArg(i, CurVT, CurVT, CCValAssign::Full, Args[i], CCInfo))
> -      return false;
> +    if (Handler.assignArg(i, CurVT, CurVT, CCValAssign::Full, Args[i], CCInfo)) {
> +      // Try to use the register type if we couldn't assign the VT.
> +      if (!Handler.isArgumentHandler())
> +        return false;
> +      CurVT = TLI->getRegisterTypeForCallingConv(
> +          F.getContext(), F.getCallingConv(), EVT(CurVT));
> +      if (Handler.assignArg(i, CurVT, CurVT, CCValAssign::Full, Args[i], CCInfo))
> +        return false;
> +    }
>    }
>
>    for (unsigned i = 0, e = Args.size(), j = 0; i != e; ++i, ++j) {
> @@ -136,12 +145,39 @@ bool CallLowering::handleAssignments(Mac
>        continue;
>      }
>
> -    if (VA.isRegLoc())
> -      Handler.assignValueToReg(Args[i].Reg, VA.getLocReg(), VA);
> -    else if (VA.isMemLoc()) {
> -      unsigned Size = VA.getValVT() == MVT::iPTR
> -                          ? DL.getPointerSize()
> -                          : alignTo(VA.getValVT().getSizeInBits(), 8) / 8;
> +    if (VA.isRegLoc()) {
> +      MVT OrigVT = MVT::getVT(Args[i].Ty);
> +      MVT VAVT = VA.getValVT();
> +      if (Handler.isArgumentHandler() && VAVT != OrigVT) {
> +        if (VAVT.getSizeInBits() < OrigVT.getSizeInBits())
> +          return false; // Can't handle this type of arg yet.
> +        const LLT VATy(VAVT);
> +        unsigned NewReg =
> +            MIRBuilder.getMRI()->createGenericVirtualRegister(VATy);
> +        Handler.assignValueToReg(NewReg, VA.getLocReg(), VA);
> +        // If it's a vector type, we either need to truncate the elements
> +        // or do an unmerge to get the lower block of elements.
> +        if (VATy.isVector() &&
> +            VATy.getNumElements() > OrigVT.getVectorNumElements()) {
> +          const LLT OrigTy(OrigVT);
> +          // Just handle the case where the VA type is 2 * original type.
> +          if (VATy.getNumElements() != OrigVT.getVectorNumElements() * 2) {
> +            LLVM_DEBUG(dbgs()
> +                       << "Incoming promoted vector arg has too many elts");
> +            return false;
> +          }
> +          auto Unmerge = MIRBuilder.buildUnmerge({OrigTy, OrigTy}, {NewReg});
> +          MIRBuilder.buildCopy(Args[i].Reg, Unmerge.getReg(0));
> +        } else {
> +          MIRBuilder.buildTrunc(Args[i].Reg, {NewReg}).getReg(0);
> +        }
> +      } else {
> +        Handler.assignValueToReg(Args[i].Reg, VA.getLocReg(), VA);
> +      }
> +    } else if (VA.isMemLoc()) {
> +      MVT VT = MVT::getVT(Args[i].Ty);
> +      unsigned Size = VT == MVT::iPTR ? DL.getPointerSize()
> +                                      : alignTo(VT.getSizeInBits(), 8) / 8;
>        unsigned Offset = VA.getLocMemOffset();
>        MachinePointerInfo MPO;
>        unsigned StackAddr = Handler.getStackAddress(Size, Offset, MPO);
> @@ -157,6 +193,8 @@ bool CallLowering::handleAssignments(Mac
>  unsigned CallLowering::ValueHandler::extendRegister(unsigned ValReg,
>                                                      CCValAssign &VA) {
>    LLT LocTy{VA.getLocVT()};
> +  if (LocTy.getSizeInBits() == MRI.getType(ValReg).getSizeInBits())
> +    return ValReg;
>    switch (VA.getLocInfo()) {
>    default: break;
>    case CCValAssign::Full:
>
> Modified: llvm/trunk/lib/Target/AArch64/AArch64CallLowering.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64CallLowering.cpp?rev=358032&r1=358031&r2=358032&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/AArch64/AArch64CallLowering.cpp (original)
> +++ llvm/trunk/lib/Target/AArch64/AArch64CallLowering.cpp Tue Apr  9 14:22:33 2019
> @@ -44,6 +44,8 @@
>  #include <cstdint>
>  #include <iterator>
>
> +#define DEBUG_TYPE "aarch64-call-lowering"
> +
>  using namespace llvm;
>
>  AArch64CallLowering::AArch64CallLowering(const AArch64TargetLowering &TLI)
> @@ -97,6 +99,8 @@ struct IncomingArgHandler : public CallL
>    /// (it's an implicit-def of the BL).
>    virtual void markPhysRegUsed(unsigned PhysReg) = 0;
>
> +  bool isArgumentHandler() const override { return true; }
> +
>    uint64_t StackUsed;
>  };
>
> @@ -250,18 +254,63 @@ bool AArch64CallLowering::lowerReturn(Ma
>             "For each split Type there should be exactly one VReg.");
>
>      SmallVector<ArgInfo, 8> SplitArgs;
> +    CallingConv::ID CC = F.getCallingConv();
> +
>      for (unsigned i = 0; i < SplitEVTs.size(); ++i) {
> -      // We zero-extend i1s to i8.
> -      unsigned CurVReg = VRegs[i];
> -      if (MRI.getType(VRegs[i]).getSizeInBits() == 1) {
> -        CurVReg = MIRBuilder.buildZExt(LLT::scalar(8), CurVReg)
> -                       ->getOperand(0)
> -                       .getReg();
> +      if (TLI.getNumRegistersForCallingConv(Ctx, CC, SplitEVTs[i]) > 1) {
> +        LLVM_DEBUG(dbgs() << "Can't handle extended arg types which need split");
> +        return false;
>        }
>
> +      unsigned CurVReg = VRegs[i];
>        ArgInfo CurArgInfo = ArgInfo{CurVReg, SplitEVTs[i].getTypeForEVT(Ctx)};
>        setArgFlags(CurArgInfo, AttributeList::ReturnIndex, DL, F);
> -      splitToValueTypes(CurArgInfo, SplitArgs, DL, MRI, F.getCallingConv(),
> +
> +      // i1 is a special case because SDAG i1 true is naturally zero extended
> +      // when widened using ANYEXT. We need to do it explicitly here.
> +      if (MRI.getType(CurVReg).getSizeInBits() == 1) {
> +        CurVReg = MIRBuilder.buildZExt(LLT::scalar(8), CurVReg).getReg(0);
> +      } else {
> +        // Some types will need extending as specified by the CC.
> +        MVT NewVT = TLI.getRegisterTypeForCallingConv(Ctx, CC, SplitEVTs[i]);
> +        if (EVT(NewVT) != SplitEVTs[i]) {
> +          unsigned ExtendOp = TargetOpcode::G_ANYEXT;
> +          if (F.getAttributes().hasAttribute(AttributeList::ReturnIndex,
> +                                             Attribute::SExt))
> +            ExtendOp = TargetOpcode::G_SEXT;
> +          else if (F.getAttributes().hasAttribute(AttributeList::ReturnIndex,
> +                                                  Attribute::ZExt))
> +            ExtendOp = TargetOpcode::G_ZEXT;
> +
> +          LLT NewLLT(NewVT);
> +          LLT OldLLT(MVT::getVT(CurArgInfo.Ty));
> +          CurArgInfo.Ty = EVT(NewVT).getTypeForEVT(Ctx);
> +          // Instead of an extend, we might have a vector type which needs
> +          // padding with more elements, e.g. <2 x half> -> <4 x half>
> +          if (NewVT.isVector() &&
> +              NewLLT.getNumElements() > OldLLT.getNumElements()) {
> +            // We don't handle VA types which are not exactly twice the size,
> +            // but can easily be done in future.
> +            if (NewLLT.getNumElements() != OldLLT.getNumElements() * 2) {
> +              LLVM_DEBUG(dbgs() << "Outgoing vector ret has too many elts");
> +              return false;
> +            }
> +            auto Undef = MIRBuilder.buildUndef({OldLLT});
> +            CurVReg =
> +                MIRBuilder.buildMerge({NewLLT}, {CurVReg, Undef.getReg(0)})
> +                    .getReg(0);
> +          } else {
> +            CurVReg =
> +                MIRBuilder.buildInstr(ExtendOp, {NewLLT}, {CurVReg}).getReg(0);
> +          }
> +        }
> +      }
> +      if (CurVReg != CurArgInfo.Reg) {
> +        CurArgInfo.Reg = CurVReg;
> +        // Reset the arg flags after modifying CurVReg.
> +        setArgFlags(CurArgInfo, AttributeList::ReturnIndex, DL, F);
> +      }
> +     splitToValueTypes(CurArgInfo, SplitArgs, DL, MRI, CC,
>                          [&](unsigned Reg, uint64_t Offset) {
>                            MIRBuilder.buildExtract(Reg, CurVReg, Offset);
>                          });
>
> Modified: llvm/trunk/lib/Target/ARM/ARMCallLowering.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMCallLowering.cpp?rev=358032&r1=358031&r2=358032&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/ARM/ARMCallLowering.cpp (original)
> +++ llvm/trunk/lib/Target/ARM/ARMCallLowering.cpp Tue Apr  9 14:22:33 2019
> @@ -301,6 +301,8 @@ struct IncomingValueHandler : public Cal
>                         CCAssignFn AssignFn)
>        : ValueHandler(MIRBuilder, MRI, AssignFn) {}
>
> +  bool isArgumentHandler() const override { return true; }
> +
>    unsigned getStackAddress(uint64_t Size, int64_t Offset,
>                             MachinePointerInfo &MPO) override {
>      assert((Size == 1 || Size == 2 || Size == 4 || Size == 8) &&
>
> Modified: llvm/trunk/lib/Target/X86/X86CallLowering.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86CallLowering.cpp?rev=358032&r1=358031&r2=358032&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/X86/X86CallLowering.cpp (original)
> +++ llvm/trunk/lib/Target/X86/X86CallLowering.cpp Tue Apr  9 14:22:33 2019
> @@ -228,6 +228,8 @@ struct IncomingValueHandler : public Cal
>        : ValueHandler(MIRBuilder, MRI, AssignFn),
>          DL(MIRBuilder.getMF().getDataLayout()) {}
>
> +  bool isArgumentHandler() const override { return true; }
> +
>    unsigned getStackAddress(uint64_t Size, int64_t Offset,
>                             MachinePointerInfo &MPO) override {
>      auto &MFI = MIRBuilder.getMF().getFrameInfo();
>
> Added: llvm/trunk/test/CodeGen/AArch64/GlobalISel/ret-vec-promote.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/GlobalISel/ret-vec-promote.ll?rev=358032&view=auto
> ==============================================================================
> --- llvm/trunk/test/CodeGen/AArch64/GlobalISel/ret-vec-promote.ll (added)
> +++ llvm/trunk/test/CodeGen/AArch64/GlobalISel/ret-vec-promote.ll Tue Apr  9 14:22:33 2019
> @@ -0,0 +1,16 @@
> +; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
> +; RUN: llc -mtriple=aarch64-linux-gnu -O0 -global-isel -stop-after=irtranslator -o - %s | FileCheck %s
> +
> +; Tests vectors of i1 types can appropriately extended first before return handles it.
> +define <4 x i1> @ret_v4i1(<4 x i1> *%v) {
> +  ; CHECK-LABEL: name: ret_v4i1
> +  ; CHECK: bb.1 (%ir-block.0):
> +  ; CHECK:   liveins: $x0
> +  ; CHECK:   [[COPY:%[0-9]+]]:_(p0) = COPY $x0
> +  ; CHECK:   [[LOAD:%[0-9]+]]:_(<4 x s1>) = G_LOAD [[COPY]](p0) :: (load 1 from %ir.v, align 4)
> +  ; CHECK:   [[ANYEXT:%[0-9]+]]:_(<4 x s16>) = G_ANYEXT [[LOAD]](<4 x s1>)
> +  ; CHECK:   $d0 = COPY [[ANYEXT]](<4 x s16>)
> +  ; CHECK:   RET_ReallyLR implicit $d0
> +  %v2 = load <4 x i1>, <4 x i1> *%v
> +  ret <4 x i1> %v2
> +}
>
> Added: llvm/trunk/test/CodeGen/AArch64/GlobalISel/vec-s16-param.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/GlobalISel/vec-s16-param.ll?rev=358032&view=auto
> ==============================================================================
> --- llvm/trunk/test/CodeGen/AArch64/GlobalISel/vec-s16-param.ll (added)
> +++ llvm/trunk/test/CodeGen/AArch64/GlobalISel/vec-s16-param.ll Tue Apr  9 14:22:33 2019
> @@ -0,0 +1,28 @@
> +; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
> +; RUN: llc -mtriple=aarch64-linux-gnu -O0 -stop-after=irtranslator -verify-machineinstrs -o - %s | FileCheck %s
> +
> +define <2 x half> @f16_vec_param(<2 x half> %v) {
> +  ; CHECK-LABEL: name: f16_vec_param
> +  ; CHECK: bb.1 (%ir-block.0):
> +  ; CHECK:   liveins: $d0
> +  ; CHECK:   [[COPY:%[0-9]+]]:_(<4 x s16>) = COPY $d0
> +  ; CHECK:   [[UV:%[0-9]+]]:_(<2 x s16>), [[UV1:%[0-9]+]]:_(<2 x s16>) = G_UNMERGE_VALUES [[COPY]](<4 x s16>)
> +  ; CHECK:   [[COPY1:%[0-9]+]]:_(<2 x s16>) = COPY [[UV]](<2 x s16>)
> +  ; CHECK:   [[DEF:%[0-9]+]]:_(<2 x s16>) = G_IMPLICIT_DEF
> +  ; CHECK:   [[CONCAT_VECTORS:%[0-9]+]]:_(<4 x s16>) = G_CONCAT_VECTORS [[COPY1]](<2 x s16>), [[DEF]](<2 x s16>)
> +  ; CHECK:   $d0 = COPY [[CONCAT_VECTORS]](<4 x s16>)
> +  ; CHECK:   RET_ReallyLR implicit $d0
> +  ret <2 x half> %v
> +}
> +
> +define <2 x i16> @i16_vec_param(<2 x i16> %v) {
> +  ; CHECK-LABEL: name: i16_vec_param
> +  ; CHECK: bb.1 (%ir-block.0):
> +  ; CHECK:   liveins: $d0
> +  ; CHECK:   [[COPY:%[0-9]+]]:_(<2 x s32>) = COPY $d0
> +  ; CHECK:   [[TRUNC:%[0-9]+]]:_(<2 x s16>) = G_TRUNC [[COPY]](<2 x s32>)
> +  ; CHECK:   [[ANYEXT:%[0-9]+]]:_(<2 x s32>) = G_ANYEXT [[TRUNC]](<2 x s16>)
> +  ; CHECK:   $d0 = COPY [[ANYEXT]](<2 x s32>)
> +  ; CHECK:   RET_ReallyLR implicit $d0
> +  ret <2 x i16> %v
> +}
>
> Modified: llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-unsupported.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-unsupported.ll?rev=358032&r1=358031&r2=358032&view=diff
> ==============================================================================
> --- llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-unsupported.ll (original)
> +++ llvm/trunk/test/CodeGen/ARM/GlobalISel/arm-unsupported.ll Tue Apr  9 14:22:33 2019
> @@ -43,7 +43,7 @@ define i17 @test_funny_ints(i17 %a, i17
>  }
>
>  define half @test_half(half %a, half %b) {
> -; CHECK: remark: {{.*}} unable to lower arguments: half (half, half)* (in function: test_half)
> +; CHECK: remark: {{.*}} unable to translate instruction: ret: '  ret half %res' (in function: test_half)
>  ; CHECK-LABEL: warning: Instruction selection used fallback path for test_half
>    %res = fadd half %a, %b
>    ret half %res
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits


More information about the llvm-commits mailing list