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

Chris Lattner sabre at nondot.org
Wed Jan 5 22:19:46 PST 2011


Author: lattner
Date: Thu Jan  6 00:19:46 2011
New Revision: 122950

URL: http://llvm.org/viewvc/llvm-project?rev=122950&view=rev
Log:
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.


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

Modified: llvm/trunk/lib/Analysis/ConstantFolding.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ConstantFolding.cpp?rev=122950&r1=122949&r2=122950&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/ConstantFolding.cpp (original)
+++ llvm/trunk/lib/Analysis/ConstantFolding.cpp Thu Jan  6 00:19:46 2011
@@ -575,8 +575,26 @@
   // 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(),

Modified: llvm/trunk/test/Transforms/InstCombine/constant-fold-gep.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/constant-fold-gep.ll?rev=122950&r1=122949&r2=122950&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/constant-fold-gep.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/constant-fold-gep.ll Thu Jan  6 00:19:46 2011
@@ -53,3 +53,22 @@
   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
+ at 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
+}





More information about the llvm-commits mailing list