summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Transforms/Scalar/InstructionCombining.cpp22
1 files changed, 14 insertions, 8 deletions
diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp
index f81f10e71e..48eaef59e7 100644
--- a/lib/Transforms/Scalar/InstructionCombining.cpp
+++ b/lib/Transforms/Scalar/InstructionCombining.cpp
@@ -8186,23 +8186,29 @@ static Instruction *InstCombineStoreToCast(InstCombiner &IC, StoreInst &SI) {
IC.getTargetData().getTypeSize(DestPTy)) {
// Okay, we are casting from one integer or pointer type to another of
- // the same size. Instead of casting the pointer before the store, cast
- // the value to be stored.
+ // the same size. Instead of casting the pointer before
+ // the store, cast the value to be stored.
Value *NewCast;
- Instruction::CastOps opcode = Instruction::BitCast;
Value *SIOp0 = SI.getOperand(0);
- if (isa<PointerType>(SrcPTy)) {
- if (SIOp0->getType()->isInteger())
+ Instruction::CastOps opcode = Instruction::BitCast;
+ const Type* CastSrcTy = SIOp0->getType();
+ const Type* CastDstTy = SrcPTy;
+ if (isa<PointerType>(CastDstTy)) {
+ if (CastSrcTy->isInteger())
opcode = Instruction::IntToPtr;
- } else if (SrcPTy->isInteger()) {
+ } else if (const IntegerType* DITy = dyn_cast<IntegerType>(CastDstTy)) {
if (isa<PointerType>(SIOp0->getType()))
opcode = Instruction::PtrToInt;
+ else if (const IntegerType* SITy = dyn_cast<IntegerType>(CastSrcTy))
+ assert(DITy->getBitWidth() == SITy->getBitWidth() &&
+ "Illegal store instruction");
}
if (Constant *C = dyn_cast<Constant>(SIOp0))
- NewCast = ConstantExpr::getCast(opcode, C, SrcPTy);
+ NewCast = ConstantExpr::getCast(opcode, C, CastDstTy);
else
NewCast = IC.InsertNewInstBefore(
- CastInst::create(opcode, SIOp0, SrcPTy, SIOp0->getName()+".c"), SI);
+ CastInst::create(opcode, SIOp0, CastDstTy, SIOp0->getName()+".c"),
+ SI);
return new StoreInst(NewCast, CastOp);
}
}