-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[ValueTracking] a - b == NonZero -> a != b #159792
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@zyw-bot mfuzz |
@llvm/pr-subscribers-llvm-analysis Author: Yingwei Zheng (dtcxzyw) ChangesAlive2: https://alive2.llvm.org/ce/z/8rX5Rk Full diff: https://github.com/llvm/llvm-project/pull/159792.diff 2 Files Affected:
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index bb0db2d31971d..48167e3777447 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -9425,6 +9425,21 @@ isImpliedCondICmps(CmpPredicate LPred, const Value *L0, const Value *L1,
return true;
}
+ // a - b == NonZero -> a != b
+ // ptrtoint(a) - ptrtoint(b) == NonZero -> a != b
+ const APInt *RHSC;
+ Value *A, *B;
+ if (LPred == ICmpInst::ICMP_EQ && ICmpInst::isEquality(RPred) &&
+ match(L1, m_APInt(RHSC)) && !RHSC->isZero() &&
+ match(L0, m_Sub(m_Value(A), m_Value(B))) &&
+ ((A == R0 && B == R1) || (A == R1 && B == R0) ||
+ (match(A, m_PtrToInt(m_Specific(R0))) &&
+ match(B, m_PtrToInt(m_Specific(R1)))) ||
+ (match(A, m_PtrToInt(m_Specific(R1))) &&
+ match(B, m_PtrToInt(m_Specific(R0)))))) {
+ return RPred.dropSameSign() == ICmpInst::ICMP_NE;
+ }
+
// L0 = R0 = L1 + R1, L0 >=u L1 implies R0 >=u R1, L0 <u L1 implies R0 <u R1
if (L0 == R0 &&
(LPred == ICmpInst::ICMP_ULT || LPred == ICmpInst::ICMP_UGE) &&
@@ -10180,15 +10195,20 @@ void llvm::findValuesAffectedByCondition(
AddAffected(B);
if (HasRHSC) {
Value *Y;
- // (X & C) or (X | C).
// (X << C) or (X >>_s C) or (X >>_u C).
if (match(A, m_Shift(m_Value(X), m_ConstantInt())))
AddAffected(X);
+ // (X & C) or (X | C).
else if (match(A, m_And(m_Value(X), m_Value(Y))) ||
match(A, m_Or(m_Value(X), m_Value(Y)))) {
AddAffected(X);
AddAffected(Y);
}
+ // X - Y
+ else if (match(A, m_Sub(m_Value(X), m_Value(Y)))) {
+ AddAffected(X);
+ AddAffected(Y);
+ }
}
} else {
AddCmpOperands(A, B);
diff --git a/llvm/test/Transforms/InstCombine/icmp.ll b/llvm/test/Transforms/InstCombine/icmp.ll
index 0faa7da482ef2..696208b903798 100644
--- a/llvm/test/Transforms/InstCombine/icmp.ll
+++ b/llvm/test/Transforms/InstCombine/icmp.ll
@@ -6054,3 +6054,189 @@ define i1 @icmp_samesign_logical_or(i32 %In) {
%V = select i1 %c1, i1 true, i1 %c2
ret i1 %V
}
+
+define i1 @non_zero_ptrdiff_implies_icmp_eq(ptr %p0, ptr %p1) {
+; CHECK-LABEL: define i1 @non_zero_ptrdiff_implies_icmp_eq(
+; CHECK-SAME: ptr [[P0:%.*]], ptr [[P1:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[I0:%.*]] = ptrtoint ptr [[P0]] to i64
+; CHECK-NEXT: [[I1:%.*]] = ptrtoint ptr [[P1]] to i64
+; CHECK-NEXT: [[DIFF:%.*]] = sub i64 [[I0]], [[I1]]
+; CHECK-NEXT: [[COND:%.*]] = icmp eq i64 [[DIFF]], 12
+; CHECK-NEXT: call void @llvm.assume(i1 [[COND]])
+; CHECK-NEXT: ret i1 false
+;
+entry:
+ %i0 = ptrtoint ptr %p0 to i64
+ %i1 = ptrtoint ptr %p1 to i64
+ %diff = sub i64 %i0, %i1
+ %cond = icmp eq i64 %diff, 12
+ call void @llvm.assume(i1 %cond)
+ %cmp = icmp eq ptr %p0, %p1
+ ret i1 %cmp
+}
+
+define i1 @non_zero_ptrdiff_implies_icmp_eq_commuted(ptr %p0, ptr %p1) {
+; CHECK-LABEL: define i1 @non_zero_ptrdiff_implies_icmp_eq_commuted(
+; CHECK-SAME: ptr [[P0:%.*]], ptr [[P1:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[I0:%.*]] = ptrtoint ptr [[P0]] to i64
+; CHECK-NEXT: [[I1:%.*]] = ptrtoint ptr [[P1]] to i64
+; CHECK-NEXT: [[DIFF:%.*]] = sub i64 [[I0]], [[I1]]
+; CHECK-NEXT: [[COND:%.*]] = icmp eq i64 [[DIFF]], 12
+; CHECK-NEXT: call void @llvm.assume(i1 [[COND]])
+; CHECK-NEXT: ret i1 false
+;
+entry:
+ %i0 = ptrtoint ptr %p0 to i64
+ %i1 = ptrtoint ptr %p1 to i64
+ %diff = sub i64 %i0, %i1
+ %cond = icmp eq i64 %diff, 12
+ call void @llvm.assume(i1 %cond)
+ %cmp = icmp eq ptr %p1, %p0
+ ret i1 %cmp
+}
+
+define i1 @non_zero_ptrdiff_implies_icmp_ne(ptr %p0, ptr %p1) {
+; CHECK-LABEL: define i1 @non_zero_ptrdiff_implies_icmp_ne(
+; CHECK-SAME: ptr [[P0:%.*]], ptr [[P1:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[I0:%.*]] = ptrtoint ptr [[P0]] to i64
+; CHECK-NEXT: [[I1:%.*]] = ptrtoint ptr [[P1]] to i64
+; CHECK-NEXT: [[DIFF:%.*]] = sub i64 [[I0]], [[I1]]
+; CHECK-NEXT: [[COND:%.*]] = icmp eq i64 [[DIFF]], 12
+; CHECK-NEXT: call void @llvm.assume(i1 [[COND]])
+; CHECK-NEXT: ret i1 true
+;
+entry:
+ %i0 = ptrtoint ptr %p0 to i64
+ %i1 = ptrtoint ptr %p1 to i64
+ %diff = sub i64 %i0, %i1
+ %cond = icmp eq i64 %diff, 12
+ call void @llvm.assume(i1 %cond)
+ %cmp = icmp ne ptr %p0, %p1
+ ret i1 %cmp
+}
+
+; TODO: Handle this case if it is shown in real code.
+define i1 @non_zero_truncated_ptrdiff_implies_icmp_ne(ptr %p0, ptr %p1) {
+; CHECK-LABEL: define i1 @non_zero_truncated_ptrdiff_implies_icmp_ne(
+; CHECK-SAME: ptr [[P0:%.*]], ptr [[P1:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[TMP0:%.*]] = ptrtoint ptr [[P0]] to i64
+; CHECK-NEXT: [[I0:%.*]] = trunc i64 [[TMP0]] to i8
+; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[P1]] to i64
+; CHECK-NEXT: [[I1:%.*]] = trunc i64 [[TMP1]] to i8
+; CHECK-NEXT: [[DIFF:%.*]] = sub i8 [[I0]], [[I1]]
+; CHECK-NEXT: [[COND:%.*]] = icmp eq i8 [[DIFF]], 12
+; CHECK-NEXT: call void @llvm.assume(i1 [[COND]])
+; CHECK-NEXT: [[CMP:%.*]] = icmp ne ptr [[P0]], [[P1]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+entry:
+ %i0 = ptrtoint ptr %p0 to i8
+ %i1 = ptrtoint ptr %p1 to i8
+ %diff = sub i8 %i0, %i1
+ %cond = icmp eq i8 %diff, 12
+ call void @llvm.assume(i1 %cond)
+ %cmp = icmp ne ptr %p0, %p1
+ ret i1 %cmp
+}
+
+define i1 @non_zero_diff_implies_icmp_eq(i8 %p0, i8 %p1) {
+; CHECK-LABEL: define i1 @non_zero_diff_implies_icmp_eq(
+; CHECK-SAME: i8 [[P0:%.*]], i8 [[P1:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[DIFF:%.*]] = sub i8 [[P0]], [[P1]]
+; CHECK-NEXT: [[COND:%.*]] = icmp eq i8 [[DIFF]], 12
+; CHECK-NEXT: call void @llvm.assume(i1 [[COND]])
+; CHECK-NEXT: ret i1 false
+;
+entry:
+ %diff = sub i8 %p0, %p1
+ %cond = icmp eq i8 %diff, 12
+ call void @llvm.assume(i1 %cond)
+ %cmp = icmp eq i8 %p0, %p1
+ ret i1 %cmp
+}
+
+define i1 @non_zero_diff_implies_icmp_eq_commuted(i8 %p0, i8 %p1) {
+; CHECK-LABEL: define i1 @non_zero_diff_implies_icmp_eq_commuted(
+; CHECK-SAME: i8 [[P0:%.*]], i8 [[P1:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[DIFF:%.*]] = sub i8 [[P0]], [[P1]]
+; CHECK-NEXT: [[COND:%.*]] = icmp eq i8 [[DIFF]], 12
+; CHECK-NEXT: call void @llvm.assume(i1 [[COND]])
+; CHECK-NEXT: ret i1 false
+;
+entry:
+ %diff = sub i8 %p0, %p1
+ %cond = icmp eq i8 %diff, 12
+ call void @llvm.assume(i1 %cond)
+ %cmp = icmp eq i8 %p1, %p0
+ ret i1 %cmp
+}
+
+; Negative tests
+
+define i1 @unknown_ptrdiff_implies_icmp_eq1(ptr %p0, ptr %p1) {
+; CHECK-LABEL: define i1 @unknown_ptrdiff_implies_icmp_eq1(
+; CHECK-SAME: ptr [[P0:%.*]], ptr [[P1:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[I0:%.*]] = ptrtoint ptr [[P0]] to i64
+; CHECK-NEXT: [[I1:%.*]] = ptrtoint ptr [[P1]] to i64
+; CHECK-NEXT: [[DIFF:%.*]] = sub i64 [[I0]], [[I1]]
+; CHECK-NEXT: [[COND:%.*]] = icmp ne i64 [[DIFF]], 12
+; CHECK-NEXT: call void @llvm.assume(i1 [[COND]])
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[P0]], [[P1]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+entry:
+ %i0 = ptrtoint ptr %p0 to i64
+ %i1 = ptrtoint ptr %p1 to i64
+ %diff = sub i64 %i0, %i1
+ %cond = icmp ne i64 %diff, 12
+ call void @llvm.assume(i1 %cond)
+ %cmp = icmp eq ptr %p0, %p1
+ ret i1 %cmp
+}
+
+define i1 @unknown_ptrdiff_implies_icmp_eq2(ptr %p0, ptr %p1, i64 %x) {
+; CHECK-LABEL: define i1 @unknown_ptrdiff_implies_icmp_eq2(
+; CHECK-SAME: ptr [[P0:%.*]], ptr [[P1:%.*]], i64 [[X:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[I0:%.*]] = ptrtoint ptr [[P0]] to i64
+; CHECK-NEXT: [[I1:%.*]] = ptrtoint ptr [[P1]] to i64
+; CHECK-NEXT: [[DIFF:%.*]] = sub i64 [[I0]], [[I1]]
+; CHECK-NEXT: [[COND:%.*]] = icmp eq i64 [[DIFF]], [[X]]
+; CHECK-NEXT: call void @llvm.assume(i1 [[COND]])
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[P0]], [[P1]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+entry:
+ %i0 = ptrtoint ptr %p0 to i64
+ %i1 = ptrtoint ptr %p1 to i64
+ %diff = sub i64 %i0, %i1
+ %cond = icmp eq i64 %diff, %x
+ call void @llvm.assume(i1 %cond)
+ %cmp = icmp eq ptr %p0, %p1
+ ret i1 %cmp
+}
+
+define i1 @non_zero_diff_implies_icmp_ult(i8 %p0, i8 %p1) {
+; CHECK-LABEL: define i1 @non_zero_diff_implies_icmp_ult(
+; CHECK-SAME: i8 [[P0:%.*]], i8 [[P1:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[DIFF:%.*]] = sub i8 [[P0]], [[P1]]
+; CHECK-NEXT: [[COND:%.*]] = icmp eq i8 [[DIFF]], 12
+; CHECK-NEXT: call void @llvm.assume(i1 [[COND]])
+; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[P0]], [[P1]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+entry:
+ %diff = sub i8 %p0, %p1
+ %cond = icmp eq i8 %diff, 12
+ call void @llvm.assume(i1 %cond)
+ %cmp = icmp ult i8 %p0, %p1
+ ret i1 %cmp
+}
|
@llvm/pr-subscribers-llvm-transforms Author: Yingwei Zheng (dtcxzyw) ChangesAlive2: https://alive2.llvm.org/ce/z/8rX5Rk Full diff: https://github.com/llvm/llvm-project/pull/159792.diff 2 Files Affected:
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index bb0db2d31971d..48167e3777447 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -9425,6 +9425,21 @@ isImpliedCondICmps(CmpPredicate LPred, const Value *L0, const Value *L1,
return true;
}
+ // a - b == NonZero -> a != b
+ // ptrtoint(a) - ptrtoint(b) == NonZero -> a != b
+ const APInt *RHSC;
+ Value *A, *B;
+ if (LPred == ICmpInst::ICMP_EQ && ICmpInst::isEquality(RPred) &&
+ match(L1, m_APInt(RHSC)) && !RHSC->isZero() &&
+ match(L0, m_Sub(m_Value(A), m_Value(B))) &&
+ ((A == R0 && B == R1) || (A == R1 && B == R0) ||
+ (match(A, m_PtrToInt(m_Specific(R0))) &&
+ match(B, m_PtrToInt(m_Specific(R1)))) ||
+ (match(A, m_PtrToInt(m_Specific(R1))) &&
+ match(B, m_PtrToInt(m_Specific(R0)))))) {
+ return RPred.dropSameSign() == ICmpInst::ICMP_NE;
+ }
+
// L0 = R0 = L1 + R1, L0 >=u L1 implies R0 >=u R1, L0 <u L1 implies R0 <u R1
if (L0 == R0 &&
(LPred == ICmpInst::ICMP_ULT || LPred == ICmpInst::ICMP_UGE) &&
@@ -10180,15 +10195,20 @@ void llvm::findValuesAffectedByCondition(
AddAffected(B);
if (HasRHSC) {
Value *Y;
- // (X & C) or (X | C).
// (X << C) or (X >>_s C) or (X >>_u C).
if (match(A, m_Shift(m_Value(X), m_ConstantInt())))
AddAffected(X);
+ // (X & C) or (X | C).
else if (match(A, m_And(m_Value(X), m_Value(Y))) ||
match(A, m_Or(m_Value(X), m_Value(Y)))) {
AddAffected(X);
AddAffected(Y);
}
+ // X - Y
+ else if (match(A, m_Sub(m_Value(X), m_Value(Y)))) {
+ AddAffected(X);
+ AddAffected(Y);
+ }
}
} else {
AddCmpOperands(A, B);
diff --git a/llvm/test/Transforms/InstCombine/icmp.ll b/llvm/test/Transforms/InstCombine/icmp.ll
index 0faa7da482ef2..696208b903798 100644
--- a/llvm/test/Transforms/InstCombine/icmp.ll
+++ b/llvm/test/Transforms/InstCombine/icmp.ll
@@ -6054,3 +6054,189 @@ define i1 @icmp_samesign_logical_or(i32 %In) {
%V = select i1 %c1, i1 true, i1 %c2
ret i1 %V
}
+
+define i1 @non_zero_ptrdiff_implies_icmp_eq(ptr %p0, ptr %p1) {
+; CHECK-LABEL: define i1 @non_zero_ptrdiff_implies_icmp_eq(
+; CHECK-SAME: ptr [[P0:%.*]], ptr [[P1:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[I0:%.*]] = ptrtoint ptr [[P0]] to i64
+; CHECK-NEXT: [[I1:%.*]] = ptrtoint ptr [[P1]] to i64
+; CHECK-NEXT: [[DIFF:%.*]] = sub i64 [[I0]], [[I1]]
+; CHECK-NEXT: [[COND:%.*]] = icmp eq i64 [[DIFF]], 12
+; CHECK-NEXT: call void @llvm.assume(i1 [[COND]])
+; CHECK-NEXT: ret i1 false
+;
+entry:
+ %i0 = ptrtoint ptr %p0 to i64
+ %i1 = ptrtoint ptr %p1 to i64
+ %diff = sub i64 %i0, %i1
+ %cond = icmp eq i64 %diff, 12
+ call void @llvm.assume(i1 %cond)
+ %cmp = icmp eq ptr %p0, %p1
+ ret i1 %cmp
+}
+
+define i1 @non_zero_ptrdiff_implies_icmp_eq_commuted(ptr %p0, ptr %p1) {
+; CHECK-LABEL: define i1 @non_zero_ptrdiff_implies_icmp_eq_commuted(
+; CHECK-SAME: ptr [[P0:%.*]], ptr [[P1:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[I0:%.*]] = ptrtoint ptr [[P0]] to i64
+; CHECK-NEXT: [[I1:%.*]] = ptrtoint ptr [[P1]] to i64
+; CHECK-NEXT: [[DIFF:%.*]] = sub i64 [[I0]], [[I1]]
+; CHECK-NEXT: [[COND:%.*]] = icmp eq i64 [[DIFF]], 12
+; CHECK-NEXT: call void @llvm.assume(i1 [[COND]])
+; CHECK-NEXT: ret i1 false
+;
+entry:
+ %i0 = ptrtoint ptr %p0 to i64
+ %i1 = ptrtoint ptr %p1 to i64
+ %diff = sub i64 %i0, %i1
+ %cond = icmp eq i64 %diff, 12
+ call void @llvm.assume(i1 %cond)
+ %cmp = icmp eq ptr %p1, %p0
+ ret i1 %cmp
+}
+
+define i1 @non_zero_ptrdiff_implies_icmp_ne(ptr %p0, ptr %p1) {
+; CHECK-LABEL: define i1 @non_zero_ptrdiff_implies_icmp_ne(
+; CHECK-SAME: ptr [[P0:%.*]], ptr [[P1:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[I0:%.*]] = ptrtoint ptr [[P0]] to i64
+; CHECK-NEXT: [[I1:%.*]] = ptrtoint ptr [[P1]] to i64
+; CHECK-NEXT: [[DIFF:%.*]] = sub i64 [[I0]], [[I1]]
+; CHECK-NEXT: [[COND:%.*]] = icmp eq i64 [[DIFF]], 12
+; CHECK-NEXT: call void @llvm.assume(i1 [[COND]])
+; CHECK-NEXT: ret i1 true
+;
+entry:
+ %i0 = ptrtoint ptr %p0 to i64
+ %i1 = ptrtoint ptr %p1 to i64
+ %diff = sub i64 %i0, %i1
+ %cond = icmp eq i64 %diff, 12
+ call void @llvm.assume(i1 %cond)
+ %cmp = icmp ne ptr %p0, %p1
+ ret i1 %cmp
+}
+
+; TODO: Handle this case if it is shown in real code.
+define i1 @non_zero_truncated_ptrdiff_implies_icmp_ne(ptr %p0, ptr %p1) {
+; CHECK-LABEL: define i1 @non_zero_truncated_ptrdiff_implies_icmp_ne(
+; CHECK-SAME: ptr [[P0:%.*]], ptr [[P1:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[TMP0:%.*]] = ptrtoint ptr [[P0]] to i64
+; CHECK-NEXT: [[I0:%.*]] = trunc i64 [[TMP0]] to i8
+; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[P1]] to i64
+; CHECK-NEXT: [[I1:%.*]] = trunc i64 [[TMP1]] to i8
+; CHECK-NEXT: [[DIFF:%.*]] = sub i8 [[I0]], [[I1]]
+; CHECK-NEXT: [[COND:%.*]] = icmp eq i8 [[DIFF]], 12
+; CHECK-NEXT: call void @llvm.assume(i1 [[COND]])
+; CHECK-NEXT: [[CMP:%.*]] = icmp ne ptr [[P0]], [[P1]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+entry:
+ %i0 = ptrtoint ptr %p0 to i8
+ %i1 = ptrtoint ptr %p1 to i8
+ %diff = sub i8 %i0, %i1
+ %cond = icmp eq i8 %diff, 12
+ call void @llvm.assume(i1 %cond)
+ %cmp = icmp ne ptr %p0, %p1
+ ret i1 %cmp
+}
+
+define i1 @non_zero_diff_implies_icmp_eq(i8 %p0, i8 %p1) {
+; CHECK-LABEL: define i1 @non_zero_diff_implies_icmp_eq(
+; CHECK-SAME: i8 [[P0:%.*]], i8 [[P1:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[DIFF:%.*]] = sub i8 [[P0]], [[P1]]
+; CHECK-NEXT: [[COND:%.*]] = icmp eq i8 [[DIFF]], 12
+; CHECK-NEXT: call void @llvm.assume(i1 [[COND]])
+; CHECK-NEXT: ret i1 false
+;
+entry:
+ %diff = sub i8 %p0, %p1
+ %cond = icmp eq i8 %diff, 12
+ call void @llvm.assume(i1 %cond)
+ %cmp = icmp eq i8 %p0, %p1
+ ret i1 %cmp
+}
+
+define i1 @non_zero_diff_implies_icmp_eq_commuted(i8 %p0, i8 %p1) {
+; CHECK-LABEL: define i1 @non_zero_diff_implies_icmp_eq_commuted(
+; CHECK-SAME: i8 [[P0:%.*]], i8 [[P1:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[DIFF:%.*]] = sub i8 [[P0]], [[P1]]
+; CHECK-NEXT: [[COND:%.*]] = icmp eq i8 [[DIFF]], 12
+; CHECK-NEXT: call void @llvm.assume(i1 [[COND]])
+; CHECK-NEXT: ret i1 false
+;
+entry:
+ %diff = sub i8 %p0, %p1
+ %cond = icmp eq i8 %diff, 12
+ call void @llvm.assume(i1 %cond)
+ %cmp = icmp eq i8 %p1, %p0
+ ret i1 %cmp
+}
+
+; Negative tests
+
+define i1 @unknown_ptrdiff_implies_icmp_eq1(ptr %p0, ptr %p1) {
+; CHECK-LABEL: define i1 @unknown_ptrdiff_implies_icmp_eq1(
+; CHECK-SAME: ptr [[P0:%.*]], ptr [[P1:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[I0:%.*]] = ptrtoint ptr [[P0]] to i64
+; CHECK-NEXT: [[I1:%.*]] = ptrtoint ptr [[P1]] to i64
+; CHECK-NEXT: [[DIFF:%.*]] = sub i64 [[I0]], [[I1]]
+; CHECK-NEXT: [[COND:%.*]] = icmp ne i64 [[DIFF]], 12
+; CHECK-NEXT: call void @llvm.assume(i1 [[COND]])
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[P0]], [[P1]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+entry:
+ %i0 = ptrtoint ptr %p0 to i64
+ %i1 = ptrtoint ptr %p1 to i64
+ %diff = sub i64 %i0, %i1
+ %cond = icmp ne i64 %diff, 12
+ call void @llvm.assume(i1 %cond)
+ %cmp = icmp eq ptr %p0, %p1
+ ret i1 %cmp
+}
+
+define i1 @unknown_ptrdiff_implies_icmp_eq2(ptr %p0, ptr %p1, i64 %x) {
+; CHECK-LABEL: define i1 @unknown_ptrdiff_implies_icmp_eq2(
+; CHECK-SAME: ptr [[P0:%.*]], ptr [[P1:%.*]], i64 [[X:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[I0:%.*]] = ptrtoint ptr [[P0]] to i64
+; CHECK-NEXT: [[I1:%.*]] = ptrtoint ptr [[P1]] to i64
+; CHECK-NEXT: [[DIFF:%.*]] = sub i64 [[I0]], [[I1]]
+; CHECK-NEXT: [[COND:%.*]] = icmp eq i64 [[DIFF]], [[X]]
+; CHECK-NEXT: call void @llvm.assume(i1 [[COND]])
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[P0]], [[P1]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+entry:
+ %i0 = ptrtoint ptr %p0 to i64
+ %i1 = ptrtoint ptr %p1 to i64
+ %diff = sub i64 %i0, %i1
+ %cond = icmp eq i64 %diff, %x
+ call void @llvm.assume(i1 %cond)
+ %cmp = icmp eq ptr %p0, %p1
+ ret i1 %cmp
+}
+
+define i1 @non_zero_diff_implies_icmp_ult(i8 %p0, i8 %p1) {
+; CHECK-LABEL: define i1 @non_zero_diff_implies_icmp_ult(
+; CHECK-SAME: i8 [[P0:%.*]], i8 [[P1:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[DIFF:%.*]] = sub i8 [[P0]], [[P1]]
+; CHECK-NEXT: [[COND:%.*]] = icmp eq i8 [[DIFF]], 12
+; CHECK-NEXT: call void @llvm.assume(i1 [[COND]])
+; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[P0]], [[P1]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+entry:
+ %diff = sub i8 %p0, %p1
+ %cond = icmp eq i8 %diff, 12
+ call void @llvm.assume(i1 %cond)
+ %cmp = icmp ult i8 %p0, %p1
+ ret i1 %cmp
+}
|
@zyw-bot mfuzz |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Alive2: https://alive2.llvm.org/ce/z/8rX5Rk
Closes #118106.