Generalize this code to turn any cast-to-first-element-of into a gep constexpr
authorChris Lattner <sabre@nondot.org>
Wed, 17 Nov 2004 17:59:35 +0000 (17:59 +0000)
committerChris Lattner <sabre@nondot.org>
Wed, 17 Nov 2004 17:59:35 +0000 (17:59 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@17914 91177308-0d34-0410-b5e6-96231b3b80d8

lib/VMCore/ConstantFold.cpp

index d224afefc5c6bde78cf44e7dcceb8a7fea300aae..02b7fe2975a981e596c4d0e65cee1fcc7b39fea4 100644 (file)
@@ -565,16 +565,29 @@ Constant *llvm::ConstantFoldCastInstruction(const Constant *V,
     return UndefValue::get(DestTy);
   }
 
-  // Check to see if we are casting an array of X to a pointer to X.  If so, use
-  // a GEP to get to the first element of the array instead of a cast!
+  // Check to see if we are casting an pointer to an aggregate to a pointer to
+  // the first element.  If so, return the appropriate GEP instruction.
   if (const PointerType *PTy = dyn_cast<PointerType>(V->getType()))
-    if (const ArrayType *ATy = dyn_cast<ArrayType>(PTy->getElementType()))
-      if (const PointerType *DPTy = dyn_cast<PointerType>(DestTy))
-        if (DPTy->getElementType() == ATy->getElementType()) {
-          std::vector<Constant*> IdxList(2,Constant::getNullValue(Type::IntTy));
-          return ConstantExpr::getGetElementPtr(const_cast<Constant*>(V),
-                                                IdxList);
+    if (const PointerType *DPTy = dyn_cast<PointerType>(DestTy)) {
+      std::vector<Value*> IdxList;
+      IdxList.push_back(Constant::getNullValue(Type::IntTy));
+      const Type *ElTy = PTy->getElementType();
+      while (ElTy != DPTy->getElementType()) {
+        if (const StructType *STy = dyn_cast<StructType>(ElTy)) {
+          ElTy = STy->getElementType(0);
+          IdxList.push_back(Constant::getNullValue(Type::UIntTy));
+        } else if (const SequentialType *STy = dyn_cast<SequentialType>(ElTy)) {
+          if (isa<PointerType>(ElTy)) break;  // Can't index into pointers!
+          ElTy = STy->getElementType();
+          IdxList.push_back(IdxList[0]);
+        } else {
+          break;
         }
+      }
+
+      if (ElTy == DPTy->getElementType())
+        return ConstantExpr::getGetElementPtr(const_cast<Constant*>(V),IdxList);
+    }
 
   ConstRules &Rules = ConstRules::get(V, V);