From: Nick Lewycky Date: Sat, 7 Apr 2007 15:48:32 +0000 (+0000) Subject: Add support for cast instructions. X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=ac4d664d45a09055bb64dbe4bb78fd7668d3ed80;p=oota-llvm.git Add support for cast instructions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@35734 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Transforms/Scalar/PredicateSimplifier.cpp b/lib/Transforms/Scalar/PredicateSimplifier.cpp index 2febab9838f..bd60a9b9d99 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(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(I)) { - const Type *Ty = CI->getDestTy(); - if (Ty->isFPOrFPVector()) return; + const Type *DestTy = CI->getDestTy(); + if (DestTy->isFPOrFPVector()) return; - if (Constant *C = dyn_cast( - 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(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(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);