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