Skip to content

Commit 55d86f0

Browse files
committed
[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
1 parent e297ad1 commit 55d86f0

File tree

3 files changed

+37
-6
lines changed

3 files changed

+37
-6
lines changed

llvm/lib/CodeGen/GlobalISel/CallLowering.cpp

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -243,8 +243,8 @@ bool CallLowering::handleAssignments(CCState &CCInfo,
243243
}
244244
Args[i].Regs.push_back(Reg);
245245
Args[i].Flags.push_back(Flags);
246-
if (Handler.assignArg(i, NewVT, NewVT, CCValAssign::Full, Args[i],
247-
Args[i].Flags[Part], CCInfo)) {
246+
if (Handler.assignArg(i + Part, NewVT, NewVT, CCValAssign::Full,
247+
Args[i], Args[i].Flags[Part], CCInfo)) {
248248
// Still couldn't assign this smaller part type for some reason.
249249
return false;
250250
}
@@ -276,8 +276,8 @@ bool CallLowering::handleAssignments(CCState &CCInfo,
276276
}
277277
Args[i].Regs.push_back(Unmerge.getReg(PartIdx));
278278
Args[i].Flags.push_back(Flags);
279-
if (Handler.assignArg(i, NewVT, NewVT, CCValAssign::Full, Args[i],
280-
Args[i].Flags[PartIdx], CCInfo))
279+
if (Handler.assignArg(i + PartIdx, NewVT, NewVT, CCValAssign::Full,
280+
Args[i], Args[i].Flags[PartIdx], CCInfo))
281281
return false;
282282
}
283283
}
@@ -298,9 +298,9 @@ bool CallLowering::handleAssignments(CCState &CCInfo,
298298
// FIXME: Pack registers if we have more than one.
299299
Register ArgReg = Args[i].Regs[0];
300300

301+
MVT OrigVT = MVT::getVT(Args[i].Ty);
302+
MVT VAVT = VA.getValVT();
301303
if (VA.isRegLoc()) {
302-
MVT OrigVT = MVT::getVT(Args[i].Ty);
303-
MVT VAVT = VA.getValVT();
304304
if (Handler.isIncomingArgumentHandler() && VAVT != OrigVT) {
305305
if (VAVT.getSizeInBits() < OrigVT.getSizeInBits()) {
306306
// Expected to be multiple regs for a single incoming arg.
@@ -355,6 +355,14 @@ bool CallLowering::handleAssignments(CCState &CCInfo,
355355
Handler.assignValueToReg(ArgReg, VA.getLocReg(), VA);
356356
}
357357
} else if (VA.isMemLoc()) {
358+
// Don't currently support loading/storing a type that needs to be split
359+
// to the stack. Should be easy, just not implemented yet.
360+
if (Args[i].Regs.size() > 1) {
361+
LLVM_DEBUG(
362+
dbgs()
363+
<< "Load/store a split arg to/from the stack not implemented yet");
364+
return false;
365+
}
358366
MVT VT = MVT::getVT(Args[i].Ty);
359367
unsigned Size = VT == MVT::iPTR ? DL.getPointerSize()
360368
: alignTo(VT.getSizeInBits(), 8) / 8;

llvm/test/CodeGen/AArch64/GlobalISel/arm64-fallback.ll

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,3 +189,14 @@ define void @nonpow2_vector_add_fewerelements() {
189189
store i64 %ex, i64* undef
190190
ret void
191191
}
192+
193+
; Currently can't handle dealing with a split type (s128 -> 2 x s64) on the stack yet.
194+
declare void @use_s128(i128 %a, i128 %b)
195+
; FALLBACK-WITH-REPORT-ERR: remark: <unknown>:0:0: unable to lower arguments: i32 (i32, i128, i32, i32, i32, i128, i32)* (in function: fn1)
196+
; FALLBACK-WITH-REPORT-ERR: warning: Instruction selection used fallback path for fn1
197+
; FALLBACK-WITH-REPORT-OUT-LABEL: fn1:
198+
define i32 @fn1(i32 %p1, i128 %p2, i32 %p3, i32 %p4, i32 %p5, i128 %p6, i32 %p7) {
199+
entry:
200+
call void @use_s128(i128 %p2, i128 %p6)
201+
ret i32 0
202+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
; RUN: llc -O0 -global-isel -verify-machineinstrs %s -o - 2>&1 | FileCheck %s
2+
3+
target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
4+
target triple = "aarch64-linux-gnu"
5+
6+
; Check we don't assert when handling an i128 split arg on the stack.
7+
; CHECK-LABEL: fn1
8+
; CHECK: ret
9+
define i32 @fn1(i32 %p1, i128 %p2.coerce, i32 %p3, i32 %p4, i32 %p5, i128 %p6.coerce, i32 %p7) {
10+
entry:
11+
ret i32 undef
12+
}

0 commit comments

Comments
 (0)