[llvm-dev] Reasoning about known bits of the absolute value of a signed integer

Sanjoy Das via llvm-dev llvm-dev at lists.llvm.org
Tue May 3 15:55:02 PDT 2016


Hi Carlos,

Carlos Liam via llvm-dev wrote:
 > I'm trying to reason about how to find certain bit positions of the
 > absolute value of a given integer value. Specifically, I want to know
 > the highest possibly set bit and lowest possibly set bit of the absolute
 > value, in order to find the range between the two.
 >
 > Note that I'm specifically trying to be as conservative as possible.

I don't think you are or want to be as conservative as possible. :P

The most conservative answer will always be "highest possibly set bit"
== WordSize-1, "lowest possibly set bit" == 0.  I think you want you
want to be as *precise* as possible while still being correct.


I would approach the problem slightly differently than you have: the
KnownZero and KnownOne bitvectors are really approximations to the
actual integer you'll see at runtime.  I'd try to think of how you
can map the 100% precise runtime notion of ABS into this imperfect
approximation.  Once you can pipe KnownZero and KnownOne through an
approximation of ABS, then you know what bits of the absolute value are
known, and can compute the highest and lowest "possibly set" bit
positions from that (basically just by looking at CLZ(KnownZero) and
CTZ(KnownZero)).

A rough sketch of how to map ABS to KnownZero and KnownOne (let's call
the result ApproxABS) is (please _carefully_ verify this :) ):

We know:

ABS(x) == NOT(x) + 1

Giving:

Let {A, B} denote the approximation KnownZero = A, KnownOne = B

ApproxABS({A, B}) == ApproxIncrement(ApproxNot({A, B}))

== ApproxIncrement(({B, A}))

`ApproxIncrement` is a little trickier:

   Carry = 1;  // since we're adding 1. This can be 0, 1 or unknown
   for i = 0 to wordSize-1:
     if KnownZero[i]:
       if Carry is 1:
         Result.KnownOne[i] = 1
       else if Carry is 0:
         Result.KnownZero[i] = 1
       Carry = 0
       continue  // never any carry
     if KnownOne[i]:
       if Carry is 1:
         Result.KnownZero[i] = 1
	Carry = 1
       else if Carry is 0:
         Result.KnownOne[i] = 1
	Carry = 0
       else if Carry is unknown:
         Carry = unknown
       continue
     // if neither one or zero is known:
     if Carry == 1:
       Carry = unknown

-- Sanjoy


More information about the llvm-dev mailing list