[llvm-commits] [llvm] r71158 - in /llvm/trunk: lib/Analysis/ConstantFolding.cpp test/Transforms/InstCombine/constant-fold-ptr-casts.ll

Dan Gohman gohman at apple.com
Thu May 7 07:25:13 PDT 2009


Author: djg
Date: Thu May  7 09:24:56 2009
New Revision: 71158

URL: http://llvm.org/viewvc/llvm-project?rev=71158&view=rev
Log:
Constant-fold ptrtoint+add+inttoptr to gep when the pointer is an
array and the add is within range. This helps simplify expressions
expanded by ScalarEvolutionExpander.

Added:
    llvm/trunk/test/Transforms/InstCombine/constant-fold-ptr-casts.ll
Modified:
    llvm/trunk/lib/Analysis/ConstantFolding.cpp

Modified: llvm/trunk/lib/Analysis/ConstantFolding.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ConstantFolding.cpp?rev=71158&r1=71157&r2=71158&view=diff

==============================================================================
--- llvm/trunk/lib/Analysis/ConstantFolding.cpp (original)
+++ llvm/trunk/lib/Analysis/ConstantFolding.cpp Thu May  7 09:24:56 2009
@@ -16,6 +16,7 @@
 #include "llvm/Constants.h"
 #include "llvm/DerivedTypes.h"
 #include "llvm/Function.h"
+#include "llvm/GlobalVariable.h"
 #include "llvm/Instructions.h"
 #include "llvm/Intrinsics.h"
 #include "llvm/ADT/SmallVector.h"
@@ -383,12 +384,43 @@
     // the int size is >= the ptr size.  This requires knowing the width of a
     // pointer, so it can't be done in ConstantExpr::getCast.
     if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Ops[0])) {
-      if (TD && CE->getOpcode() == Instruction::PtrToInt &&
+      if (TD &&
           TD->getPointerSizeInBits() <=
           CE->getType()->getPrimitiveSizeInBits()) {
-        Constant *Input = CE->getOperand(0);
-        Constant *C = FoldBitCast(Input, DestTy, *TD);
-        return C ? C : ConstantExpr::getBitCast(Input, DestTy);
+        if (CE->getOpcode() == Instruction::PtrToInt) {
+          Constant *Input = CE->getOperand(0);
+          Constant *C = FoldBitCast(Input, DestTy, *TD);
+          return C ? C : ConstantExpr::getBitCast(Input, DestTy);
+        }
+        // If there's a constant offset added to the integer value before
+        // it is casted back to a pointer, see if the expression can be
+        // converted into a GEP.
+        if (CE->getOpcode() == Instruction::Add)
+          if (ConstantInt *L = dyn_cast<ConstantInt>(CE->getOperand(0)))
+            if (ConstantExpr *R = dyn_cast<ConstantExpr>(CE->getOperand(1)))
+              if (R->getOpcode() == Instruction::PtrToInt)
+                if (GlobalVariable *GV =
+                      dyn_cast<GlobalVariable>(R->getOperand(0))) {
+                  const PointerType *GVTy = cast<PointerType>(GV->getType());
+                  if (const ArrayType *AT =
+                        dyn_cast<ArrayType>(GVTy->getElementType())) {
+                    const Type *ElTy = AT->getElementType();
+                    uint64_t PaddedSize = TD->getTypePaddedSize(ElTy);
+                    APInt PSA(L->getValue().getBitWidth(), PaddedSize);
+                    if (ElTy == cast<PointerType>(DestTy)->getElementType() &&
+                        L->getValue().urem(PSA) == 0) {
+                      APInt ElemIdx = L->getValue().udiv(PSA);
+                      if (ElemIdx.ult(APInt(ElemIdx.getBitWidth(),
+                                            AT->getNumElements()))) {
+                        Constant *Index[] = {
+                          Constant::getNullValue(CE->getType()),
+                          ConstantInt::get(ElemIdx)
+                        };
+                        return ConstantExpr::getGetElementPtr(GV, &Index[0], 2);
+                      }
+                    }
+                  }
+                }
       }
     }
     return ConstantExpr::getCast(Opcode, Ops[0], DestTy);

Added: llvm/trunk/test/Transforms/InstCombine/constant-fold-ptr-casts.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/constant-fold-ptr-casts.ll?rev=71158&view=auto

==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/constant-fold-ptr-casts.ll (added)
+++ llvm/trunk/test/Transforms/InstCombine/constant-fold-ptr-casts.ll Thu May  7 09:24:56 2009
@@ -0,0 +1,18 @@
+; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep {ret i32 2143034560}
+
+; Instcombine should be able to completely fold this code.
+
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
+target triple = "i686-apple-darwin8"
+
+ at bar = constant [3 x i64] [i64 9220983451228067448, i64 9220983451228067449, i64 9220983450959631991], align 8
+
+define i32 @foo() nounwind {
+entry:
+	%tmp87.2 = load i64* inttoptr (i32 add (i32 16, i32 ptrtoint ([3 x i64]* @bar to i32)) to i64*), align 8
+	%t0 = bitcast i64 %tmp87.2 to double
+	%tmp9192.2 = fptrunc double %t0 to float
+	%t1 = bitcast float %tmp9192.2 to i32
+	ret i32 %t1
+}
+





More information about the llvm-commits mailing list