Don't Place Entry Safepoints Before the llvm.frameescape() Intrinsic
authorPhilip Reames <listmail@philipreames.com>
Sun, 26 Apr 2015 19:41:23 +0000 (19:41 +0000)
committerPhilip Reames <listmail@philipreames.com>
Sun, 26 Apr 2015 19:41:23 +0000 (19:41 +0000)
llvm.frameescape() intrinsic is not a real call. The intrinsic can only exist in the entry block. Inserting a gc.statepoint() before llvm.frameescape() may split the entry block, and push the intrinsic out of the entry block.

Patch by: Swaroop.Sridhar@microsoft.com
Differential Revision: http://reviews.llvm.org/D8910

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

lib/Transforms/Scalar/PlaceSafepoints.cpp
test/Transforms/PlaceSafepoints/statepoint-frameescape.ll [new file with mode: 0644]

index 536f2a673bbdeaadedc5f7ca5faf814cc741732a..ffed810d823b5c613803495b5ac296fde51c140a 100644 (file)
@@ -430,6 +430,13 @@ static Instruction *findLocationForEntrySafepoint(Function &F,
         if (II->getIntrinsicID() == Intrinsic::assume) {
           continue;
         }
+        // llvm.frameescape() intrinsic is not a real call. The intrinsic can 
+        // exist only in the entry block.
+        // Inserting a statepoint before llvm.frameescape() may split the 
+        // entry block, and push the intrinsic out of the entry block.
+        if (II->getIntrinsicID() == Intrinsic::frameescape) {
+          continue;
+        }
       }
       break;
     }
diff --git a/test/Transforms/PlaceSafepoints/statepoint-frameescape.ll b/test/Transforms/PlaceSafepoints/statepoint-frameescape.ll
new file mode 100644 (file)
index 0000000..e24c900
--- /dev/null
@@ -0,0 +1,29 @@
+; RUN: opt %s -S -place-safepoints | FileCheck %s
+
+declare void @llvm.frameescape(...)
+
+; Do we insert the entry safepoint after the frameescape intrinsic?
+define void @parent() gc "statepoint-example" {
+; CHECK-LABEL: @parent
+entry:
+; CHECK-LABEL: entry
+; CHECK-NEXT: alloca
+; CHECK-NEXT: frameescape
+; CHECK-NEXT: statepoint
+  %ptr = alloca i32
+  call void (...) @llvm.frameescape(i32* %ptr)
+  ret void
+}
+
+; This function is inlined when inserting a poll.  To avoid recursive 
+; issues, make sure we don't place safepoints in it.
+declare void @do_safepoint()
+define void @gc.safepoint_poll() {
+; CHECK-LABEL: gc.safepoint_poll
+; CHECK-LABEL: entry
+; CHECK-NEXT: do_safepoint
+; CHECK-NEXT: ret void 
+entry:
+  call void @do_safepoint()
+  ret void
+}