From: Amara Emerson Date: Wed, 11 Sep 2019 23:53:23 +0000 (+0000) Subject: [AArch64][GlobalISel] Fall back on attempts to allocate split types on the stack. X-Git-Tag: llvmorg-11-init~9401 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=55d86f04c737a9f9791500d5758af17e73558229;p=platform%2Fupstream%2Fllvm.git [AArch64][GlobalISel] Fall back on attempts to allocate split types on the stack. First we were asserting that the ValNo of a VA was the wrong value. It doesn't actually make a difference for us in CallLowering but fix that anyway to silence the assert. The bigger issue was that after fixing the assert we were generating invalid MIR because the merging/unmerging of values split across multiple registers wasn't also implemented for memory locs. This happens when we run out of registers and have to pass the split types like i128 -> i64 x 2 on the stack. This is do-able, but for now just fall back. llvm-svn: 371693 --- diff --git a/llvm/lib/CodeGen/GlobalISel/CallLowering.cpp b/llvm/lib/CodeGen/GlobalISel/CallLowering.cpp index 04aa072..ccbe56d 100644 --- a/llvm/lib/CodeGen/GlobalISel/CallLowering.cpp +++ b/llvm/lib/CodeGen/GlobalISel/CallLowering.cpp @@ -243,8 +243,8 @@ bool CallLowering::handleAssignments(CCState &CCInfo, } Args[i].Regs.push_back(Reg); Args[i].Flags.push_back(Flags); - if (Handler.assignArg(i, NewVT, NewVT, CCValAssign::Full, Args[i], - Args[i].Flags[Part], CCInfo)) { + if (Handler.assignArg(i + Part, NewVT, NewVT, CCValAssign::Full, + Args[i], Args[i].Flags[Part], CCInfo)) { // Still couldn't assign this smaller part type for some reason. return false; } @@ -276,8 +276,8 @@ bool CallLowering::handleAssignments(CCState &CCInfo, } Args[i].Regs.push_back(Unmerge.getReg(PartIdx)); Args[i].Flags.push_back(Flags); - if (Handler.assignArg(i, NewVT, NewVT, CCValAssign::Full, Args[i], - Args[i].Flags[PartIdx], CCInfo)) + if (Handler.assignArg(i + PartIdx, NewVT, NewVT, CCValAssign::Full, + Args[i], Args[i].Flags[PartIdx], CCInfo)) return false; } } @@ -298,9 +298,9 @@ bool CallLowering::handleAssignments(CCState &CCInfo, // FIXME: Pack registers if we have more than one. Register ArgReg = Args[i].Regs[0]; + MVT OrigVT = MVT::getVT(Args[i].Ty); + MVT VAVT = VA.getValVT(); if (VA.isRegLoc()) { - MVT OrigVT = MVT::getVT(Args[i].Ty); - MVT VAVT = VA.getValVT(); if (Handler.isIncomingArgumentHandler() && VAVT != OrigVT) { if (VAVT.getSizeInBits() < OrigVT.getSizeInBits()) { // Expected to be multiple regs for a single incoming arg. @@ -355,6 +355,14 @@ bool CallLowering::handleAssignments(CCState &CCInfo, Handler.assignValueToReg(ArgReg, VA.getLocReg(), VA); } } else if (VA.isMemLoc()) { + // Don't currently support loading/storing a type that needs to be split + // to the stack. Should be easy, just not implemented yet. + if (Args[i].Regs.size() > 1) { + LLVM_DEBUG( + dbgs() + << "Load/store a split arg to/from the stack not implemented yet"); + return false; + } MVT VT = MVT::getVT(Args[i].Ty); unsigned Size = VT == MVT::iPTR ? DL.getPointerSize() : alignTo(VT.getSizeInBits(), 8) / 8; diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-fallback.ll b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-fallback.ll index 532164e..cd24771 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-fallback.ll +++ b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-fallback.ll @@ -189,3 +189,14 @@ define void @nonpow2_vector_add_fewerelements() { store i64 %ex, i64* undef ret void } + +; Currently can't handle dealing with a split type (s128 -> 2 x s64) on the stack yet. +declare void @use_s128(i128 %a, i128 %b) +; FALLBACK-WITH-REPORT-ERR: remark: :0:0: unable to lower arguments: i32 (i32, i128, i32, i32, i32, i128, i32)* (in function: fn1) +; FALLBACK-WITH-REPORT-ERR: warning: Instruction selection used fallback path for fn1 +; FALLBACK-WITH-REPORT-OUT-LABEL: fn1: +define i32 @fn1(i32 %p1, i128 %p2, i32 %p3, i32 %p4, i32 %p5, i128 %p6, i32 %p7) { +entry: + call void @use_s128(i128 %p2, i128 %p6) + ret i32 0 +} diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/call-lowering-i128-on-stack.ll b/llvm/test/CodeGen/AArch64/GlobalISel/call-lowering-i128-on-stack.ll new file mode 100644 index 0000000..b99f89bb --- /dev/null +++ b/llvm/test/CodeGen/AArch64/GlobalISel/call-lowering-i128-on-stack.ll @@ -0,0 +1,12 @@ +; RUN: llc -O0 -global-isel -verify-machineinstrs %s -o - 2>&1 | FileCheck %s + +target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128" +target triple = "aarch64-linux-gnu" + +; Check we don't assert when handling an i128 split arg on the stack. +; CHECK-LABEL: fn1 +; CHECK: ret +define i32 @fn1(i32 %p1, i128 %p2.coerce, i32 %p3, i32 %p4, i32 %p5, i128 %p6.coerce, i32 %p7) { +entry: + ret i32 undef +}