2525#include " llvm/Analysis/VectorUtils.h"
2626#include " llvm/IR/Intrinsics.h"
2727#include " llvm/IR/PatternMatch.h"
28+ #include < deque>
2829
2930using namespace llvm ;
3031
@@ -852,9 +853,10 @@ void VPlanTransforms::clearReductionWrapFlags(VPlan &Plan) {
852853 }
853854}
854855
855- // / Try to simplify recipe \p R. Returns any new recipes introduced during
856- // / simplification, as a candidate for further simplification.
857- static VPRecipeBase *simplifyRecipe (VPRecipeBase &R, VPTypeAnalysis &TypeInfo) {
856+ // / Try to simplify recipe \p R. Returns any new recipes introduced during
857+ // / simplification, as candidates for further simplification.
858+ static SmallVector<VPRecipeBase *>
859+ simplifyRecipe (VPRecipeBase &R, VPTypeAnalysis &TypeInfo, VPlan &Plan) {
858860 using namespace llvm ::VPlanPatternMatch;
859861
860862 if (auto *Blend = dyn_cast<VPBlendRecipe>(&R)) {
@@ -869,11 +871,11 @@ static VPRecipeBase *simplifyRecipe(VPRecipeBase &R, VPTypeAnalysis &TypeInfo) {
869871 if (UniqueValues.size () == 1 ) {
870872 Blend->replaceAllUsesWith (*UniqueValues.begin ());
871873 Blend->eraseFromParent ();
872- return nullptr ;
874+ return {} ;
873875 }
874876
875877 if (Blend->isNormalized ())
876- return nullptr ;
878+ return {} ;
877879
878880 // Normalize the blend so its first incoming value is used as the initial
879881 // value with the others blended into it.
@@ -908,7 +910,7 @@ static VPRecipeBase *simplifyRecipe(VPRecipeBase &R, VPTypeAnalysis &TypeInfo) {
908910 Blend->replaceAllUsesWith (NewBlend);
909911 Blend->eraseFromParent ();
910912 recursivelyDeleteDeadRecipes (DeadMask);
911- return nullptr ;
913+ return {} ;
912914 }
913915
914916 VPValue *A;
@@ -921,7 +923,7 @@ static VPRecipeBase *simplifyRecipe(VPRecipeBase &R, VPTypeAnalysis &TypeInfo) {
921923 } else {
922924 // Don't replace a scalarizing recipe with a widened cast.
923925 if (isa<VPReplicateRecipe>(&R))
924- return nullptr ;
926+ return {} ;
925927 if (ATy->getScalarSizeInBits () < TruncTy->getScalarSizeInBits ()) {
926928
927929 unsigned ExtOpcode = match (R.getOperand (0 ), m_SExt (m_VPValue ()))
@@ -956,26 +958,73 @@ static VPRecipeBase *simplifyRecipe(VPRecipeBase &R, VPTypeAnalysis &TypeInfo) {
956958 assert (TypeInfo.inferScalarType (VPV) == TypeInfo2.inferScalarType (VPV));
957959 }
958960#endif
959- return nullptr ;
961+ return {};
962+ }
963+
964+ VPValue *X, *X1, *Y, *Z;
965+ LLVMContext &Ctx = TypeInfo.getContext ();
966+
967+ // (X || !X) -> true.
968+ if (match (&R, m_c_BinaryOr (m_VPValue (X), m_Not (m_VPValue (X1)))) && X == X1) {
969+ VPValue *VPV = Plan.getOrAddLiveIn (ConstantInt::getTrue (Ctx));
970+ R.getVPSingleValue ()->replaceAllUsesWith (VPV);
971+ return {};
972+ }
973+
974+ // (X || true) -> true.
975+ if (match (&R, m_c_BinaryOr (m_VPValue (X), m_True ()))) {
976+ VPValue *VPV = Plan.getOrAddLiveIn (ConstantInt::getTrue (Ctx));
977+ R.getVPSingleValue ()->replaceAllUsesWith (VPV);
978+ return {};
979+ }
980+
981+ // (X || false) -> X.
982+ if (match (&R, m_c_BinaryOr (m_VPValue (X), m_False ()))) {
983+ R.getVPSingleValue ()->replaceAllUsesWith (X);
984+ return {};
985+ }
986+
987+ // (X && !X) -> false.
988+ if (match (&R, m_LogicalAnd (m_VPValue (X), m_Not (m_VPValue (X1)))) && X == X1) {
989+ VPValue *VPV = Plan.getOrAddLiveIn (ConstantInt::getFalse (Ctx));
990+ R.getVPSingleValue ()->replaceAllUsesWith (VPV);
991+ return {};
992+ }
993+
994+ // (X && true) -> X.
995+ if (match (&R, m_LogicalAnd (m_VPValue (X), m_True ()))) {
996+ R.getVPSingleValue ()->replaceAllUsesWith (X);
997+ return {};
998+ }
999+
1000+ // (X && false) -> false.
1001+ if (match (&R, m_LogicalAnd (m_VPValue (X), m_False ()))) {
1002+ VPValue *VPV = Plan.getOrAddLiveIn (ConstantInt::getFalse (Ctx));
1003+ R.getVPSingleValue ()->replaceAllUsesWith (VPV);
1004+ return {};
9601005 }
9611006
962- // Simplify (X && Y) || (X && !Y) -> X.
963- // TODO: Split up into simpler, modular combines: (X && Y) || (X && Z) into X
964- // && (Y || Z) and (X || !X) into true. This requires queuing newly created
965- // recipes to be visited during simplification.
966- VPValue *X, *Y, *X1, *Y1;
967- if (match (&R,
968- m_c_BinaryOr (m_LogicalAnd (m_VPValue (X), m_VPValue (Y)),
969- m_LogicalAnd (m_VPValue (X1), m_Not (m_VPValue (Y1))))) &&
970- X == X1 && Y == Y1) {
1007+ // (X * 1) -> X.
1008+ if (match (&R, m_c_Mul (m_VPValue (X), m_SpecificInt (1 )))) {
9711009 R.getVPSingleValue ()->replaceAllUsesWith (X);
1010+ return {};
1011+ }
1012+
1013+ // (X && Y) || (X && Z) -> X && (Y || Z).
1014+ if (match (&R, m_BinaryOr (m_LogicalAnd (m_VPValue (X), m_VPValue (Y)),
1015+ m_LogicalAnd (m_VPValue (X1), m_VPValue (Z)))) &&
1016+ X == X1) {
1017+ VPBuilder Builder (&R);
1018+ VPInstruction *YorZ = Builder.createOr (Y, Z, R.getDebugLoc ());
1019+ VPInstruction *VPI = Builder.createLogicalAnd (X, YorZ, R.getDebugLoc ());
1020+ R.getVPSingleValue ()->replaceAllUsesWith (VPI);
9721021 R.eraseFromParent ();
973- return nullptr ;
1022+ // Order of simplification matters: simplify sub-recipes before root
1023+ // recipes.
1024+ return {YorZ, VPI};
9741025 }
9751026
976- if (match (&R, m_c_Mul (m_VPValue (A), m_SpecificInt (1 ))))
977- R.getVPSingleValue ()->replaceAllUsesWith (A);
978- return nullptr ;
1027+ return {};
9791028}
9801029
9811030// / Try to simplify the recipes in \p Plan.
@@ -984,10 +1033,17 @@ static void simplifyRecipes(VPlan &Plan, LLVMContext &Ctx) {
9841033 Plan.getEntry ());
9851034 VPTypeAnalysis TypeInfo (Plan.getCanonicalIV ()->getScalarType (), Ctx);
9861035 for (VPBasicBlock *VPBB : VPBlockUtils::blocksOnly<VPBasicBlock>(RPOT)) {
1036+ // Order of simplification matters: add new candidates for simplification to
1037+ // the back of the Worklist, while the Worklist processes recipes from the
1038+ // front.
1039+ std::deque<VPRecipeBase *> Worklist;
9871040 for (auto &R : make_early_inc_range (*VPBB)) {
988- VPRecipeBase *NewR = simplifyRecipe (R, TypeInfo);
989- while (NewR)
990- NewR = simplifyRecipe (*NewR, TypeInfo);
1041+ Worklist.emplace_front (&R);
1042+ while (!Worklist.empty ()) {
1043+ VPRecipeBase *R = Worklist.front ();
1044+ Worklist.pop_front ();
1045+ append_range (Worklist, simplifyRecipe (*R, TypeInfo, Plan));
1046+ }
9911047 }
9921048 }
9931049}
0 commit comments