diff options
author | Roman Lebedev <lebedev.ri@gmail.com> | 2019-11-08 10:24:46 +0300 |
---|---|---|
committer | Roman Lebedev <lebedev.ri@gmail.com> | 2019-11-08 10:31:04 +0300 |
commit | e0ea842baec00b6bf6dc0069f1c1961da5889927 (patch) | |
tree | be01b4cfe945279b071b24e0fb52e5fcfcc296fc /llvm/lib/IR/ConstantRange.cpp | |
parent | 6b8baf3062cdc7bd88867e239f26b6966ee3142c (diff) | |
download | llvm-e0ea842baec00b6bf6dc0069f1c1961da5889927.zip llvm-e0ea842baec00b6bf6dc0069f1c1961da5889927.tar.gz llvm-e0ea842baec00b6bf6dc0069f1c1961da5889927.tar.bz2 |
[ConstantRange] Add `ushl_sat()`/`sshl_sat()` methods.
Summary:
To be used in `ConstantRange::shlWithNoOverflow()`,
may in future be useful for when saturating shift/mul ops are added.
Unlike `ConstantRange::shl()`, these are precise.
Reviewers: nikic, spatel, reames
Reviewed By: nikic
Subscribers: hiraditya, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D69960
Diffstat (limited to 'llvm/lib/IR/ConstantRange.cpp')
-rw-r--r-- | llvm/lib/IR/ConstantRange.cpp | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/llvm/lib/IR/ConstantRange.cpp b/llvm/lib/IR/ConstantRange.cpp index 18d8e9d..63a6494 100644 --- a/llvm/lib/IR/ConstantRange.cpp +++ b/llvm/lib/IR/ConstantRange.cpp @@ -1333,6 +1333,26 @@ ConstantRange ConstantRange::ssub_sat(const ConstantRange &Other) const { return getNonEmpty(std::move(NewL), std::move(NewU)); } +ConstantRange ConstantRange::ushl_sat(const ConstantRange &Other) const { + if (isEmptySet() || Other.isEmptySet()) + return getEmpty(); + + APInt NewL = getUnsignedMin().ushl_sat(Other.getUnsignedMin()); + APInt NewU = getUnsignedMax().ushl_sat(Other.getUnsignedMax()) + 1; + return getNonEmpty(std::move(NewL), std::move(NewU)); +} + +ConstantRange ConstantRange::sshl_sat(const ConstantRange &Other) const { + if (isEmptySet() || Other.isEmptySet()) + return getEmpty(); + + APInt Min = getSignedMin(), Max = getSignedMax(); + APInt ShAmtMin = Other.getUnsignedMin(), ShAmtMax = Other.getUnsignedMax(); + APInt NewL = Min.sshl_sat(isAllNonNegative() ? ShAmtMin : ShAmtMax); + APInt NewU = Max.sshl_sat(isAllNegative() ? ShAmtMin : ShAmtMax) + 1; + return getNonEmpty(std::move(NewL), std::move(NewU)); +} + ConstantRange ConstantRange::inverse() const { if (isFullSet()) return getEmpty(); |