1 ; RUN: opt -S -licm < %s | FileCheck %s
2 ; RUN: opt -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop(licm)' -S %s | FileCheck %s
4 ; UDiv is safe to speculate if the denominator is known non-zero.
6 ; CHECK-LABEL: @safe_udiv(
7 ; CHECK: %div = udiv i64 %x, 2
8 ; CHECK-NEXT: br label %for.body
10 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, i32* %p, i64 %i.02
17 %0 = load i32, 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
23 %arrayidx1 = getelementptr inbounds i64, 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, i32* %p, i64 %i.02
49 %0 = load i32, 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, 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, 2
73 ; CHECK-NEXT: br label %for.body
75 define void @safe_sdiv(i64 %x, i64 %m, i64 %n, i32* %p, i64* %q) nounwind {
80 for.body: ; preds = %entry, %for.inc
81 %i.02 = phi i64 [ %inc, %for.inc ], [ 0, %entry ]
82 %arrayidx = getelementptr inbounds i32, i32* %p, i64 %i.02
83 %0 = load i32, i32* %arrayidx, align 4
84 %tobool = icmp eq i32 %0, 0
85 br i1 %tobool, label %for.inc, label %if.then
87 if.then: ; preds = %for.body
89 %arrayidx1 = getelementptr inbounds i64, i64* %q, i64 %i.02
90 store i64 %div, i64* %arrayidx1, align 8
93 for.inc: ; preds = %if.then, %for.body
94 %inc = add i64 %i.02, 1
95 %cmp = icmp slt i64 %inc, %n
96 br i1 %cmp, label %for.body, label %for.end
98 for.end: ; preds = %for.inc, %entry
102 ; SDiv is unsafe to speculate if the denominator is not known non-zero.
104 ; CHECK-LABEL: @unsafe_sdiv_a(
108 define void @unsafe_sdiv_a(i64 %x, i64 %m, i64 %n, i32* %p, i64* %q) nounwind {
113 for.body: ; preds = %entry, %for.inc
114 %i.02 = phi i64 [ %inc, %for.inc ], [ 0, %entry ]
115 %arrayidx = getelementptr inbounds i32, i32* %p, i64 %i.02
116 %0 = load i32, i32* %arrayidx, align 4
117 %tobool = icmp eq i32 %0, 0
118 br i1 %tobool, label %for.inc, label %if.then
120 if.then: ; preds = %for.body
121 %div = sdiv i64 %x, %or
122 %arrayidx1 = getelementptr inbounds i64, i64* %q, i64 %i.02
123 store i64 %div, i64* %arrayidx1, align 8
126 for.inc: ; preds = %if.then, %for.body
127 %inc = add i64 %i.02, 1
128 %cmp = icmp slt i64 %inc, %n
129 br i1 %cmp, label %for.body, label %for.end
131 for.end: ; preds = %for.inc, %entry
135 ; SDiv is unsafe to speculate if the denominator is not known to have a zero bit.
137 ; CHECK-LABEL: @unsafe_sdiv_b(
141 define void @unsafe_sdiv_b(i64 %x, i64 %m, i64 %n, i32* %p, i64* %q) nounwind {
143 %and = and i64 %m, -3
146 for.body: ; preds = %entry, %for.inc
147 %i.02 = phi i64 [ %inc, %for.inc ], [ 0, %entry ]
148 %arrayidx = getelementptr inbounds i32, i32* %p, i64 %i.02
149 %0 = load i32, i32* %arrayidx, align 4
150 %tobool = icmp eq i32 %0, 0
151 br i1 %tobool, label %for.inc, label %if.then
153 if.then: ; preds = %for.body
154 %div = sdiv i64 %x, %and
155 %arrayidx1 = getelementptr inbounds i64, i64* %q, i64 %i.02
156 store i64 %div, i64* %arrayidx1, align 8
159 for.inc: ; preds = %if.then, %for.body
160 %inc = add i64 %i.02, 1
161 %cmp = icmp slt i64 %inc, %n
162 br i1 %cmp, label %for.body, label %for.end
164 for.end: ; preds = %for.inc, %entry
168 ; SDiv is unsafe to speculate inside an infinite loop.
170 define void @unsafe_sdiv_c(i64 %a, i64 %b, i64* %p) {
174 ; CHECK: br label %for.body
178 %c = icmp eq i64 %b, 0
179 br i1 %c, label %backedge, label %if.then
183 store i64 %d, i64* %p