[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