[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