[PATCH] D14392: [ValueTracking] Teach isImpliedCondition a new bitwise trick
Sanjoy Das via llvm-commits
llvm-commits at lists.llvm.org
Thu Nov 5 13:27:16 PST 2015
sanjoy created this revision.
sanjoy added reviewers: majnemer, reames, hfinkel.
sanjoy added a subscriber: llvm-commits.
sanjoy added a dependency: D14391: [ValueTracking] Add parameters to isImpliedCondition; NFC.
This change teaches isImpliedCondition to prove things like
(A | 15) < L ==> (A | 14) < L
if the low 4 bits of A are known to be zero.
Depends on D14391
http://reviews.llvm.org/D14392
Files:
lib/Analysis/ValueTracking.cpp
test/Transforms/InstSimplify/implies.ll
Index: test/Transforms/InstSimplify/implies.ll
===================================================================
--- test/Transforms/InstSimplify/implies.ll
+++ test/Transforms/InstSimplify/implies.ll
@@ -127,6 +127,46 @@
ret i1 %res
}
+define i1 @test10(i32 %length.i, i32 %x.full) {
+; CHECK-LABEL: @test10(
+; CHECK: ret i1 true
+
+ %x = and i32 %x.full, 4294901760 ;; 4294901760 == 0xffff0000
+ %large = or i32 %x, 100
+ %small = or i32 %x, 90
+ %known = icmp ult i32 %large, %length.i
+ %to.prove = icmp ult i32 %small, %length.i
+ %res = icmp ule i1 %known, %to.prove
+ ret i1 %res
+}
+
+define i1 @test11(i32 %length.i, i32 %x) {
+; CHECK-LABEL: @test11(
+; CHECK: %res = icmp ule i1 %known, %to.prove
+; CHECK: ret i1 %res
+
+ %large = or i32 %x, 100
+ %small = or i32 %x, 90
+ %known = icmp ult i32 %large, %length.i
+ %to.prove = icmp ult i32 %small, %length.i
+ %res = icmp ule i1 %known, %to.prove
+ ret i1 %res
+}
+
+define i1 @test12(i32 %length.i, i32 %x.full) {
+; CHECK-LABEL: @test12(
+; CHECK: %res = icmp ule i1 %known, %to.prove
+; CHECK: ret i1 %res
+
+ %x = and i32 %x.full, 4294901760 ;; 4294901760 == 0xffff0000
+ %large = or i32 %x, 65536 ;; 65536 == 0x00010000
+ %small = or i32 %x, 90
+ %known = icmp ult i32 %large, %length.i
+ %to.prove = icmp ult i32 %small, %length.i
+ %res = icmp ule i1 %known, %to.prove
+ ret i1 %res
+}
+
; X >=(s) Y == X ==> Y (i1 1 becomes -1 for reasoning)
define i1 @test_sge(i32 %length.i, i32 %i) {
; CHECK-LABEL: @test_sge
Index: lib/Analysis/ValueTracking.cpp
===================================================================
--- lib/Analysis/ValueTracking.cpp
+++ lib/Analysis/ValueTracking.cpp
@@ -4119,6 +4119,36 @@
return !CI->isZero();
return true;
}
+
+ // If the low K bits of X are known to be zero, and both C0 and C1
+ // fit in K bits, then
+ //
+ // (X | C0) u< (X | C1) iff C0 u< C1
+ // (X | C0) u<= (X | C1) iff C0 u<= C1
+ //
+ // Informally, the easiest way to justify this is to see that
+ // "X | C" if C fits in K bits (where the low K bits of X are
+ // zero) is equal to "X +_{nuw} C". Then this rule is effectively
+ // the same as "C0 u< C1" ==> "(X +_{nuw} C0) u< (X +_{nuw} C1)".
+
+ Value *X;
+ ConstantInt *CI0, *CI1;
+ if (match(LHS, m_Or(m_Value(X), m_ConstantInt(CI0))) &&
+ match(RHS, m_Or(m_Specific(X), m_ConstantInt(CI1)))) {
+ unsigned BitWidth = cast<IntegerType>(LHS->getType())->getBitWidth();
+ APInt KnownZero(BitWidth, 0), KnownOne(BitWidth, 0);
+ computeKnownBits(X, KnownZero, KnownOne, DL, Depth + 1, AC, CxtI, DT);
+
+ unsigned LowZeroes = KnownZero.countTrailingOnes();
+ APInt UpperLimit =
+ APInt::getBitsSet(KnownZero.getBitWidth(), LowZeroes, LowZeroes + 1);
+
+ if (UpperLimit.ugt(CI0->getValue()) && UpperLimit.ugt(CI1->getValue())) {
+ if (Pred == CmpInst::ICMP_ULE)
+ return CI0->getValue().ule(CI1->getValue());
+ return CI0->getValue().ult(CI1->getValue());
+ }
+ }
return false;
}
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D14392.39407.patch
Type: text/x-patch
Size: 3095 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20151105/b2a5a615/attachment.bin>
More information about the llvm-commits
mailing list