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,13 +545,18 @@ // 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 original type. + if (VATy.getNumElements() % OrigVT.getVectorNumElements() != 0) { + LLVM_DEBUG(dbgs() << "Incoming promoted vector arg elts is not a " + "multiple of orig type elt"); return false; } - auto Unmerge = MIRBuilder.buildUnmerge({OrigTy, OrigTy}, {NewReg}); + SmallVector DstTys; + unsigned NumParts = + VATy.getNumElements() / OrigVT.getVectorNumElements(); + for (unsigned Idx = 0; Idx < NumParts; ++Idx) + DstTys.push_back(OrigTy); + auto Unmerge = MIRBuilder.buildUnmerge(DstTys, {NewReg}); MIRBuilder.buildCopy(ArgReg, Unmerge.getReg(0)); } else { MIRBuilder.buildTrunc(ArgReg, {NewReg}).getReg(0); diff --git a/llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp b/llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp --- a/llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp +++ b/llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp @@ -378,18 +378,15 @@ 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 + } else { + // We need to pad a <1 x S> type to . 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; + SmallVector Srcs = {CurVReg}; + for (unsigned Idx = 0; Idx < NewLLT.getNumElements() - 1; ++Idx) + Srcs.push_back(Undef.getReg(0)); + CurVReg = MIRBuilder.buildBuildVector({NewLLT}, Srcs).getReg(0); } } else { // A scalar extend. 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,18 @@ +; 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 <1 x 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: [[COPY1:%[0-9]+]]:_(s8) = COPY [[UV]](s8) + ; CHECK: [[ADD:%[0-9]+]]:_(s8) = G_ADD [[COPY1]], [[COPY1]] + ; CHECK: [[DEF:%[0-9]+]]:_(s8) = G_IMPLICIT_DEF + ; CHECK: [[BUILD_VECTOR:%[0-9]+]]:_(<8 x s8>) = G_BUILD_VECTOR [[ADD]](s8), [[DEF]](s8), [[DEF]](s8), [[DEF]](s8), [[DEF]](s8), [[DEF]](s8), [[DEF]](s8), [[DEF]](s8) + ; CHECK: $d0 = COPY [[BUILD_VECTOR]](<8 x s8>) + ; CHECK: RET_ReallyLR implicit $d0 + %res = add <1 x i8> %a0, %a0 + ret <1 x i8> %res +}