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, %or
7 ; CHECK-NEXT: br label %for.body
9 define void @safe_udiv(i64 %x, i64 %m, i64 %n, i32* %p, i64* %q) nounwind {
14 for.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
21 if.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
27 for.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
32 for.end: ; preds = %for.inc, %entry
36 ; UDiv is unsafe to speculate if the denominator is not known non-zero.
38 ; CHECK-LABEL: @unsafe_udiv(
42 define void @unsafe_udiv(i64 %x, i64 %m, i64 %n, i32* %p, i64* %q) nounwind {
46 for.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
53 if.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
59 for.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
64 for.end: ; preds = %for.inc, %entry
68 ; SDiv is safe to speculate if the denominator is known non-zero and
69 ; known to have at least one zero bit.
71 ; CHECK-LABEL: @safe_sdiv(
72 ; CHECK: %div = sdiv i64 %x, %or
73 ; CHECK-NEXT: br label %for.body
75 define void @safe_sdiv(i64 %x, i64 %m, i64 %n, i32* %p, i64* %q) nounwind {
81 for.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
88 if.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
94 for.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
99 for.end: ; preds = %for.inc, %entry
103 ; SDiv is unsafe to speculate if the denominator is not known non-zero.
105 ; CHECK-LABEL: @unsafe_sdiv_a(
109 define void @unsafe_sdiv_a(i64 %x, i64 %m, i64 %n, i32* %p, i64* %q) nounwind {
114 for.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
121 if.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
127 for.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
132 for.end: ; preds = %for.inc, %entry
136 ; SDiv is unsafe to speculate if the denominator is not known to have a zero bit.
138 ; CHECK-LABEL: @unsafe_sdiv_b(
142 define void @unsafe_sdiv_b(i64 %x, i64 %m, i64 %n, i32* %p, i64* %q) nounwind {
144 %and = and i64 %m, -3
147 for.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
154 if.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
160 for.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
165 for.end: ; preds = %for.inc, %entry
169 ; SDiv is unsafe to speculate inside an infinite loop.
171 define void @unsafe_sdiv_c(i64 %a, i64 %b, i64* %p) {
175 ; CHECK: br label %for.body
179 %c = icmp eq i64 %b, 0
180 br i1 %c, label %backedge, label %if.then
184 store i64 %d, i64* %p