D111241 added support for extractBits() with zero width. Extend this
to extractBitsAsZExtValue() as well for consistency (in which case
it will always return zero).
Differential Revision: https://reviews.llvm.org/D151788
This will be used in implementing arbitrary precision support to
FileCheck's numeric variables and expressions.
Reviewed By: foad, RKSimon
Differential Revision: https://reviews.llvm.org/D150879
Note that those functions on the left hand side are soft-deprecated in
favor of those on the right hand side:
getMinSignedBits -> getSignificantBits
getNullValue -> getZero
isNullValue -> isZero
isOneValue -> isOne
Tihs patches adds APInt::count{l,r}_{zero,one} and APInt::popcount to
be consistent with those functions in ADT/bit.h.
Once this patch lands, I'll take care of the migration.
For now, I am intentionally leaving isPowerOf2 as is.
Differential Revision: https://reviews.llvm.org/D144165
Equivalent tester for the APInt::getOneBitSet builder.
This should allow us to remove a number of cases where we're doing "Val == (1 << BitNo)" style code patterns.
Currently, APInt::getSExtValue and getZExtValue crashes on values with more than 64 bits.
Users may accidently crash the compiler with this setting when the integer may be i128.
As shown in https://github.com/llvm/llvm-project/issues/59316
In this patch we provide a trySExtValue and tryZExtValue to return an Optional, the user
needs to explictly unwrap it and condsier the possibility where there my no value in it.
Reviewed By: RKSimon
Differential Revision: https://reviews.llvm.org/D139683
This patch mechanically replaces None with std::nullopt where the
compiler would warn if None were deprecated. The intent is to reduce
the amount of manual work required in migrating from Optional to
std::optional.
This is part of an effort to migrate from llvm::Optional to
std::optional:
https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
Allow zext, sext, trunc, truncUSat and truncSSat to extend or truncate
to the same bit width, which is a no-op.
Disallowing this forced clients to use workarounds like using
zextOrTrunc (even though they never wanted truncation) or zextOrSelf
(even though they did not want its strange behaviour of allowing a
*smaller* bit width, which is also treated as a no-op).
Differential Revision: https://reviews.llvm.org/D125556
In many cases, calls to isShiftedMask are immediately followed with checks to determine the size and position of the bitmask.
This patch adds variants of APInt::isShiftedMask, isShiftedMask_32 and isShiftedMask_64 that return these values as additional arguments.
I've updated a number of cases that were either performing seperate size/position calculations or had created their own local wrapper versions of these.
Differential Revision: https://reviews.llvm.org/D119019
Remove assertion that disallows getting a zero-extended value from a
zero-width APInt. This check is too restrictive and makes it difficult
to use APInt to model zero-width things, e.g., zero-width wires in the
CIRCT project.
Signed-off-by: Schuyler Eldridge <schuyler.eldridge@sifive.com>
Reviewed By: lattner, darthscsi, nikic
Differential Revision: https://reviews.llvm.org/D114768
Inspired by D111968, provide a isNegatedPowerOf2() wrapper instead of obfuscating code with (-Value).isPowerOf2() patterns, which I'm sure are likely avenues for typos.....
Differential Revision: https://reviews.llvm.org/D111998
The sdiv used to check for overflow can itself overflow if the
LHS is signed min and the RHS is -1. The code tried to account for
this by also checking the commuted version. However, for 1-bit
values, signed min and -1 are the same value, so both divisions
overflow. As such, the overflow for -1 * -1 was not detected
(which results in -1 rather than 1 for 1-bit values). Fix this by
explicitly checking for this case instead.
Noticed while adding exhaustive test coverage for smul_ov(),
which is also part of this commit.
isAllOnes() should return true for zero bit values because
there are no zeros in it.
Thanks to Jay Foad for pointing this out.
Differential Revision: https://reviews.llvm.org/D111241
These should both clearly work with our current model for zero width
integers, but don't until now!
Differential Revision: https://reviews.llvm.org/D111113
Three unrelated changes:
1) Add a concat method as a convenience to help write bitvector
use cases in a nicer way.
2) Use LLVM_UNLIKELY as suggested by @xbolva00 in a previous patch.
3) Fix casing of some "slow" methods to follow naming standards.
Differential Revision: https://reviews.llvm.org/D109620
APInt is used to describe a bit mask in a variety of value tracking and demanded bits/elts functions.
When traversing through dst/src operands, we have a number of places where these masks need to widened/narrowed to translate through bitcasts, reductions etc. to a different type.
This patch add a APIntOps::ScaleBitMask common helper, adds unit test coverage, and updates a number of cases to use the the helper instead of their own implementation.
This came up on D109065 where we currently have to add yet another implementation of the same code.
Differential Revision: https://reviews.llvm.org/D109683
Motivation: APInt not supporting zero bit values leads to
a lot of special cases in various bits of code, particularly
when using APInt as a bit vector (where you want to start with
zero bits and then concat on more. This is particularly
challenging in the CIRCT project, where the absence of zero-bit
ConstantOp forces duplication of ops and makes instcombine-like
logic far more complicated.
Approach: zero bit integers are weird. There are two reasonable
approaches: either make it illegal to do general arithmetic on
them (e.g. sign extends), or treat them as as implicitly having
a zero value. This patch takes the conservative approach, which
enables their use in bitvector applications.
Differential Revision: https://reviews.llvm.org/D109555
This renames the primary methods for creating a zero value to `getZero`
instead of `getNullValue` and renames predicates like `isAllOnesValue`
to simply `isAllOnes`. This achieves two things:
1) This starts standardizing predicates across the LLVM codebase,
following (in this case) ConstantInt. The word "Value" doesn't
convey anything of merit, and is missing in some of the other things.
2) Calling an integer "null" doesn't make any sense. The original sin
here is mine and I've regretted it for years. This moves us to calling
it "zero" instead, which is correct!
APInt is widely used and I don't think anyone is keen to take massive source
breakage on anything so core, at least not all in one go. As such, this
doesn't actually delete any entrypoints, it "soft deprecates" them with a
comment.
Included in this patch are changes to a bunch of the codebase, but there are
more. We should normalize SelectionDAG and other APIs as well, which would
make the API change more mechanical.
Differential Revision: https://reviews.llvm.org/D109483
This moves one mid-size function out of line, inlines the
trivial tcAnd/tcOr/tcXor/tcComplement methods into their only
caller, and moves the magic/umagic functions into SelectionDAG
since they are implementation details of its algorithm. This
also removes the unit tests for magic, but these are already
tested in the divide lowering logic for various targets.
This also upgrades some C style comments to C++.
Differential Revision: https://reviews.llvm.org/D109476
<string> is currently the highest impact header in a clang+llvm build:
https://commondatastorage.googleapis.com/chromium-browser-clang/llvm-include-analysis.html
One of the most common places this is being included is the APInt.h header, which needs it for an old toString() implementation that returns std::string - an inefficient method compared to the SmallString versions that it actually wraps.
This patch replaces these APInt/APSInt methods with a pair of llvm::toString() helpers inside StringExtras.h, adjusts users accordingly and removes the <string> from APInt.h - I was hoping that more of these users could be converted to use the SmallString methods, but it appears that most end up creating a std::string anyhow. I avoided trying to use the raw_ostream << operators as well as I didn't want to lose having the integer radix explicit in the code.
Differential Revision: https://reviews.llvm.org/D103888
Truncates the APInt if the bit width is greater than the width specified,
otherwise do nothing
Reviewed By: RKSimon
Differential Revision: https://reviews.llvm.org/D91445
As noted on D74621, the bswap intrinsic has a self imposed limitation that the type's bitwidth must be divisible by 16, but there's no reason that APInt::byteSwap must have the same limitation, given that it can already handle any byte width.
Summary:
The signed one is needed for implementation of `ConstantRange::smul_sat()`,
unsigned is for completeness only.
Reviewers: nikic, RKSimon, spatel
Reviewed By: nikic
Subscribers: hiraditya, dexonsmith, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D69993
Summary:
Compare two values, and if they are different, return the position of the
most significant bit that is different in the values.
Needed for D69387.
Reviewers: nikic, spatel, sanjoy, RKSimon
Reviewed By: nikic
Subscribers: xbolva00, hiraditya, dexonsmith, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D69439
Summary:
There are `*_ov()` functions already, so at least for consistency it may be good to also have saturating variants.
These may or may not be needed for `ConstantRange`'s `shlWithNoWrap()`
Reviewers: spatel, nikic
Reviewed By: nikic
Subscribers: hiraditya, dexonsmith, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D69398
Summary:
There are `*_ov()` functions already, so at least for consistency it may be good to also have saturating variants.
These may or may not be needed for `ConstantRange`'s `mulWithNoWrap()`
Reviewers: spatel, nikic
Reviewed By: nikic
Subscribers: hiraditya, dexonsmith, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D69397