diff --git a/llvm/lib/CodeGen/GlobalISel/CallLowering.cpp b/llvm/lib/CodeGen/GlobalISel/CallLowering.cpp --- a/llvm/lib/CodeGen/GlobalISel/CallLowering.cpp +++ b/llvm/lib/CodeGen/GlobalISel/CallLowering.cpp @@ -545,14 +545,21 @@ // or do an unmerge to get the lower block of elements. if (VATy.isVector() && VATy.getNumElements() > OrigVT.getVectorNumElements()) { - // Just handle the case where the VA type is 2 * original type. - if (VATy.getNumElements() != OrigVT.getVectorNumElements() * 2) { - LLVM_DEBUG(dbgs() - << "Incoming promoted vector arg has too many elts"); + // Just handle the case where the VA type is a multiple of original + // type. + if (VATy.getNumElements() % OrigVT.getVectorNumElements() != 0) { + LLVM_DEBUG(dbgs() << "Incoming promoted vector arg elts is not a " + "multiple of orig type elt: " + << VATy << " vs " << OrigTy); return false; } - auto Unmerge = MIRBuilder.buildUnmerge({OrigTy, OrigTy}, {NewReg}); - MIRBuilder.buildCopy(ArgReg, Unmerge.getReg(0)); + SmallVector DstRegs = {ArgReg}; + unsigned NumParts = + VATy.getNumElements() / OrigVT.getVectorNumElements() - 1; + for (unsigned Idx = 0; Idx < NumParts; ++Idx) + DstRegs.push_back( + MIRBuilder.getMRI()->createGenericVirtualRegister(OrigTy)); + MIRBuilder.buildUnmerge(DstRegs, {NewReg}); } else { MIRBuilder.buildTrunc(ArgReg, {NewReg}).getReg(0); } diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/call-lowering-vectors.ll b/llvm/test/CodeGen/AArch64/GlobalISel/call-lowering-vectors.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/GlobalISel/call-lowering-vectors.ll @@ -0,0 +1,15 @@ +; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +; RUN: llc -mtriple=aarch64-linux-gnu -O0 -stop-after=irtranslator -global-isel -verify-machineinstrs %s -o - 2>&1 | FileCheck %s + +define i8 @v1s8_add(<1 x i8> %a0) nounwind { + ; CHECK-LABEL: name: v1s8_add + ; CHECK: bb.1 (%ir-block.0): + ; CHECK: liveins: $d0 + ; CHECK: [[COPY:%[0-9]+]]:_(<8 x s8>) = COPY $d0 + ; CHECK: [[UV:%[0-9]+]]:_(s8), [[UV1:%[0-9]+]]:_(s8), [[UV2:%[0-9]+]]:_(s8), [[UV3:%[0-9]+]]:_(s8), [[UV4:%[0-9]+]]:_(s8), [[UV5:%[0-9]+]]:_(s8), [[UV6:%[0-9]+]]:_(s8), [[UV7:%[0-9]+]]:_(s8) = G_UNMERGE_VALUES [[COPY]](<8 x s8>) + ; CHECK: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[UV]](s8) + ; CHECK: $w0 = COPY [[ANYEXT]](s32) + ; CHECK: RET_ReallyLR implicit $w0 + %res = bitcast <1 x i8> %a0 to i8 + ret i8 %res +} diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/ret-1x-vec.ll b/llvm/test/CodeGen/AArch64/GlobalISel/ret-1x-vec.ll --- a/llvm/test/CodeGen/AArch64/GlobalISel/ret-1x-vec.ll +++ b/llvm/test/CodeGen/AArch64/GlobalISel/ret-1x-vec.ll @@ -7,9 +7,8 @@ ; 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: [[BUILD_VECTOR:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[UV]](s32), [[DEF]](s32) ; CHECK: $d0 = COPY [[BUILD_VECTOR]](<2 x s32>) ; CHECK: RET_ReallyLR implicit $d0 ret <1 x float> %v diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/vec-s16-param.ll b/llvm/test/CodeGen/AArch64/GlobalISel/vec-s16-param.ll --- a/llvm/test/CodeGen/AArch64/GlobalISel/vec-s16-param.ll +++ b/llvm/test/CodeGen/AArch64/GlobalISel/vec-s16-param.ll @@ -7,9 +7,8 @@ ; CHECK: liveins: $d0 ; CHECK: [[COPY:%[0-9]+]]:_(<4 x s16>) = COPY $d0 ; CHECK: [[UV:%[0-9]+]]:_(<2 x s16>), [[UV1:%[0-9]+]]:_(<2 x s16>) = G_UNMERGE_VALUES [[COPY]](<4 x s16>) - ; CHECK: [[COPY1:%[0-9]+]]:_(<2 x s16>) = COPY [[UV]](<2 x s16>) ; CHECK: [[DEF:%[0-9]+]]:_(<2 x s16>) = G_IMPLICIT_DEF - ; CHECK: [[CONCAT_VECTORS:%[0-9]+]]:_(<4 x s16>) = G_CONCAT_VECTORS [[COPY1]](<2 x s16>), [[DEF]](<2 x s16>) + ; CHECK: [[CONCAT_VECTORS:%[0-9]+]]:_(<4 x s16>) = G_CONCAT_VECTORS [[UV]](<2 x s16>), [[DEF]](<2 x s16>) ; CHECK: $d0 = COPY [[CONCAT_VECTORS]](<4 x s16>) ; CHECK: RET_ReallyLR implicit $d0 ret <2 x half> %v