diff --git a/llvm/lib/Transforms/IPO/GlobalOpt.cpp b/llvm/lib/Transforms/IPO/GlobalOpt.cpp --- a/llvm/lib/Transforms/IPO/GlobalOpt.cpp +++ b/llvm/lib/Transforms/IPO/GlobalOpt.cpp @@ -315,6 +315,7 @@ CE->getType()->isPointerTy()) || CE->getOpcode() == Instruction::AddrSpaceCast) { // Pointer cast, delete any stores and memsets to the global. + // TODO: We should try to cast the Init value to the new type. Changed |= CleanupConstantGlobalUsers(CE, nullptr, DL, GetTLI); } @@ -322,6 +323,16 @@ CE->destroyConstant(); Changed = true; } + } else if (CastInst *CI = dyn_cast(U)) { + if (CI->getType()->isPointerTy()) { + // Pointer cast, delete any stores and memsets to the global. + // TODO: We should try to cast the Init value to the new type. + Changed |= CleanupConstantGlobalUsers(CI, nullptr, DL, GetTLI); + if (CI->use_empty()) { + CI->eraseFromParent(); + Changed = true; + } + } } else if (GetElementPtrInst *GEP = dyn_cast(U)) { // Do not transform "gepinst (gep constexpr (GV))" here, because forming // "gepconstexpr (gep constexpr (GV))" will cause the two gep's to fold diff --git a/llvm/test/Transforms/GlobalOpt/writeonly-internal-bitcast.ll b/llvm/test/Transforms/GlobalOpt/writeonly-internal-bitcast.ll --- a/llvm/test/Transforms/GlobalOpt/writeonly-internal-bitcast.ll +++ b/llvm/test/Transforms/GlobalOpt/writeonly-internal-bitcast.ll @@ -11,17 +11,7 @@ define void @f(i32 %I32) { ; CHECK-LABEL: @f( -; CHECK-NEXT: [[G1:%.*]] = getelementptr inbounds [[STRUCT_S:%.*]], %struct.S* @CastAccess, i32 0, i32 1, i32 [[I32:%.*]] -; CHECK-NEXT: [[BC1:%.*]] = bitcast i8* [[G1]] to i32* -; CHECK-NEXT: store i32 0, i32* [[BC1]], align 4 -; CHECK-NEXT: [[G2:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* @CastAccessConst, i32 0, i32 1, i32 42 -; CHECK-NEXT: [[BC2:%.*]] = bitcast i8* [[G2]] to i32* -; CHECK-NEXT: store i32 0, i32* [[BC2]], align 4 -; CHECK-NEXT: [[AS3:%.*]] = addrspacecast [[STRUCT_S]] addrspace(3)* @ASCastAccess to %struct.S* -; CHECK-NEXT: [[G3:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[AS3]], i32 0, i32 1, i32 [[I32]] -; CHECK-NEXT: [[BC3:%.*]] = bitcast i8* [[G3]] to i32* -; CHECK-NEXT: store i32 0, i32* [[BC3]], align 4 -; CHECK-NEXT: [[G4:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* @P2ICastAccess, i32 0, i32 1, i32 42 +; CHECK-NEXT: [[G4:%.*]] = getelementptr inbounds [[STRUCT_S:%.*]], %struct.S* @P2ICastAccess, i32 0, i32 1, i32 42 ; CHECK-NEXT: [[PTR2INT:%.*]] = ptrtoint i8* [[G4]] to i64 ; CHECK-NEXT: [[INT2PTR:%.*]] = inttoptr i64 [[PTR2INT]] to i32* ; CHECK-NEXT: store i32 0, i32* [[INT2PTR]], align 4