Index: lib/Transforms/IPO/GlobalOpt.cpp =================================================================== --- lib/Transforms/IPO/GlobalOpt.cpp +++ lib/Transforms/IPO/GlobalOpt.cpp @@ -409,8 +409,9 @@ gep_type_iterator GEPI = gep_type_begin(U), E = gep_type_end(U); ++GEPI; // Skip over the pointer index. - // If this is a use of an array allocation, do a bit more checking for sanity. - if (GEPI.isSequential()) { + // If this is a use of an array allocation (possibly inside a struct), do a + // bit more checking for sanity. + if (GEPI.isSequential() || GEPI.isStruct()) { ConstantInt *Idx = cast(U->getOperand(2)); // Check to make sure that index falls within the array. If not, Index: test/Transforms/GlobalOpt/globalsra-partial.ll =================================================================== --- test/Transforms/GlobalOpt/globalsra-partial.ll +++ test/Transforms/GlobalOpt/globalsra-partial.ll @@ -1,11 +1,12 @@ -; In this case, the global can only be broken up by one level. +; In this case, the global cannot be merged as i may be out of range ; RUN: opt < %s -globalopt -S | FileCheck %s target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" @G = internal global { i32, [4 x float] } zeroinitializer ; <{ i32, [4 x float] }*> [#uses=3] -; CHECK-NOT: 12345 +; CHECK: @G = internal unnamed_addr global { i32, [4 x float] } +; CHECK: 12345 define void @onlystore() { store i32 12345, i32* getelementptr ({ i32, [4 x float] }, { i32, [4 x float] }* @G, i32 0, i32 0) ret void