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 | 66f708f7e5f207d7a7ab259b70b5fd94795fb74c (patch) | |
tree | 613afbfede21288f10945502fa281c5ce80c2adf /lib/Transforms | |
parent | 156eb0a569a1ebac86ad8438645f690d8a3894c4 (diff) |
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.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@123563 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms')
-rw-r--r-- | lib/Transforms/IPO/GlobalOpt.cpp | 34 |
1 files changed, 22 insertions, 12 deletions
diff --git a/lib/Transforms/IPO/GlobalOpt.cpp b/lib/Transforms/IPO/GlobalOpt.cpp index 8519fce7a3..bf04594344 100644 --- a/lib/Transforms/IPO/GlobalOpt.cpp +++ b/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); } |