Index: llvm/lib/Transforms/Scalar/LICM.cpp =================================================================== --- llvm/lib/Transforms/Scalar/LICM.cpp +++ llvm/lib/Transforms/Scalar/LICM.cpp @@ -1925,8 +1925,7 @@ /// Return true iff we can prove that a caller of this function can not inspect /// the contents of the provided object in a well defined program. -bool isKnownNonEscaping(Value *Object, const Loop *L, - const TargetLibraryInfo *TLI, DominatorTree *DT) { +bool isKnownNonEscaping(Value *Object, const Loop *L, DominatorTree *DT) { if (isa(Object)) // Since the alloca goes out of scope, we know the caller can't retain a // reference to it and be well defined. Thus, we don't need to check for @@ -1939,11 +1938,8 @@ // 1) Object can't be escaped by this function. This is what // PointerMayBeCaptured checks. // 2) Object can't have been captured at definition site. For this, we - // need to know the return value is noalias. At the moment, we use a - // weaker condition and handle only AllocLikeFunctions (which are - // known to be noalias). TODO - return isAllocLikeFn(Object, TLI) && - isNotCapturedBeforeOrInLoop(Object, L, DT); + // need to know the return value is noalias. + return isNoAliasCall(Object) && isNotCapturedBeforeOrInLoop(Object, L, DT); } } // namespace @@ -2030,7 +2026,7 @@ // this by proving that the caller can't have a reference to the object // after return and thus can't possibly load from the object. Value *Object = getUnderlyingObject(SomePtr); - if (!isKnownNonEscaping(Object, CurLoop, TLI, DT)) + if (!isKnownNonEscaping(Object, CurLoop, DT)) return false; // Subtlety: Alloca's aren't visible to callers, but *are* potentially // visible to other threads if captured and used during their lifetimes. @@ -2163,7 +2159,7 @@ else { Value *Object = getUnderlyingObject(SomePtr); SafeToInsertStore = - (isAllocLikeFn(Object, TLI) || isa(Object)) && + (isNoAliasCall(Object) || isa(Object)) && isNotCapturedBeforeOrInLoop(Object, CurLoop, DT); } } Index: llvm/test/Transforms/LICM/promote-tls.ll =================================================================== --- llvm/test/Transforms/LICM/promote-tls.ll +++ llvm/test/Transforms/LICM/promote-tls.ll @@ -156,15 +156,18 @@ ; CHECK-NEXT: [[EXITCMP:%.*]] = icmp eq i8* [[GUARD]], null ; CHECK-NEXT: br i1 [[EXITCMP]], label [[FOR_BODY]], label [[EARLY_EXIT:%.*]] ; CHECK: early-exit: +; CHECK-NEXT: [[NEW1_LCSSA:%.*]] = phi i32 [ [[NEW1]], [[FOR_HEADER]] ] +; CHECK-NEXT: store i32 [[NEW1_LCSSA]], i32* [[ADDR]], align 4 ; CHECK-NEXT: ret i32* null ; CHECK: for.body: ; CHECK-NEXT: [[NEW]] = add i32 [[NEW1]], 1 -; CHECK-NEXT: store i32 [[NEW]], i32* [[ADDR]], align 4 ; CHECK-NEXT: [[INC]] = add nsw i32 [[I_02]], 1 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[INC]], [[N:%.*]] ; CHECK-NEXT: br i1 [[CMP]], label [[FOR_HEADER]], label [[FOR_COND_FOR_END_CRIT_EDGE:%.*]] ; CHECK: for.cond.for.end_crit_edge: +; CHECK-NEXT: [[NEW_LCSSA:%.*]] = phi i32 [ [[NEW]], [[FOR_BODY]] ] ; CHECK-NEXT: [[SPLIT:%.*]] = phi i32* [ [[ADDR]], [[FOR_BODY]] ] +; CHECK-NEXT: store i32 [[NEW_LCSSA]], i32* [[ADDR]], align 4 ; CHECK-NEXT: ret i32* null ; entry: