}
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;
}
}
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;
}
}
// 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.
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;
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: <unknown>: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
+}
--- /dev/null
+; 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
+}