Re-land [openmp] Fix warnings when building on Windows with latest MSVC or Clang...
[llvm-project.git] / llvm / test / Transforms / InstCombine / icmp-div-constant.ll
blob8dcb96284685ff7e83b94e7fc663f7b0ee38ae0a
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
4 target datalayout = "n32"
6 define i1 @is_rem2_neg_i8(i8 %x) {
7 ; CHECK-LABEL: @is_rem2_neg_i8(
8 ; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[X:%.*]], -127
9 ; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[TMP1]], -127
10 ; CHECK-NEXT:    ret i1 [[R]]
12   %s = srem i8 %x, 2
13   %r = icmp slt i8 %s, 0
14   ret i1 %r
17 define <2 x i1> @is_rem2_pos_v2i8(<2 x i8> %x) {
18 ; CHECK-LABEL: @is_rem2_pos_v2i8(
19 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i8> [[X:%.*]], <i8 -127, i8 -127>
20 ; CHECK-NEXT:    [[R:%.*]] = icmp eq <2 x i8> [[TMP1]], <i8 1, i8 1>
21 ; CHECK-NEXT:    ret <2 x i1> [[R]]
23   %s = srem <2 x i8> %x, <i8 2, i8 2>
24   %r = icmp sgt <2 x i8> %s, zeroinitializer
25   ret <2 x i1> %r
28 ; i8 -97 == 159 == 0b10011111
30 define i1 @is_rem32_pos_i8(i8 %x) {
31 ; CHECK-LABEL: @is_rem32_pos_i8(
32 ; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[X:%.*]], -97
33 ; CHECK-NEXT:    [[R:%.*]] = icmp sgt i8 [[TMP1]], 0
34 ; CHECK-NEXT:    ret i1 [[R]]
36   %s = srem i8 %x, 32
37   %r = icmp sgt i8 %s, 0
38   ret i1 %r
41 ; i16 -32765 == 32771 == 0b1000000000000011
43 define i1 @is_rem4_neg_i16(i16 %x) {
44 ; CHECK-LABEL: @is_rem4_neg_i16(
45 ; CHECK-NEXT:    [[TMP1:%.*]] = and i16 [[X:%.*]], -32765
46 ; CHECK-NEXT:    [[R:%.*]] = icmp ugt i16 [[TMP1]], -32768
47 ; CHECK-NEXT:    ret i1 [[R]]
49   %s = srem i16 %x, 4
50   %r = icmp slt i16 %s, 0
51   ret i1 %r
54 declare void @use(i32)
56 ; TODO: This is still worth folding because srem is difficult?
58 define i1 @is_rem32_neg_i32_extra_use(i32 %x) {
59 ; CHECK-LABEL: @is_rem32_neg_i32_extra_use(
60 ; CHECK-NEXT:    [[S:%.*]] = srem i32 [[X:%.*]], 32
61 ; CHECK-NEXT:    call void @use(i32 [[S]])
62 ; CHECK-NEXT:    [[R:%.*]] = icmp slt i32 [[S]], 0
63 ; CHECK-NEXT:    ret i1 [[R]]
65   %s = srem i32 %x, 32
66   call void @use(i32 %s)
67   %r = icmp slt i32 %s, 0
68   ret i1 %r
71 ; Negative test - wrong compare constant
73 define i1 @is_rem8_nonneg_i16(i16 %x) {
74 ; CHECK-LABEL: @is_rem8_nonneg_i16(
75 ; CHECK-NEXT:    [[S:%.*]] = srem i16 [[X:%.*]], 8
76 ; CHECK-NEXT:    [[R:%.*]] = icmp sgt i16 [[S]], -1
77 ; CHECK-NEXT:    ret i1 [[R]]
79   %s = srem i16 %x, 8
80   %r = icmp sgt i16 %s, -1
81   ret i1 %r
84 ; Negative test - wrong remainder constant
86 define i1 @is_rem3_neg_i8(i8 %x) {
87 ; CHECK-LABEL: @is_rem3_neg_i8(
88 ; CHECK-NEXT:    [[S:%.*]] = srem i8 [[X:%.*]], 3
89 ; CHECK-NEXT:    [[R:%.*]] = icmp slt i8 [[S]], 0
90 ; CHECK-NEXT:    ret i1 [[R]]
92   %s = srem i8 %x, 3
93   %r = icmp slt i8 %s, 0
94   ret i1 %r
97 ; Negative test - wrong compare constant
99 define i1 @is_rem16_something_i8(i8 %x) {
100 ; CHECK-LABEL: @is_rem16_something_i8(
101 ; CHECK-NEXT:    [[S:%.*]] = srem i8 [[X:%.*]], 16
102 ; CHECK-NEXT:    [[R:%.*]] = icmp slt i8 [[S]], 7
103 ; CHECK-NEXT:    ret i1 [[R]]
105   %s = srem i8 %x, 16
106   %r = icmp slt i8 %s, 7
107   ret i1 %r
110 ; PR30281 - https://llvm.org/bugs/show_bug.cgi?id=30281
112 ; All of these tests contain foldable division-by-constant instructions, but we
113 ; can't assert that those folds have occurred before we process the later icmp.
115 define i32 @icmp_div(i16 %a, i16 %c) {
116 ; CHECK-LABEL: @icmp_div(
117 ; CHECK-NEXT:  entry:
118 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i16 [[A:%.*]], 0
119 ; CHECK-NEXT:    br i1 [[TOBOOL]], label [[THEN:%.*]], label [[EXIT:%.*]]
120 ; CHECK:       then:
121 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i16 [[C:%.*]], 0
122 ; CHECK-NEXT:    [[TMP0:%.*]] = sext i1 [[CMP]] to i32
123 ; CHECK-NEXT:    br label [[EXIT]]
124 ; CHECK:       exit:
125 ; CHECK-NEXT:    [[PHI:%.*]] = phi i32 [ -1, [[ENTRY:%.*]] ], [ [[TMP0]], [[THEN]] ]
126 ; CHECK-NEXT:    ret i32 [[PHI]]
128 entry:
129   %tobool = icmp eq i16 %a, 0
130   br i1 %tobool, label %then, label %exit
132 then:
133   %div = sdiv i16 %c, -1
134   %cmp = icmp ne i16 %div, 0
135   br label %exit
137 exit:
138   %phi = phi i1 [ false, %entry ], [ %cmp, %then ]
139   %zext = zext i1 %phi to i32
140   %add = add nsw i32 %zext, -1
141   ret i32 %add
144 define i32 @icmp_div2(i16 %a, i16 %c) {
145 ; CHECK-LABEL: @icmp_div2(
146 ; CHECK-NEXT:  entry:
147 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i16 [[A:%.*]], 0
148 ; CHECK-NEXT:    br i1 [[TOBOOL]], label [[THEN:%.*]], label [[EXIT:%.*]]
149 ; CHECK:       then:
150 ; CHECK-NEXT:    br label [[EXIT]]
151 ; CHECK:       exit:
152 ; CHECK-NEXT:    ret i32 -1
154 entry:
155   %tobool = icmp eq i16 %a, 0
156   br i1 %tobool, label %then, label %exit
158 then:
159   %div = sdiv i16 %c, 0
160   %cmp = icmp ne i16 %div, 0
161   br label %exit
163 exit:
164   %phi = phi i1 [ false, %entry ], [ %cmp, %then ]
165   %zext = zext i1 %phi to i32
166   %add = add nsw i32 %zext, -1
167   ret i32 %add
170 define i32 @icmp_div3(i16 %a, i16 %c) {
171 ; CHECK-LABEL: @icmp_div3(
172 ; CHECK-NEXT:  entry:
173 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i16 [[A:%.*]], 0
174 ; CHECK-NEXT:    br i1 [[TOBOOL]], label [[THEN:%.*]], label [[EXIT:%.*]]
175 ; CHECK:       then:
176 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i16 [[C:%.*]], 0
177 ; CHECK-NEXT:    [[TMP0:%.*]] = sext i1 [[CMP]] to i32
178 ; CHECK-NEXT:    br label [[EXIT]]
179 ; CHECK:       exit:
180 ; CHECK-NEXT:    [[PHI:%.*]] = phi i32 [ -1, [[ENTRY:%.*]] ], [ [[TMP0]], [[THEN]] ]
181 ; CHECK-NEXT:    ret i32 [[PHI]]
183 entry:
184   %tobool = icmp eq i16 %a, 0
185   br i1 %tobool, label %then, label %exit
187 then:
188   %div = sdiv i16 %c, 1
189   %cmp = icmp ne i16 %div, 0
190   br label %exit
192 exit:
193   %phi = phi i1 [ false, %entry ], [ %cmp, %then ]
194   %zext = zext i1 %phi to i32
195   %add = add nsw i32 %zext, -1
196   ret i32 %add
199 define i1 @udiv_eq_umax(i8 %x, i8 %y) {
200 ; CHECK-LABEL: @udiv_eq_umax(
201 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i8 [[X:%.*]], -1
202 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i8 [[Y:%.*]], 1
203 ; CHECK-NEXT:    [[R:%.*]] = and i1 [[TMP1]], [[TMP2]]
204 ; CHECK-NEXT:    ret i1 [[R]]
206   %d = udiv i8 %x, %y
207   %r = icmp eq i8 %d, 255
208   ret i1 %r
211 define <2 x i1> @udiv_ne_umax(<2 x i5> %x, <2 x i5> %y) {
212 ; CHECK-LABEL: @udiv_ne_umax(
213 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne <2 x i5> [[X:%.*]], <i5 -1, i5 -1>
214 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne <2 x i5> [[Y:%.*]], <i5 1, i5 1>
215 ; CHECK-NEXT:    [[R:%.*]] = or <2 x i1> [[TMP1]], [[TMP2]]
216 ; CHECK-NEXT:    ret <2 x i1> [[R]]
218   %d = udiv <2 x i5> %x, %y
219   %r = icmp ne <2 x i5> %d, <i5 -1, i5 -1>
220   ret <2 x i1> %r
223 define i1 @udiv_eq_big(i8 %x, i8 %y) {
224 ; CHECK-LABEL: @udiv_eq_big(
225 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i8 [[X:%.*]], -128
226 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i8 [[Y:%.*]], 1
227 ; CHECK-NEXT:    [[R:%.*]] = and i1 [[TMP1]], [[TMP2]]
228 ; CHECK-NEXT:    ret i1 [[R]]
230   %d = udiv i8 %x, %y
231   %r = icmp eq i8 %d, 128
232   ret i1 %r
235 define i1 @udiv_ne_big(i8 %x, i8 %y) {
236 ; CHECK-LABEL: @udiv_ne_big(
237 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne i8 [[X:%.*]], -128
238 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i8 [[Y:%.*]], 1
239 ; CHECK-NEXT:    [[R:%.*]] = or i1 [[TMP1]], [[TMP2]]
240 ; CHECK-NEXT:    ret i1 [[R]]
242   %d = udiv i8 %x, %y
243   %r = icmp ne i8 %d, 128
244   ret i1 %r
247 ; negative test - must have negative compare constant
249 define i1 @udiv_eq_not_big(i8 %x, i8 %y) {
250 ; CHECK-LABEL: @udiv_eq_not_big(
251 ; CHECK-NEXT:    [[D:%.*]] = udiv i8 [[X:%.*]], [[Y:%.*]]
252 ; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[D]], 127
253 ; CHECK-NEXT:    ret i1 [[R]]
255   %d = udiv i8 %x, %y
256   %r = icmp eq i8 %d, 127
257   ret i1 %r
260 ; negative test - must be equality predicate
262 define i1 @udiv_slt_umax(i8 %x, i8 %y) {
263 ; CHECK-LABEL: @udiv_slt_umax(
264 ; CHECK-NEXT:    [[D:%.*]] = udiv i8 [[X:%.*]], [[Y:%.*]]
265 ; CHECK-NEXT:    [[R:%.*]] = icmp slt i8 [[D]], -1
266 ; CHECK-NEXT:    ret i1 [[R]]
268   %d = udiv i8 %x, %y
269   %r = icmp slt i8 %d, 255
270   ret i1 %r
273 ; negative test - extra use
275 define i1 @udiv_eq_umax_use(i32 %x, i32 %y) {
276 ; CHECK-LABEL: @udiv_eq_umax_use(
277 ; CHECK-NEXT:    [[D:%.*]] = udiv i32 [[X:%.*]], [[Y:%.*]]
278 ; CHECK-NEXT:    call void @use(i32 [[D]])
279 ; CHECK-NEXT:    [[R:%.*]] = icmp eq i32 [[D]], -1
280 ; CHECK-NEXT:    ret i1 [[R]]
282   %d = udiv i32 %x, %y
283   call void @use(i32 %d)
284   %r = icmp eq i32 %d, -1
285   ret i1 %r
288 define i1 @sdiv_eq_smin(i8 %x, i8 %y) {
289 ; CHECK-LABEL: @sdiv_eq_smin(
290 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i8 [[X:%.*]], -128
291 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i8 [[Y:%.*]], 1
292 ; CHECK-NEXT:    [[R:%.*]] = and i1 [[TMP1]], [[TMP2]]
293 ; CHECK-NEXT:    ret i1 [[R]]
295   %d = sdiv i8 %x, %y
296   %r = icmp eq i8 %d, -128
297   ret i1 %r
300 define <2 x i1> @sdiv_ne_smin(<2 x i5> %x, <2 x i5> %y) {
301 ; CHECK-LABEL: @sdiv_ne_smin(
302 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne <2 x i5> [[X:%.*]], <i5 -16, i5 -16>
303 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne <2 x i5> [[Y:%.*]], <i5 1, i5 1>
304 ; CHECK-NEXT:    [[R:%.*]] = or <2 x i1> [[TMP1]], [[TMP2]]
305 ; CHECK-NEXT:    ret <2 x i1> [[R]]
307   %d = sdiv <2 x i5> %x, %y
308   %r = icmp ne <2 x i5> %d, <i5 -16, i5 -16>
309   ret <2 x i1> %r
312 ; negative test - must be SMIN
314 define i1 @sdiv_eq_small(i8 %x, i8 %y) {
315 ; CHECK-LABEL: @sdiv_eq_small(
316 ; CHECK-NEXT:    [[D:%.*]] = sdiv i8 [[X:%.*]], [[Y:%.*]]
317 ; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[D]], -127
318 ; CHECK-NEXT:    ret i1 [[R]]
320   %d = sdiv i8 %x, %y
321   %r = icmp eq i8 %d, -127
322   ret i1 %r
325 ; negative test - must be SMIN
327 define i1 @sdiv_ne_big(i8 %x, i8 %y) {
328 ; CHECK-LABEL: @sdiv_ne_big(
329 ; CHECK-NEXT:    [[D:%.*]] = sdiv i8 [[X:%.*]], [[Y:%.*]]
330 ; CHECK-NEXT:    [[R:%.*]] = icmp ne i8 [[D]], 127
331 ; CHECK-NEXT:    ret i1 [[R]]
333   %d = sdiv i8 %x, %y
334   %r = icmp ne i8 %d, 127
335   ret i1 %r
338 ; negative test - must be SMIN
340 define i1 @sdiv_eq_not_big(i8 %x, i8 %y) {
341 ; CHECK-LABEL: @sdiv_eq_not_big(
342 ; CHECK-NEXT:    [[D:%.*]] = sdiv i8 [[X:%.*]], [[Y:%.*]]
343 ; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[D]], 100
344 ; CHECK-NEXT:    ret i1 [[R]]
346   %d = sdiv i8 %x, %y
347   %r = icmp eq i8 %d, 100
348   ret i1 %r
351 ; negative test - must be equality predicate
353 define i1 @sdiv_ult_smin(i8 %x, i8 %y) {
354 ; CHECK-LABEL: @sdiv_ult_smin(
355 ; CHECK-NEXT:    [[D:%.*]] = sdiv i8 [[X:%.*]], [[Y:%.*]]
356 ; CHECK-NEXT:    [[R:%.*]] = icmp sgt i8 [[D]], -1
357 ; CHECK-NEXT:    ret i1 [[R]]
359   %d = sdiv i8 %x, %y
360   %r = icmp ult i8 %d, 128
361   ret i1 %r
364 ; negative test - extra use
366 define i1 @sdiv_eq_smin_use(i32 %x, i32 %y) {
367 ; CHECK-LABEL: @sdiv_eq_smin_use(
368 ; CHECK-NEXT:    [[D:%.*]] = sdiv i32 [[X:%.*]], [[Y:%.*]]
369 ; CHECK-NEXT:    call void @use(i32 [[D]])
370 ; CHECK-NEXT:    [[R:%.*]] = icmp eq i32 [[D]], -2147483648
371 ; CHECK-NEXT:    ret i1 [[R]]
373   %d = sdiv i32 %x, %y
374   call void @use(i32 %d)
375   %r = icmp eq i32 %d, -2147483648
376   ret i1 %r