summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/Scalar/InstructionCombining.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2002-05-02 17:06:02 +0000
committerChris Lattner <sabre@nondot.org>2002-05-02 17:06:02 +0000
commit48a44f7e23b833925e9b6e73335399554918784a (patch)
treefebafcf0a88fa2ae8d9801e335286ae707d79d12 /llvm/lib/Transforms/Scalar/InstructionCombining.cpp
parent90f608c002bc45a5617bbadecb48d1bc0eea9a07 (diff)
downloadbcm5719-llvm-48a44f7e23b833925e9b6e73335399554918784a.tar.gz
bcm5719-llvm-48a44f7e23b833925e9b6e73335399554918784a.zip
* Add ability to eliminate a bunch of different cascading cast variations
* Allow elimination of getelementptr X, uint 0 (which is a noop) llvm-svn: 2428
Diffstat (limited to 'llvm/lib/Transforms/Scalar/InstructionCombining.cpp')
-rw-r--r--llvm/lib/Transforms/Scalar/InstructionCombining.cpp62
1 files changed, 60 insertions, 2 deletions
diff --git a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp
index 2ad2356de34..59172b5d018 100644
--- a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp
@@ -61,6 +61,7 @@ namespace {
Instruction *visitSub(BinaryOperator *I);
Instruction *visitMul(BinaryOperator *I);
Instruction *visitCastInst(CastInst *CI);
+ Instruction *visitGetElementPtrInst(GetElementPtrInst *GEP);
Instruction *visitMemAccessInst(MemAccessInst *MAI);
// visitInstruction - Specify what to return for unhandled instructions...
@@ -163,18 +164,75 @@ Instruction *InstCombiner::visitMul(BinaryOperator *I) {
}
-// CastInst simplification - If the user is casting a value to the same type,
-// eliminate this cast instruction...
+// isEliminableCastOfCast - Return true if it is valid to eliminate the CI
+// instruction.
+//
+static inline bool isEliminableCastOfCast(const CastInst *CI,
+ const CastInst *CSrc) {
+ assert(CI->getOperand(0) == CSrc);
+ const Type *SrcTy = CSrc->getOperand(0)->getType();
+ const Type *MidTy = CSrc->getType();
+ const Type *DstTy = CI->getType();
+
+ // It is legal to eliminate the instruction if casting A->B->A
+ if (SrcTy == DstTy) return true;
+
+ // Allow free casting and conversion of sizes as long as the sign doesn't
+ // change...
+ if (SrcTy->isSigned() == MidTy->isSigned() &&
+ MidTy->isSigned() == DstTy->isSigned())
+ return true;
+
+ // Otherwise, we cannot succeed. Specifically we do not want to allow things
+ // like: short -> ushort -> uint, because this can create wrong results if
+ // the input short is negative!
+ //
+ return false;
+}
+
+
+// CastInst simplification
//
Instruction *InstCombiner::visitCastInst(CastInst *CI) {
+ // If the user is casting a value to the same type, eliminate this cast
+ // instruction...
if (CI->getType() == CI->getOperand(0)->getType() && !CI->use_empty()) {
AddUsesToWorkList(CI); // Add all modified instrs to worklist
CI->replaceAllUsesWith(CI->getOperand(0));
return CI;
}
+
+
+ // If casting the result of another cast instruction, try to eliminate this
+ // one!
+ //
+ if (CastInst *CSrc = dyn_cast<CastInst>(CI->getOperand(0)))
+ if (isEliminableCastOfCast(CI, CSrc)) {
+ // This instruction now refers directly to the cast's src operand. This
+ // has a good chance of making CSrc dead.
+ CI->setOperand(0, CSrc->getOperand(0));
+ return CI;
+ }
+
return 0;
}
+
+
+Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst *GEP) {
+ // Is it getelementptr %P, uint 0
+ // If so, elminate the noop.
+ if (GEP->getNumOperands() == 2 && !GEP->use_empty() &&
+ GEP->getOperand(1) == Constant::getNullValue(Type::UIntTy)) {
+ AddUsesToWorkList(GEP); // Add all modified instrs to worklist
+ GEP->replaceAllUsesWith(GEP->getOperand(0));
+ return GEP;
+ }
+
+ return visitMemAccessInst(GEP);
+}
+
+
// Combine Indices - If the source pointer to this mem access instruction is a
// getelementptr instruction, combine the indices of the GEP into this
// instruction
OpenPOWER on IntegriCloud