Re-land [openmp] Fix warnings when building on Windows with latest MSVC or Clang...
[llvm-project.git] / llvm / test / CodeGen / RISCV / lack-of-signed-truncation-check.ll
blob9e7f2e9525d3b4b2acd315554897694ea373c0cf
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=riscv32-unknown-linux-gnu < %s | FileCheck %s --check-prefixes=CHECK,RV32,RV32I
3 ; RUN: llc -mtriple=riscv64-unknown-linux-gnu < %s | FileCheck %s --check-prefixes=CHECK,RV64,RV64I
4 ; RUN: llc -mtriple=riscv32-unknown-linux-gnu -mattr=+zbb < %s | FileCheck %s --check-prefixes=CHECK,RV32,RV32ZBB
5 ; RUN: llc -mtriple=riscv64-unknown-linux-gnu -mattr=+zbb < %s | FileCheck %s --check-prefixes=CHECK,RV64,RV64ZBB
7 ; https://bugs.llvm.org/show_bug.cgi?id=38149
9 ; We are truncating from wider width, and then sign-extending
10 ; back to the original width. Then we inequality-comparing orig and src.
11 ; If they don't match, then we had signed truncation during truncation.
13 ; This can be expressed in a several ways in IR:
14 ;   trunc + sext + icmp ne <- not canonical
15 ;   shl   + ashr + icmp ne
16 ;   add          + icmp ult/ule
17 ;   add          + icmp uge/ugt
18 ; However only the simplest form (with two shifts) gets lowered best.
20 ; ---------------------------------------------------------------------------- ;
21 ; shl + ashr + icmp ne
22 ; ---------------------------------------------------------------------------- ;
24 define i1 @shifts_necmp_i16_i8(i16 %x) nounwind {
25 ; RV32I-LABEL: shifts_necmp_i16_i8:
26 ; RV32I:       # %bb.0:
27 ; RV32I-NEXT:    lui a1, 16
28 ; RV32I-NEXT:    addi a1, a1, -1
29 ; RV32I-NEXT:    and a2, a0, a1
30 ; RV32I-NEXT:    slli a0, a0, 24
31 ; RV32I-NEXT:    srai a0, a0, 24
32 ; RV32I-NEXT:    and a0, a0, a1
33 ; RV32I-NEXT:    xor a0, a0, a2
34 ; RV32I-NEXT:    snez a0, a0
35 ; RV32I-NEXT:    ret
37 ; RV64I-LABEL: shifts_necmp_i16_i8:
38 ; RV64I:       # %bb.0:
39 ; RV64I-NEXT:    lui a1, 16
40 ; RV64I-NEXT:    addiw a1, a1, -1
41 ; RV64I-NEXT:    and a2, a0, a1
42 ; RV64I-NEXT:    slli a0, a0, 56
43 ; RV64I-NEXT:    srai a0, a0, 56
44 ; RV64I-NEXT:    and a0, a0, a1
45 ; RV64I-NEXT:    xor a0, a0, a2
46 ; RV64I-NEXT:    snez a0, a0
47 ; RV64I-NEXT:    ret
49 ; RV32ZBB-LABEL: shifts_necmp_i16_i8:
50 ; RV32ZBB:       # %bb.0:
51 ; RV32ZBB-NEXT:    zext.h a1, a0
52 ; RV32ZBB-NEXT:    sext.b a0, a0
53 ; RV32ZBB-NEXT:    zext.h a0, a0
54 ; RV32ZBB-NEXT:    xor a0, a0, a1
55 ; RV32ZBB-NEXT:    snez a0, a0
56 ; RV32ZBB-NEXT:    ret
58 ; RV64ZBB-LABEL: shifts_necmp_i16_i8:
59 ; RV64ZBB:       # %bb.0:
60 ; RV64ZBB-NEXT:    zext.h a1, a0
61 ; RV64ZBB-NEXT:    sext.b a0, a0
62 ; RV64ZBB-NEXT:    zext.h a0, a0
63 ; RV64ZBB-NEXT:    xor a0, a0, a1
64 ; RV64ZBB-NEXT:    snez a0, a0
65 ; RV64ZBB-NEXT:    ret
66   %tmp0 = shl i16 %x, 8 ; 16-8
67   %tmp1 = ashr exact i16 %tmp0, 8 ; 16-8
68   %tmp2 = icmp ne i16 %tmp1, %x
69   ret i1 %tmp2
72 define i1 @shifts_necmp_i32_i16(i32 %x) nounwind {
73 ; RV32I-LABEL: shifts_necmp_i32_i16:
74 ; RV32I:       # %bb.0:
75 ; RV32I-NEXT:    slli a1, a0, 16
76 ; RV32I-NEXT:    srai a1, a1, 16
77 ; RV32I-NEXT:    xor a0, a1, a0
78 ; RV32I-NEXT:    snez a0, a0
79 ; RV32I-NEXT:    ret
81 ; RV64I-LABEL: shifts_necmp_i32_i16:
82 ; RV64I:       # %bb.0:
83 ; RV64I-NEXT:    sext.w a1, a0
84 ; RV64I-NEXT:    slli a0, a0, 48
85 ; RV64I-NEXT:    srai a0, a0, 48
86 ; RV64I-NEXT:    xor a0, a0, a1
87 ; RV64I-NEXT:    snez a0, a0
88 ; RV64I-NEXT:    ret
90 ; RV32ZBB-LABEL: shifts_necmp_i32_i16:
91 ; RV32ZBB:       # %bb.0:
92 ; RV32ZBB-NEXT:    sext.h a1, a0
93 ; RV32ZBB-NEXT:    xor a0, a1, a0
94 ; RV32ZBB-NEXT:    snez a0, a0
95 ; RV32ZBB-NEXT:    ret
97 ; RV64ZBB-LABEL: shifts_necmp_i32_i16:
98 ; RV64ZBB:       # %bb.0:
99 ; RV64ZBB-NEXT:    sext.w a1, a0
100 ; RV64ZBB-NEXT:    sext.h a0, a0
101 ; RV64ZBB-NEXT:    xor a0, a0, a1
102 ; RV64ZBB-NEXT:    snez a0, a0
103 ; RV64ZBB-NEXT:    ret
104   %tmp0 = shl i32 %x, 16 ; 32-16
105   %tmp1 = ashr exact i32 %tmp0, 16 ; 32-16
106   %tmp2 = icmp ne i32 %tmp1, %x
107   ret i1 %tmp2
110 define i1 @shifts_necmp_i32_i8(i32 %x) nounwind {
111 ; RV32I-LABEL: shifts_necmp_i32_i8:
112 ; RV32I:       # %bb.0:
113 ; RV32I-NEXT:    slli a1, a0, 24
114 ; RV32I-NEXT:    srai a1, a1, 24
115 ; RV32I-NEXT:    xor a0, a1, a0
116 ; RV32I-NEXT:    snez a0, a0
117 ; RV32I-NEXT:    ret
119 ; RV64I-LABEL: shifts_necmp_i32_i8:
120 ; RV64I:       # %bb.0:
121 ; RV64I-NEXT:    sext.w a1, a0
122 ; RV64I-NEXT:    slli a0, a0, 56
123 ; RV64I-NEXT:    srai a0, a0, 56
124 ; RV64I-NEXT:    xor a0, a0, a1
125 ; RV64I-NEXT:    snez a0, a0
126 ; RV64I-NEXT:    ret
128 ; RV32ZBB-LABEL: shifts_necmp_i32_i8:
129 ; RV32ZBB:       # %bb.0:
130 ; RV32ZBB-NEXT:    sext.b a1, a0
131 ; RV32ZBB-NEXT:    xor a0, a1, a0
132 ; RV32ZBB-NEXT:    snez a0, a0
133 ; RV32ZBB-NEXT:    ret
135 ; RV64ZBB-LABEL: shifts_necmp_i32_i8:
136 ; RV64ZBB:       # %bb.0:
137 ; RV64ZBB-NEXT:    sext.w a1, a0
138 ; RV64ZBB-NEXT:    sext.b a0, a0
139 ; RV64ZBB-NEXT:    xor a0, a0, a1
140 ; RV64ZBB-NEXT:    snez a0, a0
141 ; RV64ZBB-NEXT:    ret
142   %tmp0 = shl i32 %x, 24 ; 32-8
143   %tmp1 = ashr exact i32 %tmp0, 24 ; 32-8
144   %tmp2 = icmp ne i32 %tmp1, %x
145   ret i1 %tmp2
148 define i1 @shifts_necmp_i64_i32(i64 %x) nounwind {
149 ; RV32-LABEL: shifts_necmp_i64_i32:
150 ; RV32:       # %bb.0:
151 ; RV32-NEXT:    srai a0, a0, 31
152 ; RV32-NEXT:    xor a0, a0, a1
153 ; RV32-NEXT:    snez a0, a0
154 ; RV32-NEXT:    ret
156 ; RV64-LABEL: shifts_necmp_i64_i32:
157 ; RV64:       # %bb.0:
158 ; RV64-NEXT:    sext.w a1, a0
159 ; RV64-NEXT:    xor a0, a1, a0
160 ; RV64-NEXT:    snez a0, a0
161 ; RV64-NEXT:    ret
162   %tmp0 = shl i64 %x, 32 ; 64-32
163   %tmp1 = ashr exact i64 %tmp0, 32 ; 64-32
164   %tmp2 = icmp ne i64 %tmp1, %x
165   ret i1 %tmp2
168 define i1 @shifts_necmp_i64_i16(i64 %x) nounwind {
169 ; RV32I-LABEL: shifts_necmp_i64_i16:
170 ; RV32I:       # %bb.0:
171 ; RV32I-NEXT:    slli a2, a0, 16
172 ; RV32I-NEXT:    srai a3, a2, 16
173 ; RV32I-NEXT:    srai a2, a2, 31
174 ; RV32I-NEXT:    xor a1, a2, a1
175 ; RV32I-NEXT:    xor a0, a3, a0
176 ; RV32I-NEXT:    or a0, a0, a1
177 ; RV32I-NEXT:    snez a0, a0
178 ; RV32I-NEXT:    ret
180 ; RV64I-LABEL: shifts_necmp_i64_i16:
181 ; RV64I:       # %bb.0:
182 ; RV64I-NEXT:    slli a1, a0, 48
183 ; RV64I-NEXT:    srai a1, a1, 48
184 ; RV64I-NEXT:    xor a0, a1, a0
185 ; RV64I-NEXT:    snez a0, a0
186 ; RV64I-NEXT:    ret
188 ; RV32ZBB-LABEL: shifts_necmp_i64_i16:
189 ; RV32ZBB:       # %bb.0:
190 ; RV32ZBB-NEXT:    sext.h a2, a0
191 ; RV32ZBB-NEXT:    srai a3, a2, 31
192 ; RV32ZBB-NEXT:    xor a0, a2, a0
193 ; RV32ZBB-NEXT:    xor a1, a3, a1
194 ; RV32ZBB-NEXT:    or a0, a0, a1
195 ; RV32ZBB-NEXT:    snez a0, a0
196 ; RV32ZBB-NEXT:    ret
198 ; RV64ZBB-LABEL: shifts_necmp_i64_i16:
199 ; RV64ZBB:       # %bb.0:
200 ; RV64ZBB-NEXT:    sext.h a1, a0
201 ; RV64ZBB-NEXT:    xor a0, a1, a0
202 ; RV64ZBB-NEXT:    snez a0, a0
203 ; RV64ZBB-NEXT:    ret
204   %tmp0 = shl i64 %x, 48 ; 64-16
205   %tmp1 = ashr exact i64 %tmp0, 48 ; 64-16
206   %tmp2 = icmp ne i64 %tmp1, %x
207   ret i1 %tmp2
210 define i1 @shifts_necmp_i64_i8(i64 %x) nounwind {
211 ; RV32I-LABEL: shifts_necmp_i64_i8:
212 ; RV32I:       # %bb.0:
213 ; RV32I-NEXT:    slli a2, a0, 24
214 ; RV32I-NEXT:    srai a3, a2, 24
215 ; RV32I-NEXT:    srai a2, a2, 31
216 ; RV32I-NEXT:    xor a1, a2, a1
217 ; RV32I-NEXT:    xor a0, a3, a0
218 ; RV32I-NEXT:    or a0, a0, a1
219 ; RV32I-NEXT:    snez a0, a0
220 ; RV32I-NEXT:    ret
222 ; RV64I-LABEL: shifts_necmp_i64_i8:
223 ; RV64I:       # %bb.0:
224 ; RV64I-NEXT:    slli a1, a0, 56
225 ; RV64I-NEXT:    srai a1, a1, 56
226 ; RV64I-NEXT:    xor a0, a1, a0
227 ; RV64I-NEXT:    snez a0, a0
228 ; RV64I-NEXT:    ret
230 ; RV32ZBB-LABEL: shifts_necmp_i64_i8:
231 ; RV32ZBB:       # %bb.0:
232 ; RV32ZBB-NEXT:    sext.b a2, a0
233 ; RV32ZBB-NEXT:    srai a3, a2, 31
234 ; RV32ZBB-NEXT:    xor a0, a2, a0
235 ; RV32ZBB-NEXT:    xor a1, a3, a1
236 ; RV32ZBB-NEXT:    or a0, a0, a1
237 ; RV32ZBB-NEXT:    snez a0, a0
238 ; RV32ZBB-NEXT:    ret
240 ; RV64ZBB-LABEL: shifts_necmp_i64_i8:
241 ; RV64ZBB:       # %bb.0:
242 ; RV64ZBB-NEXT:    sext.b a1, a0
243 ; RV64ZBB-NEXT:    xor a0, a1, a0
244 ; RV64ZBB-NEXT:    snez a0, a0
245 ; RV64ZBB-NEXT:    ret
246   %tmp0 = shl i64 %x, 56 ; 64-8
247   %tmp1 = ashr exact i64 %tmp0, 56 ; 64-8
248   %tmp2 = icmp ne i64 %tmp1, %x
249   ret i1 %tmp2
252 ; ---------------------------------------------------------------------------- ;
253 ; add + icmp ult
254 ; ---------------------------------------------------------------------------- ;
256 define i1 @add_ultcmp_i16_i8(i16 %x) nounwind {
257 ; RV32-LABEL: add_ultcmp_i16_i8:
258 ; RV32:       # %bb.0:
259 ; RV32-NEXT:    addi a0, a0, -128
260 ; RV32-NEXT:    slli a0, a0, 16
261 ; RV32-NEXT:    srli a0, a0, 24
262 ; RV32-NEXT:    sltiu a0, a0, 255
263 ; RV32-NEXT:    ret
265 ; RV64-LABEL: add_ultcmp_i16_i8:
266 ; RV64:       # %bb.0:
267 ; RV64-NEXT:    addi a0, a0, -128
268 ; RV64-NEXT:    slli a0, a0, 48
269 ; RV64-NEXT:    srli a0, a0, 56
270 ; RV64-NEXT:    sltiu a0, a0, 255
271 ; RV64-NEXT:    ret
272   %tmp0 = add i16 %x, -128 ; ~0U << (8-1)
273   %tmp1 = icmp ult i16 %tmp0, -256 ; ~0U << 8
274   ret i1 %tmp1
277 define i1 @add_ultcmp_i32_i16(i32 %x) nounwind {
278 ; RV32I-LABEL: add_ultcmp_i32_i16:
279 ; RV32I:       # %bb.0:
280 ; RV32I-NEXT:    lui a1, 1048568
281 ; RV32I-NEXT:    add a0, a0, a1
282 ; RV32I-NEXT:    lui a1, 1048560
283 ; RV32I-NEXT:    sltu a0, a0, a1
284 ; RV32I-NEXT:    ret
286 ; RV64I-LABEL: add_ultcmp_i32_i16:
287 ; RV64I:       # %bb.0:
288 ; RV64I-NEXT:    lui a1, 1048568
289 ; RV64I-NEXT:    addw a0, a0, a1
290 ; RV64I-NEXT:    lui a1, 1048560
291 ; RV64I-NEXT:    sltu a0, a0, a1
292 ; RV64I-NEXT:    ret
294 ; RV32ZBB-LABEL: add_ultcmp_i32_i16:
295 ; RV32ZBB:       # %bb.0:
296 ; RV32ZBB-NEXT:    sext.h a1, a0
297 ; RV32ZBB-NEXT:    xor a0, a1, a0
298 ; RV32ZBB-NEXT:    snez a0, a0
299 ; RV32ZBB-NEXT:    ret
301 ; RV64ZBB-LABEL: add_ultcmp_i32_i16:
302 ; RV64ZBB:       # %bb.0:
303 ; RV64ZBB-NEXT:    sext.w a1, a0
304 ; RV64ZBB-NEXT:    sext.h a0, a0
305 ; RV64ZBB-NEXT:    xor a0, a0, a1
306 ; RV64ZBB-NEXT:    snez a0, a0
307 ; RV64ZBB-NEXT:    ret
308   %tmp0 = add i32 %x, -32768 ; ~0U << (16-1)
309   %tmp1 = icmp ult i32 %tmp0, -65536 ; ~0U << 16
310   ret i1 %tmp1
313 define i1 @add_ultcmp_i32_i8(i32 %x) nounwind {
314 ; RV32-LABEL: add_ultcmp_i32_i8:
315 ; RV32:       # %bb.0:
316 ; RV32-NEXT:    addi a0, a0, -128
317 ; RV32-NEXT:    sltiu a0, a0, -256
318 ; RV32-NEXT:    ret
320 ; RV64-LABEL: add_ultcmp_i32_i8:
321 ; RV64:       # %bb.0:
322 ; RV64-NEXT:    addiw a0, a0, -128
323 ; RV64-NEXT:    sltiu a0, a0, -256
324 ; RV64-NEXT:    ret
325   %tmp0 = add i32 %x, -128 ; ~0U << (8-1)
326   %tmp1 = icmp ult i32 %tmp0, -256 ; ~0U << 8
327   ret i1 %tmp1
330 define i1 @add_ultcmp_i64_i32(i64 %x) nounwind {
331 ; RV32-LABEL: add_ultcmp_i64_i32:
332 ; RV32:       # %bb.0:
333 ; RV32-NEXT:    srai a0, a0, 31
334 ; RV32-NEXT:    xor a0, a0, a1
335 ; RV32-NEXT:    snez a0, a0
336 ; RV32-NEXT:    ret
338 ; RV64-LABEL: add_ultcmp_i64_i32:
339 ; RV64:       # %bb.0:
340 ; RV64-NEXT:    sext.w a1, a0
341 ; RV64-NEXT:    xor a0, a1, a0
342 ; RV64-NEXT:    snez a0, a0
343 ; RV64-NEXT:    ret
344   %tmp0 = add i64 %x, -2147483648 ; ~0U << (32-1)
345   %tmp1 = icmp ult i64 %tmp0, -4294967296 ; ~0U << 32
346   ret i1 %tmp1
349 define i1 @add_ultcmp_i64_i16(i64 %x) nounwind {
350 ; RV32I-LABEL: add_ultcmp_i64_i16:
351 ; RV32I:       # %bb.0:
352 ; RV32I-NEXT:    lui a2, 1048568
353 ; RV32I-NEXT:    add a2, a0, a2
354 ; RV32I-NEXT:    sltu a0, a2, a0
355 ; RV32I-NEXT:    add a0, a1, a0
356 ; RV32I-NEXT:    lui a1, 1048560
357 ; RV32I-NEXT:    sltu a1, a2, a1
358 ; RV32I-NEXT:    snez a0, a0
359 ; RV32I-NEXT:    or a0, a1, a0
360 ; RV32I-NEXT:    ret
362 ; RV64I-LABEL: add_ultcmp_i64_i16:
363 ; RV64I:       # %bb.0:
364 ; RV64I-NEXT:    lui a1, 1048568
365 ; RV64I-NEXT:    add a0, a0, a1
366 ; RV64I-NEXT:    lui a1, 1048560
367 ; RV64I-NEXT:    sltu a0, a0, a1
368 ; RV64I-NEXT:    ret
370 ; RV32ZBB-LABEL: add_ultcmp_i64_i16:
371 ; RV32ZBB:       # %bb.0:
372 ; RV32ZBB-NEXT:    sext.h a2, a0
373 ; RV32ZBB-NEXT:    xor a0, a2, a0
374 ; RV32ZBB-NEXT:    srai a2, a2, 31
375 ; RV32ZBB-NEXT:    xor a1, a2, a1
376 ; RV32ZBB-NEXT:    or a0, a0, a1
377 ; RV32ZBB-NEXT:    snez a0, a0
378 ; RV32ZBB-NEXT:    ret
380 ; RV64ZBB-LABEL: add_ultcmp_i64_i16:
381 ; RV64ZBB:       # %bb.0:
382 ; RV64ZBB-NEXT:    sext.h a1, a0
383 ; RV64ZBB-NEXT:    xor a0, a1, a0
384 ; RV64ZBB-NEXT:    snez a0, a0
385 ; RV64ZBB-NEXT:    ret
386   %tmp0 = add i64 %x, -32768 ; ~0U << (16-1)
387   %tmp1 = icmp ult i64 %tmp0, -65536 ; ~0U << 16
388   ret i1 %tmp1
391 define i1 @add_ultcmp_i64_i8(i64 %x) nounwind {
392 ; RV32I-LABEL: add_ultcmp_i64_i8:
393 ; RV32I:       # %bb.0:
394 ; RV32I-NEXT:    addi a2, a0, -128
395 ; RV32I-NEXT:    sltu a0, a2, a0
396 ; RV32I-NEXT:    add a0, a1, a0
397 ; RV32I-NEXT:    snez a0, a0
398 ; RV32I-NEXT:    sltiu a1, a2, -256
399 ; RV32I-NEXT:    or a0, a1, a0
400 ; RV32I-NEXT:    ret
402 ; RV64-LABEL: add_ultcmp_i64_i8:
403 ; RV64:       # %bb.0:
404 ; RV64-NEXT:    addi a0, a0, -128
405 ; RV64-NEXT:    sltiu a0, a0, -256
406 ; RV64-NEXT:    ret
408 ; RV32ZBB-LABEL: add_ultcmp_i64_i8:
409 ; RV32ZBB:       # %bb.0:
410 ; RV32ZBB-NEXT:    sext.b a2, a0
411 ; RV32ZBB-NEXT:    xor a0, a2, a0
412 ; RV32ZBB-NEXT:    srai a2, a2, 31
413 ; RV32ZBB-NEXT:    xor a1, a2, a1
414 ; RV32ZBB-NEXT:    or a0, a0, a1
415 ; RV32ZBB-NEXT:    snez a0, a0
416 ; RV32ZBB-NEXT:    ret
417   %tmp0 = add i64 %x, -128 ; ~0U << (8-1)
418   %tmp1 = icmp ult i64 %tmp0, -256 ; ~0U << 8
419   ret i1 %tmp1
422 ; Slightly more canonical variant
423 define i1 @add_ulecmp_i16_i8(i16 %x) nounwind {
424 ; RV32-LABEL: add_ulecmp_i16_i8:
425 ; RV32:       # %bb.0:
426 ; RV32-NEXT:    addi a0, a0, -128
427 ; RV32-NEXT:    slli a0, a0, 16
428 ; RV32-NEXT:    srli a0, a0, 24
429 ; RV32-NEXT:    sltiu a0, a0, 255
430 ; RV32-NEXT:    ret
432 ; RV64-LABEL: add_ulecmp_i16_i8:
433 ; RV64:       # %bb.0:
434 ; RV64-NEXT:    addi a0, a0, -128
435 ; RV64-NEXT:    slli a0, a0, 48
436 ; RV64-NEXT:    srli a0, a0, 56
437 ; RV64-NEXT:    sltiu a0, a0, 255
438 ; RV64-NEXT:    ret
439   %tmp0 = add i16 %x, -128 ; ~0U << (8-1)
440   %tmp1 = icmp ule i16 %tmp0, -257 ; ~0U << 8 - 1
441   ret i1 %tmp1
444 ; ---------------------------------------------------------------------------- ;
445 ; add + icmp uge
446 ; ---------------------------------------------------------------------------- ;
448 define i1 @add_ugecmp_i16_i8(i16 %x) nounwind {
449 ; RV32I-LABEL: add_ugecmp_i16_i8:
450 ; RV32I:       # %bb.0:
451 ; RV32I-NEXT:    addi a0, a0, 128
452 ; RV32I-NEXT:    slli a0, a0, 16
453 ; RV32I-NEXT:    srli a0, a0, 16
454 ; RV32I-NEXT:    sltiu a0, a0, 256
455 ; RV32I-NEXT:    xori a0, a0, 1
456 ; RV32I-NEXT:    ret
458 ; RV64I-LABEL: add_ugecmp_i16_i8:
459 ; RV64I:       # %bb.0:
460 ; RV64I-NEXT:    addi a0, a0, 128
461 ; RV64I-NEXT:    slli a0, a0, 48
462 ; RV64I-NEXT:    srli a0, a0, 48
463 ; RV64I-NEXT:    sltiu a0, a0, 256
464 ; RV64I-NEXT:    xori a0, a0, 1
465 ; RV64I-NEXT:    ret
467 ; RV32ZBB-LABEL: add_ugecmp_i16_i8:
468 ; RV32ZBB:       # %bb.0:
469 ; RV32ZBB-NEXT:    addi a0, a0, 128
470 ; RV32ZBB-NEXT:    zext.h a0, a0
471 ; RV32ZBB-NEXT:    sltiu a0, a0, 256
472 ; RV32ZBB-NEXT:    xori a0, a0, 1
473 ; RV32ZBB-NEXT:    ret
475 ; RV64ZBB-LABEL: add_ugecmp_i16_i8:
476 ; RV64ZBB:       # %bb.0:
477 ; RV64ZBB-NEXT:    addi a0, a0, 128
478 ; RV64ZBB-NEXT:    zext.h a0, a0
479 ; RV64ZBB-NEXT:    sltiu a0, a0, 256
480 ; RV64ZBB-NEXT:    xori a0, a0, 1
481 ; RV64ZBB-NEXT:    ret
482   %tmp0 = add i16 %x, 128 ; 1U << (8-1)
483   %tmp1 = icmp uge i16 %tmp0, 256 ; 1U << 8
484   ret i1 %tmp1
487 define i1 @add_ugecmp_i32_i16(i32 %x) nounwind {
488 ; RV32I-LABEL: add_ugecmp_i32_i16:
489 ; RV32I:       # %bb.0:
490 ; RV32I-NEXT:    lui a1, 8
491 ; RV32I-NEXT:    add a0, a0, a1
492 ; RV32I-NEXT:    srli a0, a0, 16
493 ; RV32I-NEXT:    snez a0, a0
494 ; RV32I-NEXT:    ret
496 ; RV64I-LABEL: add_ugecmp_i32_i16:
497 ; RV64I:       # %bb.0:
498 ; RV64I-NEXT:    lui a1, 8
499 ; RV64I-NEXT:    add a0, a0, a1
500 ; RV64I-NEXT:    srliw a0, a0, 16
501 ; RV64I-NEXT:    snez a0, a0
502 ; RV64I-NEXT:    ret
504 ; RV32ZBB-LABEL: add_ugecmp_i32_i16:
505 ; RV32ZBB:       # %bb.0:
506 ; RV32ZBB-NEXT:    sext.h a1, a0
507 ; RV32ZBB-NEXT:    xor a0, a1, a0
508 ; RV32ZBB-NEXT:    snez a0, a0
509 ; RV32ZBB-NEXT:    ret
511 ; RV64ZBB-LABEL: add_ugecmp_i32_i16:
512 ; RV64ZBB:       # %bb.0:
513 ; RV64ZBB-NEXT:    sext.w a1, a0
514 ; RV64ZBB-NEXT:    sext.h a0, a0
515 ; RV64ZBB-NEXT:    xor a0, a0, a1
516 ; RV64ZBB-NEXT:    snez a0, a0
517 ; RV64ZBB-NEXT:    ret
518   %tmp0 = add i32 %x, 32768 ; 1U << (16-1)
519   %tmp1 = icmp uge i32 %tmp0, 65536 ; 1U << 16
520   ret i1 %tmp1
523 define i1 @add_ugecmp_i32_i8(i32 %x) nounwind {
524 ; RV32-LABEL: add_ugecmp_i32_i8:
525 ; RV32:       # %bb.0:
526 ; RV32-NEXT:    addi a0, a0, 128
527 ; RV32-NEXT:    sltiu a0, a0, 256
528 ; RV32-NEXT:    xori a0, a0, 1
529 ; RV32-NEXT:    ret
531 ; RV64-LABEL: add_ugecmp_i32_i8:
532 ; RV64:       # %bb.0:
533 ; RV64-NEXT:    addiw a0, a0, 128
534 ; RV64-NEXT:    sltiu a0, a0, 256
535 ; RV64-NEXT:    xori a0, a0, 1
536 ; RV64-NEXT:    ret
537   %tmp0 = add i32 %x, 128 ; 1U << (8-1)
538   %tmp1 = icmp uge i32 %tmp0, 256 ; 1U << 8
539   ret i1 %tmp1
542 define i1 @add_ugecmp_i64_i32(i64 %x) nounwind {
543 ; RV32-LABEL: add_ugecmp_i64_i32:
544 ; RV32:       # %bb.0:
545 ; RV32-NEXT:    srai a0, a0, 31
546 ; RV32-NEXT:    xor a0, a0, a1
547 ; RV32-NEXT:    snez a0, a0
548 ; RV32-NEXT:    ret
550 ; RV64-LABEL: add_ugecmp_i64_i32:
551 ; RV64:       # %bb.0:
552 ; RV64-NEXT:    sext.w a1, a0
553 ; RV64-NEXT:    xor a0, a1, a0
554 ; RV64-NEXT:    snez a0, a0
555 ; RV64-NEXT:    ret
556   %tmp0 = add i64 %x, 2147483648 ; 1U << (32-1)
557   %tmp1 = icmp uge i64 %tmp0, 4294967296 ; 1U << 32
558   ret i1 %tmp1
561 define i1 @add_ugecmp_i64_i16(i64 %x) nounwind {
562 ; RV32I-LABEL: add_ugecmp_i64_i16:
563 ; RV32I:       # %bb.0:
564 ; RV32I-NEXT:    lui a2, 8
565 ; RV32I-NEXT:    add a2, a0, a2
566 ; RV32I-NEXT:    sltu a0, a2, a0
567 ; RV32I-NEXT:    add a0, a1, a0
568 ; RV32I-NEXT:    srli a2, a2, 16
569 ; RV32I-NEXT:    or a0, a0, a2
570 ; RV32I-NEXT:    snez a0, a0
571 ; RV32I-NEXT:    ret
573 ; RV64I-LABEL: add_ugecmp_i64_i16:
574 ; RV64I:       # %bb.0:
575 ; RV64I-NEXT:    lui a1, 8
576 ; RV64I-NEXT:    add a0, a0, a1
577 ; RV64I-NEXT:    srli a0, a0, 16
578 ; RV64I-NEXT:    snez a0, a0
579 ; RV64I-NEXT:    ret
581 ; RV32ZBB-LABEL: add_ugecmp_i64_i16:
582 ; RV32ZBB:       # %bb.0:
583 ; RV32ZBB-NEXT:    sext.h a2, a0
584 ; RV32ZBB-NEXT:    xor a0, a2, a0
585 ; RV32ZBB-NEXT:    srai a2, a2, 31
586 ; RV32ZBB-NEXT:    xor a1, a2, a1
587 ; RV32ZBB-NEXT:    or a0, a0, a1
588 ; RV32ZBB-NEXT:    snez a0, a0
589 ; RV32ZBB-NEXT:    ret
591 ; RV64ZBB-LABEL: add_ugecmp_i64_i16:
592 ; RV64ZBB:       # %bb.0:
593 ; RV64ZBB-NEXT:    sext.h a1, a0
594 ; RV64ZBB-NEXT:    xor a0, a1, a0
595 ; RV64ZBB-NEXT:    snez a0, a0
596 ; RV64ZBB-NEXT:    ret
597   %tmp0 = add i64 %x, 32768 ; 1U << (16-1)
598   %tmp1 = icmp uge i64 %tmp0, 65536 ; 1U << 16
599   ret i1 %tmp1
602 define i1 @add_ugecmp_i64_i8(i64 %x) nounwind {
603 ; RV32I-LABEL: add_ugecmp_i64_i8:
604 ; RV32I:       # %bb.0:
605 ; RV32I-NEXT:    addi a2, a0, 128
606 ; RV32I-NEXT:    sltu a0, a2, a0
607 ; RV32I-NEXT:    add a0, a1, a0
608 ; RV32I-NEXT:    snez a0, a0
609 ; RV32I-NEXT:    sltiu a1, a2, 256
610 ; RV32I-NEXT:    xori a1, a1, 1
611 ; RV32I-NEXT:    or a0, a1, a0
612 ; RV32I-NEXT:    ret
614 ; RV64-LABEL: add_ugecmp_i64_i8:
615 ; RV64:       # %bb.0:
616 ; RV64-NEXT:    addi a0, a0, 128
617 ; RV64-NEXT:    sltiu a0, a0, 256
618 ; RV64-NEXT:    xori a0, a0, 1
619 ; RV64-NEXT:    ret
621 ; RV32ZBB-LABEL: add_ugecmp_i64_i8:
622 ; RV32ZBB:       # %bb.0:
623 ; RV32ZBB-NEXT:    sext.b a2, a0
624 ; RV32ZBB-NEXT:    xor a0, a2, a0
625 ; RV32ZBB-NEXT:    srai a2, a2, 31
626 ; RV32ZBB-NEXT:    xor a1, a2, a1
627 ; RV32ZBB-NEXT:    or a0, a0, a1
628 ; RV32ZBB-NEXT:    snez a0, a0
629 ; RV32ZBB-NEXT:    ret
630   %tmp0 = add i64 %x, 128 ; 1U << (8-1)
631   %tmp1 = icmp uge i64 %tmp0, 256 ; 1U << 8
632   ret i1 %tmp1
635 ; Slightly more canonical variant
636 define i1 @add_ugtcmp_i16_i8(i16 %x) nounwind {
637 ; RV32I-LABEL: add_ugtcmp_i16_i8:
638 ; RV32I:       # %bb.0:
639 ; RV32I-NEXT:    addi a0, a0, 128
640 ; RV32I-NEXT:    slli a0, a0, 16
641 ; RV32I-NEXT:    srli a0, a0, 16
642 ; RV32I-NEXT:    sltiu a0, a0, 256
643 ; RV32I-NEXT:    xori a0, a0, 1
644 ; RV32I-NEXT:    ret
646 ; RV64I-LABEL: add_ugtcmp_i16_i8:
647 ; RV64I:       # %bb.0:
648 ; RV64I-NEXT:    addi a0, a0, 128
649 ; RV64I-NEXT:    slli a0, a0, 48
650 ; RV64I-NEXT:    srli a0, a0, 48
651 ; RV64I-NEXT:    sltiu a0, a0, 256
652 ; RV64I-NEXT:    xori a0, a0, 1
653 ; RV64I-NEXT:    ret
655 ; RV32ZBB-LABEL: add_ugtcmp_i16_i8:
656 ; RV32ZBB:       # %bb.0:
657 ; RV32ZBB-NEXT:    addi a0, a0, 128
658 ; RV32ZBB-NEXT:    zext.h a0, a0
659 ; RV32ZBB-NEXT:    sltiu a0, a0, 256
660 ; RV32ZBB-NEXT:    xori a0, a0, 1
661 ; RV32ZBB-NEXT:    ret
663 ; RV64ZBB-LABEL: add_ugtcmp_i16_i8:
664 ; RV64ZBB:       # %bb.0:
665 ; RV64ZBB-NEXT:    addi a0, a0, 128
666 ; RV64ZBB-NEXT:    zext.h a0, a0
667 ; RV64ZBB-NEXT:    sltiu a0, a0, 256
668 ; RV64ZBB-NEXT:    xori a0, a0, 1
669 ; RV64ZBB-NEXT:    ret
670   %tmp0 = add i16 %x, 128 ; 1U << (8-1)
671   %tmp1 = icmp ugt i16 %tmp0, 255 ; (1U << 8) - 1
672   ret i1 %tmp1
675 ; Negative tests
676 ; ---------------------------------------------------------------------------- ;
678 ; Adding not a constant
679 define i1 @add_ugecmp_bad_i16_i8_add(i16 %x, i16 %y) nounwind {
680 ; RV32I-LABEL: add_ugecmp_bad_i16_i8_add:
681 ; RV32I:       # %bb.0:
682 ; RV32I-NEXT:    add a0, a0, a1
683 ; RV32I-NEXT:    slli a0, a0, 16
684 ; RV32I-NEXT:    srli a0, a0, 16
685 ; RV32I-NEXT:    sltiu a0, a0, 256
686 ; RV32I-NEXT:    xori a0, a0, 1
687 ; RV32I-NEXT:    ret
689 ; RV64I-LABEL: add_ugecmp_bad_i16_i8_add:
690 ; RV64I:       # %bb.0:
691 ; RV64I-NEXT:    add a0, a0, a1
692 ; RV64I-NEXT:    slli a0, a0, 48
693 ; RV64I-NEXT:    srli a0, a0, 48
694 ; RV64I-NEXT:    sltiu a0, a0, 256
695 ; RV64I-NEXT:    xori a0, a0, 1
696 ; RV64I-NEXT:    ret
698 ; RV32ZBB-LABEL: add_ugecmp_bad_i16_i8_add:
699 ; RV32ZBB:       # %bb.0:
700 ; RV32ZBB-NEXT:    add a0, a0, a1
701 ; RV32ZBB-NEXT:    zext.h a0, a0
702 ; RV32ZBB-NEXT:    sltiu a0, a0, 256
703 ; RV32ZBB-NEXT:    xori a0, a0, 1
704 ; RV32ZBB-NEXT:    ret
706 ; RV64ZBB-LABEL: add_ugecmp_bad_i16_i8_add:
707 ; RV64ZBB:       # %bb.0:
708 ; RV64ZBB-NEXT:    add a0, a0, a1
709 ; RV64ZBB-NEXT:    zext.h a0, a0
710 ; RV64ZBB-NEXT:    sltiu a0, a0, 256
711 ; RV64ZBB-NEXT:    xori a0, a0, 1
712 ; RV64ZBB-NEXT:    ret
713   %tmp0 = add i16 %x, %y
714   %tmp1 = icmp uge i16 %tmp0, 256 ; 1U << 8
715   ret i1 %tmp1
718 ; Comparing not with a constant
719 define i1 @add_ugecmp_bad_i16_i8_cmp(i16 %x, i16 %y) nounwind {
720 ; RV32I-LABEL: add_ugecmp_bad_i16_i8_cmp:
721 ; RV32I:       # %bb.0:
722 ; RV32I-NEXT:    lui a2, 16
723 ; RV32I-NEXT:    addi a2, a2, -1
724 ; RV32I-NEXT:    and a1, a1, a2
725 ; RV32I-NEXT:    addi a0, a0, 128
726 ; RV32I-NEXT:    and a0, a0, a2
727 ; RV32I-NEXT:    sltu a0, a0, a1
728 ; RV32I-NEXT:    xori a0, a0, 1
729 ; RV32I-NEXT:    ret
731 ; RV64I-LABEL: add_ugecmp_bad_i16_i8_cmp:
732 ; RV64I:       # %bb.0:
733 ; RV64I-NEXT:    lui a2, 16
734 ; RV64I-NEXT:    addiw a2, a2, -1
735 ; RV64I-NEXT:    and a1, a1, a2
736 ; RV64I-NEXT:    addi a0, a0, 128
737 ; RV64I-NEXT:    and a0, a0, a2
738 ; RV64I-NEXT:    sltu a0, a0, a1
739 ; RV64I-NEXT:    xori a0, a0, 1
740 ; RV64I-NEXT:    ret
742 ; RV32ZBB-LABEL: add_ugecmp_bad_i16_i8_cmp:
743 ; RV32ZBB:       # %bb.0:
744 ; RV32ZBB-NEXT:    zext.h a1, a1
745 ; RV32ZBB-NEXT:    addi a0, a0, 128
746 ; RV32ZBB-NEXT:    zext.h a0, a0
747 ; RV32ZBB-NEXT:    sltu a0, a0, a1
748 ; RV32ZBB-NEXT:    xori a0, a0, 1
749 ; RV32ZBB-NEXT:    ret
751 ; RV64ZBB-LABEL: add_ugecmp_bad_i16_i8_cmp:
752 ; RV64ZBB:       # %bb.0:
753 ; RV64ZBB-NEXT:    zext.h a1, a1
754 ; RV64ZBB-NEXT:    addi a0, a0, 128
755 ; RV64ZBB-NEXT:    zext.h a0, a0
756 ; RV64ZBB-NEXT:    sltu a0, a0, a1
757 ; RV64ZBB-NEXT:    xori a0, a0, 1
758 ; RV64ZBB-NEXT:    ret
759   %tmp0 = add i16 %x, 128 ; 1U << (8-1)
760   %tmp1 = icmp uge i16 %tmp0, %y
761   ret i1 %tmp1
764 ; Second constant is not larger than the first one
765 define i1 @add_ugecmp_bad_i8_i16(i16 %x) nounwind {
766 ; RV32I-LABEL: add_ugecmp_bad_i8_i16:
767 ; RV32I:       # %bb.0:
768 ; RV32I-NEXT:    addi a0, a0, 128
769 ; RV32I-NEXT:    slli a0, a0, 16
770 ; RV32I-NEXT:    srli a0, a0, 16
771 ; RV32I-NEXT:    sltiu a0, a0, 128
772 ; RV32I-NEXT:    xori a0, a0, 1
773 ; RV32I-NEXT:    ret
775 ; RV64I-LABEL: add_ugecmp_bad_i8_i16:
776 ; RV64I:       # %bb.0:
777 ; RV64I-NEXT:    addi a0, a0, 128
778 ; RV64I-NEXT:    slli a0, a0, 48
779 ; RV64I-NEXT:    srli a0, a0, 48
780 ; RV64I-NEXT:    sltiu a0, a0, 128
781 ; RV64I-NEXT:    xori a0, a0, 1
782 ; RV64I-NEXT:    ret
784 ; RV32ZBB-LABEL: add_ugecmp_bad_i8_i16:
785 ; RV32ZBB:       # %bb.0:
786 ; RV32ZBB-NEXT:    addi a0, a0, 128
787 ; RV32ZBB-NEXT:    zext.h a0, a0
788 ; RV32ZBB-NEXT:    sltiu a0, a0, 128
789 ; RV32ZBB-NEXT:    xori a0, a0, 1
790 ; RV32ZBB-NEXT:    ret
792 ; RV64ZBB-LABEL: add_ugecmp_bad_i8_i16:
793 ; RV64ZBB:       # %bb.0:
794 ; RV64ZBB-NEXT:    addi a0, a0, 128
795 ; RV64ZBB-NEXT:    zext.h a0, a0
796 ; RV64ZBB-NEXT:    sltiu a0, a0, 128
797 ; RV64ZBB-NEXT:    xori a0, a0, 1
798 ; RV64ZBB-NEXT:    ret
799   %tmp0 = add i16 %x, 128 ; 1U << (8-1)
800   %tmp1 = icmp uge i16 %tmp0, 128 ; 1U << (8-1)
801   ret i1 %tmp1
804 ; First constant is not power of two
805 define i1 @add_ugecmp_bad_i16_i8_c0notpoweroftwo(i16 %x) nounwind {
806 ; RV32I-LABEL: add_ugecmp_bad_i16_i8_c0notpoweroftwo:
807 ; RV32I:       # %bb.0:
808 ; RV32I-NEXT:    addi a0, a0, 192
809 ; RV32I-NEXT:    slli a0, a0, 16
810 ; RV32I-NEXT:    srli a0, a0, 16
811 ; RV32I-NEXT:    sltiu a0, a0, 256
812 ; RV32I-NEXT:    xori a0, a0, 1
813 ; RV32I-NEXT:    ret
815 ; RV64I-LABEL: add_ugecmp_bad_i16_i8_c0notpoweroftwo:
816 ; RV64I:       # %bb.0:
817 ; RV64I-NEXT:    addi a0, a0, 192
818 ; RV64I-NEXT:    slli a0, a0, 48
819 ; RV64I-NEXT:    srli a0, a0, 48
820 ; RV64I-NEXT:    sltiu a0, a0, 256
821 ; RV64I-NEXT:    xori a0, a0, 1
822 ; RV64I-NEXT:    ret
824 ; RV32ZBB-LABEL: add_ugecmp_bad_i16_i8_c0notpoweroftwo:
825 ; RV32ZBB:       # %bb.0:
826 ; RV32ZBB-NEXT:    addi a0, a0, 192
827 ; RV32ZBB-NEXT:    zext.h a0, a0
828 ; RV32ZBB-NEXT:    sltiu a0, a0, 256
829 ; RV32ZBB-NEXT:    xori a0, a0, 1
830 ; RV32ZBB-NEXT:    ret
832 ; RV64ZBB-LABEL: add_ugecmp_bad_i16_i8_c0notpoweroftwo:
833 ; RV64ZBB:       # %bb.0:
834 ; RV64ZBB-NEXT:    addi a0, a0, 192
835 ; RV64ZBB-NEXT:    zext.h a0, a0
836 ; RV64ZBB-NEXT:    sltiu a0, a0, 256
837 ; RV64ZBB-NEXT:    xori a0, a0, 1
838 ; RV64ZBB-NEXT:    ret
839   %tmp0 = add i16 %x, 192 ; (1U << (8-1)) + (1U << (8-1-1))
840   %tmp1 = icmp uge i16 %tmp0, 256 ; 1U << 8
841   ret i1 %tmp1
844 ; Second constant is not power of two
845 define i1 @add_ugecmp_bad_i16_i8_c1notpoweroftwo(i16 %x) nounwind {
846 ; RV32I-LABEL: add_ugecmp_bad_i16_i8_c1notpoweroftwo:
847 ; RV32I:       # %bb.0:
848 ; RV32I-NEXT:    addi a0, a0, 128
849 ; RV32I-NEXT:    slli a0, a0, 16
850 ; RV32I-NEXT:    srli a0, a0, 16
851 ; RV32I-NEXT:    sltiu a0, a0, 768
852 ; RV32I-NEXT:    xori a0, a0, 1
853 ; RV32I-NEXT:    ret
855 ; RV64I-LABEL: add_ugecmp_bad_i16_i8_c1notpoweroftwo:
856 ; RV64I:       # %bb.0:
857 ; RV64I-NEXT:    addi a0, a0, 128
858 ; RV64I-NEXT:    slli a0, a0, 48
859 ; RV64I-NEXT:    srli a0, a0, 48
860 ; RV64I-NEXT:    sltiu a0, a0, 768
861 ; RV64I-NEXT:    xori a0, a0, 1
862 ; RV64I-NEXT:    ret
864 ; RV32ZBB-LABEL: add_ugecmp_bad_i16_i8_c1notpoweroftwo:
865 ; RV32ZBB:       # %bb.0:
866 ; RV32ZBB-NEXT:    addi a0, a0, 128
867 ; RV32ZBB-NEXT:    zext.h a0, a0
868 ; RV32ZBB-NEXT:    sltiu a0, a0, 768
869 ; RV32ZBB-NEXT:    xori a0, a0, 1
870 ; RV32ZBB-NEXT:    ret
872 ; RV64ZBB-LABEL: add_ugecmp_bad_i16_i8_c1notpoweroftwo:
873 ; RV64ZBB:       # %bb.0:
874 ; RV64ZBB-NEXT:    addi a0, a0, 128
875 ; RV64ZBB-NEXT:    zext.h a0, a0
876 ; RV64ZBB-NEXT:    sltiu a0, a0, 768
877 ; RV64ZBB-NEXT:    xori a0, a0, 1
878 ; RV64ZBB-NEXT:    ret
879   %tmp0 = add i16 %x, 128 ; 1U << (8-1)
880   %tmp1 = icmp uge i16 %tmp0, 768 ; (1U << 8)) + (1U << (8+1))
881   ret i1 %tmp1
884 ; Magic check fails, 64 << 1 != 256
885 define i1 @add_ugecmp_bad_i16_i8_magic(i16 %x) nounwind {
886 ; RV32I-LABEL: add_ugecmp_bad_i16_i8_magic:
887 ; RV32I:       # %bb.0:
888 ; RV32I-NEXT:    addi a0, a0, 64
889 ; RV32I-NEXT:    slli a0, a0, 16
890 ; RV32I-NEXT:    srli a0, a0, 16
891 ; RV32I-NEXT:    sltiu a0, a0, 256
892 ; RV32I-NEXT:    xori a0, a0, 1
893 ; RV32I-NEXT:    ret
895 ; RV64I-LABEL: add_ugecmp_bad_i16_i8_magic:
896 ; RV64I:       # %bb.0:
897 ; RV64I-NEXT:    addi a0, a0, 64
898 ; RV64I-NEXT:    slli a0, a0, 48
899 ; RV64I-NEXT:    srli a0, a0, 48
900 ; RV64I-NEXT:    sltiu a0, a0, 256
901 ; RV64I-NEXT:    xori a0, a0, 1
902 ; RV64I-NEXT:    ret
904 ; RV32ZBB-LABEL: add_ugecmp_bad_i16_i8_magic:
905 ; RV32ZBB:       # %bb.0:
906 ; RV32ZBB-NEXT:    addi a0, a0, 64
907 ; RV32ZBB-NEXT:    zext.h a0, a0
908 ; RV32ZBB-NEXT:    sltiu a0, a0, 256
909 ; RV32ZBB-NEXT:    xori a0, a0, 1
910 ; RV32ZBB-NEXT:    ret
912 ; RV64ZBB-LABEL: add_ugecmp_bad_i16_i8_magic:
913 ; RV64ZBB:       # %bb.0:
914 ; RV64ZBB-NEXT:    addi a0, a0, 64
915 ; RV64ZBB-NEXT:    zext.h a0, a0
916 ; RV64ZBB-NEXT:    sltiu a0, a0, 256
917 ; RV64ZBB-NEXT:    xori a0, a0, 1
918 ; RV64ZBB-NEXT:    ret
919   %tmp0 = add i16 %x, 64 ; 1U << (8-1-1)
920   %tmp1 = icmp uge i16 %tmp0, 256 ; 1U << 8
921   ret i1 %tmp1
924 ; Bad 'destination type'
925 define i1 @add_ugecmp_bad_i16_i4(i16 %x) nounwind {
926 ; RV32I-LABEL: add_ugecmp_bad_i16_i4:
927 ; RV32I:       # %bb.0:
928 ; RV32I-NEXT:    addi a0, a0, 8
929 ; RV32I-NEXT:    slli a0, a0, 16
930 ; RV32I-NEXT:    srli a0, a0, 16
931 ; RV32I-NEXT:    sltiu a0, a0, 16
932 ; RV32I-NEXT:    xori a0, a0, 1
933 ; RV32I-NEXT:    ret
935 ; RV64I-LABEL: add_ugecmp_bad_i16_i4:
936 ; RV64I:       # %bb.0:
937 ; RV64I-NEXT:    addi a0, a0, 8
938 ; RV64I-NEXT:    slli a0, a0, 48
939 ; RV64I-NEXT:    srli a0, a0, 48
940 ; RV64I-NEXT:    sltiu a0, a0, 16
941 ; RV64I-NEXT:    xori a0, a0, 1
942 ; RV64I-NEXT:    ret
944 ; RV32ZBB-LABEL: add_ugecmp_bad_i16_i4:
945 ; RV32ZBB:       # %bb.0:
946 ; RV32ZBB-NEXT:    addi a0, a0, 8
947 ; RV32ZBB-NEXT:    zext.h a0, a0
948 ; RV32ZBB-NEXT:    sltiu a0, a0, 16
949 ; RV32ZBB-NEXT:    xori a0, a0, 1
950 ; RV32ZBB-NEXT:    ret
952 ; RV64ZBB-LABEL: add_ugecmp_bad_i16_i4:
953 ; RV64ZBB:       # %bb.0:
954 ; RV64ZBB-NEXT:    addi a0, a0, 8
955 ; RV64ZBB-NEXT:    zext.h a0, a0
956 ; RV64ZBB-NEXT:    sltiu a0, a0, 16
957 ; RV64ZBB-NEXT:    xori a0, a0, 1
958 ; RV64ZBB-NEXT:    ret
959   %tmp0 = add i16 %x, 8 ; 1U << (4-1)
960   %tmp1 = icmp uge i16 %tmp0, 16 ; 1U << 4
961   ret i1 %tmp1
964 ; Bad storage type
965 define i1 @add_ugecmp_bad_i24_i8(i24 %x) nounwind {
966 ; RV32-LABEL: add_ugecmp_bad_i24_i8:
967 ; RV32:       # %bb.0:
968 ; RV32-NEXT:    addi a0, a0, 128
969 ; RV32-NEXT:    slli a0, a0, 8
970 ; RV32-NEXT:    srli a0, a0, 8
971 ; RV32-NEXT:    sltiu a0, a0, 256
972 ; RV32-NEXT:    xori a0, a0, 1
973 ; RV32-NEXT:    ret
975 ; RV64-LABEL: add_ugecmp_bad_i24_i8:
976 ; RV64:       # %bb.0:
977 ; RV64-NEXT:    addi a0, a0, 128
978 ; RV64-NEXT:    slli a0, a0, 40
979 ; RV64-NEXT:    srli a0, a0, 40
980 ; RV64-NEXT:    sltiu a0, a0, 256
981 ; RV64-NEXT:    xori a0, a0, 1
982 ; RV64-NEXT:    ret
983   %tmp0 = add i24 %x, 128 ; 1U << (8-1)
984   %tmp1 = icmp uge i24 %tmp0, 256 ; 1U << 8
985   ret i1 %tmp1
988 ; Slightly more canonical variant
989 define i1 @add_ugtcmp_bad_i16_i8(i16 %x) nounwind {
990 ; CHECK-LABEL: add_ugtcmp_bad_i16_i8:
991 ; CHECK:       # %bb.0:
992 ; CHECK-NEXT:    li a0, 0
993 ; CHECK-NEXT:    ret
994   %tmp0 = add i16 %x, 128 ; 1U << (8-1)
995   %tmp1 = icmp ugt i16 %tmp0, -1 ; when we +1 it, it will wrap to 0
996   ret i1 %tmp1