[GlobalsAA] Partially back out r248576

See PR25822 for a more full summary, but we were conflating the concepts of "capture" and "escape". We were proving nocapture and using that proof to infer noescape, which is not true. Escaped-ness is a function-local property - as soon as a value is used in a call argument it escapes. Capturedness is a related but distinct property. It implies a *temporally limited* escape. Consider:

  static int a;
  int b;
  int g(int * nocapture arg);
  int f() {
    a = 2;  // Even though a escapes to g, it is not captured so can be treated as non-escaping here.
    g(&a);  // But here it must be treated as escaping.
    g(&b);  // Now that g(&a) has returned we know it was not captured so we can treat it as non-escaping again.
  }

The original commit did not sufficiently understand this nuance and so caused PR25822 and PR26046.

r248576 included both a performance improvement (which has been backed out) and a related conformance fix (which has been kept along with its testcase).

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@257058 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
James Molloy 2016-01-07 13:33:28 +00:00
parent 699e85dc45
commit 6a8908e979
2 changed files with 0 additions and 72 deletions

View File

@ -358,21 +358,6 @@ bool GlobalsAAResult::AnalyzeUsesOfPointer(Value *V,
if (CS.isArgOperand(&U) && isFreeCall(I, &TLI)) {
if (Writers)
Writers->insert(CS->getParent()->getParent());
} else if (CS.doesNotCapture(CS.getDataOperandNo(&U))) {
Function *ParentF = CS->getParent()->getParent();
// A nocapture argument may be read from or written to, but does not
// escape unless the call can somehow recurse.
//
// nocapture "indicates that the callee does not make any copies of
// the pointer that outlive itself". Therefore if we directly or
// indirectly recurse, we must treat the pointer as escaping.
if (FunctionToSCCMap[ParentF] ==
FunctionToSCCMap[CS.getCalledFunction()])
return true;
if (Readers)
Readers->insert(ParentF);
if (Writers)
Writers->insert(ParentF);
} else {
return true; // Argument of an unknown call.
}

View File

@ -1,57 +0,0 @@
; RUN: opt < %s -globals-aa -aa-eval -print-all-alias-modref-info -disable-output 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
}
declare void @g3()
; CHECK-LABEL: Function: f3
; CHECK: NoAlias: i32* %p, i32* @b
define void @f3(i32* nocapture readonly %p) {
entry:
tail call void @g3() [ "deopt"(i32* @b, i32 *%p) ]
unreachable
}