Load tracking means that the value analyzed may
authorDuncan Sands <baldrick@free.fr>
Fri, 2 Jan 2009 15:16:38 +0000 (15:16 +0000)
committerDuncan Sands <baldrick@free.fr>
Fri, 2 Jan 2009 15:16:38 +0000 (15:16 +0000)
not have pointer type.  In particular, it may
be the condition argument for a select or a GEP
index.  While I was unable to construct a testcase
for which some bits of the original pointer are
captured due to one of these, it's very very close
to being possible - so play safe and exclude these
possibilities.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@61580 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/IPO/FunctionAttrs.cpp

index 13fb75619d45682fcec81680bb84ca3dab9effa6..aea4cb4cf2628dfc399016a998223d4aa5b7b420 100644 (file)
@@ -198,6 +198,7 @@ bool FunctionAttrs::isCaptured(Function &F, Value *V) {
     UseWithDepth UD = Worklist.pop_back_val();
     Use *U = UD.getPointer();
     Instruction *I = cast<Instruction>(U->getUser());
+    // The value V may have any type if it comes from tracking a load.
     V = U->get();
     // The depth represents the number of loads that need to be performed to
     // get back the original pointer (or a bitcast etc of it).  For example,
@@ -253,7 +254,10 @@ bool FunctionAttrs::isCaptured(Function &F, Value *V) {
       // Only passed via 'nocapture' arguments, or is the called function - not
       // captured.
     } else if (isa<BitCastInst>(I) || isa<LoadInst>(I) || isa<PHINode>(I) ||
-               isa<GetElementPtrInst>(I) || isa<SelectInst>(I)) {
+               // Play safe and exclude GEP indices.
+               (isa<GetElementPtrInst>(I) && V == I->getOperand(0)) ||
+               // Play safe and exclude the select condition.
+               (isa<SelectInst>(I) && V != I->getOperand(0))) {
 
       // Usually loads can be ignored because they dereference the original
       // pointer.  However the loaded value needs to be tracked if loading
@@ -267,7 +271,9 @@ bool FunctionAttrs::isCaptured(Function &F, Value *V) {
           continue;
         // Loading a pointer to (a pointer to...) the original pointer or a
         // variation of it.  Track uses of the loaded value, noting that one
-        // dereference was performed.
+        // dereference was performed.  Note that the loaded value need not be
+        // of pointer type.  For example, an alloca may have been bitcast to
+        // a pointer to another type, which was then loaded.
         --Depth;
       }