From 8cd4efb6a5e51b4e77039c17338f290ca3a8ee92 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Thu, 6 Jan 2011 06:19:46 +0000 Subject: [PATCH] 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 --- lib/Analysis/ConstantFolding.cpp | 20 ++++++++++++++++++- .../InstCombine/constant-fold-gep.ll | 19 ++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/lib/Analysis/ConstantFolding.cpp b/lib/Analysis/ConstantFolding.cpp index ded1d0767c6..6c5b75502fa 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(Ops[i])) + if (!isa(Ops[i])) { + + // If this is "gep i8* Ptr, (sub 0, V)", fold this as: + // "inttoptr (sub (ptrtoint Ptr), V)" + if (NumOps == 2 && + cast(ResultTy)->getElementType()->isIntegerTy(8)) { + ConstantExpr *CE = dyn_cast(Ops[1]); + if (CE && CE->getOpcode() == Instruction::Sub && + isa(CE->getOperand(0)) && + cast(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(Res)) + Res = ConstantFoldConstantExpression(ResCE, TD); + return Res; + } + } return 0; + } APInt Offset = APInt(BitWidth, TD->getIndexedOffset(Ptr->getType(), diff --git a/test/Transforms/InstCombine/constant-fold-gep.ll b/test/Transforms/InstCombine/constant-fold-gep.ll index 4be1a9c838d..c679226d4a9 100644 --- a/test/Transforms/InstCombine/constant-fold-gep.ll +++ b/test/Transforms/InstCombine/constant-fold-gep.ll @@ -53,3 +53,22 @@ define void @frob() { store i32 1, i32* getelementptr ([3 x %struct.X]* @Y, i64 0, i64 0, i32 0, i64 19), align 8 ret void } + + +; PR8883 - Constant fold exotic gep subtract +; CHECK: @test2 +@X = global [1000 x i8] zeroinitializer, align 16 + +define i64 @test2() { +entry: + %A = bitcast i8* getelementptr inbounds ([1000 x i8]* @X, i64 1, i64 0) to i8* + %B = bitcast i8* getelementptr inbounds ([1000 x i8]* @X, i64 0, i64 0) to i8* + + %B2 = ptrtoint i8* %B to i64 + %C = sub i64 0, %B2 + %D = getelementptr i8* %A, i64 %C + %E = ptrtoint i8* %D to i64 + + ret i64 %E + ; CHECK: ret i64 1000 +}