aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/IR/ConstantRange.cpp
diff options
context:
space:
mode:
authorFlorian Hahn <flo@fhahn.com>2021-06-30 09:45:50 +0100
committerFlorian Hahn <flo@fhahn.com>2021-06-30 11:18:20 +0100
commit611a02cce509d304ebf66054b7816f1e0b5a792c (patch)
tree0aac416d1a605de8d4d47e27bfbbfe89ee483c97 /llvm/lib/IR/ConstantRange.cpp
parentad8494c021d711779900bf63f01423f615b413a4 (diff)
downloadllvm-611a02cce509d304ebf66054b7816f1e0b5a792c.zip
llvm-611a02cce509d304ebf66054b7816f1e0b5a792c.tar.gz
llvm-611a02cce509d304ebf66054b7816f1e0b5a792c.tar.bz2
[ConstantRanges] Use APInt for constant case for urem/srem.
Currently UREM & SREM on constant ranges produces overly pessimistic results for single element constant ranges. Delegate to APInt's implementation if both operands are single element constant ranges. We already do something similar for other binary operators, like binary AND. Fixes PR49731. Reviewed By: lebedev.ri Differential Revision: https://reviews.llvm.org/D105115
Diffstat (limited to 'llvm/lib/IR/ConstantRange.cpp')
-rw-r--r--llvm/lib/IR/ConstantRange.cpp18
1 files changed, 18 insertions, 0 deletions
diff --git a/llvm/lib/IR/ConstantRange.cpp b/llvm/lib/IR/ConstantRange.cpp
index b38599f..0649776 100644
--- a/llvm/lib/IR/ConstantRange.cpp
+++ b/llvm/lib/IR/ConstantRange.cpp
@@ -1221,6 +1221,15 @@ ConstantRange ConstantRange::urem(const ConstantRange &RHS) const {
if (isEmptySet() || RHS.isEmptySet() || RHS.getUnsignedMax().isNullValue())
return getEmpty();
+ if (const APInt *RHSInt = RHS.getSingleElement()) {
+ // UREM by null is UB.
+ if (RHSInt->isNullValue())
+ return getEmpty();
+ // Use APInt's implementation of UREM for single element ranges.
+ if (const APInt *LHSInt = getSingleElement())
+ return {LHSInt->urem(*RHSInt)};
+ }
+
// L % R for L < R is L.
if (getUnsignedMax().ult(RHS.getUnsignedMin()))
return *this;
@@ -1234,6 +1243,15 @@ ConstantRange ConstantRange::srem(const ConstantRange &RHS) const {
if (isEmptySet() || RHS.isEmptySet())
return getEmpty();
+ if (const APInt *RHSInt = RHS.getSingleElement()) {
+ // SREM by null is UB.
+ if (RHSInt->isNullValue())
+ return getEmpty();
+ // Use APInt's implementation of SREM for single element ranges.
+ if (const APInt *LHSInt = getSingleElement())
+ return {LHSInt->srem(*RHSInt)};
+ }
+
ConstantRange AbsRHS = RHS.abs();
APInt MinAbsRHS = AbsRHS.getUnsignedMin();
APInt MaxAbsRHS = AbsRHS.getUnsignedMax();