Skip to content

Commit 0aabdad

Browse files
committed
[InstCombine] Combine code for and/or of icmps (NFC)
The implementation for and/or is the same, apart from the choice of exactIntersectWith() vs exactUnionWith(). Extract a common function to make future extension easier.
1 parent a8b2277 commit 0aabdad

File tree

1 file changed

+34
-44
lines changed

1 file changed

+34
-44
lines changed

llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp

Lines changed: 34 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1199,6 +1199,34 @@ static Value *foldAndOrOfICmpsWithConstEq(ICmpInst *Cmp0, ICmpInst *Cmp1,
11991199
return Builder.CreateBinOp(Logic.getOpcode(), Cmp0, SubstituteCmp);
12001200
}
12011201

1202+
/// Fold (icmp Pred1 V1, C1) & (icmp Pred2 V2, C2)
1203+
/// or (icmp Pred1 V1, C1) | (icmp Pred2 V2, C2)
1204+
/// into a single comparison using range-based reasoning.
1205+
static Value *foldAndOrOfICmpsUsingRanges(
1206+
ICmpInst::Predicate Pred1, Value *V1, const APInt &C1,
1207+
ICmpInst::Predicate Pred2, Value *V2, const APInt &C2,
1208+
IRBuilderBase &Builder, bool IsAnd) {
1209+
if (V1 != V2)
1210+
return nullptr;
1211+
1212+
ConstantRange CR1 = ConstantRange::makeExactICmpRegion(Pred1, C1);
1213+
ConstantRange CR2 = ConstantRange::makeExactICmpRegion(Pred2, C2);
1214+
Optional<ConstantRange> CR =
1215+
IsAnd ? CR1.exactIntersectWith(CR2) : CR1.exactUnionWith(CR2);
1216+
if (!CR)
1217+
return nullptr;
1218+
1219+
CmpInst::Predicate NewPred;
1220+
APInt NewC, Offset;
1221+
CR->getEquivalentICmp(NewPred, NewC, Offset);
1222+
1223+
Type *Ty = V1->getType();
1224+
Value *NewV = V1;
1225+
if (Offset != 0)
1226+
NewV = Builder.CreateAdd(NewV, ConstantInt::get(Ty, Offset));
1227+
return Builder.CreateICmp(NewPred, NewV, ConstantInt::get(Ty, NewC));
1228+
}
1229+
12021230
/// Fold (icmp)&(icmp) if possible.
12031231
Value *InstCombinerImpl::foldAndOfICmps(ICmpInst *LHS, ICmpInst *RHS,
12041232
BinaryOperator &And) {
@@ -1317,28 +1345,9 @@ Value *InstCombinerImpl::foldAndOfICmps(ICmpInst *LHS, ICmpInst *RHS,
13171345
}
13181346
}
13191347

1320-
// From here on, we only handle:
1321-
// (icmp1 A, C1) & (icmp2 A, C2) --> something simpler.
1322-
if (LHS0 != RHS0)
1323-
return nullptr;
1324-
1325-
ConstantRange CR1 =
1326-
ConstantRange::makeExactICmpRegion(PredL, LHSC->getValue());
1327-
ConstantRange CR2 =
1328-
ConstantRange::makeExactICmpRegion(PredR, RHSC->getValue());
1329-
Optional<ConstantRange> CR = CR1.exactIntersectWith(CR2);
1330-
if (!CR)
1331-
return nullptr;
1332-
1333-
CmpInst::Predicate Pred;
1334-
APInt NewRHS, Offset;
1335-
CR->getEquivalentICmp(Pred, NewRHS, Offset);
1336-
1337-
Type *Ty = LHS0->getType();
1338-
Value *NewLHS = LHS0;
1339-
if (Offset != 0)
1340-
NewLHS = Builder.CreateAdd(NewLHS, ConstantInt::get(Ty, Offset));
1341-
return Builder.CreateICmp(Pred, NewLHS, ConstantInt::get(Ty, NewRHS));
1348+
return foldAndOrOfICmpsUsingRanges(PredL, LHS0, LHSC->getValue(),
1349+
PredR, RHS0, RHSC->getValue(),
1350+
Builder, /* IsAnd */ true);
13421351
}
13431352

13441353
Value *InstCombinerImpl::foldLogicOfFCmps(FCmpInst *LHS, FCmpInst *RHS,
@@ -2462,28 +2471,9 @@ Value *InstCombinerImpl::foldOrOfICmps(ICmpInst *LHS, ICmpInst *RHS,
24622471
return Builder.CreateICmpULE(LHS0, LHSC);
24632472
}
24642473

2465-
// From here on, we only handle:
2466-
// (icmp1 A, C1) | (icmp2 A, C2) --> something simpler.
2467-
if (LHS0 != RHS0)
2468-
return nullptr;
2469-
2470-
ConstantRange CR1 =
2471-
ConstantRange::makeExactICmpRegion(PredL, LHSC->getValue());
2472-
ConstantRange CR2 =
2473-
ConstantRange::makeExactICmpRegion(PredR, RHSC->getValue());
2474-
Optional<ConstantRange> CR = CR1.exactUnionWith(CR2);
2475-
if (!CR)
2476-
return nullptr;
2477-
2478-
CmpInst::Predicate Pred;
2479-
APInt NewRHS, Offset;
2480-
CR->getEquivalentICmp(Pred, NewRHS, Offset);
2481-
2482-
Type *Ty = LHS0->getType();
2483-
Value *NewLHS = LHS0;
2484-
if (Offset != 0)
2485-
NewLHS = Builder.CreateAdd(NewLHS, ConstantInt::get(Ty, Offset));
2486-
return Builder.CreateICmp(Pred, NewLHS, ConstantInt::get(Ty, NewRHS));
2474+
return foldAndOrOfICmpsUsingRanges(PredL, LHS0, LHSC->getValue(),
2475+
PredR, RHS0, RHSC->getValue(),
2476+
Builder, /* IsAnd */ false);
24872477
}
24882478

24892479
// FIXME: We use commutative matchers (m_c_*) for some, but not all, matches

0 commit comments

Comments
 (0)