@@ -399,6 +399,54 @@ adderGenerator(const int32_t From, const int32_t To, const int32_t StepSize) {
399399 };
400400}
401401
402+ Register CombinerHelper::createUnmergeValue (
403+ MachineInstr &MI, const Register SrcReg, const Register DstReg,
404+ const uint8_t DestinationIndex, const uint32_t Start, const uint32_t End) {
405+ Builder.setInsertPt (*MI.getParent (), MI);
406+ const LLT DstTy = MRI.getType (DstReg);
407+ const LLT SrcTy = MRI.getType (SrcReg);
408+ assert ((DstTy.isScalar () ||
409+ (SrcTy.getNumElements () % DstTy.getNumElements ()) == 0 ) &&
410+ " destination vector must divide source cleanly" );
411+
412+ const unsigned HalfElements = SrcTy.getNumElements () / 2 ;
413+ const LLT ScalarTy = SrcTy.getScalarType ();
414+ const LLT HalfSizeTy = (HalfElements == 1 )
415+ ? ScalarTy
416+ : LLT::fixed_vector (HalfElements, ScalarTy);
417+ const Register TmpReg = MRI.createGenericVirtualRegister (HalfSizeTy);
418+ Register TargetReg = DstReg;
419+ if (DstTy != HalfSizeTy) {
420+ TargetReg = MRI.createGenericVirtualRegister (HalfSizeTy);
421+ }
422+
423+ // Each destination fits n times into the source and each iteration we exactly
424+ // half the source. Therefore we need to pick on which side we want to iterate
425+ // on.
426+ const uint32_t DstNumElements = DstTy.isVector () ? DstTy.getNumElements () : 1 ;
427+ const uint32_t HalfWay = Start + ((End - Start) / 2 );
428+ const uint32_t Position = DestinationIndex * DstNumElements;
429+
430+ uint32_t NextStart, NextEnd;
431+ if (Position < HalfWay) {
432+ Builder.buildInstr (TargetOpcode::G_UNMERGE_VALUES, {TargetReg, TmpReg},
433+ {SrcReg});
434+ NextStart = Start;
435+ NextEnd = HalfWay;
436+ } else {
437+ Builder.buildInstr (TargetOpcode::G_UNMERGE_VALUES, {TmpReg, TargetReg},
438+ {SrcReg});
439+ NextStart = HalfWay;
440+ NextEnd = End;
441+ }
442+
443+ if (HalfSizeTy.isVector () && DstTy != HalfSizeTy)
444+ return createUnmergeValue (MI, TargetReg, DstReg, DestinationIndex,
445+ NextStart, NextEnd);
446+
447+ return DstReg;
448+ }
449+
402450bool CombinerHelper::tryCombineShuffleVector (MachineInstr &MI) {
403451 const Register DstReg = MI.getOperand (0 ).getReg ();
404452 const LLT DstTy = MRI.getType (DstReg);
0 commit comments