Index: lib/CodeGen/GlobalISel/LegalizerHelper.cpp =================================================================== --- lib/CodeGen/GlobalISel/LegalizerHelper.cpp +++ lib/CodeGen/GlobalISel/LegalizerHelper.cpp @@ -2875,6 +2875,26 @@ moreElementsVectorDst(MI, MoreTy, 0); Observer.changedInstr(MI); return Legalized; + case TargetOpcode::G_UNMERGE_VALUES: { + if (TypeIdx != 1) + return UnableToLegalize; + + LLT DstTy = MRI.getType(MI.getOperand(0).getReg()); + int NumDst = MI.getNumOperands() - 1; + moreElementsVectorSrc(MI, MoreTy, NumDst); + + auto MIB = MIRBuilder.buildInstr(TargetOpcode::G_UNMERGE_VALUES); + for (int I = 0; I != NumDst; ++I) + MIB.addDef(MI.getOperand(I).getReg()); + + int NewNumDst = MoreTy.getSizeInBits() / DstTy.getSizeInBits(); + for (int I = NumDst; I != NewNumDst; ++I) + MIB.addDef(MRI.createGenericVirtualRegister(DstTy)); + + MIB.addUse(MI.getOperand(NumDst).getReg()); + MI.eraseFromParent(); + return Legalized; + } case TargetOpcode::G_PHI: return moreElementsVectorPhi(MI, TypeIdx, MoreTy); default: Index: lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp =================================================================== --- lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp +++ lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp @@ -929,6 +929,7 @@ elementTypeIs(1, S16)), changeTo(1, V2S16)) // Break up vectors with weird elements into scalars + .moreElementsIf(isSmallOddVector(BigTyIdx), oneMoreElement(BigTyIdx)) .fewerElementsIf( [=](const LegalityQuery &Query) { return notValidElt(Query, 0); }, scalarize(0)) Index: test/CodeGen/AMDGPU/GlobalISel/legalize-fexp.mir =================================================================== --- test/CodeGen/AMDGPU/GlobalISel/legalize-fexp.mir +++ test/CodeGen/AMDGPU/GlobalISel/legalize-fexp.mir @@ -9,8 +9,8 @@ ; CHECK-LABEL: name: test_fexp_s32 ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $vgpr0 - ; CHECK: [[FEXP_:%[0-9]+]]:_(s32) = G_FEXP [[COPY]] - ; CHECK: $vgpr0 = COPY [[FEXP_]](s32) + ; CHECK: [[FEXP:%[0-9]+]]:_(s32) = G_FEXP [[COPY]] + ; CHECK: $vgpr0 = COPY [[FEXP]](s32) %0:_(s32) = COPY $vgpr0 %1:_(s32) = G_FEXP %0 $vgpr0 = COPY %1 @@ -25,9 +25,9 @@ ; CHECK-LABEL: name: test_fexp_v2s32 ; CHECK: [[COPY:%[0-9]+]]:_(<2 x s32>) = COPY $vgpr0_vgpr1 ; CHECK: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[COPY]](<2 x s32>) - ; CHECK: [[FEXP_:%[0-9]+]]:_(s32) = G_FEXP [[UV]] - ; CHECK: [[FEXP_1:%[0-9]+]]:_(s32) = G_FEXP [[UV1]] - ; CHECK: [[BUILD_VECTOR:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[FEXP_]](s32), [[FEXP_1]](s32) + ; CHECK: [[FEXP:%[0-9]+]]:_(s32) = G_FEXP [[UV]] + ; CHECK: [[FEXP1:%[0-9]+]]:_(s32) = G_FEXP [[UV1]] + ; CHECK: [[BUILD_VECTOR:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[FEXP]](s32), [[FEXP1]](s32) ; CHECK: $vgpr0_vgpr1 = COPY [[BUILD_VECTOR]](<2 x s32>) %0:_(<2 x s32>) = COPY $vgpr0_vgpr1 %1:_(<2 x s32>) = G_FEXP %0 @@ -43,10 +43,10 @@ ; CHECK-LABEL: name: test_fexp_v3s32 ; CHECK: [[COPY:%[0-9]+]]:_(<3 x s32>) = COPY $vgpr0_vgpr1_vgpr2 ; CHECK: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32), [[UV2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[COPY]](<3 x s32>) - ; CHECK: [[FEXP_:%[0-9]+]]:_(s32) = G_FEXP [[UV]] - ; CHECK: [[FEXP_1:%[0-9]+]]:_(s32) = G_FEXP [[UV1]] - ; CHECK: [[FEXP_2:%[0-9]+]]:_(s32) = G_FEXP [[UV2]] - ; CHECK: [[BUILD_VECTOR:%[0-9]+]]:_(<3 x s32>) = G_BUILD_VECTOR [[FEXP_]](s32), [[FEXP_1]](s32), [[FEXP_2]](s32) + ; CHECK: [[FEXP:%[0-9]+]]:_(s32) = G_FEXP [[UV]] + ; CHECK: [[FEXP1:%[0-9]+]]:_(s32) = G_FEXP [[UV1]] + ; CHECK: [[FEXP2:%[0-9]+]]:_(s32) = G_FEXP [[UV2]] + ; CHECK: [[BUILD_VECTOR:%[0-9]+]]:_(<3 x s32>) = G_BUILD_VECTOR [[FEXP]](s32), [[FEXP1]](s32), [[FEXP2]](s32) ; CHECK: $vgpr0_vgpr1_vgpr2 = COPY [[BUILD_VECTOR]](<3 x s32>) %0:_(<3 x s32>) = COPY $vgpr0_vgpr1_vgpr2 %1:_(<3 x s32>) = G_FEXP %0