1; RUN: opt -S -licm < %s | FileCheck %s
2
3; UDiv is safe to speculate if the denominator is known non-zero.
4
5; CHECK-LABEL: @safe_udiv(
6; CHECK:      %div = udiv i64 %x, 2
7; CHECK-NEXT: br label %for.body
8
9define void @safe_udiv(i64 %x, i64 %m, i64 %n, i32* %p, i64* %q) nounwind {
10entry:
11  br label %for.body
12
13for.body:                                         ; preds = %entry, %for.inc
14  %i.02 = phi i64 [ %inc, %for.inc ], [ 0, %entry ]
15  %arrayidx = getelementptr inbounds i32* %p, i64 %i.02
16  %0 = load i32* %arrayidx, align 4
17  %tobool = icmp eq i32 %0, 0
18  br i1 %tobool, label %for.inc, label %if.then
19
20if.then:                                          ; preds = %for.body
21  %div = udiv i64 %x, 2
22  %arrayidx1 = getelementptr inbounds i64* %q, i64 %i.02
23  store i64 %div, i64* %arrayidx1, align 8
24  br label %for.inc
25
26for.inc:                                          ; preds = %if.then, %for.body
27  %inc = add i64 %i.02, 1
28  %cmp = icmp slt i64 %inc, %n
29  br i1 %cmp, label %for.body, label %for.end
30
31for.end:                                          ; preds = %for.inc, %entry
32  ret void
33}
34
35; UDiv is unsafe to speculate if the denominator is not known non-zero.
36
37; CHECK-LABEL: @unsafe_udiv(
38; CHECK-NOT:  udiv
39; CHECK: for.body:
40
41define void @unsafe_udiv(i64 %x, i64 %m, i64 %n, i32* %p, i64* %q) nounwind {
42entry:
43  br label %for.body
44
45for.body:                                         ; preds = %entry, %for.inc
46  %i.02 = phi i64 [ %inc, %for.inc ], [ 0, %entry ]
47  %arrayidx = getelementptr inbounds i32* %p, i64 %i.02
48  %0 = load i32* %arrayidx, align 4
49  %tobool = icmp eq i32 %0, 0
50  br i1 %tobool, label %for.inc, label %if.then
51
52if.then:                                          ; preds = %for.body
53  %div = udiv i64 %x, %m
54  %arrayidx1 = getelementptr inbounds i64* %q, i64 %i.02
55  store i64 %div, i64* %arrayidx1, align 8
56  br label %for.inc
57
58for.inc:                                          ; preds = %if.then, %for.body
59  %inc = add i64 %i.02, 1
60  %cmp = icmp slt i64 %inc, %n
61  br i1 %cmp, label %for.body, label %for.end
62
63for.end:                                          ; preds = %for.inc, %entry
64  ret void
65}
66
67; SDiv is safe to speculate if the denominator is known non-zero and
68; known to have at least one zero bit.
69
70; CHECK-LABEL: @safe_sdiv(
71; CHECK:      %div = sdiv i64 %x, 2
72; CHECK-NEXT: br label %for.body
73
74define void @safe_sdiv(i64 %x, i64 %m, i64 %n, i32* %p, i64* %q) nounwind {
75entry:
76  %and = and i64 %m, -3
77  br label %for.body
78
79for.body:                                         ; preds = %entry, %for.inc
80  %i.02 = phi i64 [ %inc, %for.inc ], [ 0, %entry ]
81  %arrayidx = getelementptr inbounds i32* %p, i64 %i.02
82  %0 = load i32* %arrayidx, align 4
83  %tobool = icmp eq i32 %0, 0
84  br i1 %tobool, label %for.inc, label %if.then
85
86if.then:                                          ; preds = %for.body
87  %div = sdiv i64 %x, 2
88  %arrayidx1 = getelementptr inbounds i64* %q, i64 %i.02
89  store i64 %div, i64* %arrayidx1, align 8
90  br label %for.inc
91
92for.inc:                                          ; preds = %if.then, %for.body
93  %inc = add i64 %i.02, 1
94  %cmp = icmp slt i64 %inc, %n
95  br i1 %cmp, label %for.body, label %for.end
96
97for.end:                                          ; preds = %for.inc, %entry
98  ret void
99}
100
101; SDiv is unsafe to speculate if the denominator is not known non-zero.
102
103; CHECK-LABEL: @unsafe_sdiv_a(
104; CHECK-NOT:  sdiv
105; CHECK: for.body:
106
107define void @unsafe_sdiv_a(i64 %x, i64 %m, i64 %n, i32* %p, i64* %q) nounwind {
108entry:
109  %or = or i64 %m, 1
110  br label %for.body
111
112for.body:                                         ; preds = %entry, %for.inc
113  %i.02 = phi i64 [ %inc, %for.inc ], [ 0, %entry ]
114  %arrayidx = getelementptr inbounds i32* %p, i64 %i.02
115  %0 = load i32* %arrayidx, align 4
116  %tobool = icmp eq i32 %0, 0
117  br i1 %tobool, label %for.inc, label %if.then
118
119if.then:                                          ; preds = %for.body
120  %div = sdiv i64 %x, %or
121  %arrayidx1 = getelementptr inbounds i64* %q, i64 %i.02
122  store i64 %div, i64* %arrayidx1, align 8
123  br label %for.inc
124
125for.inc:                                          ; preds = %if.then, %for.body
126  %inc = add i64 %i.02, 1
127  %cmp = icmp slt i64 %inc, %n
128  br i1 %cmp, label %for.body, label %for.end
129
130for.end:                                          ; preds = %for.inc, %entry
131  ret void
132}
133
134; SDiv is unsafe to speculate if the denominator is not known to have a zero bit.
135
136; CHECK-LABEL: @unsafe_sdiv_b(
137; CHECK-NOT:  sdiv
138; CHECK: for.body:
139
140define void @unsafe_sdiv_b(i64 %x, i64 %m, i64 %n, i32* %p, i64* %q) nounwind {
141entry:
142  %and = and i64 %m, -3
143  br label %for.body
144
145for.body:                                         ; preds = %entry, %for.inc
146  %i.02 = phi i64 [ %inc, %for.inc ], [ 0, %entry ]
147  %arrayidx = getelementptr inbounds i32* %p, i64 %i.02
148  %0 = load i32* %arrayidx, align 4
149  %tobool = icmp eq i32 %0, 0
150  br i1 %tobool, label %for.inc, label %if.then
151
152if.then:                                          ; preds = %for.body
153  %div = sdiv i64 %x, %and
154  %arrayidx1 = getelementptr inbounds i64* %q, i64 %i.02
155  store i64 %div, i64* %arrayidx1, align 8
156  br label %for.inc
157
158for.inc:                                          ; preds = %if.then, %for.body
159  %inc = add i64 %i.02, 1
160  %cmp = icmp slt i64 %inc, %n
161  br i1 %cmp, label %for.body, label %for.end
162
163for.end:                                          ; preds = %for.inc, %entry
164  ret void
165}
166
167; SDiv is unsafe to speculate inside an infinite loop.
168
169define void @unsafe_sdiv_c(i64 %a, i64 %b, i64* %p) {
170entry:
171; CHECK: entry:
172; CHECK-NOT: sdiv
173; CHECK: br label %for.body
174  br label %for.body
175
176for.body:
177  %c = icmp eq i64 %b, 0
178  br i1 %c, label %backedge, label %if.then
179
180if.then:
181  %d = sdiv i64 %a, %b
182  store i64 %d, i64* %p
183  br label %backedge
184
185backedge:
186  br label %for.body
187}
188