[PATCH] D67502: [InstSimplify] simplifyUnsignedRangeCheck(): '(a+b) </>= a/b &&/|| a/b ==/!= 0' if we known a or b is non-zero (PR43259)

Roman Lebedev via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 12 07:57:55 PDT 2019


lebedev.ri created this revision.
lebedev.ri added reviewers: spatel, nikic, xbolva00.
lebedev.ri added a project: LLVM.
Herald added a subscriber: hiraditya.
lebedev.ri added a parent revision: D67498: [InstSimplify] simplifyUnsignedRangeCheck(): handle few tautological cases (PR43251).

I realize that these get increasingly boring with each patch,
but i'm running out of commit messages here :/

Alive proofs:
https://rise4fun.com/Alive/8Bq

https://bugs.llvm.org/show_bug.cgi?id=43259


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D67502

Files:
  llvm/lib/Analysis/InstructionSimplify.cpp
  llvm/test/Transforms/InstSimplify/result-of-add-of-negative-is-non-zero-and-no-underflow.ll


Index: llvm/test/Transforms/InstSimplify/result-of-add-of-negative-is-non-zero-and-no-underflow.ll
===================================================================
--- llvm/test/Transforms/InstSimplify/result-of-add-of-negative-is-non-zero-and-no-underflow.ll
+++ llvm/test/Transforms/InstSimplify/result-of-add-of-negative-is-non-zero-and-no-underflow.ll
@@ -18,10 +18,7 @@
 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])
 ; CHECK-NEXT:    [[ADJUSTED:%.*]] = add i8 [[BASE]], [[OFFSET:%.*]]
 ; CHECK-NEXT:    call void @use8(i8 [[ADJUSTED]])
-; CHECK-NEXT:    [[NOT_NULL:%.*]] = icmp ne i8 [[ADJUSTED]], 0
-; CHECK-NEXT:    [[NO_UNDERFLOW:%.*]] = icmp ult i8 [[ADJUSTED]], [[BASE]]
-; CHECK-NEXT:    [[R:%.*]] = or i1 [[NOT_NULL]], [[NO_UNDERFLOW]]
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    ret i1 true
 ;
   %cmp = icmp slt i8 %base, 0
   call void @llvm.assume(i1 %cmp)
@@ -39,10 +36,7 @@
 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])
 ; CHECK-NEXT:    [[ADJUSTED:%.*]] = add i8 [[BASE]], [[OFFSET:%.*]]
 ; CHECK-NEXT:    call void @use8(i8 [[ADJUSTED]])
-; CHECK-NEXT:    [[NOT_NULL:%.*]] = icmp ne i8 [[ADJUSTED]], 0
-; CHECK-NEXT:    [[NO_UNDERFLOW:%.*]] = icmp ugt i8 [[BASE]], [[ADJUSTED]]
-; CHECK-NEXT:    [[R:%.*]] = or i1 [[NOT_NULL]], [[NO_UNDERFLOW]]
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    ret i1 true
 ;
   %cmp = icmp slt i8 %base, 0
   call void @llvm.assume(i1 %cmp)
@@ -63,10 +57,7 @@
 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])
 ; CHECK-NEXT:    [[ADJUSTED:%.*]] = add i8 [[BASE]], [[OFFSET:%.*]]
 ; CHECK-NEXT:    call void @use8(i8 [[ADJUSTED]])
-; CHECK-NEXT:    [[NOT_NULL:%.*]] = icmp eq i8 [[ADJUSTED]], 0
-; CHECK-NEXT:    [[NO_UNDERFLOW:%.*]] = icmp uge i8 [[ADJUSTED]], [[BASE]]
-; CHECK-NEXT:    [[R:%.*]] = and i1 [[NOT_NULL]], [[NO_UNDERFLOW]]
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    ret i1 false
 ;
   %cmp = icmp slt i8 %base, 0
   call void @llvm.assume(i1 %cmp)
@@ -84,10 +75,7 @@
 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])
 ; CHECK-NEXT:    [[ADJUSTED:%.*]] = add i8 [[BASE]], [[OFFSET:%.*]]
 ; CHECK-NEXT:    call void @use8(i8 [[ADJUSTED]])
-; CHECK-NEXT:    [[NOT_NULL:%.*]] = icmp eq i8 [[ADJUSTED]], 0
-; CHECK-NEXT:    [[NO_UNDERFLOW:%.*]] = icmp ule i8 [[BASE]], [[ADJUSTED]]
-; CHECK-NEXT:    [[R:%.*]] = and i1 [[NOT_NULL]], [[NO_UNDERFLOW]]
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    ret i1 false
 ;
   %cmp = icmp slt i8 %base, 0
   call void @llvm.assume(i1 %cmp)
Index: llvm/lib/Analysis/InstructionSimplify.cpp
===================================================================
--- llvm/lib/Analysis/InstructionSimplify.cpp
+++ llvm/lib/Analysis/InstructionSimplify.cpp
@@ -1380,9 +1380,31 @@
       !ICmpInst::isEquality(EqPred))
     return nullptr;
 
+  Value *A, *B;
   ICmpInst::Predicate UnsignedPred;
 
-  Value *A, *B;
+  // Y = (A + B);
+  if (match(Y, m_Add(m_Value(A), m_Value(B))) &&
+      match(UnsignedICmp,
+            m_c_ICmp(UnsignedPred, m_Specific(Y),
+                     m_CombineOr(m_Specific(A), m_Specific(B))))) {
+    if (UnsignedICmp->getOperand(0) != Y)
+      UnsignedPred = ICmpInst::getSwappedPredicate(UnsignedPred);
+    // Given  Y = (A - B)
+    //   Y >= A/B && Y != 0  --> false  iff A/B != 0
+    //   Y <  A/B || Y == 0  --> true   iff A/B != 0
+    if (UnsignedPred == ICmpInst::ICMP_UGE && EqPred == ICmpInst::ICMP_EQ &&
+        IsAnd &&
+        (isKnownNonZero(A, Q.DL, /*Depth=*/0, Q.AC, Q.CxtI, Q.DT) ||
+         isKnownNonZero(B, Q.DL, /*Depth=*/0, Q.AC, Q.CxtI, Q.DT)))
+      return ConstantInt::getFalse(UnsignedICmp->getType());
+    if (UnsignedPred == ICmpInst::ICMP_ULT && EqPred == ICmpInst::ICMP_NE &&
+        !IsAnd &&
+        (isKnownNonZero(A, Q.DL, /*Depth=*/0, Q.AC, Q.CxtI, Q.DT) ||
+         isKnownNonZero(B, Q.DL, /*Depth=*/0, Q.AC, Q.CxtI, Q.DT)))
+      return ConstantInt::getTrue(UnsignedICmp->getType());
+  }
+
   // Y = (A - B);
   if (match(Y, m_Sub(m_Value(A), m_Value(B)))) {
     // A >= B || (A - B) != 0  <-->  true


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D67502.219920.patch
Type: text/x-patch
Size: 4019 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190912/32bf9124/attachment.bin>


More information about the llvm-commits mailing list