summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhilip Reames <listmail@philipreames.com>2018-01-03 22:28:26 +0000
committerPhilip Reames <listmail@philipreames.com>2018-01-03 22:28:26 +0000
commitcf524a408a4343d89b3fa7a3df535dba80116e13 (patch)
treebf9807d1d0b46936df11b8ef60890b4defdd2897
parent10007815ac9f85960b36d5e9cd832d22e80c024b (diff)
downloadbcm5719-llvm-cf524a408a4343d89b3fa7a3df535dba80116e13.tar.gz
bcm5719-llvm-cf524a408a4343d89b3fa7a3df535dba80116e13.zip
[PRE] Add a bunch of test cases for LICM-like PRE patterns
These were inspired by a very old review I'm about to abandon (https://reviews.llvm.org/D7061). Several of the test cases from that worked without modification and expanding test coverage of such cases is always worthwhile. llvm-svn: 321764
-rw-r--r--llvm/test/Transforms/GVN/PRE/load-pre-licm.ll168
1 files changed, 168 insertions, 0 deletions
diff --git a/llvm/test/Transforms/GVN/PRE/load-pre-licm.ll b/llvm/test/Transforms/GVN/PRE/load-pre-licm.ll
index d14b01caf77..34edc84a96f 100644
--- a/llvm/test/Transforms/GVN/PRE/load-pre-licm.ll
+++ b/llvm/test/Transforms/GVN/PRE/load-pre-licm.ll
@@ -37,3 +37,171 @@ if.end:
while.end.loopexit:
ret void
}
+
+declare void @hold(i32) readonly
+declare void @clobber()
+
+; This is a classic LICM case
+define i32 @test1(i1 %cnd, i32* %p) {
+; CHECK-LABEL: @test1
+entry:
+; CHECK-LABEL: entry
+; CHECK-NEXT: %v1.pre = load i32, i32* %p
+ br label %header
+
+header:
+; CHECK-LABEL: header
+ %v1 = load i32, i32* %p
+ call void @hold(i32 %v1)
+ br label %header
+}
+
+
+; Slightly more complicated case to highlight that MemoryDependenceAnalysis
+; can compute availability for internal control flow. In this case, because
+; the value is fully available across the backedge, we only need to establish
+; anticipation for the preheader block (which is trivial in this case.)
+define i32 @test2(i1 %cnd, i32* %p) {
+; CHECK-LABEL: @test2
+entry:
+; CHECK-LABEL: entry
+; CHECK-NEXT: %v1.pre = load i32, i32* %p
+ br label %header
+
+header:
+; CHECK-LABEL: header
+ %v1 = load i32, i32* %p
+ call void @hold(i32 %v1)
+ br i1 %cnd, label %bb1, label %bb2
+
+bb1:
+ br label %merge
+
+bb2:
+ br label %merge
+
+merge:
+ br label %header
+}
+
+
+; TODO: at the moment, our anticipation check does not handle anything
+; other than straight-line unconditional fallthrough. This particular
+; case could be solved through either a backwards anticipation walk or
+; use of the the "safe to speculate" status (if we annotate the param)
+define i32 @test3(i1 %cnd, i32* %p) {
+entry:
+; CHECK-LABEL: @test3
+; CHECK-LABEL: entry
+ br label %header
+
+header:
+ br i1 %cnd, label %bb1, label %bb2
+
+bb1:
+ br label %merge
+
+bb2:
+ br label %merge
+
+merge:
+; CHECK-LABEL: merge
+; CHECK: load i32, i32* %p
+ %v1 = load i32, i32* %p
+ call void @hold(i32 %v1)
+ br label %header
+}
+
+; Highlight that we can PRE into a latch block when there are multiple
+; latches only one of which clobbers an otherwise invariant value.
+define i32 @test4(i1 %cnd, i32* %p) {
+; CHECK-LABEL: @test4
+entry:
+; CHECK-LABEL: entry
+ %v1 = load i32, i32* %p
+ call void @hold(i32 %v1)
+ br label %header
+
+header:
+; CHECK-LABEL: header
+ %v2 = load i32, i32* %p
+ call void @hold(i32 %v2)
+ br i1 %cnd, label %bb1, label %bb2
+
+bb1:
+ br label %header
+
+bb2:
+; CHECK-LABEL: bb2
+; CHECK: call void @clobber()
+; CHECK-NEXT: %v2.pre = load i32, i32* %p
+; CHECK-NEXT: br label %header
+
+ call void @clobber()
+ br label %header
+}
+
+; Highlight the fact that we can PRE into a single clobbering latch block
+; even in loop simplify form (though multiple applications of the same
+; transformation).
+define i32 @test5(i1 %cnd, i32* %p) {
+; CHECK-LABEL: @test5
+entry:
+; CHECK-LABEL: entry
+ %v1 = load i32, i32* %p
+ call void @hold(i32 %v1)
+ br label %header
+
+header:
+; CHECK-LABEL: header
+ %v2 = load i32, i32* %p
+ call void @hold(i32 %v2)
+ br i1 %cnd, label %bb1, label %bb2
+
+bb1:
+ br label %merge
+
+bb2:
+; CHECK-LABEL: bb2
+; CHECK: call void @clobber()
+; CHECK-NEXT: %v2.pre.pre = load i32, i32* %p
+; CHECK-NEXT: br label %merge
+
+ call void @clobber()
+ br label %merge
+
+merge:
+ br label %header
+}
+
+declare void @llvm.experimental.guard(i1 %cnd, ...)
+
+; These two tests highlight speculation safety when we can not establish
+; anticipation (since the original load might actually not execcute)
+define i32 @test6a(i1 %cnd, i32* %p) {
+entry:
+; CHECK-LABEL: @test6a
+ br label %header
+
+header:
+; CHECK-LABEL: header
+; CHECK: load i32, i32* %p
+ call void (i1, ...) @llvm.experimental.guard(i1 %cnd) ["deopt"()]
+ %v1 = load i32, i32* %p
+ call void @hold(i32 %v1)
+ br label %header
+}
+
+define i32 @test6b(i1 %cnd, i32* dereferenceable(8) %p) {
+entry:
+; CHECK-LABEL: @test6b
+; CHECK: load i32, i32* %p
+ br label %header
+
+header:
+; CHECK-LABEL: header
+ call void (i1, ...) @llvm.experimental.guard(i1 %cnd) ["deopt"()]
+ %v1 = load i32, i32* %p
+ call void @hold(i32 %v1)
+ br label %header
+}
OpenPOWER on IntegriCloud