mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-18 18:42:46 +02:00
[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. llvm-svn: 360068
This commit is contained in:
parent
f90261141b
commit
79073a3227
@ -286,20 +286,40 @@ bool AArch64CallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
|
||||
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");
|
||||
// padding with more elements, e.g. <2 x half> -> <4 x half>.
|
||||
if (NewVT.isVector()) {
|
||||
if (OldLLT.isVector()) {
|
||||
if (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 {
|
||||
// Just do a vector extend.
|
||||
CurVReg = MIRBuilder.buildInstr(ExtendOp, {NewLLT}, {CurVReg})
|
||||
.getReg(0);
|
||||
}
|
||||
} else if (NewLLT.getNumElements() == 2) {
|
||||
// We need to pad a <1 x S> type to <2 x S>. Since we don't have
|
||||
// <1 x S> vector types in GISel we use a build_vector instead
|
||||
// of a vector merge/concat.
|
||||
auto Undef = MIRBuilder.buildUndef({OldLLT});
|
||||
CurVReg =
|
||||
MIRBuilder
|
||||
.buildBuildVector({NewLLT}, {CurVReg, Undef.getReg(0)})
|
||||
.getReg(0);
|
||||
} else {
|
||||
LLVM_DEBUG(dbgs() << "Could not handle ret ty");
|
||||
return false;
|
||||
}
|
||||
auto Undef = MIRBuilder.buildUndef({OldLLT});
|
||||
CurVReg =
|
||||
MIRBuilder.buildMerge({NewLLT}, {CurVReg, Undef.getReg(0)})
|
||||
.getReg(0);
|
||||
} else {
|
||||
// A scalar extend.
|
||||
CurVReg =
|
||||
MIRBuilder.buildInstr(ExtendOp, {NewLLT}, {CurVReg}).getReg(0);
|
||||
}
|
||||
|
16
test/CodeGen/AArch64/GlobalISel/ret-1x-vec.ll
Normal file
16
test/CodeGen/AArch64/GlobalISel/ret-1x-vec.ll
Normal file
@ -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
|
||||
|
||||
define <1 x float> @foo(<1 x float> %v) {
|
||||
; CHECK-LABEL: name: foo
|
||||
; CHECK: bb.1 (%ir-block.0):
|
||||
; CHECK: liveins: $d0
|
||||
; CHECK: [[COPY:%[0-9]+]]:_(<2 x s32>) = COPY $d0
|
||||
; CHECK: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[COPY]](<2 x s32>)
|
||||
; CHECK: [[COPY1:%[0-9]+]]:_(s32) = COPY [[UV]](s32)
|
||||
; CHECK: [[DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
|
||||
; CHECK: [[BUILD_VECTOR:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[COPY1]](s32), [[DEF]](s32)
|
||||
; CHECK: $d0 = COPY [[BUILD_VECTOR]](<2 x s32>)
|
||||
; CHECK: RET_ReallyLR implicit $d0
|
||||
ret <1 x float> %v
|
||||
}
|
Loading…
Reference in New Issue
Block a user