@@ -1073,6 +1073,40 @@ static Value *foldAbsDiff(ICmpInst *Cmp, Value *TVal, Value *FVal,
1073
1073
return nullptr ;
1074
1074
}
1075
1075
1076
+ // (A % 2 == 0) ? (A/2*2) : B --> (A % 2 == 0) ? A : B
1077
+ // (A % 2 == 0) ? (A/2*2) * (A/2*2) : B --> (A % 2 == 0) ? BinOp A, A : B
1078
+ static Value *foldSelectWithIcmpEqAndPattern (ICmpInst *Cmp, Value *TVal,
1079
+ Value *FVal,
1080
+ InstCombiner::BuilderTy &Builder) {
1081
+ Value *A;
1082
+ ConstantInt *MaskedConstant;
1083
+ ICmpInst::Predicate Pred = Cmp->getPredicate ();
1084
+
1085
+ // Checks if the comparison is (A % 2 == 0) and A is not undef.
1086
+ if (!(Pred == ICmpInst::ICMP_EQ &&
1087
+ match (Cmp->getOperand (0 ), m_And (m_Value (A), m_SpecificInt (1 ))) &&
1088
+ match (Cmp->getOperand (1 ), m_SpecificInt (0 )) &&
1089
+ isGuaranteedNotToBeUndef (A)))
1090
+ return nullptr ;
1091
+
1092
+ // Checks if true branch matches (A % 2).
1093
+ if (match (TVal,
1094
+ m_OneUse (m_And (m_Specific (A), m_ConstantInt (MaskedConstant)))) &&
1095
+ MaskedConstant->getValue ().getSExtValue () == -2 )
1096
+ return Builder.CreateSelect (Cmp, A, FVal);
1097
+
1098
+ // Checks if true branch is (A/2*2) * (A/2*2).
1099
+ Value *MulVal;
1100
+ if (match (TVal, m_OneUse (m_Mul (m_Value (MulVal), m_Deferred (MulVal)))))
1101
+ if (match (MulVal, m_And (m_Specific (A), m_ConstantInt (MaskedConstant))) &&
1102
+ MaskedConstant->getValue ().getSExtValue () == -2 ) {
1103
+ Value *NewBinop = Builder.CreateMul (A, A);
1104
+ return Builder.CreateSelect (Cmp, NewBinop, FVal);
1105
+ }
1106
+
1107
+ return nullptr ;
1108
+ }
1109
+
1076
1110
// / Fold the following code sequence:
1077
1111
// / \code
1078
1112
// / int a = ctlz(x & -x);
@@ -1933,6 +1967,10 @@ Instruction *InstCombinerImpl::foldSelectInstWithICmp(SelectInst &SI,
1933
1967
if (Value *V = foldAbsDiff (ICI, TrueVal, FalseVal, Builder))
1934
1968
return replaceInstUsesWith (SI, V);
1935
1969
1970
+ if (Value *V =
1971
+ foldSelectWithIcmpEqAndPattern (ICI, TrueVal, FalseVal, Builder))
1972
+ return replaceInstUsesWith (SI, V);
1973
+
1936
1974
return Changed ? &SI : nullptr ;
1937
1975
}
1938
1976
0 commit comments