Index: lib/CodeGen/GlobalISel/LegalizerHelper.cpp =================================================================== --- lib/CodeGen/GlobalISel/LegalizerHelper.cpp +++ lib/CodeGen/GlobalISel/LegalizerHelper.cpp @@ -1239,6 +1239,32 @@ switch (Opc) { default: return UnableToLegalize; + case TargetOpcode::G_IMPLICIT_DEF: { + SmallVector DstRegs; + + unsigned NarrowSize = NarrowTy.getSizeInBits(); + unsigned DstReg = MI.getOperand(0).getReg(); + unsigned Size = MRI.getType(DstReg).getSizeInBits(); + int NumParts = Size / NarrowSize; + // FIXME: Don't know how to handle the situation where the small vectors + // aren't all the same size yet. + if (Size % NarrowSize != 0) + return UnableToLegalize; + + for (int i = 0; i < NumParts; ++i) { + unsigned TmpReg = MRI.createGenericVirtualRegister(NarrowTy); + MIRBuilder.buildUndef(TmpReg); + DstRegs.push_back(TmpReg); + } + + if (NarrowTy.isVector()) + MIRBuilder.buildConcatVectors(DstReg, DstRegs); + else + MIRBuilder.buildBuildVector(DstReg, DstRegs); + + MI.eraseFromParent(); + return Legalized; + } case TargetOpcode::G_ADD: { unsigned NarrowSize = NarrowTy.getSizeInBits(); unsigned DstReg = MI.getOperand(0).getReg(); Index: lib/Target/AArch64/AArch64LegalizerInfo.cpp =================================================================== --- lib/Target/AArch64/AArch64LegalizerInfo.cpp +++ lib/Target/AArch64/AArch64LegalizerInfo.cpp @@ -48,9 +48,21 @@ const LLT v2s64 = LLT::vector(2, 64); getActionDefinitionsBuilder(G_IMPLICIT_DEF) - .legalFor({p0, s1, s8, s16, s32, s64, v2s64}) - .clampScalar(0, s1, s64) - .widenScalarToNextPow2(0, 8); + .legalFor({p0, s1, s8, s16, s32, s64, v2s64}) + .clampScalar(0, s1, s64) + .widenScalarToNextPow2(0, 8) + .fewerElementsIf( + [=](const LegalityQuery &Query) { + return Query.Types[0].isVector() && + (Query.Types[0].getElementType() != s64 || + Query.Types[0].getNumElements() != 2); + }, + [=](const LegalityQuery &Query) { + LLT EltTy = Query.Types[0].getElementType(); + if (EltTy == s64) + return std::make_pair(0, LLT::vector(2, 64)); + return std::make_pair(0, EltTy); + }); getActionDefinitionsBuilder(G_PHI) .legalFor({p0, s16, s32, s64}) Index: test/CodeGen/AArch64/GlobalISel/legalize-undef.mir =================================================================== --- test/CodeGen/AArch64/GlobalISel/legalize-undef.mir +++ test/CodeGen/AArch64/GlobalISel/legalize-undef.mir @@ -35,3 +35,39 @@ ... # FIXME: s2 not correctly handled + +--- +name: test_implicit_def_v2s32 +body: | + bb.0: + + ; CHECK-LABEL: name: test_implicit_def_v2s32 + ; CHECK: [[DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF + ; CHECK: [[DEF1:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF + ; CHECK: [[DEF2:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF + ; CHECK: [[DEF3:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF + ; CHECK: [[BUILD_VECTOR:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[DEF]](s32), [[DEF1]](s32), [[DEF2]](s32), [[DEF3]](s32) + ; CHECK: [[UV:%[0-9]+]]:_(<2 x s32>), [[UV1:%[0-9]+]]:_(<2 x s32>) = G_UNMERGE_VALUES [[BUILD_VECTOR]](<4 x s32>) + ; CHECK: $x0 = COPY [[UV]](<2 x s32>) + ; CHECK: $x1 = COPY [[UV1]](<2 x s32>) + %0:_(<4 x s32>) = G_IMPLICIT_DEF + %1:_(<2 x s32> ), %2:_(<2 x s32>) = G_UNMERGE_VALUES %0 + $x0 = COPY %1 + $x1 = COPY %2 +... + +--- +name: test_implicit_def_v4s64 +body: | + bb.0: + + ; CHECK-LABEL: name: test_implicit_def_v4s64 + ; CHECK: [[DEF:%[0-9]+]]:_(<2 x s64>) = G_IMPLICIT_DEF + ; CHECK: [[DEF1:%[0-9]+]]:_(<2 x s64>) = G_IMPLICIT_DEF + ; CHECK: $q0 = COPY [[DEF]](<2 x s64>) + ; CHECK: $q1 = COPY [[DEF1]](<2 x s64>) + %0:_(<4 x s64>) = G_IMPLICIT_DEF + %1:_(<2 x s64> ), %2:_(<2 x s64>) = G_UNMERGE_VALUES %0 + $q0 = COPY %1 + $q1 = COPY %2 +...