summaryrefslogtreecommitdiffstats
path: root/llvm/lib/IR/ConstantRange.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/IR/ConstantRange.cpp')
-rw-r--r--llvm/lib/IR/ConstantRange.cpp15
1 files changed, 15 insertions, 0 deletions
diff --git a/llvm/lib/IR/ConstantRange.cpp b/llvm/lib/IR/ConstantRange.cpp
index b2bdd0abd9c..7e2c6727703 100644
--- a/llvm/lib/IR/ConstantRange.cpp
+++ b/llvm/lib/IR/ConstantRange.cpp
@@ -794,6 +794,8 @@ ConstantRange ConstantRange::binaryOp(Instruction::BinaryOps BinOp,
return multiply(Other);
case Instruction::UDiv:
return udiv(Other);
+ case Instruction::URem:
+ return urem(Other);
case Instruction::Shl:
return shl(Other);
case Instruction::LShr:
@@ -991,6 +993,19 @@ ConstantRange::udiv(const ConstantRange &RHS) const {
return getNonEmpty(std::move(Lower), std::move(Upper));
}
+ConstantRange ConstantRange::urem(const ConstantRange &RHS) const {
+ if (isEmptySet() || RHS.isEmptySet() || RHS.getUnsignedMax().isNullValue())
+ return getEmpty();
+
+ // L % R for L < R is L.
+ if (getUnsignedMax().ult(RHS.getUnsignedMin()))
+ return *this;
+
+ // L % R is <= L and < R.
+ APInt Upper = APIntOps::umin(getUnsignedMax(), RHS.getUnsignedMax() - 1) + 1;
+ return getNonEmpty(APInt::getNullValue(getBitWidth()), std::move(Upper));
+}
+
ConstantRange
ConstantRange::binaryAnd(const ConstantRange &Other) const {
if (isEmptySet() || Other.isEmptySet())
OpenPOWER on IntegriCloud