1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -instcombine -S | FileCheck %s
4 define i32 @sdiv1(i32 %x) {
6 ; CHECK-NEXT: [[Y:%.*]] = sdiv i32 [[X:%.*]], 8
7 ; CHECK-NEXT: ret i32 [[Y]]
13 define i32 @sdiv2(i32 %x) {
14 ; CHECK-LABEL: @sdiv2(
15 ; CHECK-NEXT: [[Y:%.*]] = ashr exact i32 [[X:%.*]], 3
16 ; CHECK-NEXT: ret i32 [[Y]]
18 %y = sdiv exact i32 %x, 8
22 define <2 x i32> @sdiv2_vec(<2 x i32> %x) {
23 ; CHECK-LABEL: @sdiv2_vec(
24 ; CHECK-NEXT: [[Y:%.*]] = ashr exact <2 x i32> [[X:%.*]], <i32 7, i32 7>
25 ; CHECK-NEXT: ret <2 x i32> [[Y]]
27 %y = sdiv exact <2 x i32> %x, <i32 128, i32 128>
31 define i32 @sdiv3(i32 %x) {
32 ; CHECK-LABEL: @sdiv3(
33 ; CHECK-NEXT: [[TMP1:%.*]] = srem i32 [[X:%.*]], 3
34 ; CHECK-NEXT: [[Z:%.*]] = sub i32 [[X]], [[TMP1]]
35 ; CHECK-NEXT: ret i32 [[Z]]
42 define i32 @sdiv4(i32 %x) {
43 ; CHECK-LABEL: @sdiv4(
44 ; CHECK-NEXT: ret i32 [[X:%.*]]
46 %y = sdiv exact i32 %x, 3
51 define i32 @sdiv5(i32 %x) {
52 ; CHECK-LABEL: @sdiv5(
53 ; CHECK-NEXT: [[TMP1:%.*]] = srem i32 [[X:%.*]], 3
54 ; CHECK-NEXT: [[Z:%.*]] = sub i32 [[TMP1]], [[X]]
55 ; CHECK-NEXT: ret i32 [[Z]]
62 define i32 @sdiv6(i32 %x) {
63 ; CHECK-LABEL: @sdiv6(
64 ; CHECK-NEXT: [[Z:%.*]] = sub i32 0, [[X:%.*]]
65 ; CHECK-NEXT: ret i32 [[Z]]
67 %y = sdiv exact i32 %x, 3
72 define i32 @udiv1(i32 %x, i32 %w) {
73 ; CHECK-LABEL: @udiv1(
74 ; CHECK-NEXT: ret i32 [[X:%.*]]
76 %y = udiv exact i32 %x, %w
81 define i32 @udiv2(i32 %x, i32 %w) {
82 ; CHECK-LABEL: @udiv2(
83 ; CHECK-NEXT: [[Z:%.*]] = lshr exact i32 [[X:%.*]], [[W:%.*]]
84 ; CHECK-NEXT: ret i32 [[Z]]
87 %z = udiv exact i32 %x, %y
91 define i64 @ashr1(i64 %X) {
92 ; CHECK-LABEL: @ashr1(
93 ; CHECK-NEXT: [[A:%.*]] = shl i64 [[X:%.*]], 8
94 ; CHECK-NEXT: [[B:%.*]] = ashr exact i64 [[A]], 2
95 ; CHECK-NEXT: ret i64 [[B]]
102 ; The vector ashr should be exact (like it is in the preceding test).
104 define <2 x i64> @ashr1_vec(<2 x i64> %X) {
105 ; CHECK-LABEL: @ashr1_vec(
106 ; CHECK-NEXT: [[A:%.*]] = shl <2 x i64> [[X:%.*]], <i64 8, i64 8>
107 ; CHECK-NEXT: [[B:%.*]] = ashr exact <2 x i64> [[A]], <i64 2, i64 2>
108 ; CHECK-NEXT: ret <2 x i64> [[B]]
110 %A = shl <2 x i64> %X, <i64 8, i64 8>
111 %B = ashr <2 x i64> %A, <i64 2, i64 2>
116 define i1 @ashr_icmp1(i64 %X) {
117 ; CHECK-LABEL: @ashr_icmp1(
118 ; CHECK-NEXT: [[B:%.*]] = icmp eq i64 [[X:%.*]], 0
119 ; CHECK-NEXT: ret i1 [[B]]
121 %A = ashr exact i64 %X, 2 ; X/4
122 %B = icmp eq i64 %A, 0
126 define i1 @ashr_icmp2(i64 %X) {
127 ; CHECK-LABEL: @ashr_icmp2(
128 ; CHECK-NEXT: [[Z:%.*]] = icmp slt i64 [[X:%.*]], 16
129 ; CHECK-NEXT: ret i1 [[Z]]
131 %Y = ashr exact i64 %X, 2 ; x / 4
132 %Z = icmp slt i64 %Y, 4 ; x < 16
136 define <2 x i1> @ashr_icmp2_vec(<2 x i64> %X) {
137 ; CHECK-LABEL: @ashr_icmp2_vec(
138 ; CHECK-NEXT: [[Z:%.*]] = icmp slt <2 x i64> [[X:%.*]], <i64 16, i64 16>
139 ; CHECK-NEXT: ret <2 x i1> [[Z]]
141 %Y = ashr exact <2 x i64> %X, <i64 2, i64 2>
142 %Z = icmp slt <2 x i64> %Y, <i64 4, i64 4>
147 ; Make sure we don't transform the ashr here into an sdiv
148 define i1 @pr9998(i32 %V) {
149 ; CHECK-LABEL: @pr9998(
150 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[V:%.*]], 1
151 ; CHECK-NEXT: [[Z:%.*]] = icmp ne i32 [[TMP1]], 0
152 ; CHECK-NEXT: ret i1 [[Z]]
155 %X = ashr exact i32 %W, 31
156 %Y = sext i32 %X to i64
157 %Z = icmp ugt i64 %Y, 7297771788697658747
161 ; FIXME: Vectors should fold the same way.
162 define <2 x i1> @pr9998vec(<2 x i32> %V) {
163 ; CHECK-LABEL: @pr9998vec(
164 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[V:%.*]], <i32 1, i32 1>
165 ; CHECK-NEXT: [[X:%.*]] = sub nsw <2 x i32> zeroinitializer, [[TMP1]]
166 ; CHECK-NEXT: [[Y:%.*]] = sext <2 x i32> [[X]] to <2 x i64>
167 ; CHECK-NEXT: [[Z:%.*]] = icmp ugt <2 x i64> [[Y]], <i64 7297771788697658747, i64 7297771788697658747>
168 ; CHECK-NEXT: ret <2 x i1> [[Z]]
170 %W = shl <2 x i32> %V, <i32 31, i32 31>
171 %X = ashr exact <2 x i32> %W, <i32 31, i32 31>
172 %Y = sext <2 x i32> %X to <2 x i64>
173 %Z = icmp ugt <2 x i64> %Y, <i64 7297771788697658747, i64 7297771788697658747>
177 define i1 @udiv_icmp1(i64 %X) {
178 ; CHECK-LABEL: @udiv_icmp1(
179 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i64 [[X:%.*]], 0
180 ; CHECK-NEXT: ret i1 [[TMP1]]
182 %A = udiv exact i64 %X, 5 ; X/5
183 %B = icmp ne i64 %A, 0
187 define <2 x i1> @udiv_icmp1_vec(<2 x i64> %X) {
188 ; CHECK-LABEL: @udiv_icmp1_vec(
189 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <2 x i64> [[X:%.*]], zeroinitializer
190 ; CHECK-NEXT: ret <2 x i1> [[TMP1]]
192 %A = udiv exact <2 x i64> %X, <i64 5, i64 5>
193 %B = icmp ne <2 x i64> %A, zeroinitializer
197 define i1 @udiv_icmp2(i64 %X) {
198 ; CHECK-LABEL: @udiv_icmp2(
199 ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 [[X:%.*]], 0
200 ; CHECK-NEXT: ret i1 [[TMP1]]
202 %A = udiv exact i64 %X, 5 ; X/5 == 0 --> x == 0
203 %B = icmp eq i64 %A, 0
207 define <2 x i1> @udiv_icmp2_vec(<2 x i64> %X) {
208 ; CHECK-LABEL: @udiv_icmp2_vec(
209 ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i64> [[X:%.*]], zeroinitializer
210 ; CHECK-NEXT: ret <2 x i1> [[TMP1]]
212 %A = udiv exact <2 x i64> %X, <i64 5, i64 5>
213 %B = icmp eq <2 x i64> %A, zeroinitializer
217 define i1 @sdiv_icmp1(i64 %X) {
218 ; CHECK-LABEL: @sdiv_icmp1(
219 ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 [[X:%.*]], 0
220 ; CHECK-NEXT: ret i1 [[TMP1]]
222 %A = sdiv exact i64 %X, 5 ; X/5 == 0 --> x == 0
223 %B = icmp eq i64 %A, 0
227 define <2 x i1> @sdiv_icmp1_vec(<2 x i64> %X) {
228 ; CHECK-LABEL: @sdiv_icmp1_vec(
229 ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i64> [[X:%.*]], zeroinitializer
230 ; CHECK-NEXT: ret <2 x i1> [[TMP1]]
232 %A = sdiv exact <2 x i64> %X, <i64 5, i64 5>
233 %B = icmp eq <2 x i64> %A, zeroinitializer
237 define i1 @sdiv_icmp2(i64 %X) {
238 ; CHECK-LABEL: @sdiv_icmp2(
239 ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 [[X:%.*]], 5
240 ; CHECK-NEXT: ret i1 [[TMP1]]
242 %A = sdiv exact i64 %X, 5 ; X/5 == 1 --> x == 5
243 %B = icmp eq i64 %A, 1
247 define <2 x i1> @sdiv_icmp2_vec(<2 x i64> %X) {
248 ; CHECK-LABEL: @sdiv_icmp2_vec(
249 ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i64> [[X:%.*]], <i64 5, i64 5>
250 ; CHECK-NEXT: ret <2 x i1> [[TMP1]]
252 %A = sdiv exact <2 x i64> %X, <i64 5, i64 5>
253 %B = icmp eq <2 x i64> %A, <i64 1, i64 1>
257 define i1 @sdiv_icmp3(i64 %X) {
258 ; CHECK-LABEL: @sdiv_icmp3(
259 ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 [[X:%.*]], -5
260 ; CHECK-NEXT: ret i1 [[TMP1]]
262 %A = sdiv exact i64 %X, 5 ; X/5 == -1 --> x == -5
263 %B = icmp eq i64 %A, -1
267 define <2 x i1> @sdiv_icmp3_vec(<2 x i64> %X) {
268 ; CHECK-LABEL: @sdiv_icmp3_vec(
269 ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i64> [[X:%.*]], <i64 -5, i64 -5>
270 ; CHECK-NEXT: ret <2 x i1> [[TMP1]]
272 %A = sdiv exact <2 x i64> %X, <i64 5, i64 5>
273 %B = icmp eq <2 x i64> %A, <i64 -1, i64 -1>
277 define i1 @sdiv_icmp4(i64 %X) {
278 ; CHECK-LABEL: @sdiv_icmp4(
279 ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 [[X:%.*]], 0
280 ; CHECK-NEXT: ret i1 [[TMP1]]
282 %A = sdiv exact i64 %X, -5 ; X/-5 == 0 --> x == 0
283 %B = icmp eq i64 %A, 0
287 define <2 x i1> @sdiv_icmp4_vec(<2 x i64> %X) {
288 ; CHECK-LABEL: @sdiv_icmp4_vec(
289 ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i64> [[X:%.*]], zeroinitializer
290 ; CHECK-NEXT: ret <2 x i1> [[TMP1]]
292 %A = sdiv exact <2 x i64> %X, <i64 -5, i64 -5>
293 %B = icmp eq <2 x i64> %A, zeroinitializer
297 define i1 @sdiv_icmp5(i64 %X) {
298 ; CHECK-LABEL: @sdiv_icmp5(
299 ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 [[X:%.*]], -5
300 ; CHECK-NEXT: ret i1 [[TMP1]]
302 %A = sdiv exact i64 %X, -5 ; X/-5 == 1 --> x == -5
303 %B = icmp eq i64 %A, 1
307 define <2 x i1> @sdiv_icmp5_vec(<2 x i64> %X) {
308 ; CHECK-LABEL: @sdiv_icmp5_vec(
309 ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i64> [[X:%.*]], <i64 -5, i64 -5>
310 ; CHECK-NEXT: ret <2 x i1> [[TMP1]]
312 %A = sdiv exact <2 x i64> %X, <i64 -5, i64 -5>
313 %B = icmp eq <2 x i64> %A, <i64 1, i64 1>
317 define i1 @sdiv_icmp6(i64 %X) {
318 ; CHECK-LABEL: @sdiv_icmp6(
319 ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 [[X:%.*]], 5
320 ; CHECK-NEXT: ret i1 [[TMP1]]
322 %A = sdiv exact i64 %X, -5 ; X/-5 == -1 --> x == 5
323 %B = icmp eq i64 %A, -1
327 define <2 x i1> @sdiv_icmp6_vec(<2 x i64> %X) {
328 ; CHECK-LABEL: @sdiv_icmp6_vec(
329 ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i64> [[X:%.*]], <i64 5, i64 5>
330 ; CHECK-NEXT: ret <2 x i1> [[TMP1]]
332 %A = sdiv exact <2 x i64> %X, <i64 -5, i64 -5>
333 %B = icmp eq <2 x i64> %A, <i64 -1, i64 -1>