aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Lenharth <andrewl@lenharth.org>2006-09-19 18:24:51 +0000
committerAndrew Lenharth <andrewl@lenharth.org>2006-09-19 18:24:51 +0000
commit16d7955eb0f1e9e000976c4e714e7fd36471ea19 (patch)
tree0cff570c1d809b27c1fbf7a80033dae8d6f9e796
parente454200b954c8ffc4f7e348376833fcab855dd51 (diff)
If we have an add, do it in the pointer realm, not the int realm. This is critical in the linux kernel for pointer analysis correctness
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@30496 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Transforms/Scalar/InstructionCombining.cpp22
1 files changed, 22 insertions, 0 deletions
diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp
index 40dfb4163c..e5f2d9294e 100644
--- a/lib/Transforms/Scalar/InstructionCombining.cpp
+++ b/lib/Transforms/Scalar/InstructionCombining.cpp
@@ -1595,6 +1595,28 @@ FoundSExt:
return R;
}
+ // add (cast *A to intptrtype) B -> cast (GEP (cast *A to sbyte*) B) -> intptrtype
+ {
+ CastInst* CI = dyn_cast<CastInst>(LHS);
+ Value* Other = RHS;
+ if (!CI) {
+ CI = dyn_cast<CastInst>(RHS);
+ Other = LHS;
+ }
+ if (CI) {
+ const Type *UIntPtrTy = TD->getIntPtrType();
+ const Type *SIntPtrTy = UIntPtrTy->getSignedVersion();
+ if((CI->getType() == UIntPtrTy || CI->getType() == SIntPtrTy)
+ && isa<PointerType>(CI->getOperand(0)->getType())) {
+ Instruction* I2 = new CastInst(CI->getOperand(0), PointerType::get(Type::SByteTy), "ctg", &I);
+ WorkList.push_back(I2);
+ I2 = new GetElementPtrInst(I2, Other, "ctg", &I);
+ WorkList.push_back(I2);
+ return new CastInst(I2, CI->getType());
+ }
+ }
+ }
+
return Changed ? &I : 0;
}