summaryrefslogtreecommitdiff
path: root/lib/Transforms/Scalar/PredicateSimplifier.cpp
diff options
context:
space:
mode:
authorNick Lewycky <nicholas@mxc.ca>2007-04-07 15:48:32 +0000
committerNick Lewycky <nicholas@mxc.ca>2007-04-07 15:48:32 +0000
commitac4d664d45a09055bb64dbe4bb78fd7668d3ed80 (patch)
treec2adf8c8c8c94a3aa6fe9f4ceeb2ad8c7b773bf9 /lib/Transforms/Scalar/PredicateSimplifier.cpp
parente32157c6098ee7536315e9793eed98d21bf71fd0 (diff)
downloadllvm-ac4d664d45a09055bb64dbe4bb78fd7668d3ed80.tar.gz
llvm-ac4d664d45a09055bb64dbe4bb78fd7668d3ed80.tar.bz2
llvm-ac4d664d45a09055bb64dbe4bb78fd7668d3ed80.tar.xz
Add support for cast instructions.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@35734 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/Scalar/PredicateSimplifier.cpp')
-rw-r--r--lib/Transforms/Scalar/PredicateSimplifier.cpp92
1 files changed, 75 insertions, 17 deletions
diff --git a/lib/Transforms/Scalar/PredicateSimplifier.cpp b/lib/Transforms/Scalar/PredicateSimplifier.cpp
index 2febab9838..bd60a9b9d9 100644
--- a/lib/Transforms/Scalar/PredicateSimplifier.cpp
+++ b/lib/Transforms/Scalar/PredicateSimplifier.cpp
@@ -813,6 +813,14 @@ namespace {
return Range;
}
+#ifndef NDEBUG
+ bool isCanonical(Value *V, ETNode *Subtree, VRPSolver *VRP);
+#endif
+
+ public:
+
+ explicit ValueRanges(TargetData *TD) : TD(TD) {}
+
// rangeFromValue - converts a Value into a range. If the value is a
// constant it constructs the single element range, otherwise it performs
// a lookup. The width W must be retrieved from typeToWidth and may not
@@ -842,14 +850,6 @@ namespace {
return 0;
}
-#ifndef NDEBUG
- bool isCanonical(Value *V, ETNode *Subtree, VRPSolver *VRP);
-#endif
-
- public:
-
- explicit ValueRanges(TargetData *TD) : TD(TD) {}
-
bool isRelatedBy(Value *V1, Value *V2, ETNode *Subtree, LatticeVal LV) {
uint32_t W = typeToWidth(V1->getType());
if (!W) return false;
@@ -907,6 +907,7 @@ namespace {
void addToWorklist(Value *V, Constant *C, ICmpInst::Predicate Pred,
VRPSolver *VRP);
+ void markBlock(VRPSolver *VRP);
void mergeInto(Value **I, unsigned n, Value *New, ETNode *Subtree,
VRPSolver *VRP) {
@@ -946,7 +947,14 @@ namespace {
}
}
- update(V, CR, Subtree);
+ ConstantRange Merged = CR.intersectWith(
+ rangeFromValue(V, Subtree, CR.getBitWidth()));
+ if (Merged.isEmptySet()) {
+ markBlock(VRP);
+ return;
+ }
+
+ update(V, Merged, Subtree);
}
void addNotEquals(Value *V1, Value *V2, ETNode *Subtree, VRPSolver *VRP) {
@@ -1608,8 +1616,29 @@ namespace {
add(Ptr, Constant::getNullValue(Ptr->getType()), ICmpInst::ICMP_NE,
NewContext);
}
+ } else if (CastInst *CI = dyn_cast<CastInst>(I)) {
+ const Type *SrcTy = CI->getSrcTy();
+
+ Value *TheCI = IG.canonicalize(CI, Top);
+ uint32_t W = VR.typeToWidth(SrcTy);
+ if (!W) return;
+ ConstantRange CR = VR.rangeFromValue(TheCI, Top, W);
+
+ if (CR.isFullSet()) return;
+
+ switch (CI->getOpcode()) {
+ default: break;
+ case Instruction::ZExt:
+ case Instruction::SExt:
+ VR.applyRange(IG.canonicalize(CI->getOperand(0), Top),
+ CR.truncate(W), Top, this);
+ break;
+ case Instruction::BitCast:
+ VR.applyRange(IG.canonicalize(CI->getOperand(0), Top),
+ CR, Top, this);
+ break;
+ }
}
- // TODO: CastInst "%a = cast ... %b" where %a is EQ or NE a constant.
}
/// opsToDef - A new relationship was discovered involving one of this
@@ -1639,7 +1668,7 @@ namespace {
assert(!Ty->isFPOrFPVector() && "Float in work queue!");
Constant *Zero = Constant::getNullValue(Ty);
- Constant *AllOnes = ConstantInt::getAllOnesValue(Ty);
+ ConstantInt *AllOnes = ConstantInt::getAllOnesValue(Ty);
switch (Opcode) {
default: break;
@@ -1753,16 +1782,41 @@ namespace {
add(SI, SI->getTrueValue(), ICmpInst::ICMP_EQ, NewContext);
}
} else if (CastInst *CI = dyn_cast<CastInst>(I)) {
- const Type *Ty = CI->getDestTy();
- if (Ty->isFPOrFPVector()) return;
+ const Type *DestTy = CI->getDestTy();
+ if (DestTy->isFPOrFPVector()) return;
- if (Constant *C = dyn_cast<Constant>(
- IG.canonicalize(CI->getOperand(0), Top))) {
- add(CI, ConstantExpr::getCast(CI->getOpcode(), C, Ty),
+ Value *Op = IG.canonicalize(CI->getOperand(0), Top);
+ Instruction::CastOps Opcode = CI->getOpcode();
+
+ if (Constant *C = dyn_cast<Constant>(Op)) {
+ add(CI, ConstantExpr::getCast(Opcode, C, DestTy),
ICmpInst::ICMP_EQ, NewContext);
}
- // TODO: "%a = cast ... %b" where %b is NE/LT/GT a constant.
+ uint32_t W = VR.typeToWidth(DestTy);
+ Value *TheCI = IG.canonicalize(CI, Top);
+ ConstantRange CR = VR.rangeFromValue(Op, Top, W);
+
+ if (!CR.isFullSet()) {
+ switch (Opcode) {
+ default: break;
+ case Instruction::ZExt:
+ VR.applyRange(TheCI, CR.zeroExtend(W), Top, this);
+ break;
+ case Instruction::SExt:
+ VR.applyRange(TheCI, CR.signExtend(W), Top, this);
+ break;
+ case Instruction::Trunc: {
+ ConstantRange Result = CR.truncate(W);
+ if (!Result.isFullSet())
+ VR.applyRange(TheCI, Result, Top, this);
+ } break;
+ case Instruction::BitCast:
+ VR.applyRange(TheCI, CR, Top, this);
+ break;
+ // TODO: other casts?
+ }
+ }
} else if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(I)) {
for (GetElementPtrInst::op_iterator OI = GEPI->idx_begin(),
OE = GEPI->idx_end(); OI != OE; ++OI) {
@@ -1912,6 +1966,10 @@ namespace {
VRP->add(V, C, Pred, VRP->TopInst);
}
+ void ValueRanges::markBlock(VRPSolver *VRP) {
+ VRP->UB.mark(VRP->TopBB);
+ }
+
#ifndef NDEBUG
bool ValueRanges::isCanonical(Value *V, ETNode *Subtree, VRPSolver *VRP) {
return V == VRP->IG.canonicalize(V, Subtree);