[PATCH] D20555: [MemCpyOpt] Be conservative in the face of returns_twice calls

David Majnemer via llvm-commits llvm-commits at lists.llvm.org
Tue May 24 22:51:11 PDT 2016


majnemer updated this revision to Diff 58385.
majnemer added a comment.

Move this change over to functionattrs.


http://reviews.llvm.org/D20555

Files:
  lib/Analysis/CaptureTracking.cpp
  test/Transforms/FunctionAttrs/nocapture.ll

Index: test/Transforms/FunctionAttrs/nocapture.ll
===================================================================
--- test/Transforms/FunctionAttrs/nocapture.ll
+++ test/Transforms/FunctionAttrs/nocapture.ll
@@ -210,3 +210,11 @@
   atomicrmw add i32* %p, i32 1 seq_cst
   ret void
 }
+
+; CHECK: define void @test_volatile(i32* %x)
+define void @test_volatile(i32* %x) {
+entry:
+  %gep = getelementptr i32, i32* %x, i64 1
+  store volatile i32 0, i32* %gep, align 4
+  ret void
+}
Index: lib/Analysis/CaptureTracking.cpp
===================================================================
--- lib/Analysis/CaptureTracking.cpp
+++ lib/Analysis/CaptureTracking.cpp
@@ -26,6 +26,7 @@
 #include "llvm/IR/Constants.h"
 #include "llvm/IR/Dominators.h"
 #include "llvm/IR/Instructions.h"
+#include "llvm/IR/IntrinsicInst.h"
 
 using namespace llvm;
 
@@ -242,6 +243,13 @@
       if (CS.onlyReadsMemory() && CS.doesNotThrow() && I->getType()->isVoidTy())
         break;
 
+      // Volatile operations effectively capture the memory location that they
+      // load and store to.
+      if (auto *MI = dyn_cast<MemIntrinsic>(I))
+        if (MI->isVolatile())
+          if (Tracker->captured(U))
+            return;
+
       // Not captured if only passed via 'nocapture' arguments.  Note that
       // calling a function pointer does not in itself cause the pointer to
       // be captured.  This is a subtle point considering that (for example)
@@ -259,29 +267,46 @@
       break;
     }
     case Instruction::Load:
-      // Loading from a pointer does not cause it to be captured.
+      // Volatile loads make the address observable.
+      if (cast<LoadInst>(I)->isVolatile())
+        if (Tracker->captured(U))
+          return;
       break;
     case Instruction::VAArg:
       // "va-arg" from a pointer does not cause it to be captured.
       break;
     case Instruction::Store:
-      if (V == I->getOperand(0))
         // Stored the pointer - conservatively assume it may be captured.
+        // Volatile stores make the address observable.
+      if (V == I->getOperand(0) || cast<StoreInst>(I)->isVolatile())
         if (Tracker->captured(U))
           return;
-      // Storing to the pointee does not cause the pointer to be captured.
       break;
-    case Instruction::AtomicRMW:
-    case Instruction::AtomicCmpXchg:
-      // atomicrmw and cmpxchg conceptually include both a load and store from
-      // the same location.  As with a store, the location being accessed is
-      // not captured, but the value being stored is.  (For cmpxchg, we
-      // probably don't need to capture the original comparison value, but for
-      // the moment, let's be conservative.)
-      if (V != I->getOperand(0))
+    case Instruction::AtomicRMW: {
+      // atomicrmw conceptually includes both a load and store from
+      // the same location.
+      // As with a store, the location being accessed is not captured,
+      // but the value being stored is.
+      // Volatile stores make the address observable.
+      auto *ARMWI = cast<AtomicRMWInst>(I);
+      if (ARMWI->getValOperand() == V || ARMWI->isVolatile())
         if (Tracker->captured(U))
           return;
       break;
+    }
+    case Instruction::AtomicCmpXchg: {
+      // cmpxchg conceptually includes both a load and store from
+      // the same location.
+      // As with a store, the location being accessed is not captured,
+      // but the value being stored is.
+      // Volatile stores make the address observable.
+      auto *ACXI = cast<AtomicCmpXchgInst>(I);
+      if (ACXI->getCompareOperand() == V || ACXI->getNewValOperand() == V ||
+          ACXI->isVolatile())
+        if (Tracker->captured(U))
+          return;
+      break;
+    }
     case Instruction::BitCast:
     case Instruction::GetElementPtr:
     case Instruction::PHI:


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D20555.58385.patch
Type: text/x-patch
Size: 3859 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160525/9c8ed0bb/attachment.bin>


More information about the llvm-commits mailing list