@@ -943,56 +943,98 @@ static void recursivelyDeleteDeadRecipes(VPValue *V) {
943943  }
944944}
945945
946+ // / Get any instruction opcode or intrinsic ID data embedded in recipe \p R.
947+ // / Returns an optional pair, where the first element indicates whether it is
948+ // / an intrinsic ID.
949+ static  std::optional<std::pair<bool , unsigned >>
950+ getOpcodeOrIntrinsicID (const  VPSingleDefRecipe *R) {
951+   return  TypeSwitch<const  VPSingleDefRecipe *,
952+                     std::optional<std::pair<bool , unsigned >>>(R)
953+       .Case <VPInstruction, VPWidenRecipe, VPWidenCastRecipe,
954+             VPWidenSelectRecipe, VPWidenGEPRecipe, VPReplicateRecipe>(
955+           [](auto  *I) { return  std::make_pair (false , I->getOpcode ()); })
956+       .Case <VPWidenIntrinsicRecipe>([](auto  *I) {
957+         return  std::make_pair (true , I->getVectorIntrinsicID ());
958+       })
959+       .Case <VPVectorPointerRecipe, VPPredInstPHIRecipe>([](auto  *I) {
960+         //  For recipes that do not directly map to LLVM IR instructions,
961+         //  assign opcodes after the last VPInstruction opcode (which is also
962+         //  after the last IR Instruction opcode), based on the VPDefID.
963+         return  std::make_pair (false ,
964+                               VPInstruction::OpsEnd + 1  + I->getVPDefID ());
965+       })
966+       .Default ([](auto  *) { return  std::nullopt ; });
967+ }
968+ 
946969// / Try to fold \p R using InstSimplifyFolder. Will succeed and return a
947- // / non-nullptr Value for a handled \p Opcode if corresponding \p Operands are
948- // / foldable live-ins.
949- static  Value *tryToFoldLiveIns (const  VPRecipeBase &R, unsigned  Opcode,
950-                                ArrayRef<VPValue *> Operands,
951-                                const  DataLayout &DL, VPTypeAnalysis &TypeInfo) {
970+ // / non-nullptr VPValue for a handled opcode or intrinsic ID if corresponding \p
971+ // / Operands are foldable live-ins.
972+ static  VPValue *tryToFoldLiveIns (VPSingleDefRecipe &R,
973+                                  ArrayRef<VPValue *> Operands,
974+                                  const  DataLayout &DL,
975+                                  VPTypeAnalysis &TypeInfo) {
976+   auto  OpcodeOrIID = getOpcodeOrIntrinsicID (&R);
977+   if  (!OpcodeOrIID)
978+     return  nullptr ;
979+ 
952980  SmallVector<Value *, 4 > Ops;
953981  for  (VPValue *Op : Operands) {
954982    if  (!Op->isLiveIn () || !Op->getLiveInIRValue ())
955983      return  nullptr ;
956984    Ops.push_back (Op->getLiveInIRValue ());
957985  }
958986
959-   InstSimplifyFolder Folder (DL);
960-   if  (Instruction::isBinaryOp (Opcode))
961-     return  Folder.FoldBinOp (static_cast <Instruction::BinaryOps>(Opcode), Ops[0 ],
987+   auto  FoldToIRValue = [&]() -> Value * {
988+     InstSimplifyFolder Folder (DL);
989+     if  (OpcodeOrIID->first ) {
990+       if  (R.getNumOperands () != 2 )
991+         return  nullptr ;
992+       unsigned  ID = OpcodeOrIID->second ;
993+       return  Folder.FoldBinaryIntrinsic (ID, Ops[0 ], Ops[1 ],
994+                                         TypeInfo.inferScalarType (&R));
995+     }
996+     unsigned  Opcode = OpcodeOrIID->second ;
997+     if  (Instruction::isBinaryOp (Opcode))
998+       return  Folder.FoldBinOp (static_cast <Instruction::BinaryOps>(Opcode),
999+                               Ops[0 ], Ops[1 ]);
1000+     if  (Instruction::isCast (Opcode))
1001+       return  Folder.FoldCast (static_cast <Instruction::CastOps>(Opcode), Ops[0 ],
1002+                              TypeInfo.inferScalarType (R.getVPSingleValue ()));
1003+     switch  (Opcode) {
1004+     case  VPInstruction::LogicalAnd:
1005+       return  Folder.FoldSelect (Ops[0 ], Ops[1 ],
1006+                                ConstantInt::getNullValue (Ops[1 ]->getType ()));
1007+     case  VPInstruction::Not:
1008+       return  Folder.FoldBinOp (Instruction::BinaryOps::Xor, Ops[0 ],
1009+                               Constant::getAllOnesValue (Ops[0 ]->getType ()));
1010+     case  Instruction::Select:
1011+       return  Folder.FoldSelect (Ops[0 ], Ops[1 ], Ops[2 ]);
1012+     case  Instruction::ICmp:
1013+     case  Instruction::FCmp:
1014+       return  Folder.FoldCmp (cast<VPRecipeWithIRFlags>(R).getPredicate (), Ops[0 ],
9621015                            Ops[1 ]);
963-   if  (Instruction::isCast (Opcode))
964-     return  Folder.FoldCast (static_cast <Instruction::CastOps>(Opcode), Ops[0 ],
965-                            TypeInfo.inferScalarType (R.getVPSingleValue ()));
966-   switch  (Opcode) {
967-   case  VPInstruction::LogicalAnd:
968-     return  Folder.FoldSelect (Ops[0 ], Ops[1 ],
969-                              ConstantInt::getNullValue (Ops[1 ]->getType ()));
970-   case  VPInstruction::Not:
971-     return  Folder.FoldBinOp (Instruction::BinaryOps::Xor, Ops[0 ],
972-                             Constant::getAllOnesValue (Ops[0 ]->getType ()));
973-   case  Instruction::Select:
974-     return  Folder.FoldSelect (Ops[0 ], Ops[1 ], Ops[2 ]);
975-   case  Instruction::ICmp:
976-   case  Instruction::FCmp:
977-     return  Folder.FoldCmp (cast<VPRecipeWithIRFlags>(R).getPredicate (), Ops[0 ],
978-                           Ops[1 ]);
979-   case  Instruction::GetElementPtr: {
980-     auto  &RFlags = cast<VPRecipeWithIRFlags>(R);
981-     auto  *GEP = cast<GetElementPtrInst>(RFlags.getUnderlyingInstr ());
982-     return  Folder.FoldGEP (GEP->getSourceElementType (), Ops[0 ], drop_begin (Ops),
983-                           RFlags.getGEPNoWrapFlags ());
984-   }
985-   case  VPInstruction::PtrAdd:
986-   case  VPInstruction::WidePtrAdd:
987-     return  Folder.FoldGEP (IntegerType::getInt8Ty (TypeInfo.getContext ()), Ops[0 ],
988-                           Ops[1 ],
989-                           cast<VPRecipeWithIRFlags>(R).getGEPNoWrapFlags ());
990-   //  An extract of a live-in is an extract of a broadcast, so return the
991-   //  broadcasted element.
992-   case  Instruction::ExtractElement:
993-     assert (!Ops[0 ]->getType ()->isVectorTy () && " Live-ins should be scalar" 
994-     return  Ops[0 ];
995-   }
1016+     case  Instruction::GetElementPtr: {
1017+       auto  &RFlags = cast<VPRecipeWithIRFlags>(R);
1018+       auto  *GEP = cast<GetElementPtrInst>(RFlags.getUnderlyingInstr ());
1019+       return  Folder.FoldGEP (GEP->getSourceElementType (), Ops[0 ],
1020+                             drop_begin (Ops), RFlags.getGEPNoWrapFlags ());
1021+     }
1022+     case  VPInstruction::PtrAdd:
1023+     case  VPInstruction::WidePtrAdd:
1024+       return  Folder.FoldGEP (IntegerType::getInt8Ty (TypeInfo.getContext ()),
1025+                             Ops[0 ], Ops[1 ],
1026+                             cast<VPRecipeWithIRFlags>(R).getGEPNoWrapFlags ());
1027+     //  An extract of a live-in is an extract of a broadcast, so return the
1028+     //  broadcasted element.
1029+     case  Instruction::ExtractElement:
1030+       assert (!Ops[0 ]->getType ()->isVectorTy () && " Live-ins should be scalar" 
1031+       return  Ops[0 ];
1032+     }
1033+     return  nullptr ;
1034+   };
1035+ 
1036+   if  (Value *V = FoldToIRValue ())
1037+     return  R.getParent ()->getPlan ()->getOrAddLiveIn (V);
9961038  return  nullptr ;
9971039}
9981040
@@ -1006,19 +1048,10 @@ static void simplifyRecipe(VPRecipeBase &R, VPTypeAnalysis &TypeInfo) {
10061048
10071049  //  Simplification of live-in IR values for SingleDef recipes using
10081050  //  InstSimplifyFolder.
1009-   if  (TypeSwitch<VPRecipeBase *, bool >(&R)
1010-           .Case <VPInstruction, VPWidenRecipe, VPWidenCastRecipe,
1011-                 VPReplicateRecipe, VPWidenSelectRecipe>([&](auto  *I) {
1012-             const  DataLayout &DL =
1013-                 Plan->getScalarHeader ()->getIRBasicBlock ()->getDataLayout ();
1014-             Value *V = tryToFoldLiveIns (*I, I->getOpcode (), I->operands (), DL,
1015-                                         TypeInfo);
1016-             if  (V)
1017-               I->replaceAllUsesWith (Plan->getOrAddLiveIn (V));
1018-             return  V;
1019-           })
1020-           .Default ([](auto  *) { return  false ; }))
1021-     return ;
1051+   const  DataLayout &DL =
1052+       Plan->getScalarHeader ()->getIRBasicBlock ()->getDataLayout ();
1053+   if  (VPValue *V = tryToFoldLiveIns (*Def, Def->operands (), DL, TypeInfo))
1054+     return  Def->replaceAllUsesWith (V);
10221055
10231056  //  Fold PredPHI LiveIn -> LiveIn.
10241057  if  (auto  *PredPHI = dyn_cast<VPPredInstPHIRecipe>(&R)) {
@@ -1996,29 +2029,6 @@ struct VPCSEDenseMapInfo : public DenseMapInfo<VPSingleDefRecipe *> {
19962029    return  Def == getEmptyKey () || Def == getTombstoneKey ();
19972030  }
19982031
1999-   // / Get any instruction opcode or intrinsic ID data embedded in recipe \p R.
2000-   // / Returns an optional pair, where the first element indicates whether it is
2001-   // / an intrinsic ID.
2002-   static  std::optional<std::pair<bool , unsigned >>
2003-   getOpcodeOrIntrinsicID (const  VPSingleDefRecipe *R) {
2004-     return  TypeSwitch<const  VPSingleDefRecipe *,
2005-                       std::optional<std::pair<bool , unsigned >>>(R)
2006-         .Case <VPInstruction, VPWidenRecipe, VPWidenCastRecipe,
2007-               VPWidenSelectRecipe, VPWidenGEPRecipe, VPReplicateRecipe>(
2008-             [](auto  *I) { return  std::make_pair (false , I->getOpcode ()); })
2009-         .Case <VPWidenIntrinsicRecipe>([](auto  *I) {
2010-           return  std::make_pair (true , I->getVectorIntrinsicID ());
2011-         })
2012-         .Case <VPVectorPointerRecipe, VPPredInstPHIRecipe>([](auto  *I) {
2013-           //  For recipes that do not directly map to LLVM IR instructions,
2014-           //  assign opcodes after the last VPInstruction opcode (which is also
2015-           //  after the last IR Instruction opcode), based on the VPDefID.
2016-           return  std::make_pair (false ,
2017-                                 VPInstruction::OpsEnd + 1  + I->getVPDefID ());
2018-         })
2019-         .Default ([](auto  *) { return  std::nullopt ; });
2020-   }
2021- 
20222032  // / If recipe \p R will lower to a GEP with a non-i8 source element type,
20232033  // / return that source element type.
20242034  static  Type *getGEPSourceElementType (const  VPSingleDefRecipe *R) {
0 commit comments