diff options
author | Owen Anderson <resistor@mac.com> | 2011-01-16 04:33:33 +0000 |
---|---|---|
committer | Owen Anderson <resistor@mac.com> | 2011-01-16 04:33:33 +0000 |
commit | 4e54efd6253da76632588ac0ef0dc838db28b51b (patch) | |
tree | 7579a77b73dec8624bf51fdaa76ff89c285e6fca /llvm/lib/Transforms/IPO | |
parent | 08f43456c9e1916ea2a9ec136c6f47d8bce9f9f8 (diff) | |
download | bcm5719-llvm-4e54efd6253da76632588ac0ef0dc838db28b51b.tar.gz bcm5719-llvm-4e54efd6253da76632588ac0ef0dc838db28b51b.zip |
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
Diffstat (limited to 'llvm/lib/Transforms/IPO')
-rw-r--r-- | llvm/lib/Transforms/IPO/GlobalOpt.cpp | 34 |
1 files changed, 22 insertions, 12 deletions
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<PointerType>(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<StructType>(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<StructType>(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<PointerType>(NewTy)) return false; + // If we found compatible types, go ahead and push the bitcast + // onto the stored value. Val = ConstantExpr::getBitCast(Val, NewTy); } |