[llvm-commits] [llvm] r130840 - in /llvm/trunk: lib/Analysis/InstructionSimplify.cpp test/Transforms/InstSimplify/maxmin.ll
Duncan Sands
baldrick at free.fr
Wed May 4 09:05:05 PDT 2011
Author: baldrick
Date: Wed May 4 11:05:05 2011
New Revision: 130840
URL: http://llvm.org/viewvc/llvm-project?rev=130840&view=rev
Log:
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!
Modified:
llvm/trunk/lib/Analysis/InstructionSimplify.cpp
llvm/trunk/test/Transforms/InstSimplify/maxmin.ll
Modified: llvm/trunk/lib/Analysis/InstructionSimplify.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/InstructionSimplify.cpp?rev=130840&r1=130839&r2=130840&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/InstructionSimplify.cpp (original)
+++ llvm/trunk/lib/Analysis/InstructionSimplify.cpp Wed May 4 11:05:05 2011
@@ -1873,7 +1873,7 @@
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 @@
}
}
- // 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 @@
}
}
+ // 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))
Modified: llvm/trunk/test/Transforms/InstSimplify/maxmin.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstSimplify/maxmin.ll?rev=130840&r1=130839&r2=130840&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstSimplify/maxmin.ll (original)
+++ llvm/trunk/test/Transforms/InstSimplify/maxmin.ll Wed May 4 11:05:05 2011
@@ -143,3 +143,91 @@
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
+}
More information about the llvm-commits
mailing list