diff --git a/lib/Transforms/IPO/GlobalOpt.cpp b/lib/Transforms/IPO/GlobalOpt.cpp index 2555ed59f57..294904212e3 100644 --- a/lib/Transforms/IPO/GlobalOpt.cpp +++ b/lib/Transforms/IPO/GlobalOpt.cpp @@ -2091,8 +2091,8 @@ static Constant *EvaluateStoreInto(Constant *Init, Constant *Val, return Val; } + std::vector Elts; if (const StructType *STy = dyn_cast(Init->getType())) { - std::vector Elts; // Break up the constant into its elements. if (ConstantStruct *CS = dyn_cast(Init)) { @@ -2120,28 +2120,35 @@ static Constant *EvaluateStoreInto(Constant *Init, Constant *Val, STy->isPacked()); } else { ConstantInt *CI = cast(Addr->getOperand(OpNo)); - const ArrayType *ATy = cast(Init->getType()); + const SequentialType *InitTy = cast(Init->getType()); + uint64_t NumElts; + if (const ArrayType *ATy = dyn_cast(InitTy)) + NumElts = ATy->getNumElements(); + else + NumElts = cast(InitTy)->getNumElements(); + + // Break up the array into elements. - std::vector Elts; if (ConstantArray *CA = dyn_cast(Init)) { for (User::op_iterator i = CA->op_begin(), e = CA->op_end(); i != e; ++i) Elts.push_back(cast(*i)); } else if (isa(Init)) { - Constant *Elt = Constant::getNullValue(ATy->getElementType()); - Elts.assign(ATy->getNumElements(), Elt); - } else if (isa(Init)) { - Constant *Elt = UndefValue::get(ATy->getElementType()); - Elts.assign(ATy->getNumElements(), Elt); + Elts.assign(NumElts, Constant::getNullValue(InitTy->getElementType())); } else { - llvm_unreachable("This code is out of sync with " + assert(isa(Init) && "This code is out of sync with " " ConstantFoldLoadThroughGEPConstantExpr"); + Elts.assign(NumElts, UndefValue::get(InitTy->getElementType())); } - assert(CI->getZExtValue() < ATy->getNumElements()); + assert(CI->getZExtValue() < NumElts); Elts[CI->getZExtValue()] = EvaluateStoreInto(Elts[CI->getZExtValue()], Val, Addr, OpNo+1); - return ConstantArray::get(ATy, Elts); + + if (isa(Init->getType())) + return ConstantArray::get(cast(InitTy), Elts); + else + return ConstantVector::get(&Elts[0], Elts.size()); } } @@ -2153,13 +2160,10 @@ static void CommitValueTo(Constant *Val, Constant *Addr) { GV->setInitializer(Val); return; } - + ConstantExpr *CE = cast(Addr); GlobalVariable *GV = cast(CE->getOperand(0)); - - Constant *Init = GV->getInitializer(); - Init = EvaluateStoreInto(Init, Val, CE, 2); - GV->setInitializer(Init); + GV->setInitializer(EvaluateStoreInto(GV->getInitializer(), Val, CE, 2)); } /// ComputeLoadResult - Return the value that would be computed by a load from diff --git a/test/Transforms/GlobalOpt/crash.ll b/test/Transforms/GlobalOpt/crash.ll new file mode 100644 index 00000000000..a45cbe9c0f6 --- /dev/null +++ b/test/Transforms/GlobalOpt/crash.ll @@ -0,0 +1,16 @@ +; RUN: opt -globalopt -disable-output %s +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-f80:128:128-n8:16:32" +target triple = "i386-apple-darwin9.8" + +%0 = type { i32, void ()* } +%struct.btSimdScalar = type { %"union.btSimdScalar::$_14" } +%"union.btSimdScalar::$_14" = type { <4 x float> } + +@_ZL6vTwist = global %struct.btSimdScalar zeroinitializer ; <%struct.btSimdScalar*> [#uses=1] +@llvm.global_ctors = appending global [1 x %0] [%0 { i32 65535, void ()* @_GLOBAL__I__ZN21btConeTwistConstraintC2Ev }] ; <[12 x %0]*> [#uses=0] + +define internal void @_GLOBAL__I__ZN21btConeTwistConstraintC2Ev() nounwind section "__TEXT,__StaticInit,regular,pure_instructions" { +entry: + store float 1.0, float* getelementptr inbounds (%struct.btSimdScalar* @_ZL6vTwist, i32 0, i32 0, i32 0, i32 3), align 4 + ret void +}