@@ -892,8 +892,9 @@ void VPlanTransforms::clearReductionWrapFlags(VPlan &Plan) {
892
892
}
893
893
}
894
894
895
- // / Try to simplify recipe \p R.
896
- static void simplifyRecipe (VPRecipeBase &R, VPTypeAnalysis &TypeInfo) {
895
+ // / Try to simplify recipe \p R. Returns candidates for further simplification.
896
+ static SmallVector<VPRecipeBase *>
897
+ simplifyRecipe (VPRecipeBase &R, VPTypeAnalysis &TypeInfo, LLVMContext &Ctx) {
897
898
using namespace llvm ::VPlanPatternMatch;
898
899
899
900
if (auto *Blend = dyn_cast<VPBlendRecipe>(&R)) {
@@ -908,11 +909,11 @@ static void simplifyRecipe(VPRecipeBase &R, VPTypeAnalysis &TypeInfo) {
908
909
if (UniqueValues.size () == 1 ) {
909
910
Blend->replaceAllUsesWith (*UniqueValues.begin ());
910
911
Blend->eraseFromParent ();
911
- return ;
912
+ return {} ;
912
913
}
913
914
914
915
if (Blend->isNormalized ())
915
- return ;
916
+ return {} ;
916
917
917
918
// Normalize the blend so its first incomming value is used as the initial
918
919
// value with the others blended into it.
@@ -936,26 +937,27 @@ static void simplifyRecipe(VPRecipeBase &R, VPTypeAnalysis &TypeInfo) {
936
937
Blend->replaceAllUsesWith (NewBlend);
937
938
Blend->eraseFromParent ();
938
939
recursivelyDeleteDeadRecipes (DeadMask);
939
- return ;
940
+ return {} ;
940
941
}
941
942
942
943
VPValue *A;
943
944
if (match (&R, m_Trunc (m_ZExtOrSExt (m_VPValue (A))))) {
944
945
VPValue *Trunc = R.getVPSingleValue ();
945
946
Type *TruncTy = TypeInfo.inferScalarType (Trunc);
946
947
Type *ATy = TypeInfo.inferScalarType (A);
948
+ VPWidenCastRecipe *VPC = nullptr ;
947
949
if (TruncTy == ATy) {
948
950
Trunc->replaceAllUsesWith (A);
949
951
} else {
950
952
// Don't replace a scalarizing recipe with a widened cast.
951
953
if (isa<VPReplicateRecipe>(&R))
952
- return ;
954
+ return {} ;
953
955
if (ATy->getScalarSizeInBits () < TruncTy->getScalarSizeInBits ()) {
954
956
955
957
unsigned ExtOpcode = match (R.getOperand (0 ), m_SExt (m_VPValue ()))
956
958
? Instruction::SExt
957
959
: Instruction::ZExt;
958
- auto * VPC =
960
+ VPC =
959
961
new VPWidenCastRecipe (Instruction::CastOps (ExtOpcode), A, TruncTy);
960
962
if (auto *UnderlyingExt = R.getOperand (0 )->getUnderlyingValue ()) {
961
963
// UnderlyingExt has distinct return type, used to retain legacy cost.
@@ -964,7 +966,7 @@ static void simplifyRecipe(VPRecipeBase &R, VPTypeAnalysis &TypeInfo) {
964
966
VPC->insertBefore (&R);
965
967
Trunc->replaceAllUsesWith (VPC);
966
968
} else if (ATy->getScalarSizeInBits () > TruncTy->getScalarSizeInBits ()) {
967
- auto * VPC = new VPWidenCastRecipe (Instruction::Trunc, A, TruncTy);
969
+ VPC = new VPWidenCastRecipe (Instruction::Trunc, A, TruncTy);
968
970
VPC->insertBefore (&R);
969
971
Trunc->replaceAllUsesWith (VPC);
970
972
}
@@ -984,23 +986,71 @@ static void simplifyRecipe(VPRecipeBase &R, VPTypeAnalysis &TypeInfo) {
984
986
assert (TypeInfo.inferScalarType (VPV) == TypeInfo2.inferScalarType (VPV));
985
987
}
986
988
#endif
989
+ if (VPC)
990
+ return {VPC};
991
+ return {};
992
+ }
993
+
994
+ VPValue *X, *X1, *Y, *Z;
995
+
996
+ // (X || !X) -> true.
997
+ if (match (&R, m_c_BinaryOr (m_VPValue (X), m_Not (m_VPValue (X1)))) && X == X1) {
998
+ auto *VPV = new VPValue (ConstantInt::getTrue (Ctx));
999
+ R.getVPSingleValue ()->replaceAllUsesWith (VPV);
1000
+ return {};
987
1001
}
988
1002
989
- // Simplify (X && Y) || (X && !Y ) -> X .
990
- // TODO: Split up into simpler, modular combines: (X && Y) || (X && Z) into X
991
- // && (Y || Z) and (X || !X) into true. This requires queuing newly created
992
- // recipes to be visited during simplification.
993
- VPValue *X, *Y, *X1, *Y1 ;
994
- if ( match (&R,
995
- m_c_BinaryOr ( m_LogicalAnd ( m_VPValue (X), m_VPValue (Y)),
996
- m_LogicalAnd ( m_VPValue (X1), m_Not ( m_VPValue (Y1))))) &&
997
- X == X1 && Y == Y1 ) {
1003
+ // (X || true ) -> true .
1004
+ if ( match (&R, m_c_BinaryOr ( m_VPValue (X), m_True ()))) {
1005
+ auto *VPV = new VPValue ( ConstantInt::getTrue (Ctx));
1006
+ R. getVPSingleValue ()-> replaceAllUsesWith (VPV);
1007
+ return {} ;
1008
+ }
1009
+
1010
+ // (X || false) -> X.
1011
+ if ( match (&R, m_c_BinaryOr ( m_VPValue (X), m_False ())) ) {
998
1012
R.getVPSingleValue ()->replaceAllUsesWith (X);
999
- return ;
1013
+ return {};
1014
+ }
1015
+
1016
+ // (X && !X) -> false.
1017
+ if (match (&R, m_LogicalAnd (m_VPValue (X), m_Not (m_VPValue (X1)))) && X == X1) {
1018
+ auto *VPV = new VPValue (ConstantInt::getFalse (Ctx));
1019
+ R.getVPSingleValue ()->replaceAllUsesWith (VPV);
1020
+ return {};
1021
+ }
1022
+
1023
+ // (X && true) -> X.
1024
+ if (match (&R, m_LogicalAnd (m_VPValue (X), m_True ()))) {
1025
+ R.getVPSingleValue ()->replaceAllUsesWith (X);
1026
+ return {};
1027
+ }
1028
+
1029
+ // (X && false) -> false.
1030
+ if (match (&R, m_LogicalAnd (m_VPValue (X), m_False ()))) {
1031
+ auto *VPV = new VPValue (ConstantInt::getFalse (Ctx));
1032
+ R.getVPSingleValue ()->replaceAllUsesWith (VPV);
1033
+ return {};
1034
+ }
1035
+
1036
+ // (X * 1) -> X.
1037
+ if (match (&R, m_c_Mul (m_VPValue (X), m_SpecificInt (1 )))) {
1038
+ R.getVPSingleValue ()->replaceAllUsesWith (X);
1039
+ return {};
1040
+ }
1041
+
1042
+ // (X && Y) || (X && Z) -> X && (Y || Z).
1043
+ if (match (&R, m_BinaryOr (m_LogicalAnd (m_VPValue (X), m_VPValue (Y)),
1044
+ m_LogicalAnd (m_VPValue (X1), m_VPValue (Z)))) &&
1045
+ X == X1) {
1046
+ VPBuilder Builder (&R);
1047
+ VPInstruction *YorZ = Builder.createOr (Y, Z, R.getDebugLoc ());
1048
+ VPInstruction *VPI = Builder.createLogicalAnd (X, YorZ, R.getDebugLoc ());
1049
+ R.getVPSingleValue ()->replaceAllUsesWith (VPI);
1050
+ return {VPI, YorZ};
1000
1051
}
1001
1052
1002
- if (match (&R, m_c_Mul (m_VPValue (A), m_SpecificInt (1 ))))
1003
- return R.getVPSingleValue ()->replaceAllUsesWith (A);
1053
+ return {};
1004
1054
}
1005
1055
1006
1056
// / Try to simplify the recipes in \p Plan.
@@ -1009,8 +1059,16 @@ static void simplifyRecipes(VPlan &Plan, LLVMContext &Ctx) {
1009
1059
Plan.getEntry ());
1010
1060
VPTypeAnalysis TypeInfo (Plan.getCanonicalIV ()->getScalarType (), Ctx);
1011
1061
for (VPBasicBlock *VPBB : VPBlockUtils::blocksOnly<VPBasicBlock>(RPOT)) {
1012
- for (VPRecipeBase &R : make_early_inc_range (*VPBB)) {
1013
- simplifyRecipe (R, TypeInfo);
1062
+ // Populate a Worklist, as simplifyRecipe might return a new recipe that we
1063
+ // need to re-process.
1064
+ SmallVector<VPRecipeBase *> Worklist;
1065
+ for (auto &R : VPBB->getRecipeList ())
1066
+ Worklist.push_back (&R);
1067
+
1068
+ while (!Worklist.empty ()) {
1069
+ VPRecipeBase *R = Worklist.pop_back_val ();
1070
+ for (VPRecipeBase *Cand : simplifyRecipe (*R, TypeInfo, Ctx))
1071
+ Worklist.push_back (Cand);
1014
1072
}
1015
1073
}
1016
1074
}
0 commit comments