1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-02-01 05:01:59 +01:00

[GlobalISel][CallLowering] Fix crash when handling a v3s32 type that's being passed as v2s64.

This commit is contained in:
Amara Emerson 2021-05-14 16:21:53 -07:00
parent ecfab87534
commit 7c35883ebc
2 changed files with 42 additions and 7 deletions

View File

@ -328,19 +328,23 @@ static void buildCopyFromRegs(MachineIRBuilder &B, ArrayRef<Register> OrigRegs,
return;
}
// A vector PartLLT needs extending to LLTy's element size.
// E.g. <2 x s64> = G_SEXT <2 x s32>.
if (PartLLT.isVector() == LLTy.isVector() &&
PartLLT.getScalarSizeInBits() > LLTy.getScalarSizeInBits() &&
(!PartLLT.isVector() ||
PartLLT.getNumElements() == LLTy.getNumElements()) &&
OrigRegs.size() == 1 && Regs.size() == 1) {
Register SrcReg = Regs[0];
LLT LocTy = MRI.getType(SrcReg);
if (Flags.isSExt()) {
SrcReg = B.buildAssertSExt(LocTy, SrcReg,
LLTy.getScalarSizeInBits()).getReg(0);
SrcReg = B.buildAssertSExt(LocTy, SrcReg, LLTy.getScalarSizeInBits())
.getReg(0);
} else if (Flags.isZExt()) {
SrcReg = B.buildAssertZExt(LocTy, SrcReg,
LLTy.getScalarSizeInBits()).getReg(0);
SrcReg = B.buildAssertZExt(LocTy, SrcReg, LLTy.getScalarSizeInBits())
.getReg(0);
}
B.buildTrunc(OrigRegs[0], SrcReg);
@ -364,18 +368,30 @@ static void buildCopyFromRegs(MachineIRBuilder &B, ArrayRef<Register> OrigRegs,
if (PartLLT.isVector()) {
assert(OrigRegs.size() == 1);
SmallVector<Register> CastRegs(Regs.begin(), Regs.end());
// If PartLLT is a mismatched vector in both number of elements and element
// size, e.g. PartLLT == v2s64 and LLTy is v3s32, then first coerce it to
// have the same elt type, i.e. v4s32.
if (PartLLT.getSizeInBits() > LLTy.getSizeInBits() &&
PartLLT.getScalarSizeInBits() == LLTy.getScalarSizeInBits() * 2 &&
Regs.size() == 1) {
LLT NewTy = PartLLT.changeElementType(LLTy.getElementType())
.changeNumElements(PartLLT.getNumElements() * 2);
CastRegs[0] = B.buildBitcast(NewTy, Regs[0]).getReg(0);
PartLLT = NewTy;
}
if (LLTy.getScalarType() == PartLLT.getElementType()) {
mergeVectorRegsToResultRegs(B, OrigRegs, Regs);
mergeVectorRegsToResultRegs(B, OrigRegs, CastRegs);
} else {
SmallVector<Register> CastRegs(Regs.size());
unsigned I = 0;
LLT GCDTy = getGCDType(LLTy, PartLLT);
// We are both splitting a vector, and bitcasting its element types. Cast
// the source pieces into the appropriate number of pieces with the result
// element type.
for (Register SrcReg : Regs)
for (Register SrcReg : CastRegs)
CastRegs[I++] = B.buildBitcast(GCDTy, SrcReg).getReg(0);
mergeVectorRegsToResultRegs(B, OrigRegs, CastRegs);
}

View File

@ -44,3 +44,22 @@ define <1 x half> @test_v1s16(<1 x float> %x) {
%tmp = fptrunc <1 x float> %x to <1 x half>
ret <1 x half> %tmp
}
declare <3 x float> @bar(float)
define void @test_return_v3f32() {
; CHECK-LABEL: name: test_return_v3f32
; CHECK: bb.1 (%ir-block.0):
; CHECK: [[DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
; CHECK: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp
; CHECK: $s0 = COPY [[DEF]](s32)
; CHECK: BL @bar, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $s0, implicit-def $q0
; CHECK: [[COPY:%[0-9]+]]:_(<2 x s64>) = COPY $q0
; CHECK: [[BITCAST:%[0-9]+]]:_(<4 x s32>) = G_BITCAST [[COPY]](<2 x s64>)
; CHECK: [[DEF1:%[0-9]+]]:_(<4 x s32>) = G_IMPLICIT_DEF
; CHECK: [[CONCAT_VECTORS:%[0-9]+]]:_(<12 x s32>) = G_CONCAT_VECTORS [[BITCAST]](<4 x s32>), [[DEF1]](<4 x s32>), [[DEF1]](<4 x s32>)
; CHECK: [[UV:%[0-9]+]]:_(<3 x s32>), [[UV1:%[0-9]+]]:_(<3 x s32>), [[UV2:%[0-9]+]]:_(<3 x s32>), [[UV3:%[0-9]+]]:_(<3 x s32>) = G_UNMERGE_VALUES [[CONCAT_VECTORS]](<12 x s32>)
; CHECK: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp
; CHECK: RET_ReallyLR
%call = call <3 x float> @bar(float undef)
ret void
}