25
25
#include " llvm/Analysis/VectorUtils.h"
26
26
#include " llvm/IR/Intrinsics.h"
27
27
#include " llvm/IR/PatternMatch.h"
28
+ #include < deque>
28
29
29
30
using namespace llvm ;
30
31
@@ -852,9 +853,10 @@ void VPlanTransforms::clearReductionWrapFlags(VPlan &Plan) {
852
853
}
853
854
}
854
855
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) {
858
860
using namespace llvm ::VPlanPatternMatch;
859
861
860
862
if (auto *Blend = dyn_cast<VPBlendRecipe>(&R)) {
@@ -869,11 +871,11 @@ static VPRecipeBase *simplifyRecipe(VPRecipeBase &R, VPTypeAnalysis &TypeInfo) {
869
871
if (UniqueValues.size () == 1 ) {
870
872
Blend->replaceAllUsesWith (*UniqueValues.begin ());
871
873
Blend->eraseFromParent ();
872
- return nullptr ;
874
+ return {} ;
873
875
}
874
876
875
877
if (Blend->isNormalized ())
876
- return nullptr ;
878
+ return {} ;
877
879
878
880
// Normalize the blend so its first incoming value is used as the initial
879
881
// value with the others blended into it.
@@ -908,7 +910,7 @@ static VPRecipeBase *simplifyRecipe(VPRecipeBase &R, VPTypeAnalysis &TypeInfo) {
908
910
Blend->replaceAllUsesWith (NewBlend);
909
911
Blend->eraseFromParent ();
910
912
recursivelyDeleteDeadRecipes (DeadMask);
911
- return nullptr ;
913
+ return {} ;
912
914
}
913
915
914
916
VPValue *A;
@@ -921,7 +923,7 @@ static VPRecipeBase *simplifyRecipe(VPRecipeBase &R, VPTypeAnalysis &TypeInfo) {
921
923
} else {
922
924
// Don't replace a scalarizing recipe with a widened cast.
923
925
if (isa<VPReplicateRecipe>(&R))
924
- return nullptr ;
926
+ return {} ;
925
927
if (ATy->getScalarSizeInBits () < TruncTy->getScalarSizeInBits ()) {
926
928
927
929
unsigned ExtOpcode = match (R.getOperand (0 ), m_SExt (m_VPValue ()))
@@ -956,26 +958,73 @@ static VPRecipeBase *simplifyRecipe(VPRecipeBase &R, VPTypeAnalysis &TypeInfo) {
956
958
assert (TypeInfo.inferScalarType (VPV) == TypeInfo2.inferScalarType (VPV));
957
959
}
958
960
#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 {};
960
1005
}
961
1006
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 )))) {
971
1009
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);
972
1021
R.eraseFromParent ();
973
- return nullptr ;
1022
+ // Order of simplification matters: simplify sub-recipes before root
1023
+ // recipes.
1024
+ return {YorZ, VPI};
974
1025
}
975
1026
976
- if (match (&R, m_c_Mul (m_VPValue (A), m_SpecificInt (1 ))))
977
- R.getVPSingleValue ()->replaceAllUsesWith (A);
978
- return nullptr ;
1027
+ return {};
979
1028
}
980
1029
981
1030
// / Try to simplify the recipes in \p Plan.
@@ -984,10 +1033,17 @@ static void simplifyRecipes(VPlan &Plan, LLVMContext &Ctx) {
984
1033
Plan.getEntry ());
985
1034
VPTypeAnalysis TypeInfo (Plan.getCanonicalIV ()->getScalarType (), Ctx);
986
1035
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;
987
1040
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
+ }
991
1047
}
992
1048
}
993
1049
}
0 commit comments