Skip to content

Commit 4ad9ccc

Browse files
committed
[GlobalISel] Handle <1 x T> vector return types properly.
After support for dealing with types that need to be extended in some way was added in r358032 we didn't correctly handle <1 x T> return types. These types don't have a GISel direct representation, instead we just see them as scalars. When we need to pad them into <2 x T> types however we need to use a G_BUILD_VECTOR instead of trying to do a G_CONCAT_VECTOR. This fixes PR41738. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@360068 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 577c662 commit 4ad9ccc

File tree

2 files changed

+47
-11
lines changed

2 files changed

+47
-11
lines changed

lib/Target/AArch64/AArch64CallLowering.cpp

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -286,20 +286,40 @@ bool AArch64CallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
286286
LLT OldLLT(MVT::getVT(CurArgInfo.Ty));
287287
CurArgInfo.Ty = EVT(NewVT).getTypeForEVT(Ctx);
288288
// Instead of an extend, we might have a vector type which needs
289-
// padding with more elements, e.g. <2 x half> -> <4 x half>
290-
if (NewVT.isVector() &&
291-
NewLLT.getNumElements() > OldLLT.getNumElements()) {
292-
// We don't handle VA types which are not exactly twice the size,
293-
// but can easily be done in future.
294-
if (NewLLT.getNumElements() != OldLLT.getNumElements() * 2) {
295-
LLVM_DEBUG(dbgs() << "Outgoing vector ret has too many elts");
289+
// padding with more elements, e.g. <2 x half> -> <4 x half>.
290+
if (NewVT.isVector()) {
291+
if (OldLLT.isVector()) {
292+
if (NewLLT.getNumElements() > OldLLT.getNumElements()) {
293+
// We don't handle VA types which are not exactly twice the
294+
// size, but can easily be done in future.
295+
if (NewLLT.getNumElements() != OldLLT.getNumElements() * 2) {
296+
LLVM_DEBUG(dbgs() << "Outgoing vector ret has too many elts");
297+
return false;
298+
}
299+
auto Undef = MIRBuilder.buildUndef({OldLLT});
300+
CurVReg =
301+
MIRBuilder.buildMerge({NewLLT}, {CurVReg, Undef.getReg(0)})
302+
.getReg(0);
303+
} else {
304+
// Just do a vector extend.
305+
CurVReg = MIRBuilder.buildInstr(ExtendOp, {NewLLT}, {CurVReg})
306+
.getReg(0);
307+
}
308+
} else if (NewLLT.getNumElements() == 2) {
309+
// We need to pad a <1 x S> type to <2 x S>. Since we don't have
310+
// <1 x S> vector types in GISel we use a build_vector instead
311+
// of a vector merge/concat.
312+
auto Undef = MIRBuilder.buildUndef({OldLLT});
313+
CurVReg =
314+
MIRBuilder
315+
.buildBuildVector({NewLLT}, {CurVReg, Undef.getReg(0)})
316+
.getReg(0);
317+
} else {
318+
LLVM_DEBUG(dbgs() << "Could not handle ret ty");
296319
return false;
297320
}
298-
auto Undef = MIRBuilder.buildUndef({OldLLT});
299-
CurVReg =
300-
MIRBuilder.buildMerge({NewLLT}, {CurVReg, Undef.getReg(0)})
301-
.getReg(0);
302321
} else {
322+
// A scalar extend.
303323
CurVReg =
304324
MIRBuilder.buildInstr(ExtendOp, {NewLLT}, {CurVReg}).getReg(0);
305325
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
2+
; RUN: llc -mtriple=aarch64-linux-gnu -O0 -global-isel -stop-after=irtranslator -o - %s | FileCheck %s
3+
4+
define <1 x float> @foo(<1 x float> %v) {
5+
; CHECK-LABEL: name: foo
6+
; CHECK: bb.1 (%ir-block.0):
7+
; CHECK: liveins: $d0
8+
; CHECK: [[COPY:%[0-9]+]]:_(<2 x s32>) = COPY $d0
9+
; CHECK: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[COPY]](<2 x s32>)
10+
; CHECK: [[COPY1:%[0-9]+]]:_(s32) = COPY [[UV]](s32)
11+
; CHECK: [[DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
12+
; CHECK: [[BUILD_VECTOR:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[COPY1]](s32), [[DEF]](s32)
13+
; CHECK: $d0 = COPY [[BUILD_VECTOR]](<2 x s32>)
14+
; CHECK: RET_ReallyLR implicit $d0
15+
ret <1 x float> %v
16+
}

0 commit comments

Comments
 (0)