Index: llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp =================================================================== --- llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp +++ llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp @@ -1924,11 +1924,13 @@ return true; if (auto *MemSetI = dyn_cast(UpperInst)) { if (auto *SI = dyn_cast(DefInst)) { - // MemSetInst must have a write location. - MemoryLocation UpperLoc = *getLocForWrite(UpperInst); + Optional UpperLoc = getLocForWrite(UpperInst); + if (!UpperLoc) + return false; + int64_t InstWriteOffset = 0; int64_t DepWriteOffset = 0; - auto OR = isOverwrite(UpperInst, DefInst, UpperLoc, *MaybeDefLoc, + auto OR = isOverwrite(UpperInst, DefInst, *UpperLoc, *MaybeDefLoc, InstWriteOffset, DepWriteOffset); Value *StoredByte = isBytewiseValue(SI->getValueOperand(), DL); return StoredByte && StoredByte == MemSetI->getOperand(1) && Index: llvm/test/Transforms/DeadStoreElimination/memset-presplitcoroutine.ll =================================================================== --- /dev/null +++ llvm/test/Transforms/DeadStoreElimination/memset-presplitcoroutine.ll @@ -0,0 +1,40 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt -dse -S %s | FileCheck %s + +declare i8* @_Znwm() local_unnamed_addr #0 + +; Function Attrs: argmemonly nounwind willreturn writeonly +declare void @llvm.memset.p0i8.i64(i8* nocapture writeonly, i8, i64, i1 immarg) #1 + +define i8* @test2(i1 %c, i64 %N) presplitcoroutine { +; CHECK-LABEL: @test2( +; CHECK-NEXT: entry: +; CHECK-NEXT: br i1 [[C:%.*]], label [[COND_TRUE_I_I_I:%.*]], label [[COND_END_I_I_I:%.*]] +; CHECK: cond.true.i.i.i: +; CHECK-NEXT: ret i8* null +; CHECK: cond.end.i.i.i: +; CHECK-NEXT: [[ALLOC:%.*]] = tail call noalias nonnull i8* @_Znam() #[[ATTR3:[0-9]+]] +; CHECK-NEXT: [[ALLOC_BC:%.*]] = bitcast i8* [[ALLOC]] to i64* +; CHECK-NEXT: tail call void @llvm.memset.p0i8.i64(i8* nonnull align 8 [[ALLOC]], i8 0, i64 [[N:%.*]], i1 false) #[[ATTR4:[0-9]+]] +; CHECK-NEXT: store i64 0, i64* [[ALLOC_BC]], align 8 +; CHECK-NEXT: ret i8* [[ALLOC]] +; +entry: + br i1 %c, label %cond.true.i.i.i, label %cond.end.i.i.i + +cond.true.i.i.i: ; preds = %entry + ret i8* null + +cond.end.i.i.i: ; preds = %entry + %alloc = tail call noalias nonnull i8* @_Znam() #2 + %alloc.bc = bitcast i8* %alloc to i64* + tail call void @llvm.memset.p0i8.i64(i8* nonnull align 8 %alloc, i8 0, i64 %N, i1 false) #1 + store i64 0, i64* %alloc.bc, align 8 + ret i8* %alloc +} + +declare i8* @_Znam() + +attributes #0 = { "use-soft-float"="false" } +attributes #1 = { argmemonly nounwind willreturn writeonly } +attributes #2 = { builtin nounwind }