2424#include " llvm/Analysis/VectorUtils.h"
2525#include " llvm/IR/Intrinsics.h"
2626#include " llvm/IR/PatternMatch.h"
27+ #include < deque>
2728
2829using namespace llvm ;
2930
@@ -892,9 +893,10 @@ void VPlanTransforms::clearReductionWrapFlags(VPlan &Plan) {
892893 }
893894}
894895
895- // / Try to simplify recipe \p R. Returns any new recipes introduced during
896- // / simplification, as a candidate for further simplification.
897- static VPRecipeBase *simplifyRecipe (VPRecipeBase &R, VPTypeAnalysis &TypeInfo) {
896+ // / Try to simplify recipe \p R. Returns any new recipes introduced during
897+ // / simplification, as candidates for further simplification.
898+ static SmallVector<VPRecipeBase *>
899+ simplifyRecipe (VPRecipeBase &R, VPTypeAnalysis &TypeInfo, VPlan &Plan) {
898900 using namespace llvm ::VPlanPatternMatch;
899901
900902 if (auto *Blend = dyn_cast<VPBlendRecipe>(&R)) {
@@ -909,11 +911,11 @@ static VPRecipeBase *simplifyRecipe(VPRecipeBase &R, VPTypeAnalysis &TypeInfo) {
909911 if (UniqueValues.size () == 1 ) {
910912 Blend->replaceAllUsesWith (*UniqueValues.begin ());
911913 Blend->eraseFromParent ();
912- return nullptr ;
914+ return {} ;
913915 }
914916
915917 if (Blend->isNormalized ())
916- return nullptr ;
918+ return {} ;
917919
918920 // Normalize the blend so its first incomming value is used as the initial
919921 // value with the others blended into it.
@@ -937,7 +939,7 @@ static VPRecipeBase *simplifyRecipe(VPRecipeBase &R, VPTypeAnalysis &TypeInfo) {
937939 Blend->replaceAllUsesWith (NewBlend);
938940 Blend->eraseFromParent ();
939941 recursivelyDeleteDeadRecipes (DeadMask);
940- return nullptr ;
942+ return {} ;
941943 }
942944
943945 VPValue *A;
@@ -986,25 +988,74 @@ static VPRecipeBase *simplifyRecipe(VPRecipeBase &R, VPTypeAnalysis &TypeInfo) {
986988 assert (TypeInfo.inferScalarType (VPV) == TypeInfo2.inferScalarType (VPV));
987989 }
988990#endif
989- return VPC;
991+ if (VPC)
992+ return {VPC};
993+ return {};
994+ }
995+
996+ VPValue *X, *X1, *Y, *Z;
997+ LLVMContext &Ctx = TypeInfo.getContext ();
998+
999+ // (X || !X) -> true.
1000+ if (match (&R, m_c_BinaryOr (m_VPValue (X), m_Not (m_VPValue (X1)))) && X == X1) {
1001+ VPValue *VPV = Plan.getOrAddLiveIn (ConstantInt::getTrue (Ctx));
1002+ R.getVPSingleValue ()->replaceAllUsesWith (VPV);
1003+ return {};
1004+ }
1005+
1006+ // (X || true) -> true.
1007+ if (match (&R, m_c_BinaryOr (m_VPValue (X), m_True ()))) {
1008+ VPValue *VPV = Plan.getOrAddLiveIn (ConstantInt::getTrue (Ctx));
1009+ R.getVPSingleValue ()->replaceAllUsesWith (VPV);
1010+ return {};
9901011 }
9911012
992- // Simplify (X && Y) || (X && !Y) -> X.
993- // TODO: Split up into simpler, modular combines: (X && Y) || (X && Z) into X
994- // && (Y || Z) and (X || !X) into true. This requires queuing newly created
995- // recipes to be visited during simplification.
996- VPValue *X, *Y, *X1, *Y1;
997- if (match (&R,
998- m_c_BinaryOr (m_LogicalAnd (m_VPValue (X), m_VPValue (Y)),
999- m_LogicalAnd (m_VPValue (X1), m_Not (m_VPValue (Y1))))) &&
1000- X == X1 && Y == Y1) {
1013+ // (X || false) -> X.
1014+ if (match (&R, m_c_BinaryOr (m_VPValue (X), m_False ()))) {
10011015 R.getVPSingleValue ()->replaceAllUsesWith (X);
1002- return nullptr ;
1016+ return {} ;
10031017 }
10041018
1005- if (match (&R, m_c_Mul (m_VPValue (A), m_SpecificInt (1 ))))
1006- R.getVPSingleValue ()->replaceAllUsesWith (A);
1007- return nullptr ;
1019+ // (X && !X) -> false.
1020+ if (match (&R, m_LogicalAnd (m_VPValue (X), m_Not (m_VPValue (X1)))) && X == X1) {
1021+ VPValue *VPV = Plan.getOrAddLiveIn (ConstantInt::getFalse (Ctx));
1022+ R.getVPSingleValue ()->replaceAllUsesWith (VPV);
1023+ return {};
1024+ }
1025+
1026+ // (X && true) -> X.
1027+ if (match (&R, m_LogicalAnd (m_VPValue (X), m_True ()))) {
1028+ R.getVPSingleValue ()->replaceAllUsesWith (X);
1029+ return {};
1030+ }
1031+
1032+ // (X && false) -> false.
1033+ if (match (&R, m_LogicalAnd (m_VPValue (X), m_False ()))) {
1034+ VPValue *VPV = Plan.getOrAddLiveIn (ConstantInt::getFalse (Ctx));
1035+ R.getVPSingleValue ()->replaceAllUsesWith (VPV);
1036+ return {};
1037+ }
1038+
1039+ // (X * 1) -> X.
1040+ if (match (&R, m_c_Mul (m_VPValue (X), m_SpecificInt (1 )))) {
1041+ R.getVPSingleValue ()->replaceAllUsesWith (X);
1042+ return {};
1043+ }
1044+
1045+ // (X && Y) || (X && Z) -> X && (Y || Z).
1046+ if (match (&R, m_BinaryOr (m_LogicalAnd (m_VPValue (X), m_VPValue (Y)),
1047+ m_LogicalAnd (m_VPValue (X1), m_VPValue (Z)))) &&
1048+ X == X1) {
1049+ VPBuilder Builder (&R);
1050+ VPInstruction *YorZ = Builder.createOr (Y, Z, R.getDebugLoc ());
1051+ VPInstruction *VPI = Builder.createLogicalAnd (X, YorZ, R.getDebugLoc ());
1052+ R.getVPSingleValue ()->replaceAllUsesWith (VPI);
1053+ // Order of simplification matters: simplify sub-recipes before root
1054+ // recipes.
1055+ return {YorZ, VPI};
1056+ }
1057+
1058+ return {};
10081059}
10091060
10101061// / Try to simplify the recipes in \p Plan.
@@ -1013,10 +1064,14 @@ static void simplifyRecipes(VPlan &Plan, LLVMContext &Ctx) {
10131064 Plan.getEntry ());
10141065 VPTypeAnalysis TypeInfo (Plan.getCanonicalIV ()->getScalarType (), Ctx);
10151066 for (VPBasicBlock *VPBB : VPBlockUtils::blocksOnly<VPBasicBlock>(RPOT)) {
1067+ std::deque<VPRecipeBase *> Worklist;
10161068 for (auto &R : make_early_inc_range (*VPBB)) {
1017- VPRecipeBase *NewR = simplifyRecipe (R, TypeInfo);
1018- while (NewR)
1019- NewR = simplifyRecipe (*NewR, TypeInfo);
1069+ Worklist.emplace_front (&R);
1070+ while (!Worklist.empty ()) {
1071+ VPRecipeBase *R = Worklist.front ();
1072+ Worklist.pop_front ();
1073+ append_range (Worklist, simplifyRecipe (*R, TypeInfo, Plan));
1074+ }
10201075 }
10211076 }
10221077}
0 commit comments