From: Chris Lattner Date: Thu, 15 Aug 2002 16:15:25 +0000 (+0000) Subject: Handle more cases of cast-of-cast in more general forms. X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=3ecce66e253be217aa3c2bda60b8e8908602b001;p=oota-llvm.git Handle more cases of cast-of-cast in more general forms. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@3347 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index cc00093c78a..f5acaf47e62 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -501,20 +501,47 @@ static inline bool isEliminableCastOfCast(const CastInst &CI, // Allow free casting and conversion of sizes as long as the sign doesn't // change... - if (isCIntegral(SrcTy) && isCIntegral(MidTy) && isCIntegral(DstTy) && - SrcTy->isSigned() == MidTy->isSigned() && - MidTy->isSigned() == DstTy->isSigned()) { - // Only accept cases where we are either monotonically increasing the type - // size, or monotonically decreasing it. - // + if (isCIntegral(SrcTy) && isCIntegral(MidTy) && isCIntegral(DstTy)) { unsigned SrcSize = SrcTy->getPrimitiveSize(); unsigned MidSize = MidTy->getPrimitiveSize(); unsigned DstSize = DstTy->getPrimitiveSize(); - if (SrcSize <= MidSize && MidSize <= DstSize) - return true; + // Cases where we are monotonically decreasing the size of the type are + // always ok, regardless of what sign changes are going on. + // if (SrcSize >= MidSize && MidSize >= DstSize) return true; + + // If we are monotonically growing, things are more complex. + // + if (SrcSize <= MidSize && MidSize <= DstSize) { + // We have eight combinations of signedness to worry about. Here's the + // table: + static const int SignTable[8] = { + // CODE, SrcSigned, MidSigned, DstSigned, Comment + 1, // U U U Always ok + 1, // U U S Always ok + 3, // U S U Ok iff SrcSize != MidSize + 3, // U S S Ok iff SrcSize != MidSize + 0, // S U U Never ok + 2, // S U S Ok iff MidSize == DstSize + 1, // S S U Always ok + 1, // S S S Always ok + }; + + // Choose an action based on the current entry of the signtable that this + // cast of cast refers to... + unsigned Row = SrcTy->isSigned()*4+MidTy->isSigned()*2+DstTy->isSigned(); + switch (SignTable[Row]) { + case 0: return false; // Never ok + case 1: return true; // Always ok + case 2: return MidSize == DstSize; // Ok iff MidSize == DstSize + case 3: // Ok iff SrcSize != MidSize + return SrcSize != MidSize || SrcTy == Type::BoolTy; + default: assert(0 && "Bad entry in sign table!"); + } + return false; // NOT REACHED + } } // Otherwise, we cannot succeed. Specifically we do not want to allow things