summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorReid Kleckner <rnk@google.com>2018-08-14 17:35:35 +0000
committerReid Kleckner <rnk@google.com>2018-08-14 17:35:35 +0000
commit36b087d5b5501ffa2304766a1b6a5cf1264bca5b (patch)
tree2cfb52caf985f5afe388156760a6ba642c1b6e1b /test
parent9360946c87148bfd76c4cf5e39bbd98ef1d18bb7 (diff)
Merging r339636:
------------------------------------------------------------------------ r339636 | rnk | 2018-08-13 18:24:35 -0700 (Mon, 13 Aug 2018) | 17 lines [BasicAA] Don't assume tail calls with byval don't alias allocas Summary: Calls marked 'tail' cannot read or write allocas from the current frame because the current frame might be destroyed by the time they run. However, a tail call may use an alloca with byval. Calling with byval copies the contents of the alloca into argument registers or stack slots, so there is no lifetime issue. Tail calls never modify allocas, so we can return just ModRefInfo::Ref. Fixes PR38466, a longstanding bug. Reviewers: hfinkel, nlewycky, gbiv, george.burgess.iv Subscribers: hiraditya, llvm-commits Differential Revision: https://reviews.llvm.org/D50679 ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_70@339698 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test')
-rw-r--r--test/Analysis/BasicAA/tail-byval.ll15
-rw-r--r--test/Transforms/DeadStoreElimination/tail-byval.ll23
2 files changed, 38 insertions, 0 deletions
diff --git a/test/Analysis/BasicAA/tail-byval.ll b/test/Analysis/BasicAA/tail-byval.ll
new file mode 100644
index 00000000000..0aa8dfdaedf
--- /dev/null
+++ b/test/Analysis/BasicAA/tail-byval.ll
@@ -0,0 +1,15 @@
+; RUN: opt -basicaa -aa-eval -print-all-alias-modref-info -disable-output < %s 2>&1 | FileCheck %s
+
+declare void @takebyval(i32* byval %p)
+
+define i32 @tailbyval() {
+entry:
+ %p = alloca i32
+ store i32 42, i32* %p
+ tail call void @takebyval(i32* byval %p)
+ %rv = load i32, i32* %p
+ ret i32 %rv
+}
+; FIXME: This should be Just Ref.
+; CHECK-LABEL: Function: tailbyval: 1 pointers, 1 call sites
+; CHECK-NEXT: Both ModRef: Ptr: i32* %p <-> tail call void @takebyval(i32* byval %p)
diff --git a/test/Transforms/DeadStoreElimination/tail-byval.ll b/test/Transforms/DeadStoreElimination/tail-byval.ll
new file mode 100644
index 00000000000..ed2fbd434a7
--- /dev/null
+++ b/test/Transforms/DeadStoreElimination/tail-byval.ll
@@ -0,0 +1,23 @@
+; RUN: opt -dse -S < %s | FileCheck %s
+
+; Don't eliminate stores to allocas before tail calls to functions that use
+; byval. It's correct to mark calls like these as 'tail'. To implement this tail
+; call, the backend should copy the bytes from the alloca into the argument area
+; before clearing the stack.
+
+target datalayout = "e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128"
+target triple = "i386-unknown-linux-gnu"
+
+declare void @g(i32* byval %p)
+
+define void @f(i32* byval %x) {
+entry:
+ %p = alloca i32
+ %v = load i32, i32* %x
+ store i32 %v, i32* %p
+ tail call void @g(i32* byval %p)
+ ret void
+}
+; CHECK-LABEL: define void @f(i32* byval %x)
+; CHECK: store i32 %v, i32* %p
+; CHECK: tail call void @g(i32* byval %p)