Index: lib/Transforms/Scalar/LICM.cpp =================================================================== --- lib/Transforms/Scalar/LICM.cpp +++ lib/Transforms/Scalar/LICM.cpp @@ -1004,8 +1004,18 @@ // That said, we can't actually make the unwind edge explicit. Therefore, // we have to prove that the store is dead along the unwind edge. // - // Currently, this code just special-cases alloca instructions. - if (!isa(GetUnderlyingObject(SomePtr, MDL))) + // If the underlying object is not an alloca, nor a pointer that does not + // escape, then we can not effectively prove that the store is dead along + // the unwind edge. i.e. the caller of this function could have ways to + // access the pointed object. + // + // NOTE: PointerMayBeCaptured is not enough as the pointer may have escaped + // even though its not captured by the enclosing function. Standard allocation + // functions like malloc, calloc, and operator new return values which can + // be assumed not to have previously escaped. + Value *Object = GetUnderlyingObject(SomePtr, MDL); + if (!isa(Object) && + (!isAllocLikeFn(Object, TLI) || PointerMayBeCaptured(Object, true, true))) return false; } Index: test/Transforms/LICM/scalar-promote-unwind.ll =================================================================== --- test/Transforms/LICM/scalar-promote-unwind.ll +++ test/Transforms/LICM/scalar-promote-unwind.ll @@ -137,6 +137,42 @@ resume { i8*, i32 } %lpad.val3 } +; This is a local allocation by new and the returned pointer is +; not captured, so in case of unwind, the caller will have no way +; to access this memory. +define void @local_allocation(i1 zeroext %y) uwtable { +entry: + %n = call i8* @_Znwm(i64 4) + %a = bitcast i8* %n to i32* + br label %for.body + +; CHECK: for.body: +; CHECK-NOT: load +; CHECK-NOT: store +; CHECK: br +for.body: + %i.03 = phi i32 [ 0, %entry ], [ %inc, %for.inc ] + %0 = load i32, i32* %a, align 4 + %add = add nsw i32 %0, 1 + store i32 %add, i32* %a, align 4 + br i1 %y, label %if.then, label %for.inc + +if.then: + tail call void @f() + br label %for.inc + +for.inc: + %inc = add nuw nsw i32 %i.03, 1 + %exitcond = icmp eq i32 %inc, 10000 + br i1 %exitcond, label %for.cond.cleanup, label %for.body + +; CHECK: for.cond.cleanup: +; CHECK: store +; CHECK: ret void +for.cond.cleanup: + ret void +} + declare void @boo() declare i32 @__gxx_personality_v0(...) @@ -148,3 +184,6 @@ declare void @__cxa_end_catch() declare void @f() uwtable + +; Function Attrs: nobuiltin +declare noalias i8* @_Znwm(i64)