[llvm] r286294 - [BasicAA] Teach BasicAA to handle the inaccessiblememonly and inaccessiblemem_or_argmemonly attributes
Andrew Kaylor via llvm-commits
llvm-commits at lists.llvm.org
Tue Nov 8 13:07:42 PST 2016
Author: akaylor
Date: Tue Nov 8 15:07:42 2016
New Revision: 286294
URL: http://llvm.org/viewvc/llvm-project?rev=286294&view=rev
Log:
[BasicAA] Teach BasicAA to handle the inaccessiblememonly and inaccessiblemem_or_argmemonly attributes
Differential Revision: https://reviews.llvm.org/D26382
Modified:
llvm/trunk/include/llvm/Analysis/AliasAnalysis.h
llvm/trunk/lib/Analysis/AliasAnalysis.cpp
llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp
llvm/trunk/test/Analysis/BasicAA/cs-cs.ll
Modified: llvm/trunk/include/llvm/Analysis/AliasAnalysis.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/AliasAnalysis.h?rev=286294&r1=286293&r2=286294&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/AliasAnalysis.h (original)
+++ llvm/trunk/include/llvm/Analysis/AliasAnalysis.h Tue Nov 8 15:07:42 2016
@@ -112,8 +112,10 @@ enum FunctionModRefLocation {
FMRL_Nowhere = 0,
/// Access to memory via argument pointers.
FMRL_ArgumentPointees = 4,
+ /// Memory that is inaccessible via LLVM IR.
+ FMRL_InaccessibleMem = 8,
/// Access to any memory.
- FMRL_Anywhere = 8 | FMRL_ArgumentPointees
+ FMRL_Anywhere = 16 | FMRL_InaccessibleMem | FMRL_ArgumentPointees
};
/// Summary of how a function affects memory in the program.
@@ -143,6 +145,22 @@ enum FunctionModRefBehavior {
/// This property corresponds to the IntrArgMemOnly LLVM intrinsic flag.
FMRB_OnlyAccessesArgumentPointees = FMRL_ArgumentPointees | MRI_ModRef,
+ /// The only memory references in this function (if it has any) are
+ /// references of memory that is otherwise inaccessible via LLVM IR.
+ ///
+ /// This property corresponds to the LLVM IR inaccessiblememonly attribute.
+ FMRB_OnlyAccessesInaccessibleMem = FMRL_InaccessibleMem | MRI_ModRef,
+
+ /// The function may perform non-volatile loads and stores of objects
+ /// pointed to by its pointer-typed arguments, with arbitrary offsets, and
+ /// it may also perform loads and stores of memory that is otherwise
+ /// inaccessible via LLVM IR.
+ ///
+ /// This property corresponds to the LLVM IR
+ /// inaccessiblemem_or_argmemonly attribute.
+ FMRB_OnlyAccessesInaccessibleOrArgMem = FMRL_InaccessibleMem |
+ FMRL_ArgumentPointees | MRI_ModRef,
+
/// This function does not perform any non-local stores or volatile loads,
/// but may read from any memory location.
///
@@ -339,6 +357,26 @@ public:
return (MRB & MRI_ModRef) && (MRB & FMRL_ArgumentPointees);
}
+ /// Checks if functions with the specified behavior are known to read and
+ /// write at most from memory that is inaccessible from LLVM IR.
+ static bool onlyAccessesInaccessibleMem(FunctionModRefBehavior MRB) {
+ return !(MRB & FMRL_Anywhere & ~FMRL_InaccessibleMem);
+ }
+
+ /// Checks if functions with the specified behavior are known to potentially
+ /// read or write from memory that is inaccessible from LLVM IR.
+ static bool doesAccessInaccessibleMem(FunctionModRefBehavior MRB) {
+ return (MRB & MRI_ModRef) && (MRB & FMRL_InaccessibleMem);
+ }
+
+ /// Checks if functions with the specified behavior are known to read and
+ /// write at most from memory that is inaccessible from LLVM IR or objects
+ /// pointed to by their pointer-typed arguments (with arbitrary offsets).
+ static bool onlyAccessesInaccessibleOrArgMem(FunctionModRefBehavior MRB) {
+ return !(MRB & FMRL_Anywhere &
+ ~(FMRL_InaccessibleMem | FMRL_ArgumentPointees));
+ }
+
/// getModRefInfo (for call sites) - Return information about whether
/// a particular call site modifies or reads the specified memory location.
ModRefInfo getModRefInfo(ImmutableCallSite CS, const MemoryLocation &Loc);
Modified: llvm/trunk/lib/Analysis/AliasAnalysis.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/AliasAnalysis.cpp?rev=286294&r1=286293&r2=286294&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/AliasAnalysis.cpp (original)
+++ llvm/trunk/lib/Analysis/AliasAnalysis.cpp Tue Nov 8 15:07:42 2016
@@ -141,7 +141,8 @@ ModRefInfo AAResults::getModRefInfo(Immu
// Try to refine the mod-ref info further using other API entry points to the
// aggregate set of AA results.
auto MRB = getModRefBehavior(CS);
- if (MRB == FMRB_DoesNotAccessMemory)
+ if (MRB == FMRB_DoesNotAccessMemory ||
+ MRB == FMRB_OnlyAccessesInaccessibleMem)
return MRI_NoModRef;
if (onlyReadsMemory(MRB))
@@ -149,7 +150,7 @@ ModRefInfo AAResults::getModRefInfo(Immu
else if (doesNotReadMemory(MRB))
Result = ModRefInfo(Result & MRI_Mod);
- if (onlyAccessesArgPointees(MRB)) {
+ if (onlyAccessesArgPointees(MRB) || onlyAccessesInaccessibleOrArgMem(MRB)) {
bool DoesAlias = false;
ModRefInfo AllArgsMask = MRI_NoModRef;
if (doesAccessArgPointees(MRB)) {
Modified: llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp?rev=286294&r1=286293&r2=286294&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp (original)
+++ llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp Tue Nov 8 15:07:42 2016
@@ -609,6 +609,10 @@ FunctionModRefBehavior BasicAAResult::ge
if (F->onlyAccessesArgMemory())
Min = FunctionModRefBehavior(Min & FMRB_OnlyAccessesArgumentPointees);
+ else if (F->onlyAccessesInaccessibleMemory())
+ Min = FunctionModRefBehavior(Min & FMRB_OnlyAccessesInaccessibleMem);
+ else if (F->onlyAccessesInaccessibleMemOrArgMem())
+ Min = FunctionModRefBehavior(Min & FMRB_OnlyAccessesInaccessibleOrArgMem);
return Min;
}
Modified: llvm/trunk/test/Analysis/BasicAA/cs-cs.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/BasicAA/cs-cs.ll?rev=286294&r1=286293&r2=286294&view=diff
==============================================================================
--- llvm/trunk/test/Analysis/BasicAA/cs-cs.ll (original)
+++ llvm/trunk/test/Analysis/BasicAA/cs-cs.ll Tue Nov 8 15:07:42 2016
@@ -23,18 +23,18 @@ entry:
; CHECK-LABEL: Function: test1:
; CHECK: NoAlias: i8* %p, i8* %q
-; CHECK: Just Ref: Ptr: i8* %p <-> %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #5
-; CHECK: NoModRef: Ptr: i8* %q <-> %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #5
+; CHECK: Just Ref: Ptr: i8* %p <-> %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16)
+; CHECK: NoModRef: Ptr: i8* %q <-> %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16)
; CHECK: NoModRef: Ptr: i8* %p <-> call void @llvm.arm.neon.vst1.p0i8.v8i16(i8* %q, <8 x i16> %y, i32 16)
; CHECK: Both ModRef: Ptr: i8* %q <-> call void @llvm.arm.neon.vst1.p0i8.v8i16(i8* %q, <8 x i16> %y, i32 16)
-; CHECK: Just Ref: Ptr: i8* %p <-> %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #5
-; CHECK: NoModRef: Ptr: i8* %q <-> %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #5
-; CHECK: NoModRef: %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #5 <-> call void @llvm.arm.neon.vst1.p0i8.v8i16(i8* %q, <8 x i16> %y, i32 16)
-; CHECK: NoModRef: %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #5 <-> %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #5
-; CHECK: NoModRef: call void @llvm.arm.neon.vst1.p0i8.v8i16(i8* %q, <8 x i16> %y, i32 16) <-> %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #5
-; CHECK: NoModRef: call void @llvm.arm.neon.vst1.p0i8.v8i16(i8* %q, <8 x i16> %y, i32 16) <-> %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #5
-; CHECK: NoModRef: %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #5 <-> %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #5
-; CHECK: NoModRef: %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #5 <-> call void @llvm.arm.neon.vst1.p0i8.v8i16(i8* %q, <8 x i16> %y, i32 16)
+; CHECK: Just Ref: Ptr: i8* %p <-> %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16)
+; CHECK: NoModRef: Ptr: i8* %q <-> %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16)
+; CHECK: NoModRef: %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #{{[0-9]+}} <-> call void @llvm.arm.neon.vst1.p0i8.v8i16(i8* %q, <8 x i16> %y, i32 16)
+; CHECK: NoModRef: %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #{{[0-9]+}} <-> %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16)
+; CHECK: NoModRef: call void @llvm.arm.neon.vst1.p0i8.v8i16(i8* %q, <8 x i16> %y, i32 16) <-> %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16)
+; CHECK: NoModRef: call void @llvm.arm.neon.vst1.p0i8.v8i16(i8* %q, <8 x i16> %y, i32 16) <-> %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16)
+; CHECK: NoModRef: %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #{{[0-9]+}} <-> %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16)
+; CHECK: NoModRef: %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16.p0i8(i8* %p, i32 16) #{{[0-9]+}} <-> call void @llvm.arm.neon.vst1.p0i8.v8i16(i8* %q, <8 x i16> %y, i32 16)
}
define void @test2(i8* %P, i8* %Q) nounwind ssp {
@@ -247,10 +247,45 @@ define void @test7(i8* %P) nounwind ssp
; CHECK: Just Ref: call void @a_readonly_func(i8* %P) <-> call void @a_writeonly_func(i8* %P)
}
-attributes #0 = { argmemonly nounwind readonly }
-attributes #1 = { argmemonly nounwind }
-attributes #2 = { noinline nounwind readonly }
-attributes #3 = { noinline nounwind writeonly }
-attributes #4 = { nounwind ssp }
-attributes #5 = { nounwind }
-
+declare void @an_inaccessiblememonly_func() nounwind inaccessiblememonly
+declare void @an_inaccessibleorargmemonly_func(i8 *) nounwind inaccessiblemem_or_argmemonly
+declare void @an_argmemonly_func(i8 *) nounwind argmemonly
+
+define void @test8(i8* %p) {
+entry:
+ %q = getelementptr i8, i8* %p, i64 16
+ call void @a_readonly_func(i8* %p)
+ call void @an_inaccessiblememonly_func()
+ call void @a_writeonly_func(i8* %q)
+ call void @an_inaccessiblememonly_func()
+ call void @an_inaccessibleorargmemonly_func(i8* %q)
+ call void @an_argmemonly_func(i8* %q)
+ ret void
+
+; CHECK-LABEL: Function: test8
+; CHECK: NoModRef: Ptr: i8* %p <-> call void @an_inaccessiblememonly_func()
+; CHECK: NoModRef: Ptr: i8* %q <-> call void @an_inaccessiblememonly_func()
+; CHECK: NoModRef: Ptr: i8* %p <-> call void @an_inaccessibleorargmemonly_func(i8* %q)
+; CHECK: Both ModRef: Ptr: i8* %q <-> call void @an_inaccessibleorargmemonly_func(i8* %q)
+; CHECK: NoModRef: Ptr: i8* %p <-> call void @an_argmemonly_func(i8* %q)
+; CHECK: Both ModRef: Ptr: i8* %q <-> call void @an_argmemonly_func(i8* %q)
+; CHECK: Just Ref: call void @a_readonly_func(i8* %p) <-> call void @an_inaccessiblememonly_func()
+; CHECK: Just Ref: call void @a_readonly_func(i8* %p) <-> call void @an_inaccessibleorargmemonly_func(i8* %q)
+; CHECK: Just Ref: call void @a_readonly_func(i8* %p) <-> call void @an_argmemonly_func(i8* %q)
+; CHECK: Both ModRef: call void @an_inaccessiblememonly_func() <-> call void @a_readonly_func(i8* %p)
+; CHECK: Both ModRef: call void @an_inaccessiblememonly_func() <-> call void @a_writeonly_func(i8* %q)
+; CHECK: Both ModRef: call void @an_inaccessiblememonly_func() <-> call void @an_inaccessiblememonly_func()
+; CHECK: Both ModRef: call void @an_inaccessiblememonly_func() <-> call void @an_inaccessibleorargmemonly_func(i8* %q)
+; CHECK: NoModRef: call void @an_inaccessiblememonly_func() <-> call void @an_argmemonly_func(i8* %q)
+; CHECK: Just Mod: call void @a_writeonly_func(i8* %q) <-> call void @an_inaccessiblememonly_func()
+; CHECK: Just Mod: call void @a_writeonly_func(i8* %q) <-> call void @an_inaccessibleorargmemonly_func(i8* %q)
+; CHECK: Just Mod: call void @a_writeonly_func(i8* %q) <-> call void @an_argmemonly_func(i8* %q)
+; CHECK: Both ModRef: call void @an_inaccessibleorargmemonly_func(i8* %q) <-> call void @a_readonly_func(i8* %p)
+; CHECK: Both ModRef: call void @an_inaccessibleorargmemonly_func(i8* %q) <-> call void @a_writeonly_func(i8* %q)
+; CHECK: Both ModRef: call void @an_inaccessibleorargmemonly_func(i8* %q) <-> call void @an_inaccessiblememonly_func()
+; CHECK: Both ModRef: call void @an_inaccessibleorargmemonly_func(i8* %q) <-> call void @an_argmemonly_func(i8* %q)
+; CHECK: Both ModRef: call void @an_argmemonly_func(i8* %q) <-> call void @a_readonly_func(i8* %p)
+; CHECK: Both ModRef: call void @an_argmemonly_func(i8* %q) <-> call void @a_writeonly_func(i8* %q)
+; CHECK: NoModRef: call void @an_argmemonly_func(i8* %q) <-> call void @an_inaccessiblememonly_func()
+; CHECK: Both ModRef: call void @an_argmemonly_func(i8* %q) <-> call void @an_inaccessibleorargmemonly_func(i8* %q)
+}
More information about the llvm-commits
mailing list