summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/Analysis/CFLAliasAnalysis.cpp14
-rw-r--r--llvm/test/Analysis/CFLAliasAnalysis/arguments-globals.ll20
-rw-r--r--llvm/test/Analysis/CFLAliasAnalysis/arguments.ll15
-rw-r--r--llvm/test/Analysis/CFLAliasAnalysis/basic-interproc-ret.ll26
-rw-r--r--llvm/test/Analysis/CFLAliasAnalysis/basic-interproc.ll24
-rw-r--r--llvm/test/Analysis/CFLAliasAnalysis/multilevel-combine.ll31
-rw-r--r--llvm/test/Analysis/CFLAliasAnalysis/multilevel.ll30
7 files changed, 157 insertions, 3 deletions
diff --git a/llvm/lib/Analysis/CFLAliasAnalysis.cpp b/llvm/lib/Analysis/CFLAliasAnalysis.cpp
index db94f2868c4..0386afeb23a 100644
--- a/llvm/lib/Analysis/CFLAliasAnalysis.cpp
+++ b/llvm/lib/Analysis/CFLAliasAnalysis.cpp
@@ -986,9 +986,17 @@ CFLAliasAnalysis::query(const AliasAnalysis::Location &LocA,
auto AttrsA = Sets.getLink(SetA.Index).Attrs;
auto AttrsB = Sets.getLink(SetB.Index).Attrs;
- auto CombinedAttrs = AttrsA | AttrsB;
- if (CombinedAttrs.any())
- return AliasAnalysis::PartialAlias;
+ // Stratified set attributes are used as markets to signify whether a member
+ // of a StratifiedSet (or a member of a set above the current set) has
+ // interacted with either arguments or globals. "Interacted with" meaning
+ // its value may be different depending on the value of an argument or
+ // global. The thought behind this is that, because arguments and globals
+ // may alias each other, if AttrsA and AttrsB have touched args/globals,
+ // we must conservatively say that they alias. However, if at least one of
+ // the sets has no values that could legally be altered by changing the value
+ // of an argument or global, then we don't have to be as conservative.
+ if (AttrsA.any() && AttrsB.any())
+ return AliasAnalysis::MayAlias;
return AliasAnalysis::NoAlias;
}
diff --git a/llvm/test/Analysis/CFLAliasAnalysis/arguments-globals.ll b/llvm/test/Analysis/CFLAliasAnalysis/arguments-globals.ll
new file mode 100644
index 00000000000..18bbe8b6b41
--- /dev/null
+++ b/llvm/test/Analysis/CFLAliasAnalysis/arguments-globals.ll
@@ -0,0 +1,20 @@
+; This testcase ensures that CFL AA gives conservative answers on variables
+; that involve arguments.
+; (Everything should alias everything, because args can alias globals, so the
+; aliasing sets should of args+alloca+global should be combined)
+
+; RUN: opt < %s -cfl-aa -aa-eval -print-may-aliases -disable-output 2>&1 | FileCheck %s
+
+; CHECK: Function: test
+
+@g = external global i32
+
+define void @test(i1 %c, i32* %arg1, i32* %arg2) {
+ ; CHECK: 15 Total Alias Queries Performed
+ ; CHECK: 0 no alias responses
+ %A = alloca i32, align 4
+ %B = select i1 %c, i32* %arg1, i32* %arg2
+ %C = select i1 %c, i32* @g, i32* %A
+
+ ret void
+}
diff --git a/llvm/test/Analysis/CFLAliasAnalysis/arguments.ll b/llvm/test/Analysis/CFLAliasAnalysis/arguments.ll
new file mode 100644
index 00000000000..f3e6679c35e
--- /dev/null
+++ b/llvm/test/Analysis/CFLAliasAnalysis/arguments.ll
@@ -0,0 +1,15 @@
+; This testcase ensures that CFL AA gives conservative answers on variables
+; that involve arguments.
+
+; RUN: opt < %s -cfl-aa -aa-eval -print-may-aliases -disable-output 2>&1 | FileCheck %s
+
+; CHECK: Function: test
+
+define void @test(i1 %c, i32* %arg1, i32* %arg2) {
+ ; CHECK: 6 Total Alias Queries Performed
+ ; CHECK: 3 no alias responses
+ %a = alloca i32, align 4
+ %b = select i1 %c, i32* %arg1, i32* %arg2
+
+ ret void
+}
diff --git a/llvm/test/Analysis/CFLAliasAnalysis/basic-interproc-ret.ll b/llvm/test/Analysis/CFLAliasAnalysis/basic-interproc-ret.ll
new file mode 100644
index 00000000000..d56a4552b51
--- /dev/null
+++ b/llvm/test/Analysis/CFLAliasAnalysis/basic-interproc-ret.ll
@@ -0,0 +1,26 @@
+; This testcase ensures that CFL AA gives conservative answers on variables
+; that involve arguments.
+
+; RUN: opt < %s -cfl-aa -aa-eval -print-may-aliases -disable-output 2>&1 | FileCheck %s
+
+; CHECK: Function: test
+; CHECK: 4 Total Alias Queries Performed
+; CHECK: 3 no alias responses
+; ^ The 1 MayAlias is due to %arg1. Sadly, we don't currently have machinery
+; in place to check whether %arg1 aliases %a, because BasicAA takes care of
+; that for us.
+
+define i32* @test2(i32* %arg1) {
+ store i32 0, i32* %arg1
+
+ %a = alloca i32, align 4
+ ret i32* %a
+}
+
+define void @test() {
+ %a = alloca i32, align 4
+ %b = alloca i32, align 4
+ %c = call i32* @test2(i32* %a)
+
+ ret void
+}
diff --git a/llvm/test/Analysis/CFLAliasAnalysis/basic-interproc.ll b/llvm/test/Analysis/CFLAliasAnalysis/basic-interproc.ll
new file mode 100644
index 00000000000..c0a5404eab6
--- /dev/null
+++ b/llvm/test/Analysis/CFLAliasAnalysis/basic-interproc.ll
@@ -0,0 +1,24 @@
+; This testcase ensures that CFL AA gives conservative answers on variables
+; that involve arguments.
+
+; RUN: opt < %s -cfl-aa -aa-eval -print-may-aliases -disable-output 2>&1 | FileCheck %s
+
+; CHECK: Function: test
+; CHECK: 2 Total Alias Queries Performed
+; CHECK: 1 no alias responses
+; ^^ In @test2, %arg1 and %arg2 may alias
+
+define void @test2(i32* %arg1, i32* %arg2) {
+ store i32 0, i32* %arg1
+ store i32 0, i32* %arg2
+
+ ret void
+}
+
+define void @test() {
+ %a = alloca i32, align 4
+ %b = alloca i32, align 4
+ call void @test2(i32* %a, i32* %b)
+
+ ret void
+}
diff --git a/llvm/test/Analysis/CFLAliasAnalysis/multilevel-combine.ll b/llvm/test/Analysis/CFLAliasAnalysis/multilevel-combine.ll
new file mode 100644
index 00000000000..9bbc721a7b1
--- /dev/null
+++ b/llvm/test/Analysis/CFLAliasAnalysis/multilevel-combine.ll
@@ -0,0 +1,31 @@
+; This testcase ensures that CFL AA responds conservatively when we union
+; groups of pointers together through ternary/conditional operations
+; Derived from:
+; void foo(bool c) {
+; char a, b;
+; char *m = c ? &a : &b;
+; *m;
+; }
+;
+
+; RUN: opt < %s -cfl-aa -aa-eval -print-may-aliases -disable-output 2>&1 | FileCheck %s
+
+%T = type { i32, [10 x i8] }
+
+; CHECK: Function: test
+
+define void @test(i1 %C) {
+; CHECK: 10 Total Alias Queries Performed
+; CHECK: 4 no alias responses
+ %M = alloca %T*, align 8 ; NoAlias with %A, %B, %MS, %AP
+ %A = alloca %T, align 8
+ %B = alloca %T, align 8
+
+ %MS = select i1 %C, %T* %B, %T* %A
+
+ store %T* %MS, %T** %M
+
+ %AP = load %T** %M ; PartialAlias with %A, %B
+
+ ret void
+}
diff --git a/llvm/test/Analysis/CFLAliasAnalysis/multilevel.ll b/llvm/test/Analysis/CFLAliasAnalysis/multilevel.ll
new file mode 100644
index 00000000000..9c9eb9a4977
--- /dev/null
+++ b/llvm/test/Analysis/CFLAliasAnalysis/multilevel.ll
@@ -0,0 +1,30 @@
+; This testcase ensures that CFL AA handles trivial cases with storing
+; pointers in pointers appropriately.
+; Derived from:
+; char a, b;
+; char *m = &a, *n = &b;
+; *m;
+; *n;
+
+; RUN: opt < %s -cfl-aa -aa-eval -print-may-aliases -disable-output 2>&1 | FileCheck %s
+
+%T = type { i32, [10 x i8] }
+
+; CHECK: Function: test
+
+define void @test() {
+; CHECK: 15 Total Alias Queries Performed
+; CHECK: 13 no alias responses
+ %M = alloca %T*, align 8
+ %N = alloca %T*, align 8
+ %A = alloca %T, align 8
+ %B = alloca %T, align 8
+
+ store %T* %A, %T** %M
+ store %T* %B, %T** %N
+
+ %AP = load %T** %M ; PartialAlias with %A
+ %BP = load %T** %N ; PartialAlias with %B
+
+ ret void
+}
OpenPOWER on IntegriCloud