Revert 71165. It did more than just revert 71158 and it introduced
several regressions. The problem due to 71158 is now fixed.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@71176 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Analysis/ConstantFolding.cpp b/lib/Analysis/ConstantFolding.cpp
index ac2670a..7c99325 100644
--- a/lib/Analysis/ConstantFolding.cpp
+++ b/lib/Analysis/ConstantFolding.cpp
@@ -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);
diff --git a/lib/Analysis/DebugInfo.cpp b/lib/Analysis/DebugInfo.cpp
index 4e398f2..181f3e9 100644
--- a/lib/Analysis/DebugInfo.cpp
+++ b/lib/Analysis/DebugInfo.cpp
@@ -59,9 +59,6 @@
   case DW_TAG_subprogram:
     assert(DISubprogram(GV).Verify() && "Invalid DebugInfo value");
     break;
-  case DW_TAG_inlined_subroutine:
-    assert(DIInlinedSubprogram(GV).Verify() && "Invalid DebugInfo value");
-    break;
   case DW_TAG_lexical_block:
     /// FIXME. This interfers with the quality of generated code when
     /// during optimization.
@@ -149,8 +146,6 @@
   : DIType(GV, dwarf::DW_TAG_base_type) {}
 DISubprogram::DISubprogram(GlobalVariable *GV)
   : DIGlobal(GV, dwarf::DW_TAG_subprogram) {}
-DIInlinedSubprogram::DIInlinedSubprogram(GlobalVariable *GV)
-  : DIGlobal(GV, dwarf::DW_TAG_inlined_subroutine) {}
 DIGlobalVariable::DIGlobalVariable(GlobalVariable *GV)
   : DIGlobal(GV, dwarf::DW_TAG_variable) {}
 DIBlock::DIBlock(GlobalVariable *GV)
@@ -291,25 +286,6 @@
   return true;
 }
 
-/// Verify - Verify that an inlined subprogram descriptor is well formed.
-bool DIInlinedSubprogram::Verify() const {
-  if (isNull())
-    return false;
-  
-  if (getContext().isNull())
-    return false;
-
-  DICompileUnit CU = getCompileUnit();
-  if (!CU.Verify()) 
-    return false;
-
-  DICompositeType Ty = getType();
-  if (!Ty.isNull() && !Ty.Verify())
-    return false;
-
-  return true;
-}
-
 /// Verify - Verify that a global variable descriptor is well formed.
 bool DIGlobalVariable::Verify() const {
   if (isNull())
@@ -1007,8 +983,7 @@
 
 /// dump - print descriptor.
 void DIDescriptor::dump() const {
-  cerr << "[" << dwarf::TagString(getTag()) << "] ";
-  cerr << std::hex << "[GV:" << GV << "]" << std::dec;
+  cerr << " [" << dwarf::TagString(getTag()) << "]\n";
 }
 
 /// dump - print compile unit.
@@ -1110,11 +1085,6 @@
   DIGlobal::dump();
 }
 
-/// dump - print subprogram.
-void DIInlinedSubprogram::dump() const {
-  DIGlobal::dump();
-}
-
 /// dump - print global variable.
 void DIGlobalVariable::dump() const {
   cerr << " ["; getGlobal()->dump(); cerr << "] ";