summaryrefslogtreecommitdiff
path: root/llvm
diff options
context:
space:
mode:
authorNikita Popov <npopov@redhat.com>2022-01-06 10:20:42 +0100
committerNikita Popov <npopov@redhat.com>2022-01-06 14:38:19 +0100
commit41a522779dffb79c055097b2d16aaac689e1b5e3 (patch)
tree104488426cfa5e085242b9963d5345b08b5d3290 /llvm
parentf430c1eb6443282481e72e4fd209c9ada61e7cf1 (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.cpp14
-rw-r--r--llvm/test/Transforms/LICM/promote-tls.ll5
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: