1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 19:23:23 +01:00
llvm-mirror/test/Analysis/GlobalsModRef/nocapture.ll
James Molloy 07acfd5604 [GlobalsAA] Teach GlobalsAA about nocapture
Arguments to function calls marked "nocapture" can be marked as
non-escaping. However, nocapture is defined in terms of the lifetime
of the callee, and if the callee can directly or indirectly recurse to
the caller, the semantics of nocapture are invalid.

Therefore, we eagerly discover which SCC each function belongs to,
and later can check if callee and caller of a callsite belong to
the same SCC, in which case there could be recursion.

This means that we can't be so optimistic in
getModRefInfo(ImmutableCallsite) - previously we assumed all call
arguments never aliased with an escaping global. Now we need to check,
because a global could now be passed as an argument but still not
escape.

This also solves a related conformance problem: MemCpyOptimizer can
turn non-escaping stores of globals into calls to intrinsics like
llvm.memcpy/llvm/memset. This confuses GlobalsAA, which knows the
global can't escape and so returns NoModRef when queried, when
obviously a memcpy/memset call does indeed reference and modify its
arguments.

This fixes PR24800, PR24801, and PR24802.

llvm-svn: 248576
2015-09-25 15:39:29 +00:00

48 lines
1.4 KiB
LLVM

; RUN: opt < %s -globals-aa -aa-eval -print-all-alias-modref-info -S 2>&1 | FileCheck %s
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-apple-macosx10.10.0"
@a = internal global i32 0, align 4
@b = internal global i32 0, align 4
define void @g(i32* %p, void (i32*)* nocapture %ptr) {
entry:
tail call void %ptr(i32* %p) #1
ret void
}
; CHECK-LABEL: Function: f
; CHECK: MayAlias: i32* %p, i32* @a
; CHECK: MayAlias: i32* %q, i32* @a
define i32 @f(i32 %n, i32* nocapture readonly %p, i32* nocapture %q, void (i32*)* nocapture %ptr) {
entry:
tail call void @g(i32* nonnull @a, void (i32*)* %ptr)
%arrayidx = getelementptr inbounds i32, i32* %p, i64 0
%z1 = load i32, i32* %arrayidx, align 4
%z2 = load i32, i32* %q, align 4
%add = add nsw i32 %z2, %z1
store i32 %add, i32* %q, align 4
ret i32 4
}
define void @g2(i32* nocapture %p, void (i32*)* nocapture %ptr) {
entry:
tail call void %ptr(i32* %p) #1
ret void
}
; CHECK-LABEL: Function: f2
; CHECK: NoAlias: i32* %p, i32* @b
; CHECK: NoAlias: i32* %q, i32* @b
define i32 @f2(i32 %n, i32* nocapture readonly %p, i32* nocapture %q, void (i32*)* nocapture %ptr) {
entry:
tail call void @g2(i32* nonnull @b, void (i32*)* %ptr)
%arrayidx = getelementptr inbounds i32, i32* %p, i64 0
%z1 = load i32, i32* %arrayidx, align 4
%z2 = load i32, i32* %q, align 4
%add = add nsw i32 %z2, %z1
store i32 %add, i32* %q, align 4
ret i32 4
}