diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp index 8e61e3d9fdb2d6..e31023607e8079 100644 --- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -2450,12 +2450,13 @@ Instruction *InstCombiner::visitAllocSite(Instruction &MI) { replaceInstUsesWith(*C, ConstantInt::get(Type::getInt1Ty(C->getContext()), C->isFalseWhenEqual())); - } else if (isa(I) || isa(I) || - isa(I)) { - replaceInstUsesWith(*I, UndefValue::get(I->getType())); } else if (auto *SI = dyn_cast(I)) { for (auto *DII : DIIs) ConvertDebugDeclareToDebugValue(DII, SI, *DIB); + } else { + // Casts, GEP, or anything else: we're about to delete this instruction, + // so it can not have any valid uses. + replaceInstUsesWith(*I, UndefValue::get(I->getType())); } eraseInstFromFunction(*I); } diff --git a/llvm/test/Transforms/InstCombine/builtin-object-size-ptr.ll b/llvm/test/Transforms/InstCombine/builtin-object-size-ptr.ll index 4475e9554a5384..7747aea11ddab1 100644 --- a/llvm/test/Transforms/InstCombine/builtin-object-size-ptr.ll +++ b/llvm/test/Transforms/InstCombine/builtin-object-size-ptr.ll @@ -28,6 +28,48 @@ define i32 @foo() #0 { ret i32 %conv } +; This used to crash while erasing instructions: +; https://bugs.llvm.org/show_bug.cgi?id=43723 + +define void @PR43723() { +; CHECK-LABEL: @PR43723( +; CHECK-NEXT: ret void +; + %tab = alloca [10 x i8], align 16 + %t0 = bitcast [10 x i8]* %tab to i8* + call void @llvm.memset.p0i8.i64(i8* align 16 %t0, i8 9, i64 10, i1 false) + %t1 = call {}* @llvm.invariant.start.p0i8(i64 10, i8* align 16 %t0) + call void @llvm.invariant.end.p0i8({}* %t1, i64 10, i8* align 16 %t0) + ret void + + uselistorder i8* %t0, { 1, 0, 2 } +} + +define void @unknown_use_of_invariant_start({}** %p) { +; CHECK-LABEL: @unknown_use_of_invariant_start( +; CHECK-NEXT: ret void +; + %tab = alloca [10 x i8], align 16 + %t0 = bitcast [10 x i8]* %tab to i8* + call void @llvm.memset.p0i8.i64(i8* align 16 %t0, i8 9, i64 10, i1 false) + %t1 = call {}* @llvm.invariant.start.p0i8(i64 10, i8* align 16 %t0) + call void @llvm.invariant.end.p0i8({}* %t1, i64 10, i8* align 16 %t0) + store {}* %t1, {}** %p + ret void +} + +define {}* @minimal_invariant_start_use(i8 %x) { +; CHECK-LABEL: @minimal_invariant_start_use( +; CHECK-NEXT: ret {}* undef +; + %a = alloca i8 + %i = call {}* @llvm.invariant.start.p0i8(i64 1, i8* %a) + ret {}* %i +} + declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) #1 declare i64 @llvm.objectsize.i64.p0i8(i8*, i1) #2 declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) #1 +declare void @llvm.memset.p0i8.i64(i8* nocapture writeonly, i8, i64, i1 immarg) #0 +declare {}* @llvm.invariant.start.p0i8(i64 immarg, i8* nocapture) #0 +declare void @llvm.invariant.end.p0i8({}*, i64 immarg, i8* nocapture) #0