[llvm-commits] [PATCH] Patch to fix bug14172

Micah Villmow villmow at gmail.com
Tue Oct 30 15:44:35 PDT 2012


http://llvm.org/bugs/show_bug.cgi?id=14172

Null Pointers to structures that have all the types the same are loosing their address space when going through the constant folder. This patch fixes this specific case. A more robust approach needs to be implemented that allows Constant/ConstantFolder to take into account the address space.


http://llvm-reviews.chandlerc.com/D88

Files:
  lib/VMCore/ConstantFold.cpp
  lib/VMCore/Constants.cpp
  include/llvm/Constants.h

Index: lib/VMCore/ConstantFold.cpp
===================================================================
--- lib/VMCore/ConstantFold.cpp
+++ lib/VMCore/ConstantFold.cpp
@@ -334,10 +334,10 @@
 /// bouncing an unfoldable expression back into the top-level folder.
 ///
 static Constant *getFoldedSizeOf(Type *Ty, Type *DestTy,
-                                 bool Folded) {
+                                 bool Folded, unsigned AS) {
   if (ArrayType *ATy = dyn_cast<ArrayType>(Ty)) {
     Constant *N = ConstantInt::get(DestTy, ATy->getNumElements());
-    Constant *E = getFoldedSizeOf(ATy->getElementType(), DestTy, true);
+    Constant *E = getFoldedSizeOf(ATy->getElementType(), DestTy, true, AS);
     return ConstantExpr::getNUWMul(E, N);
   }
 
@@ -349,11 +349,11 @@
         return ConstantExpr::getNullValue(DestTy);
       // Check for a struct with all members having the same size.
       Constant *MemberSize =
-        getFoldedSizeOf(STy->getElementType(0), DestTy, true);
+        getFoldedSizeOf(STy->getElementType(0), DestTy, true, AS);
       bool AllSame = true;
       for (unsigned i = 1; i != NumElems; ++i)
         if (MemberSize !=
-            getFoldedSizeOf(STy->getElementType(i), DestTy, true)) {
+            getFoldedSizeOf(STy->getElementType(i), DestTy, true, AS)) {
           AllSame = false;
           break;
         }
@@ -368,9 +368,8 @@
   if (PointerType *PTy = dyn_cast<PointerType>(Ty))
     if (!PTy->getElementType()->isIntegerTy(1))
       return
-        getFoldedSizeOf(PointerType::get(IntegerType::get(PTy->getContext(), 1),
-                                         PTy->getAddressSpace()),
-                        DestTy, true);
+        getFoldedSizeOf(PointerType::get(IntegerType::get(PTy->getContext(), 1), AS),
+                        DestTy, true, AS);
 
   // If there's no interesting folding happening, bail so that we don't create
   // a constant that looks like it needs folding but really doesn't.
@@ -378,7 +377,7 @@
     return 0;
 
   // Base case: Get a regular sizeof expression.
-  Constant *C = ConstantExpr::getSizeOf(Ty);
+  Constant *C = ConstantExpr::getSizeOf(Ty, AS);
   C = ConstantExpr::getCast(CastInst::getCastOpcode(C, false,
                                                     DestTy, false),
                             C, DestTy);
@@ -458,12 +457,12 @@
 ///
 static Constant *getFoldedOffsetOf(Type *Ty, Constant *FieldNo,
                                    Type *DestTy,
-                                   bool Folded) {
+                                   bool Folded, unsigned AS) {
   if (ArrayType *ATy = dyn_cast<ArrayType>(Ty)) {
     Constant *N = ConstantExpr::getCast(CastInst::getCastOpcode(FieldNo, false,
                                                                 DestTy, false),
                                         FieldNo, DestTy);
-    Constant *E = getFoldedSizeOf(ATy->getElementType(), DestTy, true);
+    Constant *E = getFoldedSizeOf(ATy->getElementType(), DestTy, true, AS);
     return ConstantExpr::getNUWMul(E, N);
   }
 
@@ -475,11 +474,11 @@
         return 0;
       // Check for a struct with all members having the same size.
       Constant *MemberSize =
-        getFoldedSizeOf(STy->getElementType(0), DestTy, true);
+        getFoldedSizeOf(STy->getElementType(0), DestTy, true, AS);
       bool AllSame = true;
       for (unsigned i = 1; i != NumElems; ++i)
         if (MemberSize !=
-            getFoldedSizeOf(STy->getElementType(i), DestTy, true)) {
+            getFoldedSizeOf(STy->getElementType(i), DestTy, true, AS)) {
           AllSame = false;
           break;
         }
@@ -611,11 +610,12 @@
           CE->getOperand(0)->isNullValue()) {
         Type *Ty =
           cast<PointerType>(CE->getOperand(0)->getType())->getElementType();
+        unsigned AS = CE->getOperand(0)->getType()->getPointerAddressSpace();
         if (CE->getNumOperands() == 2) {
           // Handle a sizeof-like expression.
           Constant *Idx = CE->getOperand(1);
           bool isOne = isa<ConstantInt>(Idx) && cast<ConstantInt>(Idx)->isOne();
-          if (Constant *C = getFoldedSizeOf(Ty, DestTy, !isOne)) {
+          if (Constant *C = getFoldedSizeOf(Ty, DestTy, !isOne, AS)) {
             Idx = ConstantExpr::getCast(CastInst::getCastOpcode(Idx, true,
                                                                 DestTy, false),
                                         Idx, DestTy);
@@ -636,7 +636,7 @@
           // Handle an offsetof-like expression.
           if (Ty->isStructTy() || Ty->isArrayTy()) {
             if (Constant *C = getFoldedOffsetOf(Ty, CE->getOperand(2),
-                                                DestTy, false))
+                                                DestTy, false, AS))
               return C;
           }
         }
Index: lib/VMCore/Constants.cpp
===================================================================
--- lib/VMCore/Constants.cpp
+++ lib/VMCore/Constants.cpp
@@ -1658,12 +1658,12 @@
   return pImpl->ExprConstants.getOrCreate(C1->getType(), Key);
 }
 
-Constant *ConstantExpr::getSizeOf(Type* Ty) {
-  // sizeof is implemented as: (i64) gep (Ty*)null, 1
+Constant *ConstantExpr::getSizeOf(Type* Ty, unsigned AS) {
+  // sizeof is implemented as: (i64) gep (Ty addrspace(AS)*)null, 1
   // Note that a non-inbounds gep is used, as null isn't within any object.
   Constant *GEPIdx = ConstantInt::get(Type::getInt32Ty(Ty->getContext()), 1);
   Constant *GEP = getGetElementPtr(
-                 Constant::getNullValue(PointerType::getUnqual(Ty)), GEPIdx);
+                 Constant::getNullValue(PointerType::get(Ty, AS)), GEPIdx);
   return getPtrToInt(GEP, 
                      Type::getInt64Ty(Ty->getContext()));
 }
Index: include/llvm/Constants.h
===================================================================
--- include/llvm/Constants.h
+++ include/llvm/Constants.h
@@ -814,7 +814,7 @@
   /// address-units, not bits) in a target independent way (Note: the return
   /// type is an i64).
   ///
-  static Constant *getSizeOf(Type *Ty);
+  static Constant *getSizeOf(Type *Ty, unsigned AS = 0);
 
   /// getOffsetOf constant expr - computes the offset of a struct field in a 
   /// target independent way (Note: the return type is an i64).
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D88.1.patch
Type: text/x-patch
Size: 6276 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20121030/24d45e86/attachment.bin>


More information about the llvm-commits mailing list