[DAGCombiner] Add target hook function to decide folding (mul (add x, c1), c2)
[llvm-project.git] / llvm / test / Transforms / LICM / speculate.ll
blobdc6059cfe8ae52bce853e6a6c504b2361f1f8518
1 ; RUN: opt -S -licm < %s | FileCheck %s
2 ; RUN: opt -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop-mssa(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 {
11 entry:
12   br label %for.body
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
22   %div = udiv i64 %x, 2
23   %arrayidx1 = getelementptr inbounds i64, i64* %q, i64 %i.02
24   store i64 %div, i64* %arrayidx1, align 8
25   br label %for.inc
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
33   ret void
36 ; UDiv is unsafe to speculate if the denominator is not known non-zero.
38 ; CHECK-LABEL: @unsafe_udiv(
39 ; CHECK-NOT:  udiv
40 ; CHECK: for.body:
42 define void @unsafe_udiv(i64 %x, i64 %m, i64 %n, i32* %p, i64* %q) nounwind {
43 entry:
44   br label %for.body
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
57   br label %for.inc
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
65   ret void
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 {
76 entry:
77   %and = and i64 %m, -3
78   br label %for.body
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
88   %div = sdiv i64 %x, 2
89   %arrayidx1 = getelementptr inbounds i64, i64* %q, i64 %i.02
90   store i64 %div, i64* %arrayidx1, align 8
91   br label %for.inc
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
99   ret void
102 ; SDiv is unsafe to speculate if the denominator is not known non-zero.
104 ; CHECK-LABEL: @unsafe_sdiv_a(
105 ; CHECK-NOT:  sdiv
106 ; CHECK: for.body:
108 define void @unsafe_sdiv_a(i64 %x, i64 %m, i64 %n, i32* %p, i64* %q) nounwind {
109 entry:
110   %or = or i64 %m, 1
111   br label %for.body
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
124   br label %for.inc
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
132   ret void
135 ; SDiv is unsafe to speculate if the denominator is not known to have a zero bit.
137 ; CHECK-LABEL: @unsafe_sdiv_b(
138 ; CHECK-NOT:  sdiv
139 ; CHECK: for.body:
141 define void @unsafe_sdiv_b(i64 %x, i64 %m, i64 %n, i32* %p, i64* %q) nounwind {
142 entry:
143   %and = and i64 %m, -3
144   br label %for.body
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
157   br label %for.inc
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
165   ret void
168 ; SDiv is unsafe to speculate inside an infinite loop.
170 define void @unsafe_sdiv_c(i64 %a, i64 %b, i64* %p) {
171 entry:
172 ; CHECK: entry:
173 ; CHECK-NOT: sdiv
174 ; CHECK: br label %for.body
175   br label %for.body
177 for.body:
178   %c = icmp eq i64 %b, 0
179   br i1 %c, label %backedge, label %if.then
181 if.then:
182   %d = sdiv i64 %a, %b
183   store i64 %d, i64* %p
184   br label %backedge
186 backedge:
187   br label %for.body