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

Philip Reames via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 29 10:26:03 PDT 2015


reames created this revision.
reames added reviewers: majnemer, spatel, hfinkel, regehr.
reames added a subscriber: llvm-commits.

This is a cleaned up patch from the one written by John Regehr based on the findings of the Souper superoptimizer.

The basic idea here is that input bits that are known zero reduce the maximum count that the intrinsic could return.  We know that the number of bits required to represent a particular count is at most log2(N)+1.

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,47 @@
+; 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
@@ -1368,8 +1368,24 @@
         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);
+        // bits known to be zero can't contribute to the population
+        unsigned BitsPossiblySet = BitWidth - KnownZero2.countPopulation();
+        if (BitsPossiblySet) {
+          // we can bound the space the count needs
+          unsigned LowBits = Log2_32(BitsPossiblySet)+1;
+          KnownZero |= APInt::getHighBitsSet(BitWidth, BitWidth - LowBits);
+          // TODO: we could bound KnownOne using the lower bound on the number
+          // of bits which might be set provided by popcnt KnownOne2.
+        } else {
+          // If no bits are set, we can essentially constant fold the result.
+          // This is also handled in constant folding, but since we need to
+          // prevent a log2(0) from occuring anyways, we might as well handle
+          // it here.
+          KnownZero = APInt::getAllOnesValue(BitWidth);
+          KnownOne = APInt(BitWidth, 0);
+        }
         break;
       }
       case Intrinsic::x86_sse42_crc32_64_64:


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D13253.35996.patch
Type: text/x-patch
Size: 2812 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150929/7bc8423c/attachment.bin>


More information about the llvm-commits mailing list