[llvm-commits] [llvm] r94750 - in /llvm/trunk: lib/VMCore/ConstantFold.cpp test/Other/constant-fold-gep.ll

Dan Gohman gohman at apple.com
Thu Jan 28 10:08:27 PST 2010


Author: djg
Date: Thu Jan 28 12:08:26 2010
New Revision: 94750

URL: http://llvm.org/viewvc/llvm-project?rev=94750&view=rev
Log:
Remove the folding rule
  getelementptr (i8* inttoptr (i64 1 to i8*), i32 -1) 
  to
  inttoptr (i64 0 to i8*)
from the VMCore constant folder. It didn't handle sign-extension properly
in the case where the source integer is smaller than a pointer size. And,
it relied on an assumption about sizeof(i8).

The Analysis constant folder still folds these kinds of things; it has
access to TargetData, so it can do them right.

Add a testcase which tests that the VMCore constant folder doesn't
miscompile this, and that the Analysis folder does fold it.

Added:
    llvm/trunk/test/Other/constant-fold-gep.ll
Modified:
    llvm/trunk/lib/VMCore/ConstantFold.cpp

Modified: llvm/trunk/lib/VMCore/ConstantFold.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/ConstantFold.cpp?rev=94750&r1=94749&r2=94750&view=diff

==============================================================================
--- llvm/trunk/lib/VMCore/ConstantFold.cpp (original)
+++ llvm/trunk/lib/VMCore/ConstantFold.cpp Thu Jan 28 12:08:26 2010
@@ -2021,28 +2021,6 @@
                 ConstantExpr::getGetElementPtr(
                       (Constant*)CE->getOperand(0), Idxs, NumIdx);
     }
-
-    // Fold: getelementptr (i8* inttoptr (i64 1 to i8*), i32 -1)
-    // Into: inttoptr (i64 0 to i8*)
-    // This happens with pointers to member functions in C++.
-    if (CE->getOpcode() == Instruction::IntToPtr && NumIdx == 1 &&
-        isa<ConstantInt>(CE->getOperand(0)) && isa<ConstantInt>(Idxs[0]) &&
-        cast<PointerType>(CE->getType())->getElementType() ==
-            Type::getInt8Ty(Context)) {
-      Constant *Base = CE->getOperand(0);
-      Constant *Offset = Idxs[0];
-
-      // Convert the smaller integer to the larger type.
-      if (Offset->getType()->getPrimitiveSizeInBits() < 
-          Base->getType()->getPrimitiveSizeInBits())
-        Offset = ConstantExpr::getSExt(Offset, Base->getType());
-      else if (Base->getType()->getPrimitiveSizeInBits() <
-               Offset->getType()->getPrimitiveSizeInBits())
-        Base = ConstantExpr::getZExt(Base, Offset->getType());
-
-      Base = ConstantExpr::getAdd(Base, Offset);
-      return ConstantExpr::getIntToPtr(Base, CE->getType());
-    }
   }
 
   // Check to see if any array indices are not within the corresponding

Added: llvm/trunk/test/Other/constant-fold-gep.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Other/constant-fold-gep.ll?rev=94750&view=auto

==============================================================================
--- llvm/trunk/test/Other/constant-fold-gep.ll (added)
+++ llvm/trunk/test/Other/constant-fold-gep.ll Thu Jan 28 12:08:26 2010
@@ -0,0 +1,84 @@
+; RUN: opt -S -o - < %s | FileCheck --check-prefix=PLAIN %s
+; RUN: opt -S -o - -instcombine -globalopt < %s | FileCheck --check-prefix=OPT %s
+
+; The automatic constant folder in opt does not have targetdata access, so
+; it can't fold gep arithmetic, in general. However, the constant folder run
+; from instcombine and global opt does, and can.
+
+; PLAIN: @G8 = global i8* getelementptr (i8* inttoptr (i32 1 to i8*), i32 -1)
+; PLAIN: @G1 = global i1* getelementptr (i1* inttoptr (i32 1 to i1*), i32 -1)
+; PLAIN: @F8 = global i8* getelementptr (i8* inttoptr (i32 1 to i8*), i32 -2)
+; PLAIN: @F1 = global i1* getelementptr (i1* inttoptr (i32 1 to i1*), i32 -2)
+; PLAIN: @H8 = global i8* getelementptr (i8* null, i32 -1)
+; PLAIN: @H1 = global i1* getelementptr (i1* null, i32 -1)
+; PLAIN: define i8* @goo8() nounwind {
+; PLAIN:   ret i8* getelementptr (i8* inttoptr (i32 1 to i8*), i32 -1)
+; PLAIN: }
+; PLAIN: define i1* @goo1() nounwind {
+; PLAIN:   ret i1* getelementptr (i1* inttoptr (i32 1 to i1*), i32 -1)
+; PLAIN: }
+; PLAIN: define i8* @foo8() nounwind {
+; PLAIN:   ret i8* getelementptr (i8* inttoptr (i32 1 to i8*), i32 -2)
+; PLAIN: }
+; PLAIN: define i1* @foo1() nounwind {
+; PLAIN:   ret i1* getelementptr (i1* inttoptr (i32 1 to i1*), i32 -2)
+; PLAIN: }
+; PLAIN: define i8* @hoo8() nounwind {
+; PLAIN:   ret i8* getelementptr (i8* null, i32 -1)
+; PLAIN: }
+; PLAIN: define i1* @hoo1() nounwind {
+; PLAIN:   ret i1* getelementptr (i1* null, i32 -1)
+; PLAIN: }
+
+; OPT: @G8 = global i8* null
+; OPT: @G1 = global i1* null
+; OPT: @F8 = global i8* inttoptr (i64 -1 to i8*)
+; OPT: @F1 = global i1* inttoptr (i64 -1 to i1*)
+; OPT: @H8 = global i8* inttoptr (i64 -1 to i8*)
+; OPT: @H1 = global i1* inttoptr (i64 -1 to i1*)
+; OPT: define i8* @goo8() nounwind {
+; OPT:   ret i8* null
+; OPT: }
+; OPT: define i1* @goo1() nounwind {
+; OPT:   ret i1* null
+; OPT: }
+; OPT: define i8* @foo8() nounwind {
+; OPT:   ret i8* inttoptr (i64 -1 to i8*)
+; OPT: }
+; OPT: define i1* @foo1() nounwind {
+; OPT:   ret i1* inttoptr (i64 -1 to i1*)
+; OPT: }
+; OPT: define i8* @hoo8() nounwind {
+; OPT:   ret i8* inttoptr (i64 -1 to i8*)
+; OPT: }
+; OPT: define i1* @hoo1() nounwind {
+; OPT:   ret i1* inttoptr (i64 -1 to i1*)
+; OPT: }
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64"
+
+ at G8 = global i8* getelementptr (i8* inttoptr (i32 1 to i8*), i32 -1)
+ at G1 = global i1* getelementptr (i1* inttoptr (i32 1 to i1*), i32 -1)
+ at F8 = global i8* getelementptr (i8* inttoptr (i32 1 to i8*), i32 -2)
+ at F1 = global i1* getelementptr (i1* inttoptr (i32 1 to i1*), i32 -2)
+ at H8 = global i8* getelementptr (i8* inttoptr (i32 0 to i8*), i32 -1)
+ at H1 = global i1* getelementptr (i1* inttoptr (i32 0 to i1*), i32 -1)
+
+define i8* @goo8() nounwind {
+  ret i8* getelementptr (i8* inttoptr (i32 1 to i8*), i32 -1)
+}
+define i1* @goo1() nounwind {
+  ret i1* getelementptr (i1* inttoptr (i32 1 to i1*), i32 -1)
+}
+define i8* @foo8() nounwind {
+  ret i8* getelementptr (i8* inttoptr (i32 1 to i8*), i32 -2)
+}
+define i1* @foo1() nounwind {
+  ret i1* getelementptr (i1* inttoptr (i32 1 to i1*), i32 -2)
+}
+define i8* @hoo8() nounwind {
+  ret i8* getelementptr (i8* inttoptr (i32 0 to i8*), i32 -1)
+}
+define i1* @hoo1() nounwind {
+  ret i1* getelementptr (i1* inttoptr (i32 0 to i1*), i32 -1)
+}





More information about the llvm-commits mailing list