@@ -493,6 +493,9 @@ Value *VPInstruction::generate(VPTransformState &State) {
493493  }
494494  case  Instruction::ExtractElement: {
495495    assert (State.VF .isVector () && " Only extract elements from vectors" 
496+     return  State.get (getOperand (0 ),
497+                      VPLane (cast<ConstantInt>(getOperand (1 )->getLiveInIRValue ())
498+                                 ->getZExtValue ()));
496499    Value *Vec = State.get (getOperand (0 ));
497500    Value *Idx = State.get (getOperand (1 ), /* IsScalar=*/ true );
498501    return  Builder.CreateExtractElement (Vec, Idx, Name);
@@ -604,6 +607,33 @@ Value *VPInstruction::generate(VPTransformState &State) {
604607    return  Builder.CreateVectorSplat (
605608        State.VF , State.get (getOperand (0 ), /* IsScalar*/ true ), " broadcast" 
606609  }
610+   case  VPInstruction::BuildVector: {
611+     auto  *ScalarTy = State.TypeAnalysis .inferScalarType (getOperand (0 ));
612+     Value *Res = PoisonValue::get (
613+         toVectorizedTy (ScalarTy, ElementCount::getFixed (getNumOperands ())));
614+     for  (const  auto  &[Idx, Op] : enumerate(operands ()))
615+       Res = State.Builder .CreateInsertElement (Res, State.get (Op, true ),
616+                                               State.Builder .getInt32 (Idx));
617+     return  Res;
618+   }
619+   case  VPInstruction::BuildStructVector: {
620+     //  For struct types, we need to build a new 'wide' struct type, where each
621+     //  element is widened.
622+     auto  *STy =
623+         cast<StructType>(State.TypeAnalysis .inferScalarType (getOperand (0 )));
624+     Value *Res = PoisonValue::get (
625+         toVectorizedTy (STy, ElementCount::getFixed (getNumOperands ())));
626+     for  (const  auto  &[Idx, Op] : enumerate(operands ())) {
627+       for  (unsigned  I = 0 , E = STy->getNumElements (); I != E; I++) {
628+         Value *ScalarValue = Builder.CreateExtractValue (State.get (Op, true ), I);
629+         Value *VectorValue = Builder.CreateExtractValue (Res, I);
630+         VectorValue =
631+             Builder.CreateInsertElement (VectorValue, ScalarValue, Idx);
632+         Res = Builder.CreateInsertValue (Res, VectorValue, I);
633+       }
634+     }
635+     return  Res;
636+   }
607637  case  VPInstruction::ComputeAnyOfResult: {
608638    //  FIXME: The cross-recipe dependency on VPReductionPHIRecipe is temporary
609639    //  and will be removed by breaking up the recipe further.
@@ -872,10 +902,11 @@ void VPInstruction::execute(VPTransformState &State) {
872902  if  (!hasResult ())
873903    return ;
874904  assert (GeneratedValue && " generate must produce a value" 
875-   assert (
876-       (GeneratedValue->getType ()->isVectorTy () == !GeneratesPerFirstLaneOnly ||
877-        State.VF .isScalar ()) &&
878-       " scalar value but not only first lane defined" 
905+   assert ((((GeneratedValue->getType ()->isVectorTy () ||
906+             GeneratedValue->getType ()->isStructTy ()) ==
907+            !GeneratesPerFirstLaneOnly) ||
908+           State.VF .isScalar ()) &&
909+          " scalar value but not only first lane defined" 
879910  State.set (this , GeneratedValue,
880911            /* IsScalar*/ 
881912}
@@ -889,6 +920,8 @@ bool VPInstruction::opcodeMayReadOrWriteFromMemory() const {
889920  case  Instruction::ICmp:
890921  case  Instruction::Select:
891922  case  VPInstruction::AnyOf:
923+   case  VPInstruction::BuildVector:
924+   case  VPInstruction::BuildStructVector:
892925  case  VPInstruction::CalculateTripCountMinusVF:
893926  case  VPInstruction::CanonicalIVIncrementForPart:
894927  case  VPInstruction::ExtractLastElement:
@@ -1008,6 +1041,12 @@ void VPInstruction::print(raw_ostream &O, const Twine &Indent,
10081041  case  VPInstruction::Broadcast:
10091042    O << " broadcast" 
10101043    break ;
1044+   case  VPInstruction::BuildVector:
1045+     O << " buildvector" 
1046+     break ;
1047+   case  VPInstruction::BuildStructVector:
1048+     O << " buildstructvector" 
1049+     break ;
10111050  case  VPInstruction::ExtractLastElement:
10121051    O << " extract-last-element" 
10131052    break ;
@@ -2763,20 +2802,6 @@ void VPReplicateRecipe::execute(VPTransformState &State) {
27632802    scalarizeInstruction (UI, this , VPLane (0 ), State);
27642803    return ;
27652804  }
2766- 
2767-   //  A store of a loop varying value to a uniform address only needs the last
2768-   //  copy of the store.
2769-   if  (isa<StoreInst>(UI) && vputils::isSingleScalar (getOperand (1 ))) {
2770-     auto  Lane = VPLane::getLastLaneForVF (State.VF );
2771-     scalarizeInstruction (UI, this , VPLane (Lane), State);
2772-     return ;
2773-   }
2774- 
2775-   //  Generate scalar instances for all VF lanes.
2776-   assert (!State.VF .isScalable () && " Can't scalarize a scalable vector" 
2777-   const  unsigned  EndLane = State.VF .getKnownMinValue ();
2778-   for  (unsigned  Lane = 0 ; Lane < EndLane; ++Lane)
2779-     scalarizeInstruction (UI, this , VPLane (Lane), State);
27802805}
27812806
27822807bool  VPReplicateRecipe::shouldPack () const  {
0 commit comments