mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-26 05:32:25 +00:00
Add variations on: max(x,y) >= min(x,z) folds to true. This isn't that common,
but according to my super-optimizer there are only two missed simplifications of -instsimplify kind when compiling bzip2, and this is one of them. It amuses me to have bzip2 be perfectly optimized as far as instsimplify goes! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@130840 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
269687fa35
commit
8140ad32ce
@ -1873,7 +1873,7 @@ static Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
|
||||
CmpInst::Predicate P = CmpInst::BAD_ICMP_PREDICATE;
|
||||
CmpInst::Predicate EqP; // Chosen so that "A == max/min(A,B)" iff "A EqP B".
|
||||
|
||||
// Signed max/min.
|
||||
// Signed variants on "max(a,b)>=a -> true".
|
||||
if (match(LHS, m_SMax(m_Value(A), m_Value(B))) && (A == RHS || B == RHS)) {
|
||||
if (A != RHS) std::swap(A, B); // smax(A, B) pred A.
|
||||
EqP = CmpInst::ICMP_SGE; // "A == smax(A, B)" iff "A sge B".
|
||||
@ -1929,7 +1929,7 @@ static Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
|
||||
}
|
||||
}
|
||||
|
||||
// Unsigned max/min.
|
||||
// Unsigned variants on "max(a,b)>=a -> true".
|
||||
P = CmpInst::BAD_ICMP_PREDICATE;
|
||||
if (match(LHS, m_UMax(m_Value(A), m_Value(B))) && (A == RHS || B == RHS)) {
|
||||
if (A != RHS) std::swap(A, B); // umax(A, B) pred A.
|
||||
@ -1986,6 +1986,50 @@ static Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
|
||||
}
|
||||
}
|
||||
|
||||
// Variants on "max(x,y) >= min(x,z)".
|
||||
Value *C, *D;
|
||||
if (match(LHS, m_SMax(m_Value(A), m_Value(B))) &&
|
||||
match(RHS, m_SMin(m_Value(C), m_Value(D))) &&
|
||||
(A == C || A == D || B == C || B == D)) {
|
||||
// max(x, ?) pred min(x, ?).
|
||||
if (Pred == CmpInst::ICMP_SGE)
|
||||
// Always true.
|
||||
return Constant::getAllOnesValue(ITy);
|
||||
if (Pred == CmpInst::ICMP_SLT)
|
||||
// Always false.
|
||||
return Constant::getNullValue(ITy);
|
||||
} else if (match(LHS, m_SMin(m_Value(A), m_Value(B))) &&
|
||||
match(RHS, m_SMax(m_Value(C), m_Value(D))) &&
|
||||
(A == C || A == D || B == C || B == D)) {
|
||||
// min(x, ?) pred max(x, ?).
|
||||
if (Pred == CmpInst::ICMP_SLE)
|
||||
// Always true.
|
||||
return Constant::getAllOnesValue(ITy);
|
||||
if (Pred == CmpInst::ICMP_SGT)
|
||||
// Always false.
|
||||
return Constant::getNullValue(ITy);
|
||||
} else if (match(LHS, m_UMax(m_Value(A), m_Value(B))) &&
|
||||
match(RHS, m_UMin(m_Value(C), m_Value(D))) &&
|
||||
(A == C || A == D || B == C || B == D)) {
|
||||
// max(x, ?) pred min(x, ?).
|
||||
if (Pred == CmpInst::ICMP_UGE)
|
||||
// Always true.
|
||||
return Constant::getAllOnesValue(ITy);
|
||||
if (Pred == CmpInst::ICMP_ULT)
|
||||
// Always false.
|
||||
return Constant::getNullValue(ITy);
|
||||
} else if (match(LHS, m_UMin(m_Value(A), m_Value(B))) &&
|
||||
match(RHS, m_UMax(m_Value(C), m_Value(D))) &&
|
||||
(A == C || A == D || B == C || B == D)) {
|
||||
// min(x, ?) pred max(x, ?).
|
||||
if (Pred == CmpInst::ICMP_ULE)
|
||||
// Always true.
|
||||
return Constant::getAllOnesValue(ITy);
|
||||
if (Pred == CmpInst::ICMP_UGT)
|
||||
// Always false.
|
||||
return Constant::getNullValue(ITy);
|
||||
}
|
||||
|
||||
// If the comparison is with the result of a select instruction, check whether
|
||||
// comparing with either branch of the select always yields the same value.
|
||||
if (isa<SelectInst>(LHS) || isa<SelectInst>(RHS))
|
||||
|
@ -143,3 +143,91 @@ define i1 @min8(i32 %x, i32 %y) {
|
||||
ret i1 %r
|
||||
; CHECK: ret i1 true
|
||||
}
|
||||
|
||||
define i1 @maxmin1(i32 %x, i32 %y, i32 %z) {
|
||||
; CHECK: @maxmin1
|
||||
%c1 = icmp sge i32 %x, %y
|
||||
%max = select i1 %c1, i32 %x, i32 %y
|
||||
%c2 = icmp sge i32 %x, %z
|
||||
%min = select i1 %c2, i32 %z, i32 %x
|
||||
%c = icmp sge i32 %max, %min
|
||||
ret i1 %c
|
||||
; CHECK: ret i1 true
|
||||
}
|
||||
|
||||
define i1 @maxmin2(i32 %x, i32 %y, i32 %z) {
|
||||
; CHECK: @maxmin2
|
||||
%c1 = icmp sge i32 %x, %y
|
||||
%max = select i1 %c1, i32 %x, i32 %y
|
||||
%c2 = icmp sge i32 %x, %z
|
||||
%min = select i1 %c2, i32 %z, i32 %x
|
||||
%c = icmp sgt i32 %min, %max
|
||||
ret i1 %c
|
||||
; CHECK: ret i1 false
|
||||
}
|
||||
|
||||
define i1 @maxmin3(i32 %x, i32 %y, i32 %z) {
|
||||
; CHECK: @maxmin3
|
||||
%c1 = icmp sge i32 %x, %y
|
||||
%max = select i1 %c1, i32 %x, i32 %y
|
||||
%c2 = icmp sge i32 %x, %z
|
||||
%min = select i1 %c2, i32 %z, i32 %x
|
||||
%c = icmp sle i32 %min, %max
|
||||
ret i1 %c
|
||||
; CHECK: ret i1 true
|
||||
}
|
||||
|
||||
define i1 @maxmin4(i32 %x, i32 %y, i32 %z) {
|
||||
; CHECK: @maxmin4
|
||||
%c1 = icmp sge i32 %x, %y
|
||||
%max = select i1 %c1, i32 %x, i32 %y
|
||||
%c2 = icmp sge i32 %x, %z
|
||||
%min = select i1 %c2, i32 %z, i32 %x
|
||||
%c = icmp slt i32 %max, %min
|
||||
ret i1 %c
|
||||
; CHECK: ret i1 false
|
||||
}
|
||||
|
||||
define i1 @maxmin5(i32 %x, i32 %y, i32 %z) {
|
||||
; CHECK: @maxmin5
|
||||
%c1 = icmp uge i32 %x, %y
|
||||
%max = select i1 %c1, i32 %x, i32 %y
|
||||
%c2 = icmp uge i32 %x, %z
|
||||
%min = select i1 %c2, i32 %z, i32 %x
|
||||
%c = icmp uge i32 %max, %min
|
||||
ret i1 %c
|
||||
; CHECK: ret i1 true
|
||||
}
|
||||
|
||||
define i1 @maxmin6(i32 %x, i32 %y, i32 %z) {
|
||||
; CHECK: @maxmin6
|
||||
%c1 = icmp uge i32 %x, %y
|
||||
%max = select i1 %c1, i32 %x, i32 %y
|
||||
%c2 = icmp uge i32 %x, %z
|
||||
%min = select i1 %c2, i32 %z, i32 %x
|
||||
%c = icmp ugt i32 %min, %max
|
||||
ret i1 %c
|
||||
; CHECK: ret i1 false
|
||||
}
|
||||
|
||||
define i1 @maxmin7(i32 %x, i32 %y, i32 %z) {
|
||||
; CHECK: @maxmin7
|
||||
%c1 = icmp uge i32 %x, %y
|
||||
%max = select i1 %c1, i32 %x, i32 %y
|
||||
%c2 = icmp uge i32 %x, %z
|
||||
%min = select i1 %c2, i32 %z, i32 %x
|
||||
%c = icmp ule i32 %min, %max
|
||||
ret i1 %c
|
||||
; CHECK: ret i1 true
|
||||
}
|
||||
|
||||
define i1 @maxmin8(i32 %x, i32 %y, i32 %z) {
|
||||
; CHECK: @maxmin8
|
||||
%c1 = icmp uge i32 %x, %y
|
||||
%max = select i1 %c1, i32 %x, i32 %y
|
||||
%c2 = icmp uge i32 %x, %z
|
||||
%min = select i1 %c2, i32 %z, i32 %x
|
||||
%c = icmp ult i32 %max, %min
|
||||
ret i1 %c
|
||||
; CHECK: ret i1 false
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user