@@ -398,6 +398,21 @@ adderGenerator(const int32_t From, const int32_t To, const int32_t StepSize) {
398398 };
399399}
400400
401+ // Move to the next generator if it is exhausted allowing to chain generators
402+ std::function<std::optional<int32_t >()> concatGenerators (
403+ SmallVector<std::function<std::optional<int32_t >()>> Generators) {
404+ auto *GeneratorIterator = Generators.begin ();
405+
406+ return [GeneratorIterator, Generators]() mutable {
407+ std::optional<int32_t > GenValue = (*GeneratorIterator)();
408+ if (!GenValue.has_value () && GeneratorIterator != Generators.end ()) {
409+ GeneratorIterator++;
410+ GenValue = (*GeneratorIterator)();
411+ }
412+ return GenValue;
413+ };
414+ }
415+
401416Register CombinerHelper::createUnmergeValue (
402417 MachineInstr &MI, const Register SrcReg, const Register DstReg,
403418 const uint8_t DestinationIndex, const uint32_t Start, const uint32_t End) {
@@ -419,31 +434,32 @@ Register CombinerHelper::createUnmergeValue(
419434 TargetReg = MRI.createGenericVirtualRegister (HalfSizeTy);
420435 }
421436
422- // Each destination fits n times into the source and each iteration we exactly
423- // half the source. Therefore we need to pick on which side we want to iterate
424- // on.
425- const uint32_t DstNumElements = DstTy.isVector () ? DstTy.getNumElements () : 1 ;
426- const uint32_t HalfWay = Start + ((End - Start) / 2 );
427- const uint32_t Position = DestinationIndex * DstNumElements;
428-
429- uint32_t NextStart, NextEnd;
430- if (Position < HalfWay) {
431- Builder.buildInstr (TargetOpcode::G_UNMERGE_VALUES, {TargetReg, TmpReg},
432- {SrcReg});
433- NextStart = Start;
434- NextEnd = HalfWay;
435- } else {
436- Builder.buildInstr (TargetOpcode::G_UNMERGE_VALUES, {TmpReg, TargetReg},
437- {SrcReg});
438- NextStart = HalfWay;
439- NextEnd = End;
440- }
437+ // Each destination fits n times into the source and each iteration we
438+ // exactly half the source. Therefore we need to pick on which side we want
439+ // to iterate on.
440+ const uint32_t DstNumElements =
441+ DstTy.isVector () ? DstTy.getNumElements () : 1 ;
442+ const uint32_t HalfWay = Start + ((End - Start) / 2 );
443+ const uint32_t Position = DestinationIndex * DstNumElements;
444+
445+ uint32_t NextStart, NextEnd;
446+ if (Position < HalfWay) {
447+ Builder.buildInstr (TargetOpcode::G_UNMERGE_VALUES, {TargetReg, TmpReg},
448+ {SrcReg});
449+ NextStart = Start;
450+ NextEnd = HalfWay;
451+ } else {
452+ Builder.buildInstr (TargetOpcode::G_UNMERGE_VALUES, {TmpReg, TargetReg},
453+ {SrcReg});
454+ NextStart = HalfWay;
455+ NextEnd = End;
456+ }
441457
442- if (HalfSizeTy.isVector () && DstTy != HalfSizeTy)
443- return createUnmergeValue (MI, TargetReg, DstReg, DestinationIndex,
444- NextStart, NextEnd);
458+ if (HalfSizeTy.isVector () && DstTy != HalfSizeTy)
459+ return createUnmergeValue (MI, TargetReg, DstReg, DestinationIndex,
460+ NextStart, NextEnd);
445461
446- return DstReg;
462+ return DstReg;
447463}
448464
449465bool CombinerHelper::tryCombineShuffleVector (MachineInstr &MI) {
0 commit comments