@@ -316,6 +316,54 @@ adderGenerator(const int32_t From, const int32_t To, const int32_t StepSize) {
316316 };
317317}
318318
319+ Register CombinerHelper::createUnmergeValue (
320+ MachineInstr &MI, const Register SrcReg, const Register DstReg,
321+ const uint8_t DestinationIndex, const uint32_t Start, const uint32_t End) {
322+ Builder.setInsertPt (*MI.getParent (), MI);
323+ const LLT DstTy = MRI.getType (DstReg);
324+ const LLT SrcTy = MRI.getType (SrcReg);
325+ assert ((!DstTy.isVector () ||
326+ (SrcTy.getNumElements () % DstTy.getNumElements ()) == 0 ) &&
327+ " destination vector must divide source cleanly" );
328+
329+ const unsigned HalfElements = SrcTy.getNumElements () / 2 ;
330+ const LLT ScalarTy = SrcTy.getScalarType ();
331+ const LLT HalfSizeTy = (HalfElements == 1 )
332+ ? ScalarTy
333+ : LLT::fixed_vector (HalfElements, ScalarTy);
334+ const Register TmpReg = MRI.createGenericVirtualRegister (HalfSizeTy);
335+ Register TargetReg = DstReg;
336+ if (DstTy != HalfSizeTy) {
337+ 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;
346+
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+ }
359+
360+ if (HalfSizeTy.isVector () && DstTy != HalfSizeTy)
361+ return createUnmergeValue (MI, TargetReg, DstReg, DestinationIndex,
362+ NextStart, NextEnd);
363+
364+ return DstReg;
365+ }
366+
319367bool CombinerHelper::tryCombineShuffleVector (MachineInstr &MI) {
320368 const Register DstReg = MI.getOperand (0 ).getReg ();
321369 const LLT DstTy = MRI.getType (DstReg);
0 commit comments