Skip to content

Commit 41a5227

Browse files
committed
[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
1 parent f430c1e commit 41a5227

File tree

2 files changed

+9
-10
lines changed

2 files changed

+9
-10
lines changed

llvm/lib/Transforms/Scalar/LICM.cpp

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1925,8 +1925,7 @@ bool isNotCapturedBeforeOrInLoop(const Value *V, const Loop *L,
19251925

19261926
/// Return true iff we can prove that a caller of this function can not inspect
19271927
/// the contents of the provided object in a well defined program.
1928-
bool isKnownNonEscaping(Value *Object, const Loop *L,
1929-
const TargetLibraryInfo *TLI, DominatorTree *DT) {
1928+
bool isKnownNonEscaping(Value *Object, const Loop *L, DominatorTree *DT) {
19301929
if (isa<AllocaInst>(Object))
19311930
// Since the alloca goes out of scope, we know the caller can't retain a
19321931
// 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,
19391938
// 1) Object can't be escaped by this function. This is what
19401939
// PointerMayBeCaptured checks.
19411940
// 2) Object can't have been captured at definition site. For this, we
1942-
// need to know the return value is noalias. At the moment, we use a
1943-
// weaker condition and handle only AllocLikeFunctions (which are
1944-
// known to be noalias). TODO
1945-
return isAllocLikeFn(Object, TLI) &&
1946-
isNotCapturedBeforeOrInLoop(Object, L, DT);
1941+
// need to know the return value is noalias.
1942+
return isNoAliasCall(Object) && isNotCapturedBeforeOrInLoop(Object, L, DT);
19471943
}
19481944

19491945
} // namespace
@@ -2030,7 +2026,7 @@ bool llvm::promoteLoopAccessesToScalars(
20302026
// this by proving that the caller can't have a reference to the object
20312027
// after return and thus can't possibly load from the object.
20322028
Value *Object = getUnderlyingObject(SomePtr);
2033-
if (!isKnownNonEscaping(Object, CurLoop, TLI, DT))
2029+
if (!isKnownNonEscaping(Object, CurLoop, DT))
20342030
return false;
20352031
// Subtlety: Alloca's aren't visible to callers, but *are* potentially
20362032
// visible to other threads if captured and used during their lifetimes.
@@ -2163,7 +2159,7 @@ bool llvm::promoteLoopAccessesToScalars(
21632159
else {
21642160
Value *Object = getUnderlyingObject(SomePtr);
21652161
SafeToInsertStore =
2166-
(isAllocLikeFn(Object, TLI) || isa<AllocaInst>(Object)) &&
2162+
(isNoAliasCall(Object) || isa<AllocaInst>(Object)) &&
21672163
isNotCapturedBeforeOrInLoop(Object, CurLoop, DT);
21682164
}
21692165
}

llvm/test/Transforms/LICM/promote-tls.ll

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,15 +156,18 @@ define i32* @test_custom_malloc(i32 %n) {
156156
; CHECK-NEXT: [[EXITCMP:%.*]] = icmp eq i8* [[GUARD]], null
157157
; CHECK-NEXT: br i1 [[EXITCMP]], label [[FOR_BODY]], label [[EARLY_EXIT:%.*]]
158158
; CHECK: early-exit:
159+
; CHECK-NEXT: [[NEW1_LCSSA:%.*]] = phi i32 [ [[NEW1]], [[FOR_HEADER]] ]
160+
; CHECK-NEXT: store i32 [[NEW1_LCSSA]], i32* [[ADDR]], align 4
159161
; CHECK-NEXT: ret i32* null
160162
; CHECK: for.body:
161163
; CHECK-NEXT: [[NEW]] = add i32 [[NEW1]], 1
162-
; CHECK-NEXT: store i32 [[NEW]], i32* [[ADDR]], align 4
163164
; CHECK-NEXT: [[INC]] = add nsw i32 [[I_02]], 1
164165
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[INC]], [[N:%.*]]
165166
; CHECK-NEXT: br i1 [[CMP]], label [[FOR_HEADER]], label [[FOR_COND_FOR_END_CRIT_EDGE:%.*]]
166167
; CHECK: for.cond.for.end_crit_edge:
168+
; CHECK-NEXT: [[NEW_LCSSA:%.*]] = phi i32 [ [[NEW]], [[FOR_BODY]] ]
167169
; CHECK-NEXT: [[SPLIT:%.*]] = phi i32* [ [[ADDR]], [[FOR_BODY]] ]
170+
; CHECK-NEXT: store i32 [[NEW_LCSSA]], i32* [[ADDR]], align 4
168171
; CHECK-NEXT: ret i32* null
169172
;
170173
entry:

0 commit comments

Comments
 (0)