From 198381e542320265e1c5fed18e938db3563a45bf Mon Sep 17 00:00:00 2001 From: Nick Lewycky Date: Tue, 7 Sep 2010 05:39:02 +0000 Subject: [PATCH] Add completely hokey binary-and and binary-or operations to ConstantRange and teach LazyValueInfo to use them. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@113196 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Support/ConstantRange.h | 8 ++++++++ lib/Analysis/LazyValueInfo.cpp | 6 ++++++ lib/Support/ConstantRange.cpp | 26 ++++++++++++++++++++++++++ 3 files changed, 40 insertions(+) diff --git a/include/llvm/Support/ConstantRange.h b/include/llvm/Support/ConstantRange.h index 2af2cf61eae..792b4107b14 100644 --- a/include/llvm/Support/ConstantRange.h +++ b/include/llvm/Support/ConstantRange.h @@ -224,6 +224,14 @@ public: /// \p Other. ConstantRange udiv(const ConstantRange &Other) const; + /// binaryAnd - return a new range representing the possible values resulting + /// from a binary-and of a value in this range by a value in \p Other. + ConstantRange binaryAnd(const ConstantRange &Other) const; + + /// binaryOr - return a new range representing the possible values resulting + /// from a binary-or of a value in this range by a value in \p Other. + ConstantRange binaryOr(const ConstantRange &Other) const; + /// shl - Return a new range representing the possible values resulting /// from a left shift of a value in this range by a value in \p Other. /// TODO: This isn't fully implemented yet. diff --git a/lib/Analysis/LazyValueInfo.cpp b/lib/Analysis/LazyValueInfo.cpp index 9c3878b7759..2c25f80dbea 100644 --- a/lib/Analysis/LazyValueInfo.cpp +++ b/lib/Analysis/LazyValueInfo.cpp @@ -602,6 +602,12 @@ LVILatticeVal LVIQuery::getBlockValue(BasicBlock *BB) { case Instruction::BitCast: Result.markConstantRange(LHSRange); break; + case Instruction::And: + Result.markConstantRange(LHSRange.binaryAnd(RHSRange)); + break; + case Instruction::Or: + Result.markConstantRange(LHSRange.binaryOr(RHSRange)); + break; // Unhandled instructions are overdefined. default: diff --git a/lib/Support/ConstantRange.cpp b/lib/Support/ConstantRange.cpp index defb8189b62..c89ec9a2aac 100644 --- a/lib/Support/ConstantRange.cpp +++ b/lib/Support/ConstantRange.cpp @@ -607,6 +607,32 @@ ConstantRange::udiv(const ConstantRange &RHS) const { return ConstantRange(Lower, Upper); } +ConstantRange +ConstantRange::binaryAnd(const ConstantRange &Other) const { + if (isEmptySet() || Other.isEmptySet()) + return ConstantRange(getBitWidth(), /*isFullSet=*/false); + + // TODO: replace this with something less conservative + + APInt umin = APIntOps::umin(Other.getUnsignedMax(), getUnsignedMax()); + if (umin.isAllOnesValue()) + return ConstantRange(getBitWidth(), /*isFullSet=*/true); + return ConstantRange(APInt::getNullValue(getBitWidth()), umin + 1); +} + +ConstantRange +ConstantRange::binaryOr(const ConstantRange &Other) const { + if (isEmptySet() || Other.isEmptySet()) + return ConstantRange(getBitWidth(), /*isFullSet=*/false); + + // TODO: replace this with something less conservative + + APInt umax = APIntOps::umax(getUnsignedMin(), Other.getUnsignedMin()); + if (umax.isMinValue()) + return ConstantRange(getBitWidth(), /*isFullSet=*/true); + return ConstantRange(umax, APInt::getNullValue(getBitWidth())); +} + ConstantRange ConstantRange::shl(const ConstantRange &Other) const { if (isEmptySet() || Other.isEmptySet())