[OperandBundles] Teach AliasAnalysis about operand bundles

Summary:
If a `CallSite` has operand bundles, then do not peek into the called
function to get a more precise `ModRef` answer.

This is tested using `argmemonly`, `-basicaa` and `-gvn`; but the
functionality is not specific to any of these.

Depends on D13961

Reviewers: reames, chandlerc

Subscribers: llvm-commits

Differential Revision: http://reviews.llvm.org/D13962

llvm-svn: 250974
This commit is contained in:
Sanjoy Das 2015-10-22 03:12:51 +00:00
parent 98a341bc0c
commit 769e7e2f71
3 changed files with 39 additions and 4 deletions

View File

@ -759,6 +759,10 @@ public:
}
FunctionModRefBehavior getModRefBehavior(ImmutableCallSite CS) {
if (!CS.hasOperandBundles())
// If CS has operand bundles then aliasing attributes from the function it
// calls do not directly apply to the CallSite. This can be made more
// precise in the future.
if (const Function *F = CS.getCalledFunction())
return getBestAAResults().getModRefBehavior(F);

View File

@ -1255,8 +1255,8 @@ protected:
/// \brief Is the function attribute S disallowed by some operand bundle on
/// this operand bundle user?
bool isFnAttrDisallowedByOpBundle(StringRef S) const {
// Operand bundles only possibly disallow readnone and readonly attributes.
// All String attributes are fine.
// Operand bundles only possibly disallow readnone, readonly and argmenonly
// attributes. All String attributes are fine.
return false;
}
@ -1267,6 +1267,9 @@ protected:
default:
return false;
case Attribute::ArgMemOnly:
return hasReadingOperandBundles();
case Attribute::ReadNone:
return hasReadingOperandBundles();

View File

@ -0,0 +1,28 @@
; RUN: opt -S -basicaa -gvn < %s | FileCheck %s
declare void @argmemonly_function(i32 *) argmemonly
define i32 @test0(i32* %P, i32* noalias %P2) {
; CHECK-LABEL: @test0(
%v1 = load i32, i32* %P
; CHECK: %v1 = load i32, i32* %P
call void @argmemonly_function(i32* %P2) [ "tag"() ]
; CHECK: call void @argmemonly_function(
%v2 = load i32, i32* %P
; CHECK: %v2 = load i32, i32* %P
%diff = sub i32 %v1, %v2
; CHECK: %diff = sub i32 %v1, %v2
ret i32 %diff
; CHECK: ret i32 %diff
}
define i32 @test1(i32* %P, i32* noalias %P2) {
; CHECK-LABEL: @test1(
%v1 = load i32, i32* %P
call void @argmemonly_function(i32* %P2) argmemonly [ "tag"() ]
; CHECK: call void @argmemonly_function(
%v2 = load i32, i32* %P
%diff = sub i32 %v1, %v2
ret i32 %diff
; CHECK: ret i32 0
}