Implement InstCombine/getelementptr.ll:test9, which is the source of many
authorChris Lattner <sabre@nondot.org>
Sat, 16 Oct 2004 19:44:59 +0000 (19:44 +0000)
committerChris Lattner <sabre@nondot.org>
Sat, 16 Oct 2004 19:44:59 +0000 (19:44 +0000)
ugly and giant constnat exprs in some programs.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@17066 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Scalar/InstructionCombining.cpp

index 32686b3e85104c49c8332271eef2473914ea7451..a874723b5413e4c1ddc128c52d9c604a104224ee 100644 (file)
@@ -4018,6 +4018,24 @@ bool InstCombiner::runOnFunction(Function &F) {
 
     // Instruction isn't dead, see if we can constant propagate it...
     if (Constant *C = ConstantFoldInstruction(I)) {
+      if (isa<GetElementPtrInst>(I) &&
+          cast<Constant>(I->getOperand(0))->isNullValue() &&
+          !isa<ConstantPointerNull>(C)) {
+        // If this is a constant expr gep that is effectively computing an
+        // "offsetof", fold it into 'cast int X to T*' instead of 'gep 0, 0, 12'
+        bool isFoldableGEP = true;
+        for (unsigned i = 1, e = I->getNumOperands(); i != e; ++i)
+          if (!isa<ConstantInt>(I->getOperand(i)))
+            isFoldableGEP = false;
+        if (isFoldableGEP) {
+          uint64_t Offset = TD->getIndexedOffset(I->getOperand(0)->getType(),
+                             std::vector<Value*>(I->op_begin()+1, I->op_end()));
+          C = ConstantUInt::get(Type::ULongTy, Offset);
+          C = ConstantUInt::getCast(C, TD->getIntPtrType());
+          C = ConstantExpr::getCast(C, I->getType());
+        }
+      }
+
       // Add operands to the worklist...
       AddUsesToWorkList(*I);
       ReplaceInstUsesWith(*I, C);