From 4e54efd6253da76632588ac0ef0dc838db28b51b Mon Sep 17 00:00:00 2001 From: Owen Anderson Date: Sun, 16 Jan 2011 04:33:33 +0000 Subject: Improve the safety of my globalopt enhancement by ensuring that the bitcast of the stored value to the new store type is always. Also, add a testcase. llvm-svn: 123563 --- llvm/lib/Transforms/IPO/GlobalOpt.cpp | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) (limited to 'llvm/lib/Transforms/IPO') diff --git a/llvm/lib/Transforms/IPO/GlobalOpt.cpp b/llvm/lib/Transforms/IPO/GlobalOpt.cpp index 8519fce7a38..bf045943448 100644 --- a/llvm/lib/Transforms/IPO/GlobalOpt.cpp +++ b/llvm/lib/Transforms/IPO/GlobalOpt.cpp @@ -2358,21 +2358,31 @@ static bool EvaluateFunction(Function *F, Constant *&RetVal, const Type *NewTy=cast(Ptr->getType())->getElementType(); - // A bitcast'd pointer implicitly points to the first field of a - // struct. Insert implicity "gep @x, 0, 0, ..." until we get down - // to the first concrete member. - // FIXME: This could be extended to work for arrays as well. - while (const StructType *STy = dyn_cast(NewTy)) { - NewTy = STy->getTypeAtIndex(0U); + // In order to push the bitcast onto the stored value, a bitcast + // from NewTy to Val's type must be legal. If it's not, we can try + // introspecting NewTy to find a legal conversion. + while (!Val->getType()->canLosslesslyBitCastTo(NewTy)) { + // If NewTy is a struct, we can convert the pointer to the struct + // into a pointer to its first member. + // FIXME: This could be extended to support arrays as well. + if (const StructType *STy = dyn_cast(NewTy)) { + NewTy = STy->getTypeAtIndex(0U); + + const IntegerType *IdxTy =IntegerType::get(NewTy->getContext(), 32); + Constant *IdxZero = ConstantInt::get(IdxTy, 0, false); + Constant * const IdxList[] = {IdxZero, IdxZero}; + + Ptr = ConstantExpr::getGetElementPtr(Ptr, IdxList, 2); - const IntegerType *IdxTy =IntegerType::get(NewTy->getContext(), 32); - Constant *IdxZero = ConstantInt::get(IdxTy, 0, false); - Constant * const IdxList[] = {IdxZero, IdxZero}; - - Ptr = ConstantExpr::getGetElementPtr(Ptr, IdxList, 2); + // If we can't improve the situation by introspecting NewTy, + // we have to give up. + } else { + return 0; + } } - if (!isa(NewTy)) return false; + // If we found compatible types, go ahead and push the bitcast + // onto the stored value. Val = ConstantExpr::getBitCast(Val, NewTy); } -- cgit v1.2.3