aboutsummaryrefslogtreecommitdiff
path: root/lib/Transforms/LevelRaise.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2003-05-02 19:32:04 +0000
committerChris Lattner <sabre@nondot.org>2003-05-02 19:32:04 +0000
commit2d399096cf0070e9d0db3e6fd31e211ff00f10ec (patch)
treed00c3709b60025cd98842521e10931c523e28615 /lib/Transforms/LevelRaise.cpp
parente96fda3002dd0769d3dd758ac5008ba8cda92349 (diff)
Attempt to fix sumant's typesafety issue
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@5984 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/LevelRaise.cpp')
-rw-r--r--lib/Transforms/LevelRaise.cpp26
1 files changed, 21 insertions, 5 deletions
diff --git a/lib/Transforms/LevelRaise.cpp b/lib/Transforms/LevelRaise.cpp
index b2c6b05ab4..01607e1c97 100644
--- a/lib/Transforms/LevelRaise.cpp
+++ b/lib/Transforms/LevelRaise.cpp
@@ -107,33 +107,40 @@ static bool HandleCastToPointer(BasicBlock::iterator BI,
CastInst &CI = cast<CastInst>(*BI);
if (CI.use_empty()) return false;
- // Scan all of the uses, looking for any uses that are not add
+ // Scan all of the uses, looking for any uses that are not add or sub
// instructions. If we have non-adds, do not make this transformation.
//
+ bool HasSubUse = false; // Keep track of any subtracts...
for (Value::use_iterator I = CI.use_begin(), E = CI.use_end();
- I != E; ++I) {
+ I != E; ++I)
if (BinaryOperator *BO = dyn_cast<BinaryOperator>(*I)) {
- if (BO->getOpcode() != Instruction::Add ||
+ if ((BO->getOpcode() != Instruction::Add &&
+ BO->getOpcode() != Instruction::Sub) ||
// Avoid add sbyte* %X, %X cases...
BO->getOperand(0) == BO->getOperand(1))
return false;
+ else
+ HasSubUse |= BO->getOpcode() == Instruction::Sub;
} else {
return false;
}
- }
std::vector<Value*> Indices;
Value *Src = CI.getOperand(0);
const Type *Result = ConvertableToGEP(DestPTy, Src, Indices, TD, &BI);
if (Result == 0) return false; // Not convertable...
+ // Cannot handle subtracts if there is more than one index required...
+ if (HasSubUse && Indices.size() != 1) return false;
+
PRINT_PEEPHOLE2("cast-add-to-gep:in", Src, CI);
// If we have a getelementptr capability... transform all of the
// add instruction uses into getelementptr's.
while (!CI.use_empty()) {
BinaryOperator *I = cast<BinaryOperator>(*CI.use_begin());
- assert(I->getOpcode() == Instruction::Add && I->getNumOperands() == 2 &&
+ assert((I->getOpcode() == Instruction::Add ||
+ I->getOpcode() == Instruction::Sub) &&
"Use is not a valid add instruction!");
// Get the value added to the cast result pointer...
@@ -142,6 +149,15 @@ static bool HandleCastToPointer(BasicBlock::iterator BI,
Instruction *GEP = new GetElementPtrInst(OtherPtr, Indices, I->getName());
PRINT_PEEPHOLE1("cast-add-to-gep:i", I);
+ // If the instruction is actually a subtract, we are guaranteed to only have
+ // one index (from code above), so we just need to negate the pointer index
+ // long value.
+ if (I->getOpcode() == Instruction::Sub) {
+ Instruction *Neg = BinaryOperator::createNeg(GEP->getOperand(1),
+ GEP->getOperand(1)->getName()+".neg", I);
+ GEP->setOperand(1, Neg);
+ }
+
if (GEP->getType() == I->getType()) {
// Replace the old add instruction with the shiny new GEP inst
ReplaceInstWithInst(I, GEP);