[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