OSDN Git Service

[ConstantRange] Add sdiv() support
authorNikita Popov <nikita.ppv@gmail.com>
Mon, 3 Jun 2019 18:19:54 +0000 (18:19 +0000)
committerNikita Popov <nikita.ppv@gmail.com>
Mon, 3 Jun 2019 18:19:54 +0000 (18:19 +0000)
commit13a908d7ffb1b501ad83d0d472f128cd39cb589e
treed41180005fbac72538c0aeaa5c155d9198d9db1d
parent8c846ac77167690e2d7896e382153df3fe5fcb7f
[ConstantRange] Add sdiv() support

The implementation is conceptually simple: We separate the LHS and
RHS into positive and negative components and then also compute the
positive and negative components of the result, taking into account
that e.g. only pos/pos and neg/neg will give a positive result.

However, there's one significant complication: SignedMin / -1 is UB
for sdiv, and we can't just ignore it, because the APInt result of
SignedMin would break the sign segregation. Instead we drop SignedMin
or -1 from the corresponding ranges, taking into account some edge
cases with wrapped ranges.

Because of the sign segregation, the implementation ends up being
nearly fully precise even for wrapped ranges (the remaining
imprecision is due to ranges that are both signed and unsigned
wrapping and are divided by a trivial divisor like 1). This means
that the testing cannot just check the signed envelope as we
usually do. Instead we collect all possible results in a bitvector
and construct a better sign wrapped range (than the full envelope).

Differential Revision: https://reviews.llvm.org/D61238

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@362430 91177308-0d34-0410-b5e6-96231b3b80d8
include/llvm/IR/ConstantRange.h
lib/IR/ConstantRange.cpp
unittests/IR/ConstantRangeTest.cpp