1 ; RUN: opt -S -licm < %s | FileCheck %s
3 ; UDiv is safe to speculate if the denominator is known non-zero.
5 ; CHECK-LABEL: @safe_udiv(
6 ; CHECK: %div = udiv i64 %x, 2
7 ; CHECK-NEXT: br label %for.body
9 define void @safe_udiv(i64 %x, i64 %m, i64 %n, i32* %p, i64* %q) nounwind {
13 for.body: ; preds = %entry, %for.inc
14 %i.02 = phi i64 [ %inc, %for.inc ], [ 0, %entry ]
15 %arrayidx = getelementptr inbounds i32, i32* %p, i64 %i.02
16 %0 = load i32, i32* %arrayidx, align 4
17 %tobool = icmp eq i32 %0, 0
18 br i1 %tobool, label %for.inc, label %if.then
20 if.then: ; preds = %for.body
22 %arrayidx1 = getelementptr inbounds i64, i64* %q, i64 %i.02
23 store i64 %div, i64* %arrayidx1, align 8
26 for.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
31 for.end: ; preds = %for.inc, %entry
35 ; UDiv is unsafe to speculate if the denominator is not known non-zero.
37 ; CHECK-LABEL: @unsafe_udiv(
41 define void @unsafe_udiv(i64 %x, i64 %m, i64 %n, i32* %p, i64* %q) nounwind {
45 for.body: ; preds = %entry, %for.inc
46 %i.02 = phi i64 [ %inc, %for.inc ], [ 0, %entry ]
47 %arrayidx = getelementptr inbounds i32, i32* %p, i64 %i.02
48 %0 = load i32, i32* %arrayidx, align 4
49 %tobool = icmp eq i32 %0, 0
50 br i1 %tobool, label %for.inc, label %if.then
52 if.then: ; preds = %for.body
53 %div = udiv i64 %x, %m
54 %arrayidx1 = getelementptr inbounds i64, i64* %q, i64 %i.02
55 store i64 %div, i64* %arrayidx1, align 8
58 for.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
63 for.end: ; preds = %for.inc, %entry
67 ; SDiv is safe to speculate if the denominator is known non-zero and
68 ; known to have at least one zero bit.
70 ; CHECK-LABEL: @safe_sdiv(
71 ; CHECK: %div = sdiv i64 %x, 2
72 ; CHECK-NEXT: br label %for.body
74 define void @safe_sdiv(i64 %x, i64 %m, i64 %n, i32* %p, i64* %q) nounwind {
79 for.body: ; preds = %entry, %for.inc
80 %i.02 = phi i64 [ %inc, %for.inc ], [ 0, %entry ]
81 %arrayidx = getelementptr inbounds i32, i32* %p, i64 %i.02
82 %0 = load i32, i32* %arrayidx, align 4
83 %tobool = icmp eq i32 %0, 0
84 br i1 %tobool, label %for.inc, label %if.then
86 if.then: ; preds = %for.body
88 %arrayidx1 = getelementptr inbounds i64, i64* %q, i64 %i.02
89 store i64 %div, i64* %arrayidx1, align 8
92 for.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
97 for.end: ; preds = %for.inc, %entry
101 ; SDiv is unsafe to speculate if the denominator is not known non-zero.
103 ; CHECK-LABEL: @unsafe_sdiv_a(
107 define void @unsafe_sdiv_a(i64 %x, i64 %m, i64 %n, i32* %p, i64* %q) nounwind {
112 for.body: ; preds = %entry, %for.inc
113 %i.02 = phi i64 [ %inc, %for.inc ], [ 0, %entry ]
114 %arrayidx = getelementptr inbounds i32, i32* %p, i64 %i.02
115 %0 = load i32, i32* %arrayidx, align 4
116 %tobool = icmp eq i32 %0, 0
117 br i1 %tobool, label %for.inc, label %if.then
119 if.then: ; preds = %for.body
120 %div = sdiv i64 %x, %or
121 %arrayidx1 = getelementptr inbounds i64, i64* %q, i64 %i.02
122 store i64 %div, i64* %arrayidx1, align 8
125 for.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
130 for.end: ; preds = %for.inc, %entry
134 ; SDiv is unsafe to speculate if the denominator is not known to have a zero bit.
136 ; CHECK-LABEL: @unsafe_sdiv_b(
140 define void @unsafe_sdiv_b(i64 %x, i64 %m, i64 %n, i32* %p, i64* %q) nounwind {
142 %and = and i64 %m, -3
145 for.body: ; preds = %entry, %for.inc
146 %i.02 = phi i64 [ %inc, %for.inc ], [ 0, %entry ]
147 %arrayidx = getelementptr inbounds i32, i32* %p, i64 %i.02
148 %0 = load i32, i32* %arrayidx, align 4
149 %tobool = icmp eq i32 %0, 0
150 br i1 %tobool, label %for.inc, label %if.then
152 if.then: ; preds = %for.body
153 %div = sdiv i64 %x, %and
154 %arrayidx1 = getelementptr inbounds i64, i64* %q, i64 %i.02
155 store i64 %div, i64* %arrayidx1, align 8
158 for.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
163 for.end: ; preds = %for.inc, %entry
167 ; SDiv is unsafe to speculate inside an infinite loop.
169 define void @unsafe_sdiv_c(i64 %a, i64 %b, i64* %p) {
173 ; CHECK: br label %for.body
177 %c = icmp eq i64 %b, 0
178 br i1 %c, label %backedge, label %if.then
182 store i64 %d, i64* %p