aboutsummaryrefslogtreecommitdiff
path: root/test/Transforms/PhaseOrdering/globalaa-retained.ll
diff options
context:
space:
mode:
Diffstat (limited to 'test/Transforms/PhaseOrdering/globalaa-retained.ll')
-rw-r--r--test/Transforms/PhaseOrdering/globalaa-retained.ll46
1 files changed, 43 insertions, 3 deletions
diff --git a/test/Transforms/PhaseOrdering/globalaa-retained.ll b/test/Transforms/PhaseOrdering/globalaa-retained.ll
index bce193b5e851..47b8e4d7a9ed 100644
--- a/test/Transforms/PhaseOrdering/globalaa-retained.ll
+++ b/test/Transforms/PhaseOrdering/globalaa-retained.ll
@@ -5,6 +5,37 @@ target triple = "aarch64"
@v = internal unnamed_addr global i32 0, align 4
@p = common global i32* null, align 8
+
+; This test checks that a number of loads and stores are eliminated,
+; that can only be eliminated based on GlobalsAA information. As such,
+; it tests that GlobalsAA information is retained until the passes
+; that perform this optimization, and it protects against accidentally
+; dropping the GlobalsAA information earlier in the pipeline, which
+; has happened a few times.
+
+; GlobalsAA invalidation might happen later in the FunctionPassManager
+; pipeline than the optimization eliminating unnecessary loads/stores.
+; Since GlobalsAA is a module-level analysis, any FunctionPass
+; invalidating the GlobalsAA information will affect FunctionPass
+; pipelines that execute later. For example, assume a FunctionPass1 |
+; FunctionPass2 pipeline and 2 functions to be processed: f1 and f2.
+; Assume furthermore that FunctionPass1 uses GlobalsAA info to do an
+; optimization, and FunctionPass2 invalidates GlobalsAA. Assume the
+; function passes run in the following order: FunctionPass1(f1),
+; FunctionPass2(f1), FunctionPass1(f2), FunctionPass2(f2). Then
+; FunctionPass1 will not be able to optimize f2, since GlobalsAA will
+; have been invalidated in FuntionPass2(f1).
+
+; To try and also test this scenario, there is an empty function
+; before and after the function we're checking so that one of them
+; will be processed by the whole set of FunctionPasses before @f. That
+; will ensure that if the invalidation happens, it happens before the
+; actual optimizations on @f start.
+define void @bar() {
+entry:
+ ret void
+}
+
; Function Attrs: norecurse nounwind
define void @f(i32 %n) {
entry:
@@ -19,8 +50,17 @@ entry:
ret void
}
-; check variable v is loaded only once after optimization, which should be
-; prove that globalsAA survives until the optimization that can use it to
-; optimize away the duplicate load/stores on variable v.
+; check variable v is loaded/stored only once after optimization,
+; which should be prove that globalsAA survives until the optimization
+; that can use it to optimize away the duplicate load/stores on
+; variable v.
; CHECK: load i32, i32* @v, align 4
+; CHECK: store i32 {{.*}}, i32* @v, align 4
; CHECK-NOT: load i32, i32* @v, align 4
+; CHECK-NOT: store i32 {{.*}}, i32* @v, align 4
+
+; Same as @bar above, in case the functions are processed in reverse order.
+define void @bar2() {
+entry:
+ ret void
+}