1; RUN: opt -S -licm < %s | FileCheck %s
2; RUN: opt -aa-pipeline=basic-aa -passes='require<aa>,require<targetir>,require<scalar-evolution>,loop(licm)' -S %s | FileCheck %s
3
4declare void @use_nothrow(i64 %a) nounwind
5declare void @use(i64 %a)
6
7define void @nothrow(i64 %x, i64 %y, i1* %cond) {
8; CHECK-LABEL: nothrow
9; CHECK-LABEL: entry
10; CHECK: %div = udiv i64 %x, %y
11; CHECK-LABEL: loop
12; CHECK: call void @use_nothrow(i64 %div)
13entry:
14  br label %loop
15
16loop:                                         ; preds = %entry, %for.inc
17  %div = udiv i64 %x, %y
18  br label %loop2
19
20loop2:
21  call void @use_nothrow(i64 %div)
22  br label %loop
23}
24; Negative test
25define void @throw_header(i64 %x, i64 %y, i1* %cond) {
26; CHECK-LABEL: throw_header
27; CHECK-LABEL: loop
28; CHECK: %div = udiv i64 %x, %y
29; CHECK: call void @use(i64 %div)
30entry:
31  br label %loop
32
33loop:                                         ; preds = %entry, %for.inc
34  %div = udiv i64 %x, %y
35  call void @use(i64 %div)
36  br label %loop
37}
38
39; The header is known no throw, but the loop is not.  We can
40; still lift out of the header.
41define void @nothrow_header(i64 %x, i64 %y, i1 %cond) {
42; CHECK-LABEL: nothrow_header
43; CHECK-LABEL: entry
44; CHECK: %div = udiv i64 %x, %y
45; CHECK-LABEL: loop
46; CHECK: call void @use(i64 %div)
47entry:
48  br label %loop
49loop:                                         ; preds = %entry, %for.inc
50  %div = udiv i64 %x, %y
51  br i1 %cond, label %loop-if, label %exit
52loop-if:
53  call void @use(i64 %div)
54  br label %loop
55exit:
56  ret void
57}
58; Negative test - can't move out of throwing block
59define void @nothrow_header_neg(i64 %x, i64 %y, i1 %cond) {
60; CHECK-LABEL: nothrow_header_neg
61; CHECK-LABEL: entry
62; CHECK-LABEL: loop
63; CHECK: %div = udiv i64 %x, %y
64; CHECK: call void @use(i64 %div)
65entry:
66  br label %loop
67loop:                                         ; preds = %entry, %for.inc
68  br label %loop-if
69loop-if:
70  %div = udiv i64 %x, %y
71  call void @use(i64 %div)
72  br label %loop
73}
74