@@ -316,6 +316,21 @@ adderGenerator(const int32_t From, const int32_t To, const int32_t StepSize) {
316316 };
317317}
318318
319+ // Move to the next generator if it is exhausted allowing to chain generators
320+ std::function<std::optional<int32_t >()> concatGenerators (
321+ SmallVector<std::function<std::optional<int32_t >()>> Generators) {
322+ auto *GeneratorIterator = Generators.begin ();
323+
324+ return [GeneratorIterator, Generators]() mutable {
325+ std::optional<int32_t > GenValue = (*GeneratorIterator)();
326+ if (!GenValue.has_value () && GeneratorIterator != Generators.end ()) {
327+ GeneratorIterator++;
328+ GenValue = (*GeneratorIterator)();
329+ }
330+ return GenValue;
331+ };
332+ }
333+
319334Register CombinerHelper::createUnmergeValue (
320335 MachineInstr &MI, const Register SrcReg, const Register DstReg,
321336 const uint8_t DestinationIndex, const uint32_t Start, const uint32_t End) {
@@ -335,33 +350,34 @@ Register CombinerHelper::createUnmergeValue(
335350 Register TargetReg = DstReg;
336351 if (DstTy != HalfSizeTy) {
337352 TargetReg = MRI.createGenericVirtualRegister (HalfSizeTy);
338- }
339-
340- // Each destination fits n times into the source and each iteration we exactly
341- // half the source. Therefore we need to pick on which side we want to iterate
342- // on.
343- const uint32_t DstNumElements = DstTy.isVector () ? DstTy.getNumElements () : 1 ;
344- const uint32_t HalfWay = Start + ((End - Start) / 2 );
345- const uint32_t Position = DestinationIndex * DstNumElements;
353+ }
346354
347- uint32_t NextStart, NextEnd;
348- if (Position < HalfWay) {
349- Builder.buildInstr (TargetOpcode::G_UNMERGE_VALUES, {TargetReg, TmpReg},
350- {SrcReg});
351- NextStart = Start;
352- NextEnd = HalfWay;
353- } else {
354- Builder.buildInstr (TargetOpcode::G_UNMERGE_VALUES, {TmpReg, TargetReg},
355- {SrcReg});
356- NextStart = HalfWay;
357- NextEnd = End;
358- }
355+ // Each destination fits n times into the source and each iteration we
356+ // exactly half the source. Therefore we need to pick on which side we want
357+ // to iterate on.
358+ const uint32_t DstNumElements =
359+ DstTy.isVector () ? DstTy.getNumElements () : 1 ;
360+ const uint32_t HalfWay = Start + ((End - Start) / 2 );
361+ const uint32_t Position = DestinationIndex * DstNumElements;
362+
363+ uint32_t NextStart, NextEnd;
364+ if (Position < HalfWay) {
365+ Builder.buildInstr (TargetOpcode::G_UNMERGE_VALUES, {TargetReg, TmpReg},
366+ {SrcReg});
367+ NextStart = Start;
368+ NextEnd = HalfWay;
369+ } else {
370+ Builder.buildInstr (TargetOpcode::G_UNMERGE_VALUES, {TmpReg, TargetReg},
371+ {SrcReg});
372+ NextStart = HalfWay;
373+ NextEnd = End;
374+ }
359375
360- if (HalfSizeTy.isVector () && DstTy != HalfSizeTy)
361- return createUnmergeValue (MI, TargetReg, DstReg, DestinationIndex,
362- NextStart, NextEnd);
376+ if (HalfSizeTy.isVector () && DstTy != HalfSizeTy)
377+ return createUnmergeValue (MI, TargetReg, DstReg, DestinationIndex,
378+ NextStart, NextEnd);
363379
364- return DstReg;
380+ return DstReg;
365381}
366382
367383bool CombinerHelper::tryCombineShuffleVector (MachineInstr &MI) {
0 commit comments