summaryrefslogtreecommitdiffstats
path: root/llvm/test
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/test')
-rw-r--r--llvm/test/Transforms/LICM/hoist-mustexec.ll149
1 files changed, 149 insertions, 0 deletions
diff --git a/llvm/test/Transforms/LICM/hoist-mustexec.ll b/llvm/test/Transforms/LICM/hoist-mustexec.ll
index cd7c28c5e61..1248542584a 100644
--- a/llvm/test/Transforms/LICM/hoist-mustexec.ll
+++ b/llvm/test/Transforms/LICM/hoist-mustexec.ll
@@ -280,3 +280,152 @@ fail:
call void @f()
ret i32 -1
}
+
+declare void @may_throw() inaccessiblememonly
+
+; Test that we can sink a mustexecute load from loop header even in presence of
+; throwing instructions after it.
+define void @test_hoist_from_header_01(i32* %p, i32 %n) {
+
+; CHECK-LABEL: @test_hoist_from_header_01(
+; CHECK: entry:
+; CHECK-NEXT: %load = load i32, i32* %p
+; CHECK-NOT: load i32
+
+entry:
+ br label %loop
+
+loop:
+ %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]
+ %dummy = phi i32 [ 0, %entry ], [ %merge, %backedge ]
+ %load = load i32, i32* %p
+ call void @may_throw()
+ %cond = icmp slt i32 %iv, %n
+ br i1 %cond, label %if.true, label %if.false
+
+if.true:
+ %a = add i32 %iv, %iv
+ br label %backedge
+
+if.false:
+ %b = mul i32 %iv, %iv
+ br label %backedge
+
+backedge:
+ %merge = phi i32 [ %a, %if.true ], [ %b, %if.false ]
+ %iv.next = add i32 %iv, %merge
+ %loop.cond = icmp ult i32 %iv.next, %load
+ br i1 %loop.cond, label %loop, label %exit
+
+exit:
+ ret void
+}
+
+define void @test_hoist_from_header_02(i32* %p, i32 %n) {
+
+; CHECK-LABEL: @test_hoist_from_header_02(
+; CHECK: entry:
+; CHECK-NEXT: %load = load i32, i32* %p
+; CHECK-NOT: load i32
+
+entry:
+ br label %loop
+
+loop:
+ %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]
+ %dummy = phi i32 [ 0, %entry ], [ %merge, %backedge ]
+ %load = load i32, i32* %p
+ %cond = icmp slt i32 %iv, %n
+ br i1 %cond, label %if.true, label %if.false
+
+if.true:
+ call void @may_throw()
+ %a = add i32 %iv, %iv
+ br label %backedge
+
+if.false:
+ %b = mul i32 %iv, %iv
+ br label %backedge
+
+backedge:
+ %merge = phi i32 [ %a, %if.true ], [ %b, %if.false ]
+ %iv.next = add i32 %iv, %merge
+ %loop.cond = icmp ult i32 %iv.next, %load
+ br i1 %loop.cond, label %loop, label %exit
+
+exit:
+ ret void
+}
+
+define void @test_hoist_from_header_03(i32* %p, i32 %n) {
+
+; CHECK-LABEL: @test_hoist_from_header_03(
+; CHECK: entry:
+; CHECK-NEXT: %load = load i32, i32* %p
+; CHECK-NOT: load i32
+
+entry:
+ br label %loop
+
+loop:
+ %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]
+ %dummy = phi i32 [ 0, %entry ], [ %merge, %backedge ]
+ %load = load i32, i32* %p
+ %cond = icmp slt i32 %iv, %n
+ br i1 %cond, label %if.true, label %if.false
+
+if.true:
+ %a = add i32 %iv, %iv
+ br label %backedge
+
+if.false:
+ %b = mul i32 %iv, %iv
+ br label %backedge
+
+backedge:
+ %merge = phi i32 [ %a, %if.true ], [ %b, %if.false ]
+ call void @may_throw()
+ %iv.next = add i32 %iv, %merge
+ %loop.cond = icmp ult i32 %iv.next, %load
+ br i1 %loop.cond, label %loop, label %exit
+
+exit:
+ ret void
+}
+
+; Check that a throwing instruction prohibits hoisting across it.
+define void @test_hoist_from_header_04(i32* %p, i32 %n) {
+
+; CHECK-LABEL: @test_hoist_from_header_04(
+; CHECK: entry:
+; CHECK: loop:
+; CHECK: %load = load i32, i32* %p
+
+entry:
+ br label %loop
+
+loop:
+ %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]
+ %dummy = phi i32 [ 0, %entry ], [ %merge, %backedge ]
+ call void @may_throw()
+ %load = load i32, i32* %p
+ %cond = icmp slt i32 %iv, %n
+ br i1 %cond, label %if.true, label %if.false
+
+if.true:
+ %a = add i32 %iv, %iv
+ br label %backedge
+
+if.false:
+ %b = mul i32 %iv, %iv
+ br label %backedge
+
+backedge:
+ %merge = phi i32 [ %a, %if.true ], [ %b, %if.false ]
+ %iv.next = add i32 %iv, %merge
+ %loop.cond = icmp ult i32 %iv.next, %load
+ br i1 %loop.cond, label %loop, label %exit
+
+exit:
+ ret void
+}
OpenPOWER on IntegriCloud