diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index 36a2ad5e455..1175374748b 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -11145,53 +11145,56 @@ static Instruction *InstCombineStoreToCast(InstCombiner &IC, StoreInst &SI) { Value *CastOp = CI->getOperand(0); const Type *DestPTy = cast(CI->getType())->getElementType(); - if (const PointerType *SrcTy = dyn_cast(CastOp->getType())) { - const Type *SrcPTy = SrcTy->getElementType(); + const PointerType *SrcTy = dyn_cast(CastOp->getType()); + if (SrcTy == 0) return 0; + + const Type *SrcPTy = SrcTy->getElementType(); - if (DestPTy->isInteger() || isa(DestPTy)) { - // If the source is an array, the code below will not succeed. Check to - // see if a trivial 'gep P, 0, 0' will help matters. Only do this for - // constants. - if (const ArrayType *ASrcTy = dyn_cast(SrcPTy)) - if (Constant *CSrc = dyn_cast(CastOp)) - if (ASrcTy->getNumElements() != 0) { - Value* Idxs[2]; - Idxs[0] = Idxs[1] = Constant::getNullValue(Type::Int32Ty); - CastOp = ConstantExpr::getGetElementPtr(CSrc, Idxs, 2); - SrcTy = cast(CastOp->getType()); - SrcPTy = SrcTy->getElementType(); - } - - if ((SrcPTy->isInteger() || isa(SrcPTy)) && - IC.getTargetData().getTypeSizeInBits(SrcPTy) == - IC.getTargetData().getTypeSizeInBits(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. - Value *NewCast; - Value *SIOp0 = SI.getOperand(0); - Instruction::CastOps opcode = Instruction::BitCast; - const Type* CastSrcTy = SIOp0->getType(); - const Type* CastDstTy = SrcPTy; - if (isa(CastDstTy)) { - if (CastSrcTy->isInteger()) - opcode = Instruction::IntToPtr; - } else if (isa(CastDstTy)) { - if (isa(SIOp0->getType())) - opcode = Instruction::PtrToInt; - } - if (Constant *C = dyn_cast(SIOp0)) - NewCast = ConstantExpr::getCast(opcode, C, CastDstTy); - else - NewCast = IC.InsertNewInstBefore( - CastInst::Create(opcode, SIOp0, CastDstTy, SIOp0->getName()+".c"), - SI); - return new StoreInst(NewCast, CastOp); + if (!DestPTy->isInteger() && !isa(DestPTy)) + return 0; + + // If the source is an array, the code below will not succeed. Check to + // see if a trivial 'gep P, 0, 0' will help matters. Only do this for + // constants. + if (const ArrayType *ASrcTy = dyn_cast(SrcPTy)) + if (Constant *CSrc = dyn_cast(CastOp)) + if (ASrcTy->getNumElements() != 0) { + Value* Idxs[2]; + Idxs[0] = Idxs[1] = Constant::getNullValue(Type::Int32Ty); + CastOp = ConstantExpr::getGetElementPtr(CSrc, Idxs, 2); + SrcTy = cast(CastOp->getType()); + SrcPTy = SrcTy->getElementType(); } - } + + if (!SrcPTy->isInteger() && !isa(SrcPTy)) + return 0; + + if (IC.getTargetData().getTypeSizeInBits(SrcPTy) != + IC.getTargetData().getTypeSizeInBits(DestPTy)) + return 0; + + // 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. + Value *NewCast; + Value *SIOp0 = SI.getOperand(0); + Instruction::CastOps opcode = Instruction::BitCast; + const Type* CastSrcTy = SIOp0->getType(); + const Type* CastDstTy = SrcPTy; + if (isa(CastDstTy)) { + if (CastSrcTy->isInteger()) + opcode = Instruction::IntToPtr; + } else if (isa(CastDstTy)) { + if (isa(SIOp0->getType())) + opcode = Instruction::PtrToInt; } - return 0; + if (Constant *C = dyn_cast(SIOp0)) + NewCast = ConstantExpr::getCast(opcode, C, CastDstTy); + else + NewCast = IC.InsertNewInstBefore( + CastInst::Create(opcode, SIOp0, CastDstTy, SIOp0->getName()+".c"), + SI); + return new StoreInst(NewCast, CastOp); } /// equivalentAddressValues - Test if A and B will obviously have the same