Skip to content

Commit

Permalink
Propagate nonnull and dereferenceable throught launder
Browse files Browse the repository at this point in the history
Summary:
invariant.group.launder should not stop propagation
of nonnull and dereferenceable, because e.g. we would not be
able to hoist loads speculatively.

Reviewers: rsmith, amharc, kuhar, xbolva00, hfinkel

Subscribers: hiraditya, llvm-commits

Differential Revision: https://reviews.llvm.org/D46972

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@332788 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
prazek committed May 18, 2018
1 parent 6ebd054 commit 461e372
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 3 deletions.
7 changes: 5 additions & 2 deletions lib/Analysis/Loads.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,11 +107,14 @@ static bool isDereferenceableAndAlignedPointer(
return isDereferenceableAndAlignedPointer(ASC->getOperand(0), Align, Size,
DL, CtxI, DT, Visited);

if (auto CS = ImmutableCallSite(V))
if (auto CS = ImmutableCallSite(V)) {
if (const Value *RV = CS.getReturnedArgOperand())
return isDereferenceableAndAlignedPointer(RV, Align, Size, DL, CtxI, DT,
Visited);

if (CS.getIntrinsicID() == Intrinsic::launder_invariant_group)
return isDereferenceableAndAlignedPointer(CS->getOperand(0), Align, Size,
DL, CtxI, DT, Visited);
}
// If we don't know, assume the worst.
return false;
}
Expand Down
5 changes: 4 additions & 1 deletion lib/Analysis/ValueTracking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1953,9 +1953,12 @@ bool isKnownNonZero(const Value *V, unsigned Depth, const Query &Q) {
if (LI->getMetadata(LLVMContext::MD_nonnull))
return true;

if (auto CS = ImmutableCallSite(V))
if (auto CS = ImmutableCallSite(V)) {
if (CS.isReturnNonNull())
return true;
if (CS.getIntrinsicID() == Intrinsic::ID::launder_invariant_group)
return isKnownNonZero(CS->getOperand(0), Depth + 1, Q);
}
}

// The remaining tests are all recursive, so bail out if we hit the limit.
Expand Down
25 changes: 25 additions & 0 deletions test/Analysis/ValueTracking/deref-bitcast-of-gep.ll
Original file line number Diff line number Diff line change
Expand Up @@ -80,3 +80,28 @@ loop:
leave:
ret void
}

define void @checkLaunder(i8* align 4 dereferenceable(1024) %p) {
; CHECK-LABEL: @checkLaunder(
; CHECK: entry:
; CHECK: %l = call i8* @llvm.launder.invariant.group.p0i8(i8* %p)
; CHECK: %val = load i8, i8* %l
; CHECK: br label %loop
; CHECK: loop:
; CHECK: call void @use(i32 0)
; CHECK-NEXT: call void @use8(i8 %val)

entry:
%l = call i8* @llvm.launder.invariant.group.p0i8(i8* %p)
br label %loop

loop:
call void @use(i32 0)
%val = load i8, i8* %l, !invariant.load !{}
call void @use8(i8 %val)
br label %loop
}

declare i8* @llvm.launder.invariant.group.p0i8(i8*)

declare void @use8(i8)
19 changes: 19 additions & 0 deletions test/Analysis/ValueTracking/invariant.group.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
; RUN: opt -S -instsimplify -instcombine < %s | FileCheck %s

; CHECK-LABEL: define void @checkNonnull()
define void @checkNonnull() {
; CHECK: %p = call i8* @llvm.launder.invariant.group.p0i8(i8* nonnull %0)
; CHECK: %p2 = call i8* @llvm.launder.invariant.group.p0i8(i8* nonnull %p)
; CHECK: call void @use(i8* nonnull %p2)
entry:
%0 = alloca i8, align 8

%p = call i8* @llvm.launder.invariant.group.p0i8(i8* %0)
%p2 = call i8* @llvm.launder.invariant.group.p0i8(i8* %p)
call void @use(i8* %p2)

ret void
}

declare i8* @llvm.launder.invariant.group.p0i8(i8*)
declare void @use(i8*)

0 comments on commit 461e372

Please sign in to comment.