Tighten up a check for folding away loads from (newly constant) globals. This
authorChris Lattner <sabre@nondot.org>
Fri, 9 Nov 2007 17:33:02 +0000 (17:33 +0000)
committerChris Lattner <sabre@nondot.org>
Fri, 9 Nov 2007 17:33:02 +0000 (17:33 +0000)
fixes a crash on Transforms/GlobalOpt/2007-11-09-GEP-GEP-Crash.ll and
rdar://5585488.

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

lib/Transforms/IPO/GlobalOpt.cpp
test/Transforms/GlobalOpt/2007-11-09-GEP-GEP-Crash.ll [new file with mode: 0644]

index 779b4a1871c5eb6febf92a4e09eb80f7b7219c73..76f04efda618a9224c2d52b857027742819abcf9 100644 (file)
@@ -342,12 +342,17 @@ static bool CleanupConstantGlobalUsers(Value *V, Constant *Init) {
         Changed = true;
       }
     } else if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(U)) {
-      Constant *SubInit = 0;
-      ConstantExpr *CE = 
-        dyn_cast_or_null<ConstantExpr>(ConstantFoldInstruction(GEP));
-      if (Init && CE && CE->getOpcode() == Instruction::GetElementPtr)
-        SubInit = ConstantFoldLoadThroughGEPConstantExpr(Init, CE);
-      Changed |= CleanupConstantGlobalUsers(GEP, SubInit);
+      // Do not transform "gepinst (gep constexpr (GV))" here, because forming
+      // "gepconstexpr (gep constexpr (GV))" will cause the two gep's to fold
+      // and will invalidate our notion of what Init is.
+      if (!isa<ConstantExpr>(GEP->getOperand(0))) {
+        ConstantExpr *CE = 
+          dyn_cast_or_null<ConstantExpr>(ConstantFoldInstruction(GEP));
+        if (Init && CE && CE->getOpcode() == Instruction::GetElementPtr)
+          if (Constant *SubInit = 
+              ConstantFoldLoadThroughGEPConstantExpr(Init, CE))
+            Changed |= CleanupConstantGlobalUsers(GEP, SubInit);
+      }
 
       if (GEP->use_empty()) {
         GEP->eraseFromParent();
diff --git a/test/Transforms/GlobalOpt/2007-11-09-GEP-GEP-Crash.ll b/test/Transforms/GlobalOpt/2007-11-09-GEP-GEP-Crash.ll
new file mode 100644 (file)
index 0000000..0d7d036
--- /dev/null
@@ -0,0 +1,19 @@
+; RUN: llvm-as < %s | opt -globalopt -disable-output
+target datalayout = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f128:64:128"
+target triple = "powerpc-apple-darwin8"
+        %struct.empty0 = type {  }
+        %struct.es = type { %struct.empty0 }
+        %struct.es1 = type { %struct.empty0 }
+@aaui1 = internal global [6 x [2 x i32]] [ [2 x i32] [ i32 1, i32 1 ], [2 x i32] [ i32 1, i32 1 ], [2 x i32] [ i32 1, i32 1 ], [2 x i32] [ i32 1, i32 1 ], [2 x i32] [ i32 1, i32 1 ], [2 x i32] [ i32 1, i32 1 ] ]              ; <[6 x [2 x i32]]*> [#uses=1]
+@aaui0 = internal global [0 x [2 x i32]] zeroinitializer                ; <[0 x [2 x i32]]*> [#uses=1]
+
+define i8 @func() {
+entry:
+        %tmp10 = getelementptr [2 x i32]* getelementptr ([6 x [2 x i32]]* @aaui1, i32 0, i32 0), i32 5, i32 1           ; <i32*> [#uses=1]
+        %tmp11 = load i32* %tmp10, align 4              ; <i32> [#uses=1]
+        %tmp12 = call i32 (...)* @func3( i32* null, i32 0, i32 %tmp11 )         ; <i32> [#uses=0]
+        ret i8 undef
+}
+
+declare i32 @func3(...)
+