[llvm] r321764 - [PRE] Add a bunch of test cases for LICM-like PRE patterns
Philip Reames via llvm-commits
llvm-commits at lists.llvm.org
Wed Jan 3 14:28:26 PST 2018
Author: reames
Date: Wed Jan 3 14:28:26 2018
New Revision: 321764
URL: http://llvm.org/viewvc/llvm-project?rev=321764&view=rev
Log:
[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.
Modified:
llvm/trunk/test/Transforms/GVN/PRE/load-pre-licm.ll
Modified: llvm/trunk/test/Transforms/GVN/PRE/load-pre-licm.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GVN/PRE/load-pre-licm.ll?rev=321764&r1=321763&r2=321764&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/GVN/PRE/load-pre-licm.ll (original)
+++ llvm/trunk/test/Transforms/GVN/PRE/load-pre-licm.ll Wed Jan 3 14:28:26 2018
@@ -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
+}
More information about the llvm-commits
mailing list