[llvm] GlobalISel: Fix mishandling vector-as-scalar in return values (PR #175780)
Matt Arsenault via llvm-commits
llvm-commits at lists.llvm.org
Thu Jan 22 04:51:10 PST 2026
================
@@ -645,9 +654,22 @@ static void buildCopyToRegs(MachineIRBuilder &B, ArrayRef<Register> DstRegs,
}
}
- if (LCMTy.isVector() && CoveringSize != SrcSize)
+ if (LCMTy.isVector() && CoveringSize != SrcSize) {
UnmergeSrc = B.buildPadVectorWithUndefElements(LCMTy, SrcReg).getReg(0);
+ unsigned ExcessBits = CoveringSize - DstSize * DstRegs.size();
+ if (ExcessBits != 0) {
+ SmallVector<Register, 8> PaddedDstRegs(DstRegs.begin(), DstRegs.end());
+
+ MachineRegisterInfo &MRI = *B.getMRI();
+ for (unsigned I = 0; I != ExcessBits; I += PartSize)
+ PaddedDstRegs.push_back(MRI.createGenericVirtualRegister(PartTy));
+
+ B.buildUnmerge(PaddedDstRegs, UnmergeSrc);
+ return;
+ }
+ }
----------------
arsenm wrote:
This returns exactly as many registers as the target asked, the padding is just to conform to the requirements of the unmerge.
e.g. for this:
```
define <3 x i16> @ret_v3i16() {
ret <3 x i16> poison
}
```
We get:
```
%8:_(<3 x s16>) = G_IMPLICIT_DEF
%11:_(s16), %12:_(s16), %13:_(s16) = G_UNMERGE_VALUES %8(<3 x s16>)
%14:_(s16) = G_IMPLICIT_DEF
%15:_(<6 x s16>) = G_BUILD_VECTOR %11(s16), %12(s16), %13(s16), %14(s16), %14(s16), %14(s16)
%9:_(s32), %10:_(s32), %16:_(s32) = G_UNMERGE_VALUES %15(<6 x s16>)
$vgpr0 = COPY %9(s32)
$vgpr1 = COPY %10(s32)
SI_RETURN implicit $vgpr0, implicit $vgpr1
```
The padding is the unused %16
https://github.com/llvm/llvm-project/pull/175780
More information about the llvm-commits
mailing list