[LLVM][IR] Use splat syntax when printing ConstantExpr based splats. (#116856)
[llvm-project.git] / llvm / test / CodeGen / RISCV / lack-of-signed-truncation-check.ll
blob4a338ce5bd1f782bca4cb95066e3e708beb7efff
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:    slli a1, a0, 16
28 ; RV32I-NEXT:    slli a0, a0, 24
29 ; RV32I-NEXT:    srli a1, a1, 16
30 ; RV32I-NEXT:    srai a0, a0, 8
31 ; RV32I-NEXT:    srli a0, a0, 16
32 ; RV32I-NEXT:    xor a0, a0, a1
33 ; RV32I-NEXT:    snez a0, a0
34 ; RV32I-NEXT:    ret
36 ; RV64I-LABEL: shifts_necmp_i16_i8:
37 ; RV64I:       # %bb.0:
38 ; RV64I-NEXT:    slli a1, a0, 48
39 ; RV64I-NEXT:    slli a0, a0, 56
40 ; RV64I-NEXT:    srli a1, a1, 48
41 ; RV64I-NEXT:    srai a0, a0, 8
42 ; RV64I-NEXT:    srli a0, a0, 48
43 ; RV64I-NEXT:    xor a0, a0, a1
44 ; RV64I-NEXT:    snez a0, a0
45 ; RV64I-NEXT:    ret
47 ; RV32ZBB-LABEL: shifts_necmp_i16_i8:
48 ; RV32ZBB:       # %bb.0:
49 ; RV32ZBB-NEXT:    zext.h a1, a0
50 ; RV32ZBB-NEXT:    sext.b a0, a0
51 ; RV32ZBB-NEXT:    zext.h a0, a0
52 ; RV32ZBB-NEXT:    xor a0, a0, a1
53 ; RV32ZBB-NEXT:    snez a0, a0
54 ; RV32ZBB-NEXT:    ret
56 ; RV64ZBB-LABEL: shifts_necmp_i16_i8:
57 ; RV64ZBB:       # %bb.0:
58 ; RV64ZBB-NEXT:    zext.h a1, a0
59 ; RV64ZBB-NEXT:    sext.b a0, a0
60 ; RV64ZBB-NEXT:    zext.h a0, a0
61 ; RV64ZBB-NEXT:    xor a0, a0, a1
62 ; RV64ZBB-NEXT:    snez a0, a0
63 ; RV64ZBB-NEXT:    ret
64   %tmp0 = shl i16 %x, 8 ; 16-8
65   %tmp1 = ashr exact i16 %tmp0, 8 ; 16-8
66   %tmp2 = icmp ne i16 %tmp1, %x
67   ret i1 %tmp2
70 define i1 @shifts_necmp_i32_i16(i32 %x) nounwind {
71 ; RV32I-LABEL: shifts_necmp_i32_i16:
72 ; RV32I:       # %bb.0:
73 ; RV32I-NEXT:    slli a1, a0, 16
74 ; RV32I-NEXT:    srai a1, a1, 16
75 ; RV32I-NEXT:    xor a0, a1, a0
76 ; RV32I-NEXT:    snez a0, a0
77 ; RV32I-NEXT:    ret
79 ; RV64I-LABEL: shifts_necmp_i32_i16:
80 ; RV64I:       # %bb.0:
81 ; RV64I-NEXT:    sext.w a1, a0
82 ; RV64I-NEXT:    slli a0, a0, 48
83 ; RV64I-NEXT:    srai a0, a0, 48
84 ; RV64I-NEXT:    xor a0, a0, a1
85 ; RV64I-NEXT:    snez a0, a0
86 ; RV64I-NEXT:    ret
88 ; RV32ZBB-LABEL: shifts_necmp_i32_i16:
89 ; RV32ZBB:       # %bb.0:
90 ; RV32ZBB-NEXT:    sext.h a1, a0
91 ; RV32ZBB-NEXT:    xor a0, a1, a0
92 ; RV32ZBB-NEXT:    snez a0, a0
93 ; RV32ZBB-NEXT:    ret
95 ; RV64ZBB-LABEL: shifts_necmp_i32_i16:
96 ; RV64ZBB:       # %bb.0:
97 ; RV64ZBB-NEXT:    sext.w a1, a0
98 ; RV64ZBB-NEXT:    sext.h a0, a0
99 ; RV64ZBB-NEXT:    xor a0, a0, a1
100 ; RV64ZBB-NEXT:    snez a0, a0
101 ; RV64ZBB-NEXT:    ret
102   %tmp0 = shl i32 %x, 16 ; 32-16
103   %tmp1 = ashr exact i32 %tmp0, 16 ; 32-16
104   %tmp2 = icmp ne i32 %tmp1, %x
105   ret i1 %tmp2
108 define i1 @shifts_necmp_i32_i8(i32 %x) nounwind {
109 ; RV32I-LABEL: shifts_necmp_i32_i8:
110 ; RV32I:       # %bb.0:
111 ; RV32I-NEXT:    slli a1, a0, 24
112 ; RV32I-NEXT:    srai a1, a1, 24
113 ; RV32I-NEXT:    xor a0, a1, a0
114 ; RV32I-NEXT:    snez a0, a0
115 ; RV32I-NEXT:    ret
117 ; RV64I-LABEL: shifts_necmp_i32_i8:
118 ; RV64I:       # %bb.0:
119 ; RV64I-NEXT:    sext.w a1, a0
120 ; RV64I-NEXT:    slli a0, a0, 56
121 ; RV64I-NEXT:    srai a0, a0, 56
122 ; RV64I-NEXT:    xor a0, a0, a1
123 ; RV64I-NEXT:    snez a0, a0
124 ; RV64I-NEXT:    ret
126 ; RV32ZBB-LABEL: shifts_necmp_i32_i8:
127 ; RV32ZBB:       # %bb.0:
128 ; RV32ZBB-NEXT:    sext.b a1, a0
129 ; RV32ZBB-NEXT:    xor a0, a1, a0
130 ; RV32ZBB-NEXT:    snez a0, a0
131 ; RV32ZBB-NEXT:    ret
133 ; RV64ZBB-LABEL: shifts_necmp_i32_i8:
134 ; RV64ZBB:       # %bb.0:
135 ; RV64ZBB-NEXT:    sext.w a1, a0
136 ; RV64ZBB-NEXT:    sext.b a0, a0
137 ; RV64ZBB-NEXT:    xor a0, a0, a1
138 ; RV64ZBB-NEXT:    snez a0, a0
139 ; RV64ZBB-NEXT:    ret
140   %tmp0 = shl i32 %x, 24 ; 32-8
141   %tmp1 = ashr exact i32 %tmp0, 24 ; 32-8
142   %tmp2 = icmp ne i32 %tmp1, %x
143   ret i1 %tmp2
146 define i1 @shifts_necmp_i64_i32(i64 %x) nounwind {
147 ; RV32-LABEL: shifts_necmp_i64_i32:
148 ; RV32:       # %bb.0:
149 ; RV32-NEXT:    srai a0, a0, 31
150 ; RV32-NEXT:    xor a0, a0, a1
151 ; RV32-NEXT:    snez a0, a0
152 ; RV32-NEXT:    ret
154 ; RV64-LABEL: shifts_necmp_i64_i32:
155 ; RV64:       # %bb.0:
156 ; RV64-NEXT:    sext.w a1, a0
157 ; RV64-NEXT:    xor a0, a1, a0
158 ; RV64-NEXT:    snez a0, a0
159 ; RV64-NEXT:    ret
160   %tmp0 = shl i64 %x, 32 ; 64-32
161   %tmp1 = ashr exact i64 %tmp0, 32 ; 64-32
162   %tmp2 = icmp ne i64 %tmp1, %x
163   ret i1 %tmp2
166 define i1 @shifts_necmp_i64_i16(i64 %x) nounwind {
167 ; RV32I-LABEL: shifts_necmp_i64_i16:
168 ; RV32I:       # %bb.0:
169 ; RV32I-NEXT:    slli a2, a0, 16
170 ; RV32I-NEXT:    srai a3, a2, 16
171 ; RV32I-NEXT:    srai a2, a2, 31
172 ; RV32I-NEXT:    xor a1, a2, a1
173 ; RV32I-NEXT:    xor a0, a3, a0
174 ; RV32I-NEXT:    or a0, a0, a1
175 ; RV32I-NEXT:    snez a0, a0
176 ; RV32I-NEXT:    ret
178 ; RV64I-LABEL: shifts_necmp_i64_i16:
179 ; RV64I:       # %bb.0:
180 ; RV64I-NEXT:    slli a1, a0, 48
181 ; RV64I-NEXT:    srai a1, a1, 48
182 ; RV64I-NEXT:    xor a0, a1, a0
183 ; RV64I-NEXT:    snez a0, a0
184 ; RV64I-NEXT:    ret
186 ; RV32ZBB-LABEL: shifts_necmp_i64_i16:
187 ; RV32ZBB:       # %bb.0:
188 ; RV32ZBB-NEXT:    sext.h a2, a0
189 ; RV32ZBB-NEXT:    srai a3, a2, 31
190 ; RV32ZBB-NEXT:    xor a0, a2, a0
191 ; RV32ZBB-NEXT:    xor a1, a3, a1
192 ; RV32ZBB-NEXT:    or a0, a0, a1
193 ; RV32ZBB-NEXT:    snez a0, a0
194 ; RV32ZBB-NEXT:    ret
196 ; RV64ZBB-LABEL: shifts_necmp_i64_i16:
197 ; RV64ZBB:       # %bb.0:
198 ; RV64ZBB-NEXT:    sext.h a1, a0
199 ; RV64ZBB-NEXT:    xor a0, a1, a0
200 ; RV64ZBB-NEXT:    snez a0, a0
201 ; RV64ZBB-NEXT:    ret
202   %tmp0 = shl i64 %x, 48 ; 64-16
203   %tmp1 = ashr exact i64 %tmp0, 48 ; 64-16
204   %tmp2 = icmp ne i64 %tmp1, %x
205   ret i1 %tmp2
208 define i1 @shifts_necmp_i64_i8(i64 %x) nounwind {
209 ; RV32I-LABEL: shifts_necmp_i64_i8:
210 ; RV32I:       # %bb.0:
211 ; RV32I-NEXT:    slli a2, a0, 24
212 ; RV32I-NEXT:    srai a3, a2, 24
213 ; RV32I-NEXT:    srai a2, a2, 31
214 ; RV32I-NEXT:    xor a1, a2, a1
215 ; RV32I-NEXT:    xor a0, a3, a0
216 ; RV32I-NEXT:    or a0, a0, a1
217 ; RV32I-NEXT:    snez a0, a0
218 ; RV32I-NEXT:    ret
220 ; RV64I-LABEL: shifts_necmp_i64_i8:
221 ; RV64I:       # %bb.0:
222 ; RV64I-NEXT:    slli a1, a0, 56
223 ; RV64I-NEXT:    srai a1, a1, 56
224 ; RV64I-NEXT:    xor a0, a1, a0
225 ; RV64I-NEXT:    snez a0, a0
226 ; RV64I-NEXT:    ret
228 ; RV32ZBB-LABEL: shifts_necmp_i64_i8:
229 ; RV32ZBB:       # %bb.0:
230 ; RV32ZBB-NEXT:    sext.b a2, a0
231 ; RV32ZBB-NEXT:    srai a3, a2, 31
232 ; RV32ZBB-NEXT:    xor a0, a2, a0
233 ; RV32ZBB-NEXT:    xor a1, a3, a1
234 ; RV32ZBB-NEXT:    or a0, a0, a1
235 ; RV32ZBB-NEXT:    snez a0, a0
236 ; RV32ZBB-NEXT:    ret
238 ; RV64ZBB-LABEL: shifts_necmp_i64_i8:
239 ; RV64ZBB:       # %bb.0:
240 ; RV64ZBB-NEXT:    sext.b a1, a0
241 ; RV64ZBB-NEXT:    xor a0, a1, a0
242 ; RV64ZBB-NEXT:    snez a0, a0
243 ; RV64ZBB-NEXT:    ret
244   %tmp0 = shl i64 %x, 56 ; 64-8
245   %tmp1 = ashr exact i64 %tmp0, 56 ; 64-8
246   %tmp2 = icmp ne i64 %tmp1, %x
247   ret i1 %tmp2
250 ; ---------------------------------------------------------------------------- ;
251 ; add + icmp ult
252 ; ---------------------------------------------------------------------------- ;
254 define i1 @add_ultcmp_i16_i8(i16 %x) nounwind {
255 ; RV32I-LABEL: add_ultcmp_i16_i8:
256 ; RV32I:       # %bb.0:
257 ; RV32I-NEXT:    slli a0, a0, 16
258 ; RV32I-NEXT:    srli a0, a0, 16
259 ; RV32I-NEXT:    addi a0, a0, -128
260 ; RV32I-NEXT:    srli a0, a0, 8
261 ; RV32I-NEXT:    sltiu a0, a0, 255
262 ; RV32I-NEXT:    ret
264 ; RV64I-LABEL: add_ultcmp_i16_i8:
265 ; RV64I:       # %bb.0:
266 ; RV64I-NEXT:    slli a0, a0, 48
267 ; RV64I-NEXT:    srli a0, a0, 48
268 ; RV64I-NEXT:    addi a0, a0, -128
269 ; RV64I-NEXT:    srli a0, a0, 8
270 ; RV64I-NEXT:    sltiu a0, a0, 255
271 ; RV64I-NEXT:    ret
273 ; RV32ZBB-LABEL: add_ultcmp_i16_i8:
274 ; RV32ZBB:       # %bb.0:
275 ; RV32ZBB-NEXT:    zext.h a0, a0
276 ; RV32ZBB-NEXT:    addi a0, a0, -128
277 ; RV32ZBB-NEXT:    srli a0, a0, 8
278 ; RV32ZBB-NEXT:    sltiu a0, a0, 255
279 ; RV32ZBB-NEXT:    ret
281 ; RV64ZBB-LABEL: add_ultcmp_i16_i8:
282 ; RV64ZBB:       # %bb.0:
283 ; RV64ZBB-NEXT:    zext.h a0, a0
284 ; RV64ZBB-NEXT:    addi a0, a0, -128
285 ; RV64ZBB-NEXT:    srli a0, a0, 8
286 ; RV64ZBB-NEXT:    sltiu a0, a0, 255
287 ; RV64ZBB-NEXT:    ret
288   %tmp0 = add i16 %x, -128 ; ~0U << (8-1)
289   %tmp1 = icmp ult i16 %tmp0, -256 ; ~0U << 8
290   ret i1 %tmp1
293 define i1 @add_ultcmp_i32_i16(i32 %x) nounwind {
294 ; RV32I-LABEL: add_ultcmp_i32_i16:
295 ; RV32I:       # %bb.0:
296 ; RV32I-NEXT:    lui a1, 1048568
297 ; RV32I-NEXT:    add a0, a0, a1
298 ; RV32I-NEXT:    lui a1, 1048560
299 ; RV32I-NEXT:    sltu a0, a0, a1
300 ; RV32I-NEXT:    ret
302 ; RV64I-LABEL: add_ultcmp_i32_i16:
303 ; RV64I:       # %bb.0:
304 ; RV64I-NEXT:    lui a1, 1048568
305 ; RV64I-NEXT:    addw a0, a0, a1
306 ; RV64I-NEXT:    lui a1, 1048560
307 ; RV64I-NEXT:    sltu a0, a0, a1
308 ; RV64I-NEXT:    ret
310 ; RV32ZBB-LABEL: add_ultcmp_i32_i16:
311 ; RV32ZBB:       # %bb.0:
312 ; RV32ZBB-NEXT:    sext.h a1, a0
313 ; RV32ZBB-NEXT:    xor a0, a1, a0
314 ; RV32ZBB-NEXT:    snez a0, a0
315 ; RV32ZBB-NEXT:    ret
317 ; RV64ZBB-LABEL: add_ultcmp_i32_i16:
318 ; RV64ZBB:       # %bb.0:
319 ; RV64ZBB-NEXT:    sext.w a1, a0
320 ; RV64ZBB-NEXT:    sext.h a0, a0
321 ; RV64ZBB-NEXT:    xor a0, a0, a1
322 ; RV64ZBB-NEXT:    snez a0, a0
323 ; RV64ZBB-NEXT:    ret
324   %tmp0 = add i32 %x, -32768 ; ~0U << (16-1)
325   %tmp1 = icmp ult i32 %tmp0, -65536 ; ~0U << 16
326   ret i1 %tmp1
329 define i1 @add_ultcmp_i32_i8(i32 %x) nounwind {
330 ; RV32-LABEL: add_ultcmp_i32_i8:
331 ; RV32:       # %bb.0:
332 ; RV32-NEXT:    addi a0, a0, -128
333 ; RV32-NEXT:    sltiu a0, a0, -256
334 ; RV32-NEXT:    ret
336 ; RV64-LABEL: add_ultcmp_i32_i8:
337 ; RV64:       # %bb.0:
338 ; RV64-NEXT:    addiw a0, a0, -128
339 ; RV64-NEXT:    sltiu a0, a0, -256
340 ; RV64-NEXT:    ret
341   %tmp0 = add i32 %x, -128 ; ~0U << (8-1)
342   %tmp1 = icmp ult i32 %tmp0, -256 ; ~0U << 8
343   ret i1 %tmp1
346 define i1 @add_ultcmp_i64_i32(i64 %x) nounwind {
347 ; RV32-LABEL: add_ultcmp_i64_i32:
348 ; RV32:       # %bb.0:
349 ; RV32-NEXT:    srai a0, a0, 31
350 ; RV32-NEXT:    xor a0, a0, a1
351 ; RV32-NEXT:    snez a0, a0
352 ; RV32-NEXT:    ret
354 ; RV64-LABEL: add_ultcmp_i64_i32:
355 ; RV64:       # %bb.0:
356 ; RV64-NEXT:    sext.w a1, a0
357 ; RV64-NEXT:    xor a0, a1, a0
358 ; RV64-NEXT:    snez a0, a0
359 ; RV64-NEXT:    ret
360   %tmp0 = add i64 %x, -2147483648 ; ~0U << (32-1)
361   %tmp1 = icmp ult i64 %tmp0, -4294967296 ; ~0U << 32
362   ret i1 %tmp1
365 define i1 @add_ultcmp_i64_i16(i64 %x) nounwind {
366 ; RV32I-LABEL: add_ultcmp_i64_i16:
367 ; RV32I:       # %bb.0:
368 ; RV32I-NEXT:    lui a2, 1048568
369 ; RV32I-NEXT:    add a2, a0, a2
370 ; RV32I-NEXT:    sltu a0, a2, a0
371 ; RV32I-NEXT:    add a0, a1, a0
372 ; RV32I-NEXT:    lui a1, 1048560
373 ; RV32I-NEXT:    sltu a1, a2, a1
374 ; RV32I-NEXT:    snez a0, a0
375 ; RV32I-NEXT:    or a0, a1, a0
376 ; RV32I-NEXT:    ret
378 ; RV64I-LABEL: add_ultcmp_i64_i16:
379 ; RV64I:       # %bb.0:
380 ; RV64I-NEXT:    lui a1, 1048568
381 ; RV64I-NEXT:    add a0, a0, a1
382 ; RV64I-NEXT:    lui a1, 1048560
383 ; RV64I-NEXT:    sltu a0, a0, a1
384 ; RV64I-NEXT:    ret
386 ; RV32ZBB-LABEL: add_ultcmp_i64_i16:
387 ; RV32ZBB:       # %bb.0:
388 ; RV32ZBB-NEXT:    sext.h a2, a0
389 ; RV32ZBB-NEXT:    xor a0, a2, a0
390 ; RV32ZBB-NEXT:    srai a2, a2, 31
391 ; RV32ZBB-NEXT:    xor a1, a2, a1
392 ; RV32ZBB-NEXT:    or a0, a0, a1
393 ; RV32ZBB-NEXT:    snez a0, a0
394 ; RV32ZBB-NEXT:    ret
396 ; RV64ZBB-LABEL: add_ultcmp_i64_i16:
397 ; RV64ZBB:       # %bb.0:
398 ; RV64ZBB-NEXT:    sext.h a1, a0
399 ; RV64ZBB-NEXT:    xor a0, a1, a0
400 ; RV64ZBB-NEXT:    snez a0, a0
401 ; RV64ZBB-NEXT:    ret
402   %tmp0 = add i64 %x, -32768 ; ~0U << (16-1)
403   %tmp1 = icmp ult i64 %tmp0, -65536 ; ~0U << 16
404   ret i1 %tmp1
407 define i1 @add_ultcmp_i64_i8(i64 %x) nounwind {
408 ; RV32I-LABEL: add_ultcmp_i64_i8:
409 ; RV32I:       # %bb.0:
410 ; RV32I-NEXT:    addi a2, a0, -128
411 ; RV32I-NEXT:    sltu a0, a2, a0
412 ; RV32I-NEXT:    add a0, a1, a0
413 ; RV32I-NEXT:    snez a0, a0
414 ; RV32I-NEXT:    sltiu a1, a2, -256
415 ; RV32I-NEXT:    or a0, a1, a0
416 ; RV32I-NEXT:    ret
418 ; RV64-LABEL: add_ultcmp_i64_i8:
419 ; RV64:       # %bb.0:
420 ; RV64-NEXT:    addi a0, a0, -128
421 ; RV64-NEXT:    sltiu a0, a0, -256
422 ; RV64-NEXT:    ret
424 ; RV32ZBB-LABEL: add_ultcmp_i64_i8:
425 ; RV32ZBB:       # %bb.0:
426 ; RV32ZBB-NEXT:    sext.b a2, a0
427 ; RV32ZBB-NEXT:    xor a0, a2, a0
428 ; RV32ZBB-NEXT:    srai a2, a2, 31
429 ; RV32ZBB-NEXT:    xor a1, a2, a1
430 ; RV32ZBB-NEXT:    or a0, a0, a1
431 ; RV32ZBB-NEXT:    snez a0, a0
432 ; RV32ZBB-NEXT:    ret
433   %tmp0 = add i64 %x, -128 ; ~0U << (8-1)
434   %tmp1 = icmp ult i64 %tmp0, -256 ; ~0U << 8
435   ret i1 %tmp1
438 ; Slightly more canonical variant
439 define i1 @add_ulecmp_i16_i8(i16 %x) nounwind {
440 ; RV32I-LABEL: add_ulecmp_i16_i8:
441 ; RV32I:       # %bb.0:
442 ; RV32I-NEXT:    slli a0, a0, 16
443 ; RV32I-NEXT:    srli a0, a0, 16
444 ; RV32I-NEXT:    addi a0, a0, -128
445 ; RV32I-NEXT:    srli a0, a0, 8
446 ; RV32I-NEXT:    sltiu a0, a0, 255
447 ; RV32I-NEXT:    ret
449 ; RV64I-LABEL: add_ulecmp_i16_i8:
450 ; RV64I:       # %bb.0:
451 ; RV64I-NEXT:    slli a0, a0, 48
452 ; RV64I-NEXT:    srli a0, a0, 48
453 ; RV64I-NEXT:    addi a0, a0, -128
454 ; RV64I-NEXT:    srli a0, a0, 8
455 ; RV64I-NEXT:    sltiu a0, a0, 255
456 ; RV64I-NEXT:    ret
458 ; RV32ZBB-LABEL: add_ulecmp_i16_i8:
459 ; RV32ZBB:       # %bb.0:
460 ; RV32ZBB-NEXT:    zext.h a0, a0
461 ; RV32ZBB-NEXT:    addi a0, a0, -128
462 ; RV32ZBB-NEXT:    srli a0, a0, 8
463 ; RV32ZBB-NEXT:    sltiu a0, a0, 255
464 ; RV32ZBB-NEXT:    ret
466 ; RV64ZBB-LABEL: add_ulecmp_i16_i8:
467 ; RV64ZBB:       # %bb.0:
468 ; RV64ZBB-NEXT:    zext.h a0, a0
469 ; RV64ZBB-NEXT:    addi a0, a0, -128
470 ; RV64ZBB-NEXT:    srli a0, a0, 8
471 ; RV64ZBB-NEXT:    sltiu a0, a0, 255
472 ; RV64ZBB-NEXT:    ret
473   %tmp0 = add i16 %x, -128 ; ~0U << (8-1)
474   %tmp1 = icmp ule i16 %tmp0, -257 ; ~0U << 8 - 1
475   ret i1 %tmp1
478 ; ---------------------------------------------------------------------------- ;
479 ; add + icmp uge
480 ; ---------------------------------------------------------------------------- ;
482 define i1 @add_ugecmp_i16_i8(i16 %x) nounwind {
483 ; RV32I-LABEL: add_ugecmp_i16_i8:
484 ; RV32I:       # %bb.0:
485 ; RV32I-NEXT:    addi a0, a0, 128
486 ; RV32I-NEXT:    slli a0, a0, 16
487 ; RV32I-NEXT:    srli a0, a0, 16
488 ; RV32I-NEXT:    sltiu a0, a0, 256
489 ; RV32I-NEXT:    xori a0, a0, 1
490 ; RV32I-NEXT:    ret
492 ; RV64I-LABEL: add_ugecmp_i16_i8:
493 ; RV64I:       # %bb.0:
494 ; RV64I-NEXT:    addi a0, a0, 128
495 ; RV64I-NEXT:    slli a0, a0, 48
496 ; RV64I-NEXT:    srli a0, a0, 48
497 ; RV64I-NEXT:    sltiu a0, a0, 256
498 ; RV64I-NEXT:    xori a0, a0, 1
499 ; RV64I-NEXT:    ret
501 ; RV32ZBB-LABEL: add_ugecmp_i16_i8:
502 ; RV32ZBB:       # %bb.0:
503 ; RV32ZBB-NEXT:    addi a0, a0, 128
504 ; RV32ZBB-NEXT:    zext.h a0, a0
505 ; RV32ZBB-NEXT:    sltiu a0, a0, 256
506 ; RV32ZBB-NEXT:    xori a0, a0, 1
507 ; RV32ZBB-NEXT:    ret
509 ; RV64ZBB-LABEL: add_ugecmp_i16_i8:
510 ; RV64ZBB:       # %bb.0:
511 ; RV64ZBB-NEXT:    addi a0, a0, 128
512 ; RV64ZBB-NEXT:    zext.h a0, a0
513 ; RV64ZBB-NEXT:    sltiu a0, a0, 256
514 ; RV64ZBB-NEXT:    xori a0, a0, 1
515 ; RV64ZBB-NEXT:    ret
516   %tmp0 = add i16 %x, 128 ; 1U << (8-1)
517   %tmp1 = icmp uge i16 %tmp0, 256 ; 1U << 8
518   ret i1 %tmp1
521 define i1 @add_ugecmp_i32_i16(i32 %x) nounwind {
522 ; RV32I-LABEL: add_ugecmp_i32_i16:
523 ; RV32I:       # %bb.0:
524 ; RV32I-NEXT:    lui a1, 8
525 ; RV32I-NEXT:    add a0, a0, a1
526 ; RV32I-NEXT:    srli a0, a0, 16
527 ; RV32I-NEXT:    snez a0, a0
528 ; RV32I-NEXT:    ret
530 ; RV64I-LABEL: add_ugecmp_i32_i16:
531 ; RV64I:       # %bb.0:
532 ; RV64I-NEXT:    lui a1, 8
533 ; RV64I-NEXT:    add a0, a0, a1
534 ; RV64I-NEXT:    srliw a0, a0, 16
535 ; RV64I-NEXT:    snez a0, a0
536 ; RV64I-NEXT:    ret
538 ; RV32ZBB-LABEL: add_ugecmp_i32_i16:
539 ; RV32ZBB:       # %bb.0:
540 ; RV32ZBB-NEXT:    sext.h a1, a0
541 ; RV32ZBB-NEXT:    xor a0, a1, a0
542 ; RV32ZBB-NEXT:    snez a0, a0
543 ; RV32ZBB-NEXT:    ret
545 ; RV64ZBB-LABEL: add_ugecmp_i32_i16:
546 ; RV64ZBB:       # %bb.0:
547 ; RV64ZBB-NEXT:    sext.w a1, a0
548 ; RV64ZBB-NEXT:    sext.h a0, a0
549 ; RV64ZBB-NEXT:    xor a0, a0, a1
550 ; RV64ZBB-NEXT:    snez a0, a0
551 ; RV64ZBB-NEXT:    ret
552   %tmp0 = add i32 %x, 32768 ; 1U << (16-1)
553   %tmp1 = icmp uge i32 %tmp0, 65536 ; 1U << 16
554   ret i1 %tmp1
557 define i1 @add_ugecmp_i32_i8(i32 %x) nounwind {
558 ; RV32-LABEL: add_ugecmp_i32_i8:
559 ; RV32:       # %bb.0:
560 ; RV32-NEXT:    addi a0, a0, 128
561 ; RV32-NEXT:    sltiu a0, a0, 256
562 ; RV32-NEXT:    xori a0, a0, 1
563 ; RV32-NEXT:    ret
565 ; RV64-LABEL: add_ugecmp_i32_i8:
566 ; RV64:       # %bb.0:
567 ; RV64-NEXT:    addiw a0, a0, 128
568 ; RV64-NEXT:    sltiu a0, a0, 256
569 ; RV64-NEXT:    xori a0, a0, 1
570 ; RV64-NEXT:    ret
571   %tmp0 = add i32 %x, 128 ; 1U << (8-1)
572   %tmp1 = icmp uge i32 %tmp0, 256 ; 1U << 8
573   ret i1 %tmp1
576 define i1 @add_ugecmp_i64_i32(i64 %x) nounwind {
577 ; RV32-LABEL: add_ugecmp_i64_i32:
578 ; RV32:       # %bb.0:
579 ; RV32-NEXT:    srai a0, a0, 31
580 ; RV32-NEXT:    xor a0, a0, a1
581 ; RV32-NEXT:    snez a0, a0
582 ; RV32-NEXT:    ret
584 ; RV64-LABEL: add_ugecmp_i64_i32:
585 ; RV64:       # %bb.0:
586 ; RV64-NEXT:    sext.w a1, a0
587 ; RV64-NEXT:    xor a0, a1, a0
588 ; RV64-NEXT:    snez a0, a0
589 ; RV64-NEXT:    ret
590   %tmp0 = add i64 %x, 2147483648 ; 1U << (32-1)
591   %tmp1 = icmp uge i64 %tmp0, 4294967296 ; 1U << 32
592   ret i1 %tmp1
595 define i1 @add_ugecmp_i64_i16(i64 %x) nounwind {
596 ; RV32I-LABEL: add_ugecmp_i64_i16:
597 ; RV32I:       # %bb.0:
598 ; RV32I-NEXT:    lui a2, 8
599 ; RV32I-NEXT:    add a2, a0, a2
600 ; RV32I-NEXT:    sltu a0, a2, a0
601 ; RV32I-NEXT:    add a0, a1, a0
602 ; RV32I-NEXT:    srli a2, a2, 16
603 ; RV32I-NEXT:    or a0, a0, a2
604 ; RV32I-NEXT:    snez a0, a0
605 ; RV32I-NEXT:    ret
607 ; RV64I-LABEL: add_ugecmp_i64_i16:
608 ; RV64I:       # %bb.0:
609 ; RV64I-NEXT:    lui a1, 8
610 ; RV64I-NEXT:    add a0, a0, a1
611 ; RV64I-NEXT:    srli a0, a0, 16
612 ; RV64I-NEXT:    snez a0, a0
613 ; RV64I-NEXT:    ret
615 ; RV32ZBB-LABEL: add_ugecmp_i64_i16:
616 ; RV32ZBB:       # %bb.0:
617 ; RV32ZBB-NEXT:    sext.h a2, a0
618 ; RV32ZBB-NEXT:    xor a0, a2, a0
619 ; RV32ZBB-NEXT:    srai a2, a2, 31
620 ; RV32ZBB-NEXT:    xor a1, a2, a1
621 ; RV32ZBB-NEXT:    or a0, a0, a1
622 ; RV32ZBB-NEXT:    snez a0, a0
623 ; RV32ZBB-NEXT:    ret
625 ; RV64ZBB-LABEL: add_ugecmp_i64_i16:
626 ; RV64ZBB:       # %bb.0:
627 ; RV64ZBB-NEXT:    sext.h a1, a0
628 ; RV64ZBB-NEXT:    xor a0, a1, a0
629 ; RV64ZBB-NEXT:    snez a0, a0
630 ; RV64ZBB-NEXT:    ret
631   %tmp0 = add i64 %x, 32768 ; 1U << (16-1)
632   %tmp1 = icmp uge i64 %tmp0, 65536 ; 1U << 16
633   ret i1 %tmp1
636 define i1 @add_ugecmp_i64_i8(i64 %x) nounwind {
637 ; RV32I-LABEL: add_ugecmp_i64_i8:
638 ; RV32I:       # %bb.0:
639 ; RV32I-NEXT:    addi a2, a0, 128
640 ; RV32I-NEXT:    sltu a0, a2, a0
641 ; RV32I-NEXT:    sltiu a2, a2, 256
642 ; RV32I-NEXT:    add a0, a1, a0
643 ; RV32I-NEXT:    snez a0, a0
644 ; RV32I-NEXT:    xori a1, a2, 1
645 ; RV32I-NEXT:    or a0, a1, a0
646 ; RV32I-NEXT:    ret
648 ; RV64-LABEL: add_ugecmp_i64_i8:
649 ; RV64:       # %bb.0:
650 ; RV64-NEXT:    addi a0, a0, 128
651 ; RV64-NEXT:    sltiu a0, a0, 256
652 ; RV64-NEXT:    xori a0, a0, 1
653 ; RV64-NEXT:    ret
655 ; RV32ZBB-LABEL: add_ugecmp_i64_i8:
656 ; RV32ZBB:       # %bb.0:
657 ; RV32ZBB-NEXT:    sext.b a2, a0
658 ; RV32ZBB-NEXT:    xor a0, a2, a0
659 ; RV32ZBB-NEXT:    srai a2, a2, 31
660 ; RV32ZBB-NEXT:    xor a1, a2, a1
661 ; RV32ZBB-NEXT:    or a0, a0, a1
662 ; RV32ZBB-NEXT:    snez a0, a0
663 ; RV32ZBB-NEXT:    ret
664   %tmp0 = add i64 %x, 128 ; 1U << (8-1)
665   %tmp1 = icmp uge i64 %tmp0, 256 ; 1U << 8
666   ret i1 %tmp1
669 ; Slightly more canonical variant
670 define i1 @add_ugtcmp_i16_i8(i16 %x) nounwind {
671 ; RV32I-LABEL: add_ugtcmp_i16_i8:
672 ; RV32I:       # %bb.0:
673 ; RV32I-NEXT:    addi a0, a0, 128
674 ; RV32I-NEXT:    slli a0, a0, 16
675 ; RV32I-NEXT:    srli a0, a0, 16
676 ; RV32I-NEXT:    sltiu a0, a0, 256
677 ; RV32I-NEXT:    xori a0, a0, 1
678 ; RV32I-NEXT:    ret
680 ; RV64I-LABEL: add_ugtcmp_i16_i8:
681 ; RV64I:       # %bb.0:
682 ; RV64I-NEXT:    addi a0, a0, 128
683 ; RV64I-NEXT:    slli a0, a0, 48
684 ; RV64I-NEXT:    srli a0, a0, 48
685 ; RV64I-NEXT:    sltiu a0, a0, 256
686 ; RV64I-NEXT:    xori a0, a0, 1
687 ; RV64I-NEXT:    ret
689 ; RV32ZBB-LABEL: add_ugtcmp_i16_i8:
690 ; RV32ZBB:       # %bb.0:
691 ; RV32ZBB-NEXT:    addi a0, a0, 128
692 ; RV32ZBB-NEXT:    zext.h a0, a0
693 ; RV32ZBB-NEXT:    sltiu a0, a0, 256
694 ; RV32ZBB-NEXT:    xori a0, a0, 1
695 ; RV32ZBB-NEXT:    ret
697 ; RV64ZBB-LABEL: add_ugtcmp_i16_i8:
698 ; RV64ZBB:       # %bb.0:
699 ; RV64ZBB-NEXT:    addi a0, a0, 128
700 ; RV64ZBB-NEXT:    zext.h a0, a0
701 ; RV64ZBB-NEXT:    sltiu a0, a0, 256
702 ; RV64ZBB-NEXT:    xori a0, a0, 1
703 ; RV64ZBB-NEXT:    ret
704   %tmp0 = add i16 %x, 128 ; 1U << (8-1)
705   %tmp1 = icmp ugt i16 %tmp0, 255 ; (1U << 8) - 1
706   ret i1 %tmp1
709 ; Negative tests
710 ; ---------------------------------------------------------------------------- ;
712 ; Adding not a constant
713 define i1 @add_ugecmp_bad_i16_i8_add(i16 %x, i16 %y) nounwind {
714 ; RV32I-LABEL: add_ugecmp_bad_i16_i8_add:
715 ; RV32I:       # %bb.0:
716 ; RV32I-NEXT:    add a0, a0, a1
717 ; RV32I-NEXT:    slli a0, a0, 16
718 ; RV32I-NEXT:    srli a0, a0, 16
719 ; RV32I-NEXT:    sltiu a0, a0, 256
720 ; RV32I-NEXT:    xori a0, a0, 1
721 ; RV32I-NEXT:    ret
723 ; RV64I-LABEL: add_ugecmp_bad_i16_i8_add:
724 ; RV64I:       # %bb.0:
725 ; RV64I-NEXT:    add a0, a0, a1
726 ; RV64I-NEXT:    slli a0, a0, 48
727 ; RV64I-NEXT:    srli a0, a0, 48
728 ; RV64I-NEXT:    sltiu a0, a0, 256
729 ; RV64I-NEXT:    xori a0, a0, 1
730 ; RV64I-NEXT:    ret
732 ; RV32ZBB-LABEL: add_ugecmp_bad_i16_i8_add:
733 ; RV32ZBB:       # %bb.0:
734 ; RV32ZBB-NEXT:    add a0, a0, a1
735 ; RV32ZBB-NEXT:    zext.h a0, a0
736 ; RV32ZBB-NEXT:    sltiu a0, a0, 256
737 ; RV32ZBB-NEXT:    xori a0, a0, 1
738 ; RV32ZBB-NEXT:    ret
740 ; RV64ZBB-LABEL: add_ugecmp_bad_i16_i8_add:
741 ; RV64ZBB:       # %bb.0:
742 ; RV64ZBB-NEXT:    add a0, a0, a1
743 ; RV64ZBB-NEXT:    zext.h a0, a0
744 ; RV64ZBB-NEXT:    sltiu a0, a0, 256
745 ; RV64ZBB-NEXT:    xori a0, a0, 1
746 ; RV64ZBB-NEXT:    ret
747   %tmp0 = add i16 %x, %y
748   %tmp1 = icmp uge i16 %tmp0, 256 ; 1U << 8
749   ret i1 %tmp1
752 ; Comparing not with a constant
753 define i1 @add_ugecmp_bad_i16_i8_cmp(i16 %x, i16 %y) nounwind {
754 ; RV32I-LABEL: add_ugecmp_bad_i16_i8_cmp:
755 ; RV32I:       # %bb.0:
756 ; RV32I-NEXT:    lui a2, 16
757 ; RV32I-NEXT:    addi a0, a0, 128
758 ; RV32I-NEXT:    addi a2, a2, -1
759 ; RV32I-NEXT:    and a1, a1, a2
760 ; RV32I-NEXT:    and a0, a0, a2
761 ; RV32I-NEXT:    sltu a0, a0, a1
762 ; RV32I-NEXT:    xori a0, a0, 1
763 ; RV32I-NEXT:    ret
765 ; RV64I-LABEL: add_ugecmp_bad_i16_i8_cmp:
766 ; RV64I:       # %bb.0:
767 ; RV64I-NEXT:    lui a2, 16
768 ; RV64I-NEXT:    addi a0, a0, 128
769 ; RV64I-NEXT:    addiw a2, a2, -1
770 ; RV64I-NEXT:    and a1, a1, a2
771 ; RV64I-NEXT:    and a0, a0, a2
772 ; RV64I-NEXT:    sltu a0, a0, a1
773 ; RV64I-NEXT:    xori a0, a0, 1
774 ; RV64I-NEXT:    ret
776 ; RV32ZBB-LABEL: add_ugecmp_bad_i16_i8_cmp:
777 ; RV32ZBB:       # %bb.0:
778 ; RV32ZBB-NEXT:    zext.h a1, a1
779 ; RV32ZBB-NEXT:    addi a0, a0, 128
780 ; RV32ZBB-NEXT:    zext.h a0, a0
781 ; RV32ZBB-NEXT:    sltu a0, a0, a1
782 ; RV32ZBB-NEXT:    xori a0, a0, 1
783 ; RV32ZBB-NEXT:    ret
785 ; RV64ZBB-LABEL: add_ugecmp_bad_i16_i8_cmp:
786 ; RV64ZBB:       # %bb.0:
787 ; RV64ZBB-NEXT:    zext.h a1, a1
788 ; RV64ZBB-NEXT:    addi a0, a0, 128
789 ; RV64ZBB-NEXT:    zext.h a0, a0
790 ; RV64ZBB-NEXT:    sltu a0, a0, a1
791 ; RV64ZBB-NEXT:    xori a0, a0, 1
792 ; RV64ZBB-NEXT:    ret
793   %tmp0 = add i16 %x, 128 ; 1U << (8-1)
794   %tmp1 = icmp uge i16 %tmp0, %y
795   ret i1 %tmp1
798 ; Second constant is not larger than the first one
799 define i1 @add_ugecmp_bad_i8_i16(i16 %x) nounwind {
800 ; RV32I-LABEL: add_ugecmp_bad_i8_i16:
801 ; RV32I:       # %bb.0:
802 ; RV32I-NEXT:    addi a0, a0, 128
803 ; RV32I-NEXT:    slli a0, a0, 16
804 ; RV32I-NEXT:    srli a0, a0, 16
805 ; RV32I-NEXT:    sltiu a0, a0, 128
806 ; RV32I-NEXT:    xori a0, a0, 1
807 ; RV32I-NEXT:    ret
809 ; RV64I-LABEL: add_ugecmp_bad_i8_i16:
810 ; RV64I:       # %bb.0:
811 ; RV64I-NEXT:    addi a0, a0, 128
812 ; RV64I-NEXT:    slli a0, a0, 48
813 ; RV64I-NEXT:    srli a0, a0, 48
814 ; RV64I-NEXT:    sltiu a0, a0, 128
815 ; RV64I-NEXT:    xori a0, a0, 1
816 ; RV64I-NEXT:    ret
818 ; RV32ZBB-LABEL: add_ugecmp_bad_i8_i16:
819 ; RV32ZBB:       # %bb.0:
820 ; RV32ZBB-NEXT:    addi a0, a0, 128
821 ; RV32ZBB-NEXT:    zext.h a0, a0
822 ; RV32ZBB-NEXT:    sltiu a0, a0, 128
823 ; RV32ZBB-NEXT:    xori a0, a0, 1
824 ; RV32ZBB-NEXT:    ret
826 ; RV64ZBB-LABEL: add_ugecmp_bad_i8_i16:
827 ; RV64ZBB:       # %bb.0:
828 ; RV64ZBB-NEXT:    addi a0, a0, 128
829 ; RV64ZBB-NEXT:    zext.h a0, a0
830 ; RV64ZBB-NEXT:    sltiu a0, a0, 128
831 ; RV64ZBB-NEXT:    xori a0, a0, 1
832 ; RV64ZBB-NEXT:    ret
833   %tmp0 = add i16 %x, 128 ; 1U << (8-1)
834   %tmp1 = icmp uge i16 %tmp0, 128 ; 1U << (8-1)
835   ret i1 %tmp1
838 ; First constant is not power of two
839 define i1 @add_ugecmp_bad_i16_i8_c0notpoweroftwo(i16 %x) nounwind {
840 ; RV32I-LABEL: add_ugecmp_bad_i16_i8_c0notpoweroftwo:
841 ; RV32I:       # %bb.0:
842 ; RV32I-NEXT:    addi a0, a0, 192
843 ; RV32I-NEXT:    slli a0, a0, 16
844 ; RV32I-NEXT:    srli a0, a0, 16
845 ; RV32I-NEXT:    sltiu a0, a0, 256
846 ; RV32I-NEXT:    xori a0, a0, 1
847 ; RV32I-NEXT:    ret
849 ; RV64I-LABEL: add_ugecmp_bad_i16_i8_c0notpoweroftwo:
850 ; RV64I:       # %bb.0:
851 ; RV64I-NEXT:    addi a0, a0, 192
852 ; RV64I-NEXT:    slli a0, a0, 48
853 ; RV64I-NEXT:    srli a0, a0, 48
854 ; RV64I-NEXT:    sltiu a0, a0, 256
855 ; RV64I-NEXT:    xori a0, a0, 1
856 ; RV64I-NEXT:    ret
858 ; RV32ZBB-LABEL: add_ugecmp_bad_i16_i8_c0notpoweroftwo:
859 ; RV32ZBB:       # %bb.0:
860 ; RV32ZBB-NEXT:    addi a0, a0, 192
861 ; RV32ZBB-NEXT:    zext.h a0, a0
862 ; RV32ZBB-NEXT:    sltiu a0, a0, 256
863 ; RV32ZBB-NEXT:    xori a0, a0, 1
864 ; RV32ZBB-NEXT:    ret
866 ; RV64ZBB-LABEL: add_ugecmp_bad_i16_i8_c0notpoweroftwo:
867 ; RV64ZBB:       # %bb.0:
868 ; RV64ZBB-NEXT:    addi a0, a0, 192
869 ; RV64ZBB-NEXT:    zext.h a0, a0
870 ; RV64ZBB-NEXT:    sltiu a0, a0, 256
871 ; RV64ZBB-NEXT:    xori a0, a0, 1
872 ; RV64ZBB-NEXT:    ret
873   %tmp0 = add i16 %x, 192 ; (1U << (8-1)) + (1U << (8-1-1))
874   %tmp1 = icmp uge i16 %tmp0, 256 ; 1U << 8
875   ret i1 %tmp1
878 ; Second constant is not power of two
879 define i1 @add_ugecmp_bad_i16_i8_c1notpoweroftwo(i16 %x) nounwind {
880 ; RV32I-LABEL: add_ugecmp_bad_i16_i8_c1notpoweroftwo:
881 ; RV32I:       # %bb.0:
882 ; RV32I-NEXT:    addi a0, a0, 128
883 ; RV32I-NEXT:    slli a0, a0, 16
884 ; RV32I-NEXT:    srli a0, a0, 16
885 ; RV32I-NEXT:    sltiu a0, a0, 768
886 ; RV32I-NEXT:    xori a0, a0, 1
887 ; RV32I-NEXT:    ret
889 ; RV64I-LABEL: add_ugecmp_bad_i16_i8_c1notpoweroftwo:
890 ; RV64I:       # %bb.0:
891 ; RV64I-NEXT:    addi a0, a0, 128
892 ; RV64I-NEXT:    slli a0, a0, 48
893 ; RV64I-NEXT:    srli a0, a0, 48
894 ; RV64I-NEXT:    sltiu a0, a0, 768
895 ; RV64I-NEXT:    xori a0, a0, 1
896 ; RV64I-NEXT:    ret
898 ; RV32ZBB-LABEL: add_ugecmp_bad_i16_i8_c1notpoweroftwo:
899 ; RV32ZBB:       # %bb.0:
900 ; RV32ZBB-NEXT:    addi a0, a0, 128
901 ; RV32ZBB-NEXT:    zext.h a0, a0
902 ; RV32ZBB-NEXT:    sltiu a0, a0, 768
903 ; RV32ZBB-NEXT:    xori a0, a0, 1
904 ; RV32ZBB-NEXT:    ret
906 ; RV64ZBB-LABEL: add_ugecmp_bad_i16_i8_c1notpoweroftwo:
907 ; RV64ZBB:       # %bb.0:
908 ; RV64ZBB-NEXT:    addi a0, a0, 128
909 ; RV64ZBB-NEXT:    zext.h a0, a0
910 ; RV64ZBB-NEXT:    sltiu a0, a0, 768
911 ; RV64ZBB-NEXT:    xori a0, a0, 1
912 ; RV64ZBB-NEXT:    ret
913   %tmp0 = add i16 %x, 128 ; 1U << (8-1)
914   %tmp1 = icmp uge i16 %tmp0, 768 ; (1U << 8)) + (1U << (8+1))
915   ret i1 %tmp1
918 ; Magic check fails, 64 << 1 != 256
919 define i1 @add_ugecmp_bad_i16_i8_magic(i16 %x) nounwind {
920 ; RV32I-LABEL: add_ugecmp_bad_i16_i8_magic:
921 ; RV32I:       # %bb.0:
922 ; RV32I-NEXT:    addi a0, a0, 64
923 ; RV32I-NEXT:    slli a0, a0, 16
924 ; RV32I-NEXT:    srli a0, a0, 16
925 ; RV32I-NEXT:    sltiu a0, a0, 256
926 ; RV32I-NEXT:    xori a0, a0, 1
927 ; RV32I-NEXT:    ret
929 ; RV64I-LABEL: add_ugecmp_bad_i16_i8_magic:
930 ; RV64I:       # %bb.0:
931 ; RV64I-NEXT:    addi a0, a0, 64
932 ; RV64I-NEXT:    slli a0, a0, 48
933 ; RV64I-NEXT:    srli a0, a0, 48
934 ; RV64I-NEXT:    sltiu a0, a0, 256
935 ; RV64I-NEXT:    xori a0, a0, 1
936 ; RV64I-NEXT:    ret
938 ; RV32ZBB-LABEL: add_ugecmp_bad_i16_i8_magic:
939 ; RV32ZBB:       # %bb.0:
940 ; RV32ZBB-NEXT:    addi a0, a0, 64
941 ; RV32ZBB-NEXT:    zext.h a0, a0
942 ; RV32ZBB-NEXT:    sltiu a0, a0, 256
943 ; RV32ZBB-NEXT:    xori a0, a0, 1
944 ; RV32ZBB-NEXT:    ret
946 ; RV64ZBB-LABEL: add_ugecmp_bad_i16_i8_magic:
947 ; RV64ZBB:       # %bb.0:
948 ; RV64ZBB-NEXT:    addi a0, a0, 64
949 ; RV64ZBB-NEXT:    zext.h a0, a0
950 ; RV64ZBB-NEXT:    sltiu a0, a0, 256
951 ; RV64ZBB-NEXT:    xori a0, a0, 1
952 ; RV64ZBB-NEXT:    ret
953   %tmp0 = add i16 %x, 64 ; 1U << (8-1-1)
954   %tmp1 = icmp uge i16 %tmp0, 256 ; 1U << 8
955   ret i1 %tmp1
958 ; Bad 'destination type'
959 define i1 @add_ugecmp_bad_i16_i4(i16 %x) nounwind {
960 ; RV32I-LABEL: add_ugecmp_bad_i16_i4:
961 ; RV32I:       # %bb.0:
962 ; RV32I-NEXT:    addi a0, a0, 8
963 ; RV32I-NEXT:    slli a0, a0, 16
964 ; RV32I-NEXT:    srli a0, a0, 16
965 ; RV32I-NEXT:    sltiu a0, a0, 16
966 ; RV32I-NEXT:    xori a0, a0, 1
967 ; RV32I-NEXT:    ret
969 ; RV64I-LABEL: add_ugecmp_bad_i16_i4:
970 ; RV64I:       # %bb.0:
971 ; RV64I-NEXT:    addi a0, a0, 8
972 ; RV64I-NEXT:    slli a0, a0, 48
973 ; RV64I-NEXT:    srli a0, a0, 48
974 ; RV64I-NEXT:    sltiu a0, a0, 16
975 ; RV64I-NEXT:    xori a0, a0, 1
976 ; RV64I-NEXT:    ret
978 ; RV32ZBB-LABEL: add_ugecmp_bad_i16_i4:
979 ; RV32ZBB:       # %bb.0:
980 ; RV32ZBB-NEXT:    addi a0, a0, 8
981 ; RV32ZBB-NEXT:    zext.h a0, a0
982 ; RV32ZBB-NEXT:    sltiu a0, a0, 16
983 ; RV32ZBB-NEXT:    xori a0, a0, 1
984 ; RV32ZBB-NEXT:    ret
986 ; RV64ZBB-LABEL: add_ugecmp_bad_i16_i4:
987 ; RV64ZBB:       # %bb.0:
988 ; RV64ZBB-NEXT:    addi a0, a0, 8
989 ; RV64ZBB-NEXT:    zext.h a0, a0
990 ; RV64ZBB-NEXT:    sltiu a0, a0, 16
991 ; RV64ZBB-NEXT:    xori a0, a0, 1
992 ; RV64ZBB-NEXT:    ret
993   %tmp0 = add i16 %x, 8 ; 1U << (4-1)
994   %tmp1 = icmp uge i16 %tmp0, 16 ; 1U << 4
995   ret i1 %tmp1
998 ; Bad storage type
999 define i1 @add_ugecmp_bad_i24_i8(i24 %x) nounwind {
1000 ; RV32-LABEL: add_ugecmp_bad_i24_i8:
1001 ; RV32:       # %bb.0:
1002 ; RV32-NEXT:    addi a0, a0, 128
1003 ; RV32-NEXT:    slli a0, a0, 8
1004 ; RV32-NEXT:    srli a0, a0, 8
1005 ; RV32-NEXT:    sltiu a0, a0, 256
1006 ; RV32-NEXT:    xori a0, a0, 1
1007 ; RV32-NEXT:    ret
1009 ; RV64-LABEL: add_ugecmp_bad_i24_i8:
1010 ; RV64:       # %bb.0:
1011 ; RV64-NEXT:    addi a0, a0, 128
1012 ; RV64-NEXT:    slli a0, a0, 40
1013 ; RV64-NEXT:    srli a0, a0, 40
1014 ; RV64-NEXT:    sltiu a0, a0, 256
1015 ; RV64-NEXT:    xori a0, a0, 1
1016 ; RV64-NEXT:    ret
1017   %tmp0 = add i24 %x, 128 ; 1U << (8-1)
1018   %tmp1 = icmp uge i24 %tmp0, 256 ; 1U << 8
1019   ret i1 %tmp1
1022 ; Slightly more canonical variant
1023 define i1 @add_ugtcmp_bad_i16_i8(i16 %x) nounwind {
1024 ; CHECK-LABEL: add_ugtcmp_bad_i16_i8:
1025 ; CHECK:       # %bb.0:
1026 ; CHECK-NEXT:    li a0, 0
1027 ; CHECK-NEXT:    ret
1028   %tmp0 = add i16 %x, 128 ; 1U << (8-1)
1029   %tmp1 = icmp ugt i16 %tmp0, -1 ; when we +1 it, it will wrap to 0
1030   ret i1 %tmp1