[llvm] 41a5227 - [LICM] Check for noalias call instead of alloc like fn

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Thu Jan 6 05:39:15 PST 2022


Author: Nikita Popov
Date: 2022-01-06T14:38:19+01:00
New Revision: 41a522779dffb79c055097b2d16aaac689e1b5e3

URL: https://github.com/llvm/llvm-project/commit/41a522779dffb79c055097b2d16aaac689e1b5e3
DIFF: https://github.com/llvm/llvm-project/commit/41a522779dffb79c055097b2d16aaac689e1b5e3.diff

LOG: [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

Added: 
    

Modified: 
    llvm/lib/Transforms/Scalar/LICM.cpp
    llvm/test/Transforms/LICM/promote-tls.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Scalar/LICM.cpp b/llvm/lib/Transforms/Scalar/LICM.cpp
index bc792ca3d8da2..80ed671b0a523 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 a0c966eee79a1..d7d23273acf08 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:


        


More information about the llvm-commits mailing list