diff options
| author | Nikita Popov <npopov@redhat.com> | 2022-01-06 10:20:42 +0100 |
|---|---|---|
| committer | Nikita Popov <npopov@redhat.com> | 2022-01-06 14:38:19 +0100 |
| commit | 41a522779dffb79c055097b2d16aaac689e1b5e3 (patch) | |
| tree | 104488426cfa5e085242b9963d5345b08b5d3290 /llvm | |
| parent | f430c1eb6443282481e72e4fd209c9ada61e7cf1 (diff) | |
[LICM] Check for noalias call instead of alloc like fn
When determining whether the memory is local to the function (and
we can thus introduce spurious writes without thread-safety issues),
check for a noalias call rather than the hardcoded list of memory
allocation functions. Noalias calls are the more general way to
determine allocation functions, as long as we're only interested
in the property that the returned value is distinct from any other
accessible memory.
Differential Revision: https://reviews.llvm.org/D116728
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/lib/Transforms/Scalar/LICM.cpp | 14 | ||||
| -rw-r--r-- | llvm/test/Transforms/LICM/promote-tls.ll | 5 |
2 files changed, 9 insertions, 10 deletions
diff --git a/llvm/lib/Transforms/Scalar/LICM.cpp b/llvm/lib/Transforms/Scalar/LICM.cpp index bc792ca3d8da..80ed671b0a52 100644 --- a/llvm/lib/Transforms/Scalar/LICM.cpp +++ b/llvm/lib/Transforms/Scalar/LICM.cpp @@ -1925,8 +1925,7 @@ bool isNotCapturedBeforeOrInLoop(const Value *V, const Loop *L, /// 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<AllocaInst>(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 @@ bool isKnownNonEscaping(Value *Object, const Loop *L, // 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 @@ bool llvm::promoteLoopAccessesToScalars( // 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 @@ bool llvm::promoteLoopAccessesToScalars( else { Value *Object = getUnderlyingObject(SomePtr); SafeToInsertStore = - (isAllocLikeFn(Object, TLI) || isa<AllocaInst>(Object)) && + (isNoAliasCall(Object) || isa<AllocaInst>(Object)) && isNotCapturedBeforeOrInLoop(Object, CurLoop, DT); } } diff --git a/llvm/test/Transforms/LICM/promote-tls.ll b/llvm/test/Transforms/LICM/promote-tls.ll index a0c966eee79a..d7d23273acf0 100644 --- a/llvm/test/Transforms/LICM/promote-tls.ll +++ b/llvm/test/Transforms/LICM/promote-tls.ll @@ -156,15 +156,18 @@ define i32* @test_custom_malloc(i32 %n) { ; 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: |
