diff --git a/lib/Transforms/Utils/InlineFunction.cpp b/lib/Transforms/Utils/InlineFunction.cpp index a08ffbeb329..169ebcf5bfc 100644 --- a/lib/Transforms/Utils/InlineFunction.cpp +++ b/lib/Transforms/Utils/InlineFunction.cpp @@ -1167,7 +1167,11 @@ bool llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI, Type *AllocaType = AI->getAllocatedType(); uint64_t AllocaTypeSize = DL.getTypeAllocSize(AllocaType); uint64_t AllocaArraySize = AIArraySize->getLimitedValue(); - assert(AllocaArraySize > 0 && "array size of AllocaInst is zero"); + + // Don't add markers for zero-sized allocas. + if (AllocaArraySize == 0) + continue; + // Check that array size doesn't saturate uint64_t and doesn't // overflow when it's multiplied by type size. if (AllocaArraySize != ~0ULL && diff --git a/test/Transforms/Inline/crash-lifetime-marker.ll b/test/Transforms/Inline/crash-lifetime-marker.ll new file mode 100644 index 00000000000..42e926b1f63 --- /dev/null +++ b/test/Transforms/Inline/crash-lifetime-marker.ll @@ -0,0 +1,24 @@ +; RUN: opt < %s -inline -S | FileCheck %s + +; InlineFunction would assert inside the loop that leaves lifetime markers if +; there was an zero-sized AllocaInst. Check that it doesn't assert and doesn't +; leave lifetime markers in that case. + +declare i32 @callee2(i8*) + +define i32 @callee1(i32 %count) { + %a0 = alloca i8, i32 %count, align 4 + %call0 = call i32 @callee2(i8* %a0) + ret i32 %call0 +} + +; CHECK-LABEL: define i32 @caller1( +; CHECK: [[ALLOCA:%[a-z0-9\.]+]] = alloca i8 +; CHECK-NOT: call void @llvm.lifetime.start( +; CHECK: call i32 @callee2(i8* [[ALLOCA]]) +; CHECK-NOT: call void @llvm.lifetime.end( + +define i32 @caller1(i32 %count) { + %call0 = call i32 @callee1(i32 0) + ret i32 %call0 +}