[PATCH] D13253: Tighten known bits for ctpop based on zero input bits

Philip Reames via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 6 13:38:22 PDT 2015


reames updated this revision to Diff 36654.
reames added a comment.

Address Sanjoy's review comments.


http://reviews.llvm.org/D13253

Files:
  lib/Analysis/ValueTracking.cpp
  test/Transforms/InstCombine/ctpop.ll

Index: test/Transforms/InstCombine/ctpop.ll
===================================================================
--- test/Transforms/InstCombine/ctpop.ll
+++ test/Transforms/InstCombine/ctpop.ll
@@ -0,0 +1,45 @@
+; RUN: opt < %s -S -instcombine | FileCheck %s
+
+declare i32 @llvm.ctpop.i32(i32)
+declare i8 @llvm.ctpop.i8(i8)
+declare void @llvm.assume(i1)
+
+define i1 @test1(i32 %arg) {
+; CHECK: @test1
+; CHECK: ret i1 false
+  %and = and i32 %arg, 15
+  %cnt = call i32 @llvm.ctpop.i32(i32 %and)
+  %res = icmp eq i32 %cnt, 9
+  ret i1 %res
+}
+
+define i1 @test2(i32 %arg) {
+; CHECK: @test2
+; CHECK: ret i1 false
+  %and = and i32 %arg, 1
+  %cnt = call i32 @llvm.ctpop.i32(i32 %and)
+  %res = icmp eq i32 %cnt, 2
+  ret i1 %res
+}
+
+define i1 @test3(i32 %arg) {
+; CHECK: @test3
+; CHECK: ret i1 false
+  ;; Use an assume to make all the bits known without triggering constant 
+  ;; folding.  This is trying to hit a corner case where we have to avoid
+  ;; taking the log of 0.
+  %assume = icmp eq i32 %arg, 0
+  call void @llvm.assume(i1 %assume)
+  %cnt = call i32 @llvm.ctpop.i32(i32 %arg)
+  %res = icmp eq i32 %cnt, 2
+  ret i1 %res
+}
+
+; Negative test for when we know nothing
+define i1 @test4(i8 %arg) {
+; CHECK: @test4
+; CHECK: ret i1 %res
+  %cnt = call i8 @llvm.ctpop.i8(i8 %arg)
+  %res = icmp eq i8 %cnt, 2
+  ret i1 %res
+}
Index: lib/Analysis/ValueTracking.cpp
===================================================================
--- lib/Analysis/ValueTracking.cpp
+++ lib/Analysis/ValueTracking.cpp
@@ -1374,8 +1374,18 @@
         break;
       }
       case Intrinsic::ctpop: {
-        unsigned LowBits = Log2_32(BitWidth)+1;
-        KnownZero |= APInt::getHighBitsSet(BitWidth, BitWidth - LowBits);
+        computeKnownBits(I->getOperand(0), KnownZero2, KnownOne2, DL,
+                         Depth + 1, Q);
+        // we can bound the space the count needs.  Also, bits known to be zero
+        // can't contribute to the population.
+        unsigned BitsPossiblySet = BitWidth - KnownZero2.countPopulation();
+        unsigned LeadingZeros =
+          APInt(BitWidth, BitsPossiblySet).countLeadingZeros();
+        assert(LeadingZeros >= 0 && LeadingZeros <= BitWidth);
+        KnownZero |= APInt::getHighBitsSet(BitWidth, LeadingZeros);
+        KnownOne &= ~KnownZero;
+        // TODO: we could bound KnownOne using the lower bound on the number
+        // of bits which might be set provided by popcnt KnownOne2.
         break;
       }
       case Intrinsic::x86_sse42_crc32_64_64:


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D13253.36654.patch
Type: text/x-patch
Size: 2535 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20151006/24b0b6b6/attachment.bin>


More information about the llvm-commits mailing list