[llvm-commits] [llvm] r125462 - in /llvm/trunk: lib/Analysis/InstructionSimplify.cpp test/Transforms/InstSimplify/2011-01-18-Compare.ll test/Transforms/InstSimplify/compare.ll

Duncan Sands baldrick at free.fr
Sun Feb 13 09:15:40 PST 2011


Author: baldrick
Date: Sun Feb 13 11:15:40 2011
New Revision: 125462

URL: http://llvm.org/viewvc/llvm-project?rev=125462&view=rev
Log:
Teach instsimplify that X+Y>=X+Z is the same as Y>=Z if neither side overflows,
plus some variations of this.  According to my auto-simplifier this occurs a lot
but usually in combination with max/min idioms.  Because max/min aren't handled
yet this unfortunately doesn't have much effect in the testsuite.

Added:
    llvm/trunk/test/Transforms/InstSimplify/compare.ll
      - copied, changed from r125369, llvm/trunk/test/Transforms/InstSimplify/2011-01-18-Compare.ll
Removed:
    llvm/trunk/test/Transforms/InstSimplify/2011-01-18-Compare.ll
Modified:
    llvm/trunk/lib/Analysis/InstructionSimplify.cpp

Modified: llvm/trunk/lib/Analysis/InstructionSimplify.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/InstructionSimplify.cpp?rev=125462&r1=125461&r2=125462&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/InstructionSimplify.cpp (original)
+++ llvm/trunk/lib/Analysis/InstructionSimplify.cpp Sun Feb 13 11:15:40 2011
@@ -986,7 +986,7 @@
   if (match(Op0, m_Shl(m_Value(X), m_Specific(Op1))) &&
       cast<OverflowingBinaryOperator>(Op0)->hasNoUnsignedWrap())
     return X;
-  
+
   return 0;
 }
 
@@ -1016,7 +1016,7 @@
   if (match(Op0, m_Shl(m_Value(X), m_Specific(Op1))) &&
       cast<OverflowingBinaryOperator>(Op0)->hasNoSignedWrap())
     return X;
-  
+
   return 0;
 }
 
@@ -1588,6 +1588,53 @@
     }
   }
 
+  // Special logic for binary operators.
+  BinaryOperator *LBO = dyn_cast<BinaryOperator>(LHS);
+  BinaryOperator *RBO = dyn_cast<BinaryOperator>(RHS);
+  if (MaxRecurse && (LBO || RBO)) {
+
+    // Analyze the case when either LHS or RHS is an add instruction.
+    Value *A = 0, *B = 0, *C = 0, *D = 0;
+    // LHS = A + B (or A and B are null); RHS = C + D (or C and D are null).
+    bool NoLHSWrapProblem = false, NoRHSWrapProblem = false;
+    if (LBO && LBO->getOpcode() == Instruction::Add) {
+      A = LBO->getOperand(0); B = LBO->getOperand(1);
+      NoLHSWrapProblem = ICmpInst::isEquality(Pred) ||
+        (CmpInst::isUnsigned(Pred) && LBO->hasNoUnsignedWrap()) ||
+        (CmpInst::isSigned(Pred) && LBO->hasNoSignedWrap());
+    }
+    if (RBO && RBO->getOpcode() == Instruction::Add) {
+      C = RBO->getOperand(0); D = RBO->getOperand(1);
+      NoRHSWrapProblem = ICmpInst::isEquality(Pred) ||
+        (CmpInst::isUnsigned(Pred) && RBO->hasNoUnsignedWrap()) ||
+        (CmpInst::isSigned(Pred) && RBO->hasNoSignedWrap());
+    }
+
+    // icmp (X+Y), X -> icmp Y, 0 for equalities or if there is no overflow.
+    if ((A == RHS || B == RHS) && NoLHSWrapProblem)
+      if (Value *V = SimplifyICmpInst(Pred, A == RHS ? B : A,
+                                      Constant::getNullValue(RHS->getType()),
+                                      TD, DT, MaxRecurse-1))
+        return V;
+
+    // icmp X, (X+Y) -> icmp 0, Y for equalities or if there is no overflow.
+    if ((C == LHS || D == LHS) && NoRHSWrapProblem)
+      if (Value *V = SimplifyICmpInst(Pred,
+                                      Constant::getNullValue(LHS->getType()),
+                                      C == LHS ? D : C, TD, DT, MaxRecurse-1))
+        return V;
+
+    // icmp (X+Y), (X+Z) -> icmp Y,Z for equalities or if there is no overflow.
+    if (A && C && (A == C || A == D || B == C || B == D) &&
+        NoLHSWrapProblem && NoRHSWrapProblem) {
+      // Determine Y and Z in the form icmp (X+Y), (X+Z).
+      Value *Y = (A == C || A == D) ? B : A;
+      Value *Z = (C == A || C == B) ? D : C;
+      if (Value *V = SimplifyICmpInst(Pred, Y, Z, TD, DT, MaxRecurse-1))
+        return V;
+    }
+  }
+
   // 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))

Removed: llvm/trunk/test/Transforms/InstSimplify/2011-01-18-Compare.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstSimplify/2011-01-18-Compare.ll?rev=125461&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/InstSimplify/2011-01-18-Compare.ll (original)
+++ llvm/trunk/test/Transforms/InstSimplify/2011-01-18-Compare.ll (removed)
@@ -1,169 +0,0 @@
-; RUN: opt < %s -instsimplify -S | FileCheck %s
-target datalayout = "p:32:32"
-
-define i1 @ptrtoint() {
-; CHECK: @ptrtoint
-  %a = alloca i8
-  %tmp = ptrtoint i8* %a to i32
-  %r = icmp eq i32 %tmp, 0
-  ret i1 %r
-; CHECK: ret i1 false
-}
-
-define i1 @zext(i32 %x) {
-; CHECK: @zext
-  %e1 = zext i32 %x to i64
-  %e2 = zext i32 %x to i64
-  %r = icmp eq i64 %e1, %e2
-  ret i1 %r
-; CHECK: ret i1 true
-}
-
-define i1 @zext2(i1 %x) {
-; CHECK: @zext2
-  %e = zext i1 %x to i32
-  %c = icmp ne i32 %e, 0
-  ret i1 %c
-; CHECK: ret i1 %x
-}
-
-define i1 @zext3() {
-; CHECK: @zext3
-  %e = zext i1 1 to i32
-  %c = icmp ne i32 %e, 0
-  ret i1 %c
-; CHECK: ret i1 true
-}
-
-define i1 @sext(i32 %x) {
-; CHECK: @sext
-  %e1 = sext i32 %x to i64
-  %e2 = sext i32 %x to i64
-  %r = icmp eq i64 %e1, %e2
-  ret i1 %r
-; CHECK: ret i1 true
-}
-
-define i1 @sext2(i1 %x) {
-; CHECK: @sext2
-  %e = sext i1 %x to i32
-  %c = icmp ne i32 %e, 0
-  ret i1 %c
-; CHECK: ret i1 %x
-}
-
-define i1 @sext3() {
-; CHECK: @sext3
-  %e = sext i1 1 to i32
-  %c = icmp ne i32 %e, 0
-  ret i1 %c
-; CHECK: ret i1 true
-}
-
-define i1 @add(i32 %x, i32 %y) {
-; CHECK: @add
-  %l = lshr i32 %x, 1
-  %q = lshr i32 %y, 1
-  %r = or i32 %q, 1
-  %s = add i32 %l, %r
-  %c = icmp eq i32 %s, 0
-  ret i1 %c
-; CHECK: ret i1 false
-}
-
-define i1 @add2(i8 %x, i8 %y) {
-; CHECK: @add2
-  %l = or i8 %x, 128
-  %r = or i8 %y, 129
-  %s = add i8 %l, %r
-  %c = icmp eq i8 %s, 0
-  ret i1 %c
-; CHECK: ret i1 false
-}
-
-define i1 @add3(i8 %x, i8 %y) {
-; CHECK: @add3
-  %l = zext i8 %x to i32
-  %r = zext i8 %y to i32
-  %s = add i32 %l, %r
-  %c = icmp eq i32 %s, 0
-  ret i1 %c
-; CHECK: ret i1 %c
-}
-
-define i1 @addpowtwo(i32 %x, i32 %y) {
-; CHECK: @addpowtwo
-  %l = lshr i32 %x, 1
-  %r = shl i32 1, %y
-  %s = add i32 %l, %r
-  %c = icmp eq i32 %s, 0
-  ret i1 %c
-; CHECK: ret i1 false
-}
-
-define i1 @or(i32 %x) {
-; CHECK: @or
-  %o = or i32 %x, 1
-  %c = icmp eq i32 %o, 0
-  ret i1 %c
-; CHECK: ret i1 false
-}
-
-define i1 @shl(i32 %x) {
-; CHECK: @shl
-  %s = shl i32 1, %x
-  %c = icmp eq i32 %s, 0
-  ret i1 %c
-; CHECK: ret i1 false
-}
-
-define i1 @lshr(i32 %x) {
-; CHECK: @lshr
-  %s = lshr i32 -1, %x
-  %c = icmp eq i32 %s, 0
-  ret i1 %c
-; CHECK: ret i1 false
-}
-
-define i1 @ashr(i32 %x) {
-; CHECK: @ashr
-  %s = ashr i32 -1, %x
-  %c = icmp eq i32 %s, 0
-  ret i1 %c
-; CHECK: ret i1 false
-}
-
-define i1 @select1(i1 %cond) {
-; CHECK: @select1
-  %s = select i1 %cond, i32 1, i32 0
-  %c = icmp eq i32 %s, 1
-  ret i1 %c
-; CHECK: ret i1 %cond
-}
-
-define i1 @select2(i1 %cond) {
-; CHECK: @select2
-  %x = zext i1 %cond to i32
-  %s = select i1 %cond, i32 %x, i32 0
-  %c = icmp ne i32 %s, 0
-  ret i1 %c
-; CHECK: ret i1 %cond
-}
-
-define i1 @select3(i1 %cond) {
-; CHECK: @select3
-  %x = zext i1 %cond to i32
-  %s = select i1 %cond, i32 1, i32 %x
-  %c = icmp ne i32 %s, 0
-  ret i1 %c
-; CHECK: ret i1 %cond
-}
-
-define i1 @select4(i1 %cond) {
-; CHECK: @select4
-  %invert = xor i1 %cond, 1
-  %s = select i1 %invert, i32 0, i32 1
-  %c = icmp ne i32 %s, 0
-  ret i1 %c
-; CHECK: ret i1 %cond
-}

Copied: llvm/trunk/test/Transforms/InstSimplify/compare.ll (from r125369, llvm/trunk/test/Transforms/InstSimplify/2011-01-18-Compare.ll)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstSimplify/compare.ll?p2=llvm/trunk/test/Transforms/InstSimplify/compare.ll&p1=llvm/trunk/test/Transforms/InstSimplify/2011-01-18-Compare.ll&r1=125369&r2=125462&rev=125462&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstSimplify/2011-01-18-Compare.ll (original)
+++ llvm/trunk/test/Transforms/InstSimplify/compare.ll Sun Feb 13 11:15:40 2011
@@ -91,6 +91,26 @@
 ; CHECK: ret i1 %c
 }
 
+define i1 @add4(i32 %x, i32 %y) {
+; CHECK: @add4
+  %z = add nsw i32 %y, 1
+  %s1 = add nsw i32 %x, %y
+  %s2 = add nsw i32 %x, %z
+  %c = icmp slt i32 %s1, %s2
+  ret i1 %c
+; CHECK: ret i1 true
+}
+
+define i1 @add5(i32 %x, i32 %y) {
+; CHECK: @add5
+  %z = add nuw i32 %y, 1
+  %s1 = add nuw i32 %x, %z
+  %s2 = add nuw i32 %x, %y
+  %c = icmp ugt i32 %s1, %s2
+  ret i1 %c
+; CHECK: ret i1 true
+}
+
 define i1 @addpowtwo(i32 %x, i32 %y) {
 ; CHECK: @addpowtwo
   %l = lshr i32 %x, 1





More information about the llvm-commits mailing list