Index: lib/Transforms/InstCombine/InstCombineCalls.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineCalls.cpp +++ lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -1392,6 +1392,24 @@ return EraseInstFromFunction(CI); break; } + case Intrinsic::lifetime_start: { + // Remove trivially empty lifetime_start/end ranges, i.e. a start + // immediately followed by an end (ignoring debuginfo in between). + BasicBlock::iterator BI = II, BE = II->getParent()->end(); + for (++BI; BI != BE; ++BI) { + if (isa(BI)) + continue; + if (IntrinsicInst *LTE = dyn_cast(BI)) + if (LTE->getIntrinsicID() == Intrinsic::lifetime_end && + II->getOperand(0) == LTE->getOperand(0) && + II->getOperand(1) == LTE->getOperand(1)) { + EraseInstFromFunction(*LTE); + return EraseInstFromFunction(*II); + } + break; + } + break; + } case Intrinsic::assume: { // Canonicalize assume(a && b) -> assume(a); assume(b); // Note: New assumption intrinsics created here are registered by Index: test/Transforms/InstCombine/lifetime.ll =================================================================== --- /dev/null +++ test/Transforms/InstCombine/lifetime.ll @@ -0,0 +1,43 @@ +; RUN: opt < %s -instcombine -S | FileCheck %s +; RUN: opt < %s -instcombine -S | grep lifetime | count 6 + +declare void @llvm.lifetime.start(i64, i8* nocapture) +declare void @llvm.lifetime.end(i64, i8* nocapture) +declare void @bar(i8* nocapture, i8* nocapture) + +define void @foo(i1 %flag) { +entry: +; CHECK-LABEL: @foo( +; CHECK: %[[T:[^ ]+]] = getelementptr inbounds [1 x i8], [1 x i8]* %t +; CHECK: %[[B:[^ ]+]] = getelementptr inbounds [1 x i8], [1 x i8]* %b +; CHECK: call void @llvm.lifetime.start(i64 1, i8* %[[T]]) +; CHECK-NEXT: call void @llvm.lifetime.start(i64 1, i8* %[[B]]) +; CHECK-NEXT: call void @bar(i8* %[[B]], i8* %[[T]]) +; CHECK-NEXT: call void @llvm.lifetime.end(i64 1, i8* %[[B]]) +; CHECK-NEXT: call void @llvm.lifetime.end(i64 1, i8* %[[T]]) + %t = alloca [1 x i8], align 1 + %b = alloca [1 x i8], align 1 + %0 = getelementptr inbounds [1 x i8], [1 x i8]* %t, i64 0, i64 0 + %1 = getelementptr inbounds [1 x i8], [1 x i8]* %b, i64 0, i64 0 + br i1 %flag, label %if, label %else + +if: + call void @llvm.lifetime.start(i64 1, i8* %0) + call void @llvm.lifetime.start(i64 1, i8* %1) + call void @llvm.lifetime.end(i64 1, i8* %1) + call void @llvm.lifetime.end(i64 1, i8* %0) + br label %fin + +else: + call void @llvm.lifetime.start(i64 1, i8* %0) + call void @llvm.lifetime.start(i64 1, i8* %1) + call void @bar(i8* %1, i8* %0) + call void @llvm.lifetime.end(i64 1, i8* %1) + call void @llvm.lifetime.end(i64 1, i8* %0) + br label %fin + +fin: + ret void +} + +