[InstCombine] Signed saturation tests. NFC
[llvm-complete.git] / test / Transforms / LICM / preheader-safe.ll
blob03a7258df117c0254339820453de908df9428724
1 ; RUN: opt -S -licm < %s | FileCheck %s
2 ; RUN: opt -aa-pipeline=basic-aa -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop(licm)' -S %s | FileCheck %s
4 declare void @use_nothrow(i64 %a) nounwind
5 declare void @use(i64 %a)
6 declare void @maythrow()
8 define void @nothrow(i64 %x, i64 %y, i1* %cond) {
9 ; CHECK-LABEL: nothrow
10 ; CHECK-LABEL: entry
11 ; CHECK: %div = udiv i64 %x, %y
12 ; CHECK-LABEL: loop
13 ; CHECK: call void @use_nothrow(i64 %div)
14 entry:
15   br label %loop
17 loop:                                         ; preds = %entry, %for.inc
18   %div = udiv i64 %x, %y
19   br label %loop2
21 loop2:
22   call void @use_nothrow(i64 %div)
23   br label %loop
26 ; The udiv is guarantee to execute if the loop is
27 define void @throw_header_after(i64 %x, i64 %y, i1* %cond) {
28 ; CHECK-LABEL: throw_header_after
29 ; CHECK: %div = udiv i64 %x, %y
30 ; CHECK-LABEL: loop
31 ; CHECK: call void @use(i64 %div)
32 entry:
33   br label %loop
35 loop:                                         ; preds = %entry, %for.inc
36   %div = udiv i64 %x, %y
37   call void @use(i64 %div)
38   br label %loop
40 define void @throw_header_after_rec(i64* %xp, i64* %yp, i1* %cond) {
41 ; CHECK-LABEL: throw_header_after_rec
42 ; CHECK: %x = load i64, i64* %xp
43 ; CHECK: %y = load i64, i64* %yp
44 ; CHECK: %div = udiv i64 %x, %y
45 ; CHECK-LABEL: loop
46 ; CHECK: call void @use(i64 %div)
47 entry:
48   br label %loop
50 loop:                                         ; preds = %entry, %for.inc
51   %x = load i64, i64* %xp
52   %y = load i64, i64* %yp
53   %div = udiv i64 %x, %y
54   call void @use(i64 %div) readonly
55   br label %loop
58 ; Similiar to the above, but the hoistable instruction (%y in this case)
59 ; happens not to be the first instruction in the block.
60 define void @throw_header_after_nonfirst(i64* %xp, i64* %yp, i1* %cond) {
61 ; CHECK-LABEL: throw_header_after_nonfirst
62 ; CHECK: %y = load i64, i64* %yp
63 ; CHECK-LABEL: loop
64 ; CHECK: %x = load i64, i64* %gep
65 ; CHECK: %div = udiv i64 %x, %y
66 ; CHECK: call void @use(i64 %div)
67 entry:
68   br label %loop
70 loop:                                         ; preds = %entry, %for.inc
71   %iv = phi i64 [0, %entry], [%div, %loop]
72   %gep = getelementptr i64, i64* %xp, i64 %iv
73   %x = load i64, i64* %gep
74   %y = load i64, i64* %yp
75   %div = udiv i64 %x, %y
76   call void @use(i64 %div) readonly
77   br label %loop
80 ; Negative test
81 define void @throw_header_before(i64 %x, i64 %y, i1* %cond) {
82 ; CHECK-LABEL: throw_header_before
83 ; CHECK-LABEL: loop
84 ; CHECK: %div = udiv i64 %x, %y
85 ; CHECK: call void @use(i64 %div)
86 entry:
87   br label %loop
89 loop:                                         ; preds = %entry, %for.inc
90   call void @maythrow()
91   %div = udiv i64 %x, %y
92   call void @use(i64 %div)
93   br label %loop
96 ; The header is known no throw, but the loop is not.  We can
97 ; still lift out of the header.
98 define void @nothrow_header(i64 %x, i64 %y, i1 %cond) {
99 ; CHECK-LABEL: nothrow_header
100 ; CHECK-LABEL: entry
101 ; CHECK: %div = udiv i64 %x, %y
102 ; CHECK-LABEL: loop
103   ; CHECK: call void @use(i64 %div)
104 entry:
105   br label %loop
106 loop:                                         ; preds = %entry, %for.inc
107   %div = udiv i64 %x, %y
108   br i1 %cond, label %loop-if, label %exit
109 loop-if:
110   call void @use(i64 %div)
111   br label %loop
112 exit:
113   ret void
116 ; Positive test - can hoist something that happens before thrower.
117 define void @nothrow_header_pos(i64 %x, i64 %y, i1 %cond) {
118 ; CHECK-LABEL: nothrow_header_pos
119 ; CHECK-LABEL: entry
120 ; CHECK: %div = udiv i64 %x, %y
121 ; CHECK-LABEL: loop
122 ; CHECK: call void @use(i64 %div)
123 entry:
124   br label %loop
125 loop:                                         ; preds = %entry, %for.inc
126   br label %loop-if
127 loop-if:
128   %div = udiv i64 %x, %y
129   call void @use(i64 %div)
130   br label %loop
134 ; Negative test - can't move out of throwing block
135 define void @nothrow_header_neg(i64 %x, i64 %y, i1 %cond) {
136 ; CHECK-LABEL: nothrow_header_neg
137 ; CHECK-LABEL: entry
138 ; CHECK-LABEL: loop
139 ; CHECK: call void @maythrow()
140 ; CHECK: %div = udiv i64 %x, %y
141 ; CHECK: call void @use(i64 %div)
142 entry:
143   br label %loop
144 loop:                                         ; preds = %entry, %for.inc
145   br label %loop-if
146 loop-if:
147   call void @maythrow()
148   %div = udiv i64 %x, %y
149   call void @use(i64 %div)
150   br label %loop