Index: lib/CodeGen/CGDecl.cpp =================================================================== --- lib/CodeGen/CGDecl.cpp +++ lib/CodeGen/CGDecl.cpp @@ -1026,7 +1026,11 @@ // regions which need more efforts to handle them correctly. PR28267 // This is rare case, but it's better just omit intrinsics than have // them incorrectly placed. - if (!Bypasses.IsBypassed(&D)) { + // + // Skip emitting lifetime intrinsics when a label was seen in the + // current block and we are compiling for C. + if (!Bypasses.IsBypassed(&D) && + !(!getLangOpts().CPlusPlus && labelSeen())) { uint64_t size = CGM.getDataLayout().getTypeAllocSize(allocaTy); emission.SizeForLifetimeMarkers = EmitLifetimeStart(size, address.getPointer()); Index: lib/CodeGen/CodeGenFunction.h =================================================================== --- lib/CodeGen/CodeGenFunction.h +++ lib/CodeGen/CodeGenFunction.h @@ -212,6 +212,13 @@ /// value. This is invalid iff the function has no return value. Address ReturnValue; + /// Return true if a label was seen in the current block. + bool labelSeen() const { + if (CurLexicalScope) + return CurLexicalScope->hasLabels(); + return !LabelMap.empty(); + } + /// AllocaInsertPoint - This is an instruction in the entry block before which /// we prefer to insert allocas. llvm::AssertingVH AllocaInsertPt; @@ -620,6 +627,10 @@ rescopeLabels(); } + bool hasLabels() const { + return !Labels.empty(); + } + void rescopeLabels(); }; Index: test/CodeGen/lifetime2.c =================================================================== --- test/CodeGen/lifetime2.c +++ test/CodeGen/lifetime2.c @@ -1,7 +1,7 @@ -// RUN: %clang -S -emit-llvm -o - -O2 %s | FileCheck %s -check-prefixes=CHECK,O2 -// RUN: %clang -S -emit-llvm -o - -O2 -Xclang -disable-lifetime-markers %s \ +// RUN: %clang_cc1 -S -emit-llvm -o - -O2 -disable-llvm-passes %s | FileCheck %s -check-prefixes=CHECK,O2 +// RUN: %clang_cc1 -S -emit-llvm -o - -O2 -disable-lifetime-markers %s \ // RUN: | FileCheck %s -check-prefixes=CHECK,O0 -// RUN: %clang -S -emit-llvm -o - -O0 %s | FileCheck %s -check-prefixes=CHECK,O0 +// RUN: %clang_cc1 -S -emit-llvm -o - -O0 %s | FileCheck %s -check-prefixes=CHECK,O0 extern int bar(char *A, int n); @@ -25,13 +25,11 @@ char x; l1: bar(&x, 1); - // O2: @llvm.lifetime.start(i64 5 - // O2: @llvm.lifetime.end(i64 5 char y[5]; bar(y, 5); goto l1; // Infinite loop - // O2-NOT: @llvm.lifetime.end(i64 1 + // O2-NOT: @llvm.lifetime.end( } // CHECK-LABEL: @goto_bypass @@ -91,3 +89,24 @@ L: bar(&x, 1); } + +// O2-LABEL: define i32 @jump_backward_over_declaration( +// O2-NOT: call void @llvm.lifetime.{{.*}}(i64 4, + +extern void foo2(int p); + +int jump_backward_over_declaration(int a) { + int *p = 0; +label1: + if (p) { + foo2(*p); + return 0; + } + + int i = 999; + if (a != 2) { + p = &i; + goto label1; + } + return -1; +}