summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2011-01-06 06:19:46 +0000
committerChris Lattner <sabre@nondot.org>2011-01-06 06:19:46 +0000
commit8cd4efb6a5e51b4e77039c17338f290ca3a8ee92 (patch)
treeae17d657a282344d56741b227bebecd9246785e7 /lib
parent255874ff521bb81b294ec861a5d9a99d8198448c (diff)
downloadllvm-8cd4efb6a5e51b4e77039c17338f290ca3a8ee92.tar.gz
llvm-8cd4efb6a5e51b4e77039c17338f290ca3a8ee92.tar.bz2
llvm-8cd4efb6a5e51b4e77039c17338f290ca3a8ee92.tar.xz
implement constant folding support for an exotic constant expr:
ret i64 ptrtoint (i8* getelementptr ([1000 x i8]* @X, i64 1, i64 sub (i64 0, i64 ptrtoint ([1000 x i8]* @X to i64))) to i64) to "ret i64 1000". This allows us to correctly compute the trip count on a loop in PR8883, which occurs with std::fill on a char array. This allows us to transform it into a memset with a constant size. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@122950 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Analysis/ConstantFolding.cpp20
1 files changed, 19 insertions, 1 deletions
diff --git a/lib/Analysis/ConstantFolding.cpp b/lib/Analysis/ConstantFolding.cpp
index ded1d0767c..6c5b75502f 100644
--- a/lib/Analysis/ConstantFolding.cpp
+++ b/lib/Analysis/ConstantFolding.cpp
@@ -575,8 +575,26 @@ static Constant *SymbolicallyEvaluateGEP(Constant *const *Ops, unsigned NumOps,
// If this is a constant expr gep that is effectively computing an
// "offsetof", fold it into 'cast int Size to T*' instead of 'gep 0, 0, 12'
for (unsigned i = 1; i != NumOps; ++i)
- if (!isa<ConstantInt>(Ops[i]))
+ if (!isa<ConstantInt>(Ops[i])) {
+
+ // If this is "gep i8* Ptr, (sub 0, V)", fold this as:
+ // "inttoptr (sub (ptrtoint Ptr), V)"
+ if (NumOps == 2 &&
+ cast<PointerType>(ResultTy)->getElementType()->isIntegerTy(8)) {
+ ConstantExpr *CE = dyn_cast<ConstantExpr>(Ops[1]);
+ if (CE && CE->getOpcode() == Instruction::Sub &&
+ isa<ConstantInt>(CE->getOperand(0)) &&
+ cast<ConstantInt>(CE->getOperand(0))->isZero()) {
+ Constant *Res = ConstantExpr::getPtrToInt(Ptr, CE->getType());
+ Res = ConstantExpr::getSub(Res, CE->getOperand(1));
+ Res = ConstantExpr::getIntToPtr(Res, ResultTy);
+ if (ConstantExpr *ResCE = dyn_cast<ConstantExpr>(Res))
+ Res = ConstantFoldConstantExpression(ResCE, TD);
+ return Res;
+ }
+ }
return 0;
+ }
APInt Offset = APInt(BitWidth,
TD->getIndexedOffset(Ptr->getType(),