aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2010-01-07 01:16:21 +0000
committerChris Lattner <sabre@nondot.org>2010-01-07 01:16:21 +0000
commita0e9a2475cd6e45966a591de8e0740a102fe0dfe (patch)
tree9c4033d94d48d1ca9d2c906c03764170045a1a9c
parent17751dac3e0a7b7a8cdf9bd612ce20f157eb251f (diff)
fix a globalopt crash on 'bullet' (handling evaluation of a store
to an element of a vector in a static ctor) which occurs with an unrelated patch I'm testing. Annoyingly, EvaluateStoreInto basically does exactly the same stuff as InsertElement constant folding, but it now handles vectors, and you can't insertelement into a vector. It would be 'really nice' if GEP into a vector were not legal. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@92889 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Transforms/IPO/GlobalOpt.cpp36
-rw-r--r--test/Transforms/GlobalOpt/crash.ll16
2 files changed, 36 insertions, 16 deletions
diff --git a/lib/Transforms/IPO/GlobalOpt.cpp b/lib/Transforms/IPO/GlobalOpt.cpp
index 2555ed59f5..294904212e 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<Constant*> Elts;
if (const StructType *STy = dyn_cast<StructType>(Init->getType())) {
- std::vector<Constant*> Elts;
// Break up the constant into its elements.
if (ConstantStruct *CS = dyn_cast<ConstantStruct>(Init)) {
@@ -2120,28 +2120,35 @@ static Constant *EvaluateStoreInto(Constant *Init, Constant *Val,
STy->isPacked());
} else {
ConstantInt *CI = cast<ConstantInt>(Addr->getOperand(OpNo));
- const ArrayType *ATy = cast<ArrayType>(Init->getType());
+ const SequentialType *InitTy = cast<SequentialType>(Init->getType());
+ uint64_t NumElts;
+ if (const ArrayType *ATy = dyn_cast<ArrayType>(InitTy))
+ NumElts = ATy->getNumElements();
+ else
+ NumElts = cast<VectorType>(InitTy)->getNumElements();
+
+
// Break up the array into elements.
- std::vector<Constant*> Elts;
if (ConstantArray *CA = dyn_cast<ConstantArray>(Init)) {
for (User::op_iterator i = CA->op_begin(), e = CA->op_end(); i != e; ++i)
Elts.push_back(cast<Constant>(*i));
} else if (isa<ConstantAggregateZero>(Init)) {
- Constant *Elt = Constant::getNullValue(ATy->getElementType());
- Elts.assign(ATy->getNumElements(), Elt);
- } else if (isa<UndefValue>(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<UndefValue>(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<ArrayType>(Init->getType()))
+ return ConstantArray::get(cast<ArrayType>(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<ConstantExpr>(Addr);
GlobalVariable *GV = cast<GlobalVariable>(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 0000000000..a45cbe9c0f
--- /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
+}