diff options
Diffstat (limited to 'llvm/lib/IR/ConstantRange.cpp')
-rw-r--r-- | llvm/lib/IR/ConstantRange.cpp | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/llvm/lib/IR/ConstantRange.cpp b/llvm/lib/IR/ConstantRange.cpp index 59e7a9f..c3bde48 100644 --- a/llvm/lib/IR/ConstantRange.cpp +++ b/llvm/lib/IR/ConstantRange.cpp @@ -930,6 +930,8 @@ ConstantRange ConstantRange::overflowingBinaryOp(Instruction::BinaryOps BinOp, return addWithNoWrap(Other, NoWrapKind); case Instruction::Sub: return subWithNoWrap(Other, NoWrapKind); + case Instruction::Mul: + return multiplyWithNoWrap(Other, NoWrapKind); default: // Don't know about this Overflowing Binary Operation. // Conservatively fallback to plain binop handling. @@ -1167,6 +1169,26 @@ ConstantRange::multiply(const ConstantRange &Other) const { return UR.isSizeStrictlySmallerThan(SR) ? UR : SR; } +ConstantRange +ConstantRange::multiplyWithNoWrap(const ConstantRange &Other, + unsigned NoWrapKind, + PreferredRangeType RangeType) const { + if (isEmptySet() || Other.isEmptySet()) + return getEmpty(); + if (isFullSet() && Other.isFullSet()) + return getFull(); + + ConstantRange Result = multiply(Other); + + if (NoWrapKind & OverflowingBinaryOperator::NoSignedWrap) + Result = Result.intersectWith(smul_sat(Other), RangeType); + + if (NoWrapKind & OverflowingBinaryOperator::NoUnsignedWrap) + Result = Result.intersectWith(umul_sat(Other), RangeType); + + return Result; +} + ConstantRange ConstantRange::smul_fast(const ConstantRange &Other) const { if (isEmptySet() || Other.isEmptySet()) return getEmpty(); |