@@ -1320,7 +1320,8 @@ static Value *foldAndOrOfICmpsWithConstEq(ICmpInst *Cmp0, ICmpInst *Cmp1,
13201320Value *InstCombinerImpl::foldAndOrOfICmpsUsingRanges (ICmpInst *ICmp1,
13211321 ICmpInst *ICmp2,
13221322 bool IsAnd) {
1323- auto MatchRangeCheck =
1323+ // Return (V, CR) for a range check idiom V in CR.
1324+ auto MatchExactRangeCheck =
13241325 [](ICmpInst *ICmp) -> std::optional<std::pair<Value *, ConstantRange>> {
13251326 const APInt *C;
13261327 if (!match (ICmp->getOperand (1 ), m_APInt (C)))
@@ -1340,26 +1341,32 @@ Value *InstCombinerImpl::foldAndOrOfICmpsUsingRanges(ICmpInst *ICmp1,
13401341 }
13411342 ConstantRange CR = ConstantRange::makeExactICmpRegion (Pred, *C);
13421343 // Match (add X, C1) pred C
1344+ // TODO: investigate whether we should apply the one-use check on m_AddLike.
13431345 const APInt *C1;
13441346 if (match (LHS, m_AddLike (m_Value (X), m_APInt (C1))))
13451347 return std::make_pair (X, CR.subtract (*C1));
13461348 return std::make_pair (LHS, CR);
13471349 };
13481350
1349- auto RC1 = MatchRangeCheck (ICmp1);
1351+ auto RC1 = MatchExactRangeCheck (ICmp1);
13501352 if (!RC1)
13511353 return nullptr ;
13521354
1353- auto RC2 = MatchRangeCheck (ICmp2);
1355+ auto RC2 = MatchExactRangeCheck (ICmp2);
13541356 if (!RC2)
13551357 return nullptr ;
13561358
1357- if (RC1->first != RC2->first )
1359+ auto &[V1, CR1] = *RC1;
1360+ auto &[V2, CR2] = *RC2;
1361+ if (V1 != V2)
13581362 return nullptr ;
13591363
1360- Value *V = RC1->first ;
1361- auto CR1 = IsAnd ? RC1->second .inverse () : RC1->second ;
1362- auto CR2 = IsAnd ? RC2->second .inverse () : RC2->second ;
1364+ Value *V = V1;
1365+ // For 'and', we use the De Morgan's Laws to simplify the implementation.
1366+ if (IsAnd) {
1367+ CR1 = CR1.inverse ();
1368+ CR2 = CR2.inverse ();
1369+ }
13631370
13641371 Type *Ty = V->getType ();
13651372 Value *NewV = V;
0 commit comments