diff options
| author | Chris Lattner <sabre@nondot.org> | 2002-08-15 16:15:25 +0000 |
|---|---|---|
| committer | Chris Lattner <sabre@nondot.org> | 2002-08-15 16:15:25 +0000 |
| commit | 3732acab852e771ae00140633b7c3f24a742ab3d (patch) | |
| tree | 2cc48d60d7553f65240609f935c0c9808fd6cd7b /llvm/lib/Transforms | |
| parent | 8d1118fd8fa18eb36be6945ba7ea2d746ca6942c (diff) | |
| download | bcm5719-llvm-3732acab852e771ae00140633b7c3f24a742ab3d.tar.gz bcm5719-llvm-3732acab852e771ae00140633b7c3f24a742ab3d.zip | |
Handle more cases of cast-of-cast in more general forms.
llvm-svn: 3347
Diffstat (limited to 'llvm/lib/Transforms')
| -rw-r--r-- | llvm/lib/Transforms/Scalar/InstructionCombining.cpp | 43 |
1 files changed, 35 insertions, 8 deletions
diff --git a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp index cc00093c78a..f5acaf47e62 100644 --- a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/llvm/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 |

