[llvm] r331587 - [CaptureTracking] Handle capturing of launder.invariant.group

Piotr Padlewski via llvm-commits llvm-commits at lists.llvm.org
Sat May 5 03:23:27 PDT 2018


Author: prazek
Date: Sat May  5 03:23:27 2018
New Revision: 331587

URL: http://llvm.org/viewvc/llvm-project?rev=331587&view=rev
Log:
[CaptureTracking] Handle capturing of launder.invariant.group

Summary:
launder.invariant.group has the same rules of capturing as
bitcast, gep, etc - the original value is not captured
if the returned pointer is not captured.

With this patch, we mark 40% more functions as noalias when compiling with -fstrict-vtable-pointers;
1078 vs 1778  (39.37%)

Reviewers: sanjoy, davide, nlewycky, majnemer, mehdi_amini

Subscribers: JDevlieghere, llvm-commits

Differential Revision: https://reviews.llvm.org/D32673

Modified:
    llvm/trunk/lib/Analysis/CaptureTracking.cpp
    llvm/trunk/test/Transforms/FunctionAttrs/nocapture.ll

Modified: llvm/trunk/lib/Analysis/CaptureTracking.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/CaptureTracking.cpp?rev=331587&r1=331586&r2=331587&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/CaptureTracking.cpp (original)
+++ llvm/trunk/lib/Analysis/CaptureTracking.cpp Sat May  5 03:23:27 2018
@@ -215,18 +215,22 @@ void llvm::PointerMayBeCaptured(const Va
   assert(V->getType()->isPointerTy() && "Capture is for pointers only!");
   SmallVector<const Use *, Threshold> Worklist;
   SmallSet<const Use *, Threshold> Visited;
-  int Count = 0;
 
-  for (const Use &U : V->uses()) {
-    // If there are lots of uses, conservatively say that the value
-    // is captured to avoid taking too much compile time.
-    if (Count++ >= Threshold)
-      return Tracker->tooManyUses();
-
-    if (!Tracker->shouldExplore(&U)) continue;
-    Visited.insert(&U);
-    Worklist.push_back(&U);
-  }
+  auto AddUses = [&](const Value *V) {
+    int Count = 0;
+    for (const Use &U : V->uses()) {
+      // If there are lots of uses, conservatively say that the value
+      // is captured to avoid taking too much compile time.
+      if (Count++ >= Threshold)
+        return Tracker->tooManyUses();
+      if (!Visited.insert(&U).second)
+        continue;
+      if (!Tracker->shouldExplore(&U))
+        continue;
+      Worklist.push_back(&U);
+    }
+  };
+  AddUses(V);
 
   while (!Worklist.empty()) {
     const Use *U = Worklist.pop_back_val();
@@ -243,6 +247,13 @@ void llvm::PointerMayBeCaptured(const Va
       if (CS.onlyReadsMemory() && CS.doesNotThrow() && I->getType()->isVoidTy())
         break;
 
+      // launder.invariant.group only captures pointer by returning it,
+      // so the pointer wasn't captured if returned pointer is not captured.
+      if (CS.getIntrinsicID() == Intrinsic::launder_invariant_group) {
+        AddUses(I);
+        break;
+      }
+
       // Volatile operations effectively capture the memory location that they
       // load and store to.
       if (auto *MI = dyn_cast<MemIntrinsic>(I))
@@ -313,17 +324,7 @@ void llvm::PointerMayBeCaptured(const Va
     case Instruction::Select:
     case Instruction::AddrSpaceCast:
       // The original value is not captured via this if the new value isn't.
-      Count = 0;
-      for (Use &UU : I->uses()) {
-        // If there are lots of uses, conservatively say that the value
-        // is captured to avoid taking too much compile time.
-        if (Count++ >= Threshold)
-          return Tracker->tooManyUses();
-
-        if (Visited.insert(&UU).second)
-          if (Tracker->shouldExplore(&UU))
-            Worklist.push_back(&UU);
-      }
+      AddUses(I);
       break;
     case Instruction::ICmp: {
       // Don't count comparisons of a no-alias return value against null as

Modified: llvm/trunk/test/Transforms/FunctionAttrs/nocapture.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/FunctionAttrs/nocapture.ll?rev=331587&r1=331586&r2=331587&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/FunctionAttrs/nocapture.ll (original)
+++ llvm/trunk/test/Transforms/FunctionAttrs/nocapture.ll Sat May  5 03:23:27 2018
@@ -220,3 +220,21 @@ entry:
   store volatile i32 0, i32* %gep, align 4
   ret void
 }
+
+; CHECK: nocaptureLaunder(i8* nocapture %p)
+define void @nocaptureLaunder(i8* %p) {
+entry:
+  %b = call i8* @llvm.launder.invariant.group.p0i8(i8* %p)
+  store i8 42, i8* %b
+  ret void
+}
+
+ at g2 = global i8* null
+; CHECK: define void @captureLaunder(i8* %p)
+define void @captureLaunder(i8* %p) {
+  %b = call i8* @llvm.launder.invariant.group.p0i8(i8* %p)
+  store i8* %b, i8** @g2
+  ret void
+}
+
+declare i8* @llvm.launder.invariant.group.p0i8(i8*)




More information about the llvm-commits mailing list