Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / CodeGen / RISCV / lack-of-signed-truncation-check.ll
blob6e3a50542939f1526fca8651e1a7b6f784961ba2
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 ; RV32I-LABEL: add_ultcmp_i16_i8:
258 ; RV32I:       # %bb.0:
259 ; RV32I-NEXT:    slli a0, a0, 16
260 ; RV32I-NEXT:    srli a0, a0, 16
261 ; RV32I-NEXT:    addi a0, a0, -128
262 ; RV32I-NEXT:    srli a0, a0, 8
263 ; RV32I-NEXT:    sltiu a0, a0, 255
264 ; RV32I-NEXT:    ret
266 ; RV64I-LABEL: add_ultcmp_i16_i8:
267 ; RV64I:       # %bb.0:
268 ; RV64I-NEXT:    slli a0, a0, 48
269 ; RV64I-NEXT:    srli a0, a0, 48
270 ; RV64I-NEXT:    addi a0, a0, -128
271 ; RV64I-NEXT:    srli a0, a0, 8
272 ; RV64I-NEXT:    sltiu a0, a0, 255
273 ; RV64I-NEXT:    ret
275 ; RV32ZBB-LABEL: add_ultcmp_i16_i8:
276 ; RV32ZBB:       # %bb.0:
277 ; RV32ZBB-NEXT:    zext.h a0, a0
278 ; RV32ZBB-NEXT:    addi a0, a0, -128
279 ; RV32ZBB-NEXT:    srli a0, a0, 8
280 ; RV32ZBB-NEXT:    sltiu a0, a0, 255
281 ; RV32ZBB-NEXT:    ret
283 ; RV64ZBB-LABEL: add_ultcmp_i16_i8:
284 ; RV64ZBB:       # %bb.0:
285 ; RV64ZBB-NEXT:    zext.h a0, a0
286 ; RV64ZBB-NEXT:    addi a0, a0, -128
287 ; RV64ZBB-NEXT:    srli a0, a0, 8
288 ; RV64ZBB-NEXT:    sltiu a0, a0, 255
289 ; RV64ZBB-NEXT:    ret
290   %tmp0 = add i16 %x, -128 ; ~0U << (8-1)
291   %tmp1 = icmp ult i16 %tmp0, -256 ; ~0U << 8
292   ret i1 %tmp1
295 define i1 @add_ultcmp_i32_i16(i32 %x) nounwind {
296 ; RV32I-LABEL: add_ultcmp_i32_i16:
297 ; RV32I:       # %bb.0:
298 ; RV32I-NEXT:    lui a1, 1048568
299 ; RV32I-NEXT:    add a0, a0, a1
300 ; RV32I-NEXT:    lui a1, 1048560
301 ; RV32I-NEXT:    sltu a0, a0, a1
302 ; RV32I-NEXT:    ret
304 ; RV64I-LABEL: add_ultcmp_i32_i16:
305 ; RV64I:       # %bb.0:
306 ; RV64I-NEXT:    lui a1, 1048568
307 ; RV64I-NEXT:    addw a0, a0, a1
308 ; RV64I-NEXT:    lui a1, 1048560
309 ; RV64I-NEXT:    sltu a0, a0, a1
310 ; RV64I-NEXT:    ret
312 ; RV32ZBB-LABEL: add_ultcmp_i32_i16:
313 ; RV32ZBB:       # %bb.0:
314 ; RV32ZBB-NEXT:    sext.h a1, a0
315 ; RV32ZBB-NEXT:    xor a0, a1, a0
316 ; RV32ZBB-NEXT:    snez a0, a0
317 ; RV32ZBB-NEXT:    ret
319 ; RV64ZBB-LABEL: add_ultcmp_i32_i16:
320 ; RV64ZBB:       # %bb.0:
321 ; RV64ZBB-NEXT:    sext.w a1, a0
322 ; RV64ZBB-NEXT:    sext.h a0, a0
323 ; RV64ZBB-NEXT:    xor a0, a0, a1
324 ; RV64ZBB-NEXT:    snez a0, a0
325 ; RV64ZBB-NEXT:    ret
326   %tmp0 = add i32 %x, -32768 ; ~0U << (16-1)
327   %tmp1 = icmp ult i32 %tmp0, -65536 ; ~0U << 16
328   ret i1 %tmp1
331 define i1 @add_ultcmp_i32_i8(i32 %x) nounwind {
332 ; RV32-LABEL: add_ultcmp_i32_i8:
333 ; RV32:       # %bb.0:
334 ; RV32-NEXT:    addi a0, a0, -128
335 ; RV32-NEXT:    sltiu a0, a0, -256
336 ; RV32-NEXT:    ret
338 ; RV64-LABEL: add_ultcmp_i32_i8:
339 ; RV64:       # %bb.0:
340 ; RV64-NEXT:    addiw a0, a0, -128
341 ; RV64-NEXT:    sltiu a0, a0, -256
342 ; RV64-NEXT:    ret
343   %tmp0 = add i32 %x, -128 ; ~0U << (8-1)
344   %tmp1 = icmp ult i32 %tmp0, -256 ; ~0U << 8
345   ret i1 %tmp1
348 define i1 @add_ultcmp_i64_i32(i64 %x) nounwind {
349 ; RV32-LABEL: add_ultcmp_i64_i32:
350 ; RV32:       # %bb.0:
351 ; RV32-NEXT:    srai a0, a0, 31
352 ; RV32-NEXT:    xor a0, a0, a1
353 ; RV32-NEXT:    snez a0, a0
354 ; RV32-NEXT:    ret
356 ; RV64-LABEL: add_ultcmp_i64_i32:
357 ; RV64:       # %bb.0:
358 ; RV64-NEXT:    sext.w a1, a0
359 ; RV64-NEXT:    xor a0, a1, a0
360 ; RV64-NEXT:    snez a0, a0
361 ; RV64-NEXT:    ret
362   %tmp0 = add i64 %x, -2147483648 ; ~0U << (32-1)
363   %tmp1 = icmp ult i64 %tmp0, -4294967296 ; ~0U << 32
364   ret i1 %tmp1
367 define i1 @add_ultcmp_i64_i16(i64 %x) nounwind {
368 ; RV32I-LABEL: add_ultcmp_i64_i16:
369 ; RV32I:       # %bb.0:
370 ; RV32I-NEXT:    lui a2, 1048568
371 ; RV32I-NEXT:    add a2, a0, a2
372 ; RV32I-NEXT:    sltu a0, a2, a0
373 ; RV32I-NEXT:    add a0, a1, a0
374 ; RV32I-NEXT:    lui a1, 1048560
375 ; RV32I-NEXT:    sltu a1, a2, a1
376 ; RV32I-NEXT:    snez a0, a0
377 ; RV32I-NEXT:    or a0, a1, a0
378 ; RV32I-NEXT:    ret
380 ; RV64I-LABEL: add_ultcmp_i64_i16:
381 ; RV64I:       # %bb.0:
382 ; RV64I-NEXT:    lui a1, 1048568
383 ; RV64I-NEXT:    add a0, a0, a1
384 ; RV64I-NEXT:    lui a1, 1048560
385 ; RV64I-NEXT:    sltu a0, a0, a1
386 ; RV64I-NEXT:    ret
388 ; RV32ZBB-LABEL: add_ultcmp_i64_i16:
389 ; RV32ZBB:       # %bb.0:
390 ; RV32ZBB-NEXT:    sext.h a2, a0
391 ; RV32ZBB-NEXT:    xor a0, a2, a0
392 ; RV32ZBB-NEXT:    srai a2, a2, 31
393 ; RV32ZBB-NEXT:    xor a1, a2, a1
394 ; RV32ZBB-NEXT:    or a0, a0, a1
395 ; RV32ZBB-NEXT:    snez a0, a0
396 ; RV32ZBB-NEXT:    ret
398 ; RV64ZBB-LABEL: add_ultcmp_i64_i16:
399 ; RV64ZBB:       # %bb.0:
400 ; RV64ZBB-NEXT:    sext.h a1, a0
401 ; RV64ZBB-NEXT:    xor a0, a1, a0
402 ; RV64ZBB-NEXT:    snez a0, a0
403 ; RV64ZBB-NEXT:    ret
404   %tmp0 = add i64 %x, -32768 ; ~0U << (16-1)
405   %tmp1 = icmp ult i64 %tmp0, -65536 ; ~0U << 16
406   ret i1 %tmp1
409 define i1 @add_ultcmp_i64_i8(i64 %x) nounwind {
410 ; RV32I-LABEL: add_ultcmp_i64_i8:
411 ; RV32I:       # %bb.0:
412 ; RV32I-NEXT:    addi a2, a0, -128
413 ; RV32I-NEXT:    sltu a0, a2, a0
414 ; RV32I-NEXT:    add a0, a1, a0
415 ; RV32I-NEXT:    snez a0, a0
416 ; RV32I-NEXT:    sltiu a1, a2, -256
417 ; RV32I-NEXT:    or a0, a1, a0
418 ; RV32I-NEXT:    ret
420 ; RV64-LABEL: add_ultcmp_i64_i8:
421 ; RV64:       # %bb.0:
422 ; RV64-NEXT:    addi a0, a0, -128
423 ; RV64-NEXT:    sltiu a0, a0, -256
424 ; RV64-NEXT:    ret
426 ; RV32ZBB-LABEL: add_ultcmp_i64_i8:
427 ; RV32ZBB:       # %bb.0:
428 ; RV32ZBB-NEXT:    sext.b a2, a0
429 ; RV32ZBB-NEXT:    xor a0, a2, a0
430 ; RV32ZBB-NEXT:    srai a2, a2, 31
431 ; RV32ZBB-NEXT:    xor a1, a2, a1
432 ; RV32ZBB-NEXT:    or a0, a0, a1
433 ; RV32ZBB-NEXT:    snez a0, a0
434 ; RV32ZBB-NEXT:    ret
435   %tmp0 = add i64 %x, -128 ; ~0U << (8-1)
436   %tmp1 = icmp ult i64 %tmp0, -256 ; ~0U << 8
437   ret i1 %tmp1
440 ; Slightly more canonical variant
441 define i1 @add_ulecmp_i16_i8(i16 %x) nounwind {
442 ; RV32I-LABEL: add_ulecmp_i16_i8:
443 ; RV32I:       # %bb.0:
444 ; RV32I-NEXT:    slli a0, a0, 16
445 ; RV32I-NEXT:    srli a0, a0, 16
446 ; RV32I-NEXT:    addi a0, a0, -128
447 ; RV32I-NEXT:    srli a0, a0, 8
448 ; RV32I-NEXT:    sltiu a0, a0, 255
449 ; RV32I-NEXT:    ret
451 ; RV64I-LABEL: add_ulecmp_i16_i8:
452 ; RV64I:       # %bb.0:
453 ; RV64I-NEXT:    slli a0, a0, 48
454 ; RV64I-NEXT:    srli a0, a0, 48
455 ; RV64I-NEXT:    addi a0, a0, -128
456 ; RV64I-NEXT:    srli a0, a0, 8
457 ; RV64I-NEXT:    sltiu a0, a0, 255
458 ; RV64I-NEXT:    ret
460 ; RV32ZBB-LABEL: add_ulecmp_i16_i8:
461 ; RV32ZBB:       # %bb.0:
462 ; RV32ZBB-NEXT:    zext.h a0, a0
463 ; RV32ZBB-NEXT:    addi a0, a0, -128
464 ; RV32ZBB-NEXT:    srli a0, a0, 8
465 ; RV32ZBB-NEXT:    sltiu a0, a0, 255
466 ; RV32ZBB-NEXT:    ret
468 ; RV64ZBB-LABEL: add_ulecmp_i16_i8:
469 ; RV64ZBB:       # %bb.0:
470 ; RV64ZBB-NEXT:    zext.h a0, a0
471 ; RV64ZBB-NEXT:    addi a0, a0, -128
472 ; RV64ZBB-NEXT:    srli a0, a0, 8
473 ; RV64ZBB-NEXT:    sltiu a0, a0, 255
474 ; RV64ZBB-NEXT:    ret
475   %tmp0 = add i16 %x, -128 ; ~0U << (8-1)
476   %tmp1 = icmp ule i16 %tmp0, -257 ; ~0U << 8 - 1
477   ret i1 %tmp1
480 ; ---------------------------------------------------------------------------- ;
481 ; add + icmp uge
482 ; ---------------------------------------------------------------------------- ;
484 define i1 @add_ugecmp_i16_i8(i16 %x) nounwind {
485 ; RV32I-LABEL: add_ugecmp_i16_i8:
486 ; RV32I:       # %bb.0:
487 ; RV32I-NEXT:    addi a0, a0, 128
488 ; RV32I-NEXT:    slli a0, a0, 16
489 ; RV32I-NEXT:    srli a0, a0, 16
490 ; RV32I-NEXT:    sltiu a0, a0, 256
491 ; RV32I-NEXT:    xori a0, a0, 1
492 ; RV32I-NEXT:    ret
494 ; RV64I-LABEL: add_ugecmp_i16_i8:
495 ; RV64I:       # %bb.0:
496 ; RV64I-NEXT:    addi a0, a0, 128
497 ; RV64I-NEXT:    slli a0, a0, 48
498 ; RV64I-NEXT:    srli a0, a0, 48
499 ; RV64I-NEXT:    sltiu a0, a0, 256
500 ; RV64I-NEXT:    xori a0, a0, 1
501 ; RV64I-NEXT:    ret
503 ; RV32ZBB-LABEL: add_ugecmp_i16_i8:
504 ; RV32ZBB:       # %bb.0:
505 ; RV32ZBB-NEXT:    addi a0, a0, 128
506 ; RV32ZBB-NEXT:    zext.h a0, a0
507 ; RV32ZBB-NEXT:    sltiu a0, a0, 256
508 ; RV32ZBB-NEXT:    xori a0, a0, 1
509 ; RV32ZBB-NEXT:    ret
511 ; RV64ZBB-LABEL: add_ugecmp_i16_i8:
512 ; RV64ZBB:       # %bb.0:
513 ; RV64ZBB-NEXT:    addi a0, a0, 128
514 ; RV64ZBB-NEXT:    zext.h a0, a0
515 ; RV64ZBB-NEXT:    sltiu a0, a0, 256
516 ; RV64ZBB-NEXT:    xori a0, a0, 1
517 ; RV64ZBB-NEXT:    ret
518   %tmp0 = add i16 %x, 128 ; 1U << (8-1)
519   %tmp1 = icmp uge i16 %tmp0, 256 ; 1U << 8
520   ret i1 %tmp1
523 define i1 @add_ugecmp_i32_i16(i32 %x) nounwind {
524 ; RV32I-LABEL: add_ugecmp_i32_i16:
525 ; RV32I:       # %bb.0:
526 ; RV32I-NEXT:    lui a1, 8
527 ; RV32I-NEXT:    add a0, a0, a1
528 ; RV32I-NEXT:    srli a0, a0, 16
529 ; RV32I-NEXT:    snez a0, a0
530 ; RV32I-NEXT:    ret
532 ; RV64I-LABEL: add_ugecmp_i32_i16:
533 ; RV64I:       # %bb.0:
534 ; RV64I-NEXT:    lui a1, 8
535 ; RV64I-NEXT:    add a0, a0, a1
536 ; RV64I-NEXT:    srliw a0, a0, 16
537 ; RV64I-NEXT:    snez a0, a0
538 ; RV64I-NEXT:    ret
540 ; RV32ZBB-LABEL: add_ugecmp_i32_i16:
541 ; RV32ZBB:       # %bb.0:
542 ; RV32ZBB-NEXT:    sext.h a1, a0
543 ; RV32ZBB-NEXT:    xor a0, a1, a0
544 ; RV32ZBB-NEXT:    snez a0, a0
545 ; RV32ZBB-NEXT:    ret
547 ; RV64ZBB-LABEL: add_ugecmp_i32_i16:
548 ; RV64ZBB:       # %bb.0:
549 ; RV64ZBB-NEXT:    sext.w a1, a0
550 ; RV64ZBB-NEXT:    sext.h a0, a0
551 ; RV64ZBB-NEXT:    xor a0, a0, a1
552 ; RV64ZBB-NEXT:    snez a0, a0
553 ; RV64ZBB-NEXT:    ret
554   %tmp0 = add i32 %x, 32768 ; 1U << (16-1)
555   %tmp1 = icmp uge i32 %tmp0, 65536 ; 1U << 16
556   ret i1 %tmp1
559 define i1 @add_ugecmp_i32_i8(i32 %x) nounwind {
560 ; RV32-LABEL: add_ugecmp_i32_i8:
561 ; RV32:       # %bb.0:
562 ; RV32-NEXT:    addi a0, a0, 128
563 ; RV32-NEXT:    sltiu a0, a0, 256
564 ; RV32-NEXT:    xori a0, a0, 1
565 ; RV32-NEXT:    ret
567 ; RV64-LABEL: add_ugecmp_i32_i8:
568 ; RV64:       # %bb.0:
569 ; RV64-NEXT:    addiw a0, a0, 128
570 ; RV64-NEXT:    sltiu a0, a0, 256
571 ; RV64-NEXT:    xori a0, a0, 1
572 ; RV64-NEXT:    ret
573   %tmp0 = add i32 %x, 128 ; 1U << (8-1)
574   %tmp1 = icmp uge i32 %tmp0, 256 ; 1U << 8
575   ret i1 %tmp1
578 define i1 @add_ugecmp_i64_i32(i64 %x) nounwind {
579 ; RV32-LABEL: add_ugecmp_i64_i32:
580 ; RV32:       # %bb.0:
581 ; RV32-NEXT:    srai a0, a0, 31
582 ; RV32-NEXT:    xor a0, a0, a1
583 ; RV32-NEXT:    snez a0, a0
584 ; RV32-NEXT:    ret
586 ; RV64-LABEL: add_ugecmp_i64_i32:
587 ; RV64:       # %bb.0:
588 ; RV64-NEXT:    sext.w a1, a0
589 ; RV64-NEXT:    xor a0, a1, a0
590 ; RV64-NEXT:    snez a0, a0
591 ; RV64-NEXT:    ret
592   %tmp0 = add i64 %x, 2147483648 ; 1U << (32-1)
593   %tmp1 = icmp uge i64 %tmp0, 4294967296 ; 1U << 32
594   ret i1 %tmp1
597 define i1 @add_ugecmp_i64_i16(i64 %x) nounwind {
598 ; RV32I-LABEL: add_ugecmp_i64_i16:
599 ; RV32I:       # %bb.0:
600 ; RV32I-NEXT:    lui a2, 8
601 ; RV32I-NEXT:    add a2, a0, a2
602 ; RV32I-NEXT:    sltu a0, a2, a0
603 ; RV32I-NEXT:    add a0, a1, a0
604 ; RV32I-NEXT:    srli a2, a2, 16
605 ; RV32I-NEXT:    or a0, a0, a2
606 ; RV32I-NEXT:    snez a0, a0
607 ; RV32I-NEXT:    ret
609 ; RV64I-LABEL: add_ugecmp_i64_i16:
610 ; RV64I:       # %bb.0:
611 ; RV64I-NEXT:    lui a1, 8
612 ; RV64I-NEXT:    add a0, a0, a1
613 ; RV64I-NEXT:    srli a0, a0, 16
614 ; RV64I-NEXT:    snez a0, a0
615 ; RV64I-NEXT:    ret
617 ; RV32ZBB-LABEL: add_ugecmp_i64_i16:
618 ; RV32ZBB:       # %bb.0:
619 ; RV32ZBB-NEXT:    sext.h a2, a0
620 ; RV32ZBB-NEXT:    xor a0, a2, a0
621 ; RV32ZBB-NEXT:    srai a2, a2, 31
622 ; RV32ZBB-NEXT:    xor a1, a2, a1
623 ; RV32ZBB-NEXT:    or a0, a0, a1
624 ; RV32ZBB-NEXT:    snez a0, a0
625 ; RV32ZBB-NEXT:    ret
627 ; RV64ZBB-LABEL: add_ugecmp_i64_i16:
628 ; RV64ZBB:       # %bb.0:
629 ; RV64ZBB-NEXT:    sext.h a1, a0
630 ; RV64ZBB-NEXT:    xor a0, a1, a0
631 ; RV64ZBB-NEXT:    snez a0, a0
632 ; RV64ZBB-NEXT:    ret
633   %tmp0 = add i64 %x, 32768 ; 1U << (16-1)
634   %tmp1 = icmp uge i64 %tmp0, 65536 ; 1U << 16
635   ret i1 %tmp1
638 define i1 @add_ugecmp_i64_i8(i64 %x) nounwind {
639 ; RV32I-LABEL: add_ugecmp_i64_i8:
640 ; RV32I:       # %bb.0:
641 ; RV32I-NEXT:    addi a2, a0, 128
642 ; RV32I-NEXT:    sltu a0, a2, a0
643 ; RV32I-NEXT:    add a0, a1, a0
644 ; RV32I-NEXT:    snez a0, a0
645 ; RV32I-NEXT:    sltiu a1, a2, 256
646 ; RV32I-NEXT:    xori a1, a1, 1
647 ; RV32I-NEXT:    or a0, a1, a0
648 ; RV32I-NEXT:    ret
650 ; RV64-LABEL: add_ugecmp_i64_i8:
651 ; RV64:       # %bb.0:
652 ; RV64-NEXT:    addi a0, a0, 128
653 ; RV64-NEXT:    sltiu a0, a0, 256
654 ; RV64-NEXT:    xori a0, a0, 1
655 ; RV64-NEXT:    ret
657 ; RV32ZBB-LABEL: add_ugecmp_i64_i8:
658 ; RV32ZBB:       # %bb.0:
659 ; RV32ZBB-NEXT:    sext.b a2, a0
660 ; RV32ZBB-NEXT:    xor a0, a2, a0
661 ; RV32ZBB-NEXT:    srai a2, a2, 31
662 ; RV32ZBB-NEXT:    xor a1, a2, a1
663 ; RV32ZBB-NEXT:    or a0, a0, a1
664 ; RV32ZBB-NEXT:    snez a0, a0
665 ; RV32ZBB-NEXT:    ret
666   %tmp0 = add i64 %x, 128 ; 1U << (8-1)
667   %tmp1 = icmp uge i64 %tmp0, 256 ; 1U << 8
668   ret i1 %tmp1
671 ; Slightly more canonical variant
672 define i1 @add_ugtcmp_i16_i8(i16 %x) nounwind {
673 ; RV32I-LABEL: add_ugtcmp_i16_i8:
674 ; RV32I:       # %bb.0:
675 ; RV32I-NEXT:    addi a0, a0, 128
676 ; RV32I-NEXT:    slli a0, a0, 16
677 ; RV32I-NEXT:    srli a0, a0, 16
678 ; RV32I-NEXT:    sltiu a0, a0, 256
679 ; RV32I-NEXT:    xori a0, a0, 1
680 ; RV32I-NEXT:    ret
682 ; RV64I-LABEL: add_ugtcmp_i16_i8:
683 ; RV64I:       # %bb.0:
684 ; RV64I-NEXT:    addi a0, a0, 128
685 ; RV64I-NEXT:    slli a0, a0, 48
686 ; RV64I-NEXT:    srli a0, a0, 48
687 ; RV64I-NEXT:    sltiu a0, a0, 256
688 ; RV64I-NEXT:    xori a0, a0, 1
689 ; RV64I-NEXT:    ret
691 ; RV32ZBB-LABEL: add_ugtcmp_i16_i8:
692 ; RV32ZBB:       # %bb.0:
693 ; RV32ZBB-NEXT:    addi a0, a0, 128
694 ; RV32ZBB-NEXT:    zext.h a0, a0
695 ; RV32ZBB-NEXT:    sltiu a0, a0, 256
696 ; RV32ZBB-NEXT:    xori a0, a0, 1
697 ; RV32ZBB-NEXT:    ret
699 ; RV64ZBB-LABEL: add_ugtcmp_i16_i8:
700 ; RV64ZBB:       # %bb.0:
701 ; RV64ZBB-NEXT:    addi a0, a0, 128
702 ; RV64ZBB-NEXT:    zext.h a0, a0
703 ; RV64ZBB-NEXT:    sltiu a0, a0, 256
704 ; RV64ZBB-NEXT:    xori a0, a0, 1
705 ; RV64ZBB-NEXT:    ret
706   %tmp0 = add i16 %x, 128 ; 1U << (8-1)
707   %tmp1 = icmp ugt i16 %tmp0, 255 ; (1U << 8) - 1
708   ret i1 %tmp1
711 ; Negative tests
712 ; ---------------------------------------------------------------------------- ;
714 ; Adding not a constant
715 define i1 @add_ugecmp_bad_i16_i8_add(i16 %x, i16 %y) nounwind {
716 ; RV32I-LABEL: add_ugecmp_bad_i16_i8_add:
717 ; RV32I:       # %bb.0:
718 ; RV32I-NEXT:    add a0, a0, a1
719 ; RV32I-NEXT:    slli a0, a0, 16
720 ; RV32I-NEXT:    srli a0, a0, 16
721 ; RV32I-NEXT:    sltiu a0, a0, 256
722 ; RV32I-NEXT:    xori a0, a0, 1
723 ; RV32I-NEXT:    ret
725 ; RV64I-LABEL: add_ugecmp_bad_i16_i8_add:
726 ; RV64I:       # %bb.0:
727 ; RV64I-NEXT:    add a0, a0, a1
728 ; RV64I-NEXT:    slli a0, a0, 48
729 ; RV64I-NEXT:    srli a0, a0, 48
730 ; RV64I-NEXT:    sltiu a0, a0, 256
731 ; RV64I-NEXT:    xori a0, a0, 1
732 ; RV64I-NEXT:    ret
734 ; RV32ZBB-LABEL: add_ugecmp_bad_i16_i8_add:
735 ; RV32ZBB:       # %bb.0:
736 ; RV32ZBB-NEXT:    add a0, a0, a1
737 ; RV32ZBB-NEXT:    zext.h a0, a0
738 ; RV32ZBB-NEXT:    sltiu a0, a0, 256
739 ; RV32ZBB-NEXT:    xori a0, a0, 1
740 ; RV32ZBB-NEXT:    ret
742 ; RV64ZBB-LABEL: add_ugecmp_bad_i16_i8_add:
743 ; RV64ZBB:       # %bb.0:
744 ; RV64ZBB-NEXT:    add a0, a0, a1
745 ; RV64ZBB-NEXT:    zext.h a0, a0
746 ; RV64ZBB-NEXT:    sltiu a0, a0, 256
747 ; RV64ZBB-NEXT:    xori a0, a0, 1
748 ; RV64ZBB-NEXT:    ret
749   %tmp0 = add i16 %x, %y
750   %tmp1 = icmp uge i16 %tmp0, 256 ; 1U << 8
751   ret i1 %tmp1
754 ; Comparing not with a constant
755 define i1 @add_ugecmp_bad_i16_i8_cmp(i16 %x, i16 %y) nounwind {
756 ; RV32I-LABEL: add_ugecmp_bad_i16_i8_cmp:
757 ; RV32I:       # %bb.0:
758 ; RV32I-NEXT:    lui a2, 16
759 ; RV32I-NEXT:    addi a2, a2, -1
760 ; RV32I-NEXT:    and a1, a1, a2
761 ; RV32I-NEXT:    addi a0, a0, 128
762 ; RV32I-NEXT:    and a0, a0, a2
763 ; RV32I-NEXT:    sltu a0, a0, a1
764 ; RV32I-NEXT:    xori a0, a0, 1
765 ; RV32I-NEXT:    ret
767 ; RV64I-LABEL: add_ugecmp_bad_i16_i8_cmp:
768 ; RV64I:       # %bb.0:
769 ; RV64I-NEXT:    lui a2, 16
770 ; RV64I-NEXT:    addiw a2, a2, -1
771 ; RV64I-NEXT:    and a1, a1, a2
772 ; RV64I-NEXT:    addi a0, a0, 128
773 ; RV64I-NEXT:    and a0, a0, a2
774 ; RV64I-NEXT:    sltu a0, a0, a1
775 ; RV64I-NEXT:    xori a0, a0, 1
776 ; RV64I-NEXT:    ret
778 ; RV32ZBB-LABEL: add_ugecmp_bad_i16_i8_cmp:
779 ; RV32ZBB:       # %bb.0:
780 ; RV32ZBB-NEXT:    zext.h a1, a1
781 ; RV32ZBB-NEXT:    addi a0, a0, 128
782 ; RV32ZBB-NEXT:    zext.h a0, a0
783 ; RV32ZBB-NEXT:    sltu a0, a0, a1
784 ; RV32ZBB-NEXT:    xori a0, a0, 1
785 ; RV32ZBB-NEXT:    ret
787 ; RV64ZBB-LABEL: add_ugecmp_bad_i16_i8_cmp:
788 ; RV64ZBB:       # %bb.0:
789 ; RV64ZBB-NEXT:    zext.h a1, a1
790 ; RV64ZBB-NEXT:    addi a0, a0, 128
791 ; RV64ZBB-NEXT:    zext.h a0, a0
792 ; RV64ZBB-NEXT:    sltu a0, a0, a1
793 ; RV64ZBB-NEXT:    xori a0, a0, 1
794 ; RV64ZBB-NEXT:    ret
795   %tmp0 = add i16 %x, 128 ; 1U << (8-1)
796   %tmp1 = icmp uge i16 %tmp0, %y
797   ret i1 %tmp1
800 ; Second constant is not larger than the first one
801 define i1 @add_ugecmp_bad_i8_i16(i16 %x) nounwind {
802 ; RV32I-LABEL: add_ugecmp_bad_i8_i16:
803 ; RV32I:       # %bb.0:
804 ; RV32I-NEXT:    addi a0, a0, 128
805 ; RV32I-NEXT:    slli a0, a0, 16
806 ; RV32I-NEXT:    srli a0, a0, 16
807 ; RV32I-NEXT:    sltiu a0, a0, 128
808 ; RV32I-NEXT:    xori a0, a0, 1
809 ; RV32I-NEXT:    ret
811 ; RV64I-LABEL: add_ugecmp_bad_i8_i16:
812 ; RV64I:       # %bb.0:
813 ; RV64I-NEXT:    addi a0, a0, 128
814 ; RV64I-NEXT:    slli a0, a0, 48
815 ; RV64I-NEXT:    srli a0, a0, 48
816 ; RV64I-NEXT:    sltiu a0, a0, 128
817 ; RV64I-NEXT:    xori a0, a0, 1
818 ; RV64I-NEXT:    ret
820 ; RV32ZBB-LABEL: add_ugecmp_bad_i8_i16:
821 ; RV32ZBB:       # %bb.0:
822 ; RV32ZBB-NEXT:    addi a0, a0, 128
823 ; RV32ZBB-NEXT:    zext.h a0, a0
824 ; RV32ZBB-NEXT:    sltiu a0, a0, 128
825 ; RV32ZBB-NEXT:    xori a0, a0, 1
826 ; RV32ZBB-NEXT:    ret
828 ; RV64ZBB-LABEL: add_ugecmp_bad_i8_i16:
829 ; RV64ZBB:       # %bb.0:
830 ; RV64ZBB-NEXT:    addi a0, a0, 128
831 ; RV64ZBB-NEXT:    zext.h a0, a0
832 ; RV64ZBB-NEXT:    sltiu a0, a0, 128
833 ; RV64ZBB-NEXT:    xori a0, a0, 1
834 ; RV64ZBB-NEXT:    ret
835   %tmp0 = add i16 %x, 128 ; 1U << (8-1)
836   %tmp1 = icmp uge i16 %tmp0, 128 ; 1U << (8-1)
837   ret i1 %tmp1
840 ; First constant is not power of two
841 define i1 @add_ugecmp_bad_i16_i8_c0notpoweroftwo(i16 %x) nounwind {
842 ; RV32I-LABEL: add_ugecmp_bad_i16_i8_c0notpoweroftwo:
843 ; RV32I:       # %bb.0:
844 ; RV32I-NEXT:    addi a0, a0, 192
845 ; RV32I-NEXT:    slli a0, a0, 16
846 ; RV32I-NEXT:    srli a0, a0, 16
847 ; RV32I-NEXT:    sltiu a0, a0, 256
848 ; RV32I-NEXT:    xori a0, a0, 1
849 ; RV32I-NEXT:    ret
851 ; RV64I-LABEL: add_ugecmp_bad_i16_i8_c0notpoweroftwo:
852 ; RV64I:       # %bb.0:
853 ; RV64I-NEXT:    addi a0, a0, 192
854 ; RV64I-NEXT:    slli a0, a0, 48
855 ; RV64I-NEXT:    srli a0, a0, 48
856 ; RV64I-NEXT:    sltiu a0, a0, 256
857 ; RV64I-NEXT:    xori a0, a0, 1
858 ; RV64I-NEXT:    ret
860 ; RV32ZBB-LABEL: add_ugecmp_bad_i16_i8_c0notpoweroftwo:
861 ; RV32ZBB:       # %bb.0:
862 ; RV32ZBB-NEXT:    addi a0, a0, 192
863 ; RV32ZBB-NEXT:    zext.h a0, a0
864 ; RV32ZBB-NEXT:    sltiu a0, a0, 256
865 ; RV32ZBB-NEXT:    xori a0, a0, 1
866 ; RV32ZBB-NEXT:    ret
868 ; RV64ZBB-LABEL: add_ugecmp_bad_i16_i8_c0notpoweroftwo:
869 ; RV64ZBB:       # %bb.0:
870 ; RV64ZBB-NEXT:    addi a0, a0, 192
871 ; RV64ZBB-NEXT:    zext.h a0, a0
872 ; RV64ZBB-NEXT:    sltiu a0, a0, 256
873 ; RV64ZBB-NEXT:    xori a0, a0, 1
874 ; RV64ZBB-NEXT:    ret
875   %tmp0 = add i16 %x, 192 ; (1U << (8-1)) + (1U << (8-1-1))
876   %tmp1 = icmp uge i16 %tmp0, 256 ; 1U << 8
877   ret i1 %tmp1
880 ; Second constant is not power of two
881 define i1 @add_ugecmp_bad_i16_i8_c1notpoweroftwo(i16 %x) nounwind {
882 ; RV32I-LABEL: add_ugecmp_bad_i16_i8_c1notpoweroftwo:
883 ; RV32I:       # %bb.0:
884 ; RV32I-NEXT:    addi a0, a0, 128
885 ; RV32I-NEXT:    slli a0, a0, 16
886 ; RV32I-NEXT:    srli a0, a0, 16
887 ; RV32I-NEXT:    sltiu a0, a0, 768
888 ; RV32I-NEXT:    xori a0, a0, 1
889 ; RV32I-NEXT:    ret
891 ; RV64I-LABEL: add_ugecmp_bad_i16_i8_c1notpoweroftwo:
892 ; RV64I:       # %bb.0:
893 ; RV64I-NEXT:    addi a0, a0, 128
894 ; RV64I-NEXT:    slli a0, a0, 48
895 ; RV64I-NEXT:    srli a0, a0, 48
896 ; RV64I-NEXT:    sltiu a0, a0, 768
897 ; RV64I-NEXT:    xori a0, a0, 1
898 ; RV64I-NEXT:    ret
900 ; RV32ZBB-LABEL: add_ugecmp_bad_i16_i8_c1notpoweroftwo:
901 ; RV32ZBB:       # %bb.0:
902 ; RV32ZBB-NEXT:    addi a0, a0, 128
903 ; RV32ZBB-NEXT:    zext.h a0, a0
904 ; RV32ZBB-NEXT:    sltiu a0, a0, 768
905 ; RV32ZBB-NEXT:    xori a0, a0, 1
906 ; RV32ZBB-NEXT:    ret
908 ; RV64ZBB-LABEL: add_ugecmp_bad_i16_i8_c1notpoweroftwo:
909 ; RV64ZBB:       # %bb.0:
910 ; RV64ZBB-NEXT:    addi a0, a0, 128
911 ; RV64ZBB-NEXT:    zext.h a0, a0
912 ; RV64ZBB-NEXT:    sltiu a0, a0, 768
913 ; RV64ZBB-NEXT:    xori a0, a0, 1
914 ; RV64ZBB-NEXT:    ret
915   %tmp0 = add i16 %x, 128 ; 1U << (8-1)
916   %tmp1 = icmp uge i16 %tmp0, 768 ; (1U << 8)) + (1U << (8+1))
917   ret i1 %tmp1
920 ; Magic check fails, 64 << 1 != 256
921 define i1 @add_ugecmp_bad_i16_i8_magic(i16 %x) nounwind {
922 ; RV32I-LABEL: add_ugecmp_bad_i16_i8_magic:
923 ; RV32I:       # %bb.0:
924 ; RV32I-NEXT:    addi a0, a0, 64
925 ; RV32I-NEXT:    slli a0, a0, 16
926 ; RV32I-NEXT:    srli a0, a0, 16
927 ; RV32I-NEXT:    sltiu a0, a0, 256
928 ; RV32I-NEXT:    xori a0, a0, 1
929 ; RV32I-NEXT:    ret
931 ; RV64I-LABEL: add_ugecmp_bad_i16_i8_magic:
932 ; RV64I:       # %bb.0:
933 ; RV64I-NEXT:    addi a0, a0, 64
934 ; RV64I-NEXT:    slli a0, a0, 48
935 ; RV64I-NEXT:    srli a0, a0, 48
936 ; RV64I-NEXT:    sltiu a0, a0, 256
937 ; RV64I-NEXT:    xori a0, a0, 1
938 ; RV64I-NEXT:    ret
940 ; RV32ZBB-LABEL: add_ugecmp_bad_i16_i8_magic:
941 ; RV32ZBB:       # %bb.0:
942 ; RV32ZBB-NEXT:    addi a0, a0, 64
943 ; RV32ZBB-NEXT:    zext.h a0, a0
944 ; RV32ZBB-NEXT:    sltiu a0, a0, 256
945 ; RV32ZBB-NEXT:    xori a0, a0, 1
946 ; RV32ZBB-NEXT:    ret
948 ; RV64ZBB-LABEL: add_ugecmp_bad_i16_i8_magic:
949 ; RV64ZBB:       # %bb.0:
950 ; RV64ZBB-NEXT:    addi a0, a0, 64
951 ; RV64ZBB-NEXT:    zext.h a0, a0
952 ; RV64ZBB-NEXT:    sltiu a0, a0, 256
953 ; RV64ZBB-NEXT:    xori a0, a0, 1
954 ; RV64ZBB-NEXT:    ret
955   %tmp0 = add i16 %x, 64 ; 1U << (8-1-1)
956   %tmp1 = icmp uge i16 %tmp0, 256 ; 1U << 8
957   ret i1 %tmp1
960 ; Bad 'destination type'
961 define i1 @add_ugecmp_bad_i16_i4(i16 %x) nounwind {
962 ; RV32I-LABEL: add_ugecmp_bad_i16_i4:
963 ; RV32I:       # %bb.0:
964 ; RV32I-NEXT:    addi a0, a0, 8
965 ; RV32I-NEXT:    slli a0, a0, 16
966 ; RV32I-NEXT:    srli a0, a0, 16
967 ; RV32I-NEXT:    sltiu a0, a0, 16
968 ; RV32I-NEXT:    xori a0, a0, 1
969 ; RV32I-NEXT:    ret
971 ; RV64I-LABEL: add_ugecmp_bad_i16_i4:
972 ; RV64I:       # %bb.0:
973 ; RV64I-NEXT:    addi a0, a0, 8
974 ; RV64I-NEXT:    slli a0, a0, 48
975 ; RV64I-NEXT:    srli a0, a0, 48
976 ; RV64I-NEXT:    sltiu a0, a0, 16
977 ; RV64I-NEXT:    xori a0, a0, 1
978 ; RV64I-NEXT:    ret
980 ; RV32ZBB-LABEL: add_ugecmp_bad_i16_i4:
981 ; RV32ZBB:       # %bb.0:
982 ; RV32ZBB-NEXT:    addi a0, a0, 8
983 ; RV32ZBB-NEXT:    zext.h a0, a0
984 ; RV32ZBB-NEXT:    sltiu a0, a0, 16
985 ; RV32ZBB-NEXT:    xori a0, a0, 1
986 ; RV32ZBB-NEXT:    ret
988 ; RV64ZBB-LABEL: add_ugecmp_bad_i16_i4:
989 ; RV64ZBB:       # %bb.0:
990 ; RV64ZBB-NEXT:    addi a0, a0, 8
991 ; RV64ZBB-NEXT:    zext.h a0, a0
992 ; RV64ZBB-NEXT:    sltiu a0, a0, 16
993 ; RV64ZBB-NEXT:    xori a0, a0, 1
994 ; RV64ZBB-NEXT:    ret
995   %tmp0 = add i16 %x, 8 ; 1U << (4-1)
996   %tmp1 = icmp uge i16 %tmp0, 16 ; 1U << 4
997   ret i1 %tmp1
1000 ; Bad storage type
1001 define i1 @add_ugecmp_bad_i24_i8(i24 %x) nounwind {
1002 ; RV32-LABEL: add_ugecmp_bad_i24_i8:
1003 ; RV32:       # %bb.0:
1004 ; RV32-NEXT:    addi a0, a0, 128
1005 ; RV32-NEXT:    slli a0, a0, 8
1006 ; RV32-NEXT:    srli a0, a0, 8
1007 ; RV32-NEXT:    sltiu a0, a0, 256
1008 ; RV32-NEXT:    xori a0, a0, 1
1009 ; RV32-NEXT:    ret
1011 ; RV64-LABEL: add_ugecmp_bad_i24_i8:
1012 ; RV64:       # %bb.0:
1013 ; RV64-NEXT:    addi a0, a0, 128
1014 ; RV64-NEXT:    slli a0, a0, 40
1015 ; RV64-NEXT:    srli a0, a0, 40
1016 ; RV64-NEXT:    sltiu a0, a0, 256
1017 ; RV64-NEXT:    xori a0, a0, 1
1018 ; RV64-NEXT:    ret
1019   %tmp0 = add i24 %x, 128 ; 1U << (8-1)
1020   %tmp1 = icmp uge i24 %tmp0, 256 ; 1U << 8
1021   ret i1 %tmp1
1024 ; Slightly more canonical variant
1025 define i1 @add_ugtcmp_bad_i16_i8(i16 %x) nounwind {
1026 ; CHECK-LABEL: add_ugtcmp_bad_i16_i8:
1027 ; CHECK:       # %bb.0:
1028 ; CHECK-NEXT:    li a0, 0
1029 ; CHECK-NEXT:    ret
1030   %tmp0 = add i16 %x, 128 ; 1U << (8-1)
1031   %tmp1 = icmp ugt i16 %tmp0, -1 ; when we +1 it, it will wrap to 0
1032   ret i1 %tmp1