llvm.org GIT mirror llvm / 3ea7b0a
[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/trunk@339636 91177308-0d34-0410-b5e6-96231b3b80d8 Reid Kleckner 1 year, 1 month ago
3 changed file(s) with 45 addition(s) and 6 deletion(s). Raw diff Collapse all Expand all
800800
801801 const Value *Object = GetUnderlyingObject(Loc.Ptr, DL);
802802
803 // If this is a tail call and Loc.Ptr points to a stack location, we know that
804 // the tail call cannot access or modify the local stack.
805 // We cannot exclude byval arguments here; these belong to the caller of
806 // the current function not to the current function, and a tail callee
807 // may reference them.
803 // Calls marked 'tail' cannot read or write allocas from the current frame
804 // because the current frame might be destroyed by the time they run. However,
805 // a tail call may use an alloca with byval. Calling with byval copies the
806 // contents of the alloca into argument registers or stack slots, so there is
807 // no lifetime issue.
808808 if (isa(Object))
809809 if (const CallInst *CI = dyn_cast(CS.getInstruction()))
810 if (CI->isTailCall())
810 if (CI->isTailCall() &&
811 !CI->getAttributes().hasAttrSomewhere(Attribute::ByVal))
811812 return ModRefInfo::NoModRef;
812813
813814 // If the pointer is to a locally allocated object that does not escape,
0 ; RUN: opt -basicaa -aa-eval -print-all-alias-modref-info -disable-output < %s 2>&1 | FileCheck %s
1
2 declare void @takebyval(i32* byval %p)
3
4 define i32 @tailbyval() {
5 entry:
6 %p = alloca i32
7 store i32 42, i32* %p
8 tail call void @takebyval(i32* byval %p)
9 %rv = load i32, i32* %p
10 ret i32 %rv
11 }
12 ; FIXME: This should be Just Ref.
13 ; CHECK-LABEL: Function: tailbyval: 1 pointers, 1 call sites
14 ; CHECK-NEXT: Both ModRef: Ptr: i32* %p <-> tail call void @takebyval(i32* byval %p)
0 ; RUN: opt -dse -S < %s | FileCheck %s
1
2 ; Don't eliminate stores to allocas before tail calls to functions that use
3 ; byval. It's correct to mark calls like these as 'tail'. To implement this tail
4 ; call, the backend should copy the bytes from the alloca into the argument area
5 ; before clearing the stack.
6
7 target datalayout = "e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128"
8 target triple = "i386-unknown-linux-gnu"
9
10 declare void @g(i32* byval %p)
11
12 define void @f(i32* byval %x) {
13 entry:
14 %p = alloca i32
15 %v = load i32, i32* %x
16 store i32 %v, i32* %p
17 tail call void @g(i32* byval %p)
18 ret void
19 }
20 ; CHECK-LABEL: define void @f(i32* byval %x)
21 ; CHECK: store i32 %v, i32* %p
22 ; CHECK: tail call void @g(i32* byval %p)