mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-28 19:31:58 +00: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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@222928 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
69ed1ff9b3
commit
a1129621dd
@ -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