aboutsummaryrefslogtreecommitdiff
path: root/lib/Transforms/IPO/GlobalOpt.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Transforms/IPO/GlobalOpt.cpp')
-rw-r--r--lib/Transforms/IPO/GlobalOpt.cpp34
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);
}