mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-26 04:32:44 +01:00
InstCombine: FoldOrOfICmps harder
We may be in a situation where the icmps might not be near each other in a tree of or instructions. Try to dig out related compare instructions and see if they combine. N.B. This won't fire on deep trees of compares because rewritting the tree might end up creating a net increase of IR. We may have to resort to something more sophisticated if this is a real problem. llvm-svn: 222928
This commit is contained in:
parent
a072cee758
commit
87a17a0975
@ -2305,11 +2305,34 @@ Instruction *InstCombiner::visitOr(BinaryOperator &I) {
|
||||
if (SwappedForXor)
|
||||
std::swap(Op0, Op1);
|
||||
|
||||
if (ICmpInst *RHS = dyn_cast<ICmpInst>(I.getOperand(1)))
|
||||
if (ICmpInst *LHS = dyn_cast<ICmpInst>(I.getOperand(0)))
|
||||
{
|
||||
ICmpInst *LHS = dyn_cast<ICmpInst>(Op0);
|
||||
ICmpInst *RHS = dyn_cast<ICmpInst>(Op1);
|
||||
if (LHS && RHS)
|
||||
if (Value *Res = FoldOrOfICmps(LHS, RHS, &I))
|
||||
return ReplaceInstUsesWith(I, Res);
|
||||
|
||||
// TODO: Make this recursive; it's a little tricky because an arbitrary
|
||||
// number of 'or' instructions might have to be created.
|
||||
Value *X, *Y;
|
||||
if (LHS && match(Op1, m_OneUse(m_Or(m_Value(X), m_Value(Y))))) {
|
||||
if (auto *Cmp = dyn_cast<ICmpInst>(X))
|
||||
if (Value *Res = FoldOrOfICmps(LHS, Cmp, &I))
|
||||
return ReplaceInstUsesWith(I, Builder->CreateOr(Res, Y));
|
||||
if (auto *Cmp = dyn_cast<ICmpInst>(Y))
|
||||
if (Value *Res = FoldOrOfICmps(LHS, Cmp, &I))
|
||||
return ReplaceInstUsesWith(I, Builder->CreateOr(Res, X));
|
||||
}
|
||||
if (RHS && match(Op0, m_OneUse(m_Or(m_Value(X), m_Value(Y))))) {
|
||||
if (auto *Cmp = dyn_cast<ICmpInst>(X))
|
||||
if (Value *Res = FoldOrOfICmps(Cmp, RHS, &I))
|
||||
return ReplaceInstUsesWith(I, Builder->CreateOr(Res, Y));
|
||||
if (auto *Cmp = dyn_cast<ICmpInst>(Y))
|
||||
if (Value *Res = FoldOrOfICmps(Cmp, RHS, &I))
|
||||
return ReplaceInstUsesWith(I, Builder->CreateOr(Res, X));
|
||||
}
|
||||
}
|
||||
|
||||
// (fcmp uno x, c) | (fcmp uno y, c) -> (fcmp uno x, y)
|
||||
if (FCmpInst *LHS = dyn_cast<FCmpInst>(I.getOperand(0)))
|
||||
if (FCmpInst *RHS = dyn_cast<FCmpInst>(I.getOperand(1)))
|
||||
|
@ -506,3 +506,13 @@ define i1 @test47(i8 signext %c) {
|
||||
; CHECK-NEXT: add i8 %1, -65
|
||||
; CHECK-NEXT: icmp ult i8 %2, 27
|
||||
}
|
||||
|
||||
define i1 @test48(i64 %x, i1 %b) {
|
||||
%1 = icmp ult i64 %x, 2305843009213693952
|
||||
%2 = icmp ugt i64 %x, 2305843009213693951
|
||||
%.b = or i1 %2, %b
|
||||
%3 = or i1 %1, %.b
|
||||
ret i1 %3
|
||||
; CHECK-LABEL: @test48(
|
||||
; CHECK-NEXT: ret i1 true
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user