Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / CodeGen / RISCV / signed-truncation-check.ll
blobde36bcdb9106099a4545e040a56731f82a1ccc9d
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 equality-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 eq <- not canonical
15 ;   shl   + ashr + icmp eq
16 ;   add          + icmp uge/ugt
17 ;   add          + icmp ult/ule
18 ; However only the simplest form (with two shifts) gets lowered best.
20 ; ---------------------------------------------------------------------------- ;
21 ; shl + ashr + icmp eq
22 ; ---------------------------------------------------------------------------- ;
24 define i1 @shifts_eqcmp_i16_i8(i16 %x) nounwind {
25 ; RV32I-LABEL: shifts_eqcmp_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:    seqz a0, a0
35 ; RV32I-NEXT:    ret
37 ; RV64I-LABEL: shifts_eqcmp_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:    seqz a0, a0
47 ; RV64I-NEXT:    ret
49 ; RV32ZBB-LABEL: shifts_eqcmp_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:    seqz a0, a0
56 ; RV32ZBB-NEXT:    ret
58 ; RV64ZBB-LABEL: shifts_eqcmp_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:    seqz 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 eq i16 %tmp1, %x
69   ret i1 %tmp2
72 define i1 @shifts_eqcmp_i32_i16(i32 %x) nounwind {
73 ; RV32I-LABEL: shifts_eqcmp_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:    seqz a0, a0
79 ; RV32I-NEXT:    ret
81 ; RV64I-LABEL: shifts_eqcmp_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:    seqz a0, a0
88 ; RV64I-NEXT:    ret
90 ; RV32ZBB-LABEL: shifts_eqcmp_i32_i16:
91 ; RV32ZBB:       # %bb.0:
92 ; RV32ZBB-NEXT:    sext.h a1, a0
93 ; RV32ZBB-NEXT:    xor a0, a1, a0
94 ; RV32ZBB-NEXT:    seqz a0, a0
95 ; RV32ZBB-NEXT:    ret
97 ; RV64ZBB-LABEL: shifts_eqcmp_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:    seqz 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 eq i32 %tmp1, %x
107   ret i1 %tmp2
110 define i1 @shifts_eqcmp_i32_i8(i32 %x) nounwind {
111 ; RV32I-LABEL: shifts_eqcmp_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:    seqz a0, a0
117 ; RV32I-NEXT:    ret
119 ; RV64I-LABEL: shifts_eqcmp_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:    seqz a0, a0
126 ; RV64I-NEXT:    ret
128 ; RV32ZBB-LABEL: shifts_eqcmp_i32_i8:
129 ; RV32ZBB:       # %bb.0:
130 ; RV32ZBB-NEXT:    sext.b a1, a0
131 ; RV32ZBB-NEXT:    xor a0, a1, a0
132 ; RV32ZBB-NEXT:    seqz a0, a0
133 ; RV32ZBB-NEXT:    ret
135 ; RV64ZBB-LABEL: shifts_eqcmp_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:    seqz 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 eq i32 %tmp1, %x
145   ret i1 %tmp2
148 define i1 @shifts_eqcmp_i64_i32(i64 %x) nounwind {
149 ; RV32-LABEL: shifts_eqcmp_i64_i32:
150 ; RV32:       # %bb.0:
151 ; RV32-NEXT:    srai a0, a0, 31
152 ; RV32-NEXT:    xor a0, a0, a1
153 ; RV32-NEXT:    seqz a0, a0
154 ; RV32-NEXT:    ret
156 ; RV64-LABEL: shifts_eqcmp_i64_i32:
157 ; RV64:       # %bb.0:
158 ; RV64-NEXT:    sext.w a1, a0
159 ; RV64-NEXT:    xor a0, a1, a0
160 ; RV64-NEXT:    seqz 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 eq i64 %tmp1, %x
165   ret i1 %tmp2
168 define i1 @shifts_eqcmp_i64_i16(i64 %x) nounwind {
169 ; RV32I-LABEL: shifts_eqcmp_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:    seqz a0, a0
178 ; RV32I-NEXT:    ret
180 ; RV64I-LABEL: shifts_eqcmp_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:    seqz a0, a0
186 ; RV64I-NEXT:    ret
188 ; RV32ZBB-LABEL: shifts_eqcmp_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:    seqz a0, a0
196 ; RV32ZBB-NEXT:    ret
198 ; RV64ZBB-LABEL: shifts_eqcmp_i64_i16:
199 ; RV64ZBB:       # %bb.0:
200 ; RV64ZBB-NEXT:    sext.h a1, a0
201 ; RV64ZBB-NEXT:    xor a0, a1, a0
202 ; RV64ZBB-NEXT:    seqz 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 eq i64 %tmp1, %x
207   ret i1 %tmp2
210 define i1 @shifts_eqcmp_i64_i8(i64 %x) nounwind {
211 ; RV32I-LABEL: shifts_eqcmp_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:    seqz a0, a0
220 ; RV32I-NEXT:    ret
222 ; RV64I-LABEL: shifts_eqcmp_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:    seqz a0, a0
228 ; RV64I-NEXT:    ret
230 ; RV32ZBB-LABEL: shifts_eqcmp_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:    seqz a0, a0
238 ; RV32ZBB-NEXT:    ret
240 ; RV64ZBB-LABEL: shifts_eqcmp_i64_i8:
241 ; RV64ZBB:       # %bb.0:
242 ; RV64ZBB-NEXT:    sext.b a1, a0
243 ; RV64ZBB-NEXT:    xor a0, a1, a0
244 ; RV64ZBB-NEXT:    seqz 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 eq i64 %tmp1, %x
249   ret i1 %tmp2
252 ; ---------------------------------------------------------------------------- ;
253 ; add + icmp uge
254 ; ---------------------------------------------------------------------------- ;
256 define i1 @add_ugecmp_i16_i8(i16 %x) nounwind {
257 ; RV32I-LABEL: add_ugecmp_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:    xori a0, a0, 1
265 ; RV32I-NEXT:    ret
267 ; RV64I-LABEL: add_ugecmp_i16_i8:
268 ; RV64I:       # %bb.0:
269 ; RV64I-NEXT:    slli a0, a0, 48
270 ; RV64I-NEXT:    srli a0, a0, 48
271 ; RV64I-NEXT:    addi a0, a0, -128
272 ; RV64I-NEXT:    srli a0, a0, 8
273 ; RV64I-NEXT:    sltiu a0, a0, 255
274 ; RV64I-NEXT:    xori a0, a0, 1
275 ; RV64I-NEXT:    ret
277 ; RV32ZBB-LABEL: add_ugecmp_i16_i8:
278 ; RV32ZBB:       # %bb.0:
279 ; RV32ZBB-NEXT:    zext.h a0, a0
280 ; RV32ZBB-NEXT:    addi a0, a0, -128
281 ; RV32ZBB-NEXT:    srli a0, a0, 8
282 ; RV32ZBB-NEXT:    sltiu a0, a0, 255
283 ; RV32ZBB-NEXT:    xori a0, a0, 1
284 ; RV32ZBB-NEXT:    ret
286 ; RV64ZBB-LABEL: add_ugecmp_i16_i8:
287 ; RV64ZBB:       # %bb.0:
288 ; RV64ZBB-NEXT:    zext.h a0, a0
289 ; RV64ZBB-NEXT:    addi a0, a0, -128
290 ; RV64ZBB-NEXT:    srli a0, a0, 8
291 ; RV64ZBB-NEXT:    sltiu a0, a0, 255
292 ; RV64ZBB-NEXT:    xori a0, a0, 1
293 ; RV64ZBB-NEXT:    ret
294   %tmp0 = add i16 %x, -128 ; ~0U << (8-1)
295   %tmp1 = icmp uge i16 %tmp0, -256 ; ~0U << 8
296   ret i1 %tmp1
299 define i1 @add_ugecmp_i32_i16_i8(i16 %xx) nounwind {
300 ; RV32I-LABEL: add_ugecmp_i32_i16_i8:
301 ; RV32I:       # %bb.0:
302 ; RV32I-NEXT:    slli a0, a0, 16
303 ; RV32I-NEXT:    srli a0, a0, 16
304 ; RV32I-NEXT:    addi a0, a0, -128
305 ; RV32I-NEXT:    sltiu a0, a0, -256
306 ; RV32I-NEXT:    xori a0, a0, 1
307 ; RV32I-NEXT:    ret
309 ; RV64I-LABEL: add_ugecmp_i32_i16_i8:
310 ; RV64I:       # %bb.0:
311 ; RV64I-NEXT:    slli a0, a0, 48
312 ; RV64I-NEXT:    srli a0, a0, 48
313 ; RV64I-NEXT:    addi a0, a0, -128
314 ; RV64I-NEXT:    sltiu a0, a0, -256
315 ; RV64I-NEXT:    xori a0, a0, 1
316 ; RV64I-NEXT:    ret
318 ; RV32ZBB-LABEL: add_ugecmp_i32_i16_i8:
319 ; RV32ZBB:       # %bb.0:
320 ; RV32ZBB-NEXT:    zext.h a0, a0
321 ; RV32ZBB-NEXT:    addi a0, a0, -128
322 ; RV32ZBB-NEXT:    sltiu a0, a0, -256
323 ; RV32ZBB-NEXT:    xori a0, a0, 1
324 ; RV32ZBB-NEXT:    ret
326 ; RV64ZBB-LABEL: add_ugecmp_i32_i16_i8:
327 ; RV64ZBB:       # %bb.0:
328 ; RV64ZBB-NEXT:    zext.h a0, a0
329 ; RV64ZBB-NEXT:    addi a0, a0, -128
330 ; RV64ZBB-NEXT:    sltiu a0, a0, -256
331 ; RV64ZBB-NEXT:    xori a0, a0, 1
332 ; RV64ZBB-NEXT:    ret
333   %x = zext i16 %xx to i32
334   %tmp0 = add i32 %x, -128 ; ~0U << (8-1)
335   %tmp1 = icmp uge i32 %tmp0, -256 ; ~0U << 8
336   ret i1 %tmp1
339 define i1 @add_ugecmp_i32_i16(i32 %x) nounwind {
340 ; RV32I-LABEL: add_ugecmp_i32_i16:
341 ; RV32I:       # %bb.0:
342 ; RV32I-NEXT:    lui a1, 1048568
343 ; RV32I-NEXT:    add a0, a0, a1
344 ; RV32I-NEXT:    lui a1, 1048560
345 ; RV32I-NEXT:    addi a1, a1, -1
346 ; RV32I-NEXT:    sltu a0, a1, a0
347 ; RV32I-NEXT:    ret
349 ; RV64I-LABEL: add_ugecmp_i32_i16:
350 ; RV64I:       # %bb.0:
351 ; RV64I-NEXT:    lui a1, 1048568
352 ; RV64I-NEXT:    addw a0, a0, a1
353 ; RV64I-NEXT:    lui a1, 1048560
354 ; RV64I-NEXT:    addiw a1, a1, -1
355 ; RV64I-NEXT:    sltu a0, a1, a0
356 ; RV64I-NEXT:    ret
358 ; RV32ZBB-LABEL: add_ugecmp_i32_i16:
359 ; RV32ZBB:       # %bb.0:
360 ; RV32ZBB-NEXT:    sext.h a1, a0
361 ; RV32ZBB-NEXT:    xor a0, a1, a0
362 ; RV32ZBB-NEXT:    seqz a0, a0
363 ; RV32ZBB-NEXT:    ret
365 ; RV64ZBB-LABEL: add_ugecmp_i32_i16:
366 ; RV64ZBB:       # %bb.0:
367 ; RV64ZBB-NEXT:    sext.w a1, a0
368 ; RV64ZBB-NEXT:    sext.h a0, a0
369 ; RV64ZBB-NEXT:    xor a0, a0, a1
370 ; RV64ZBB-NEXT:    seqz a0, a0
371 ; RV64ZBB-NEXT:    ret
372   %tmp0 = add i32 %x, -32768 ; ~0U << (16-1)
373   %tmp1 = icmp uge i32 %tmp0, -65536 ; ~0U << 16
374   ret i1 %tmp1
377 define i1 @add_ugecmp_i32_i8(i32 %x) nounwind {
378 ; RV32-LABEL: add_ugecmp_i32_i8:
379 ; RV32:       # %bb.0:
380 ; RV32-NEXT:    addi a0, a0, -128
381 ; RV32-NEXT:    sltiu a0, a0, -256
382 ; RV32-NEXT:    xori a0, a0, 1
383 ; RV32-NEXT:    ret
385 ; RV64-LABEL: add_ugecmp_i32_i8:
386 ; RV64:       # %bb.0:
387 ; RV64-NEXT:    addiw a0, a0, -128
388 ; RV64-NEXT:    sltiu a0, a0, -256
389 ; RV64-NEXT:    xori a0, a0, 1
390 ; RV64-NEXT:    ret
391   %tmp0 = add i32 %x, -128 ; ~0U << (8-1)
392   %tmp1 = icmp uge i32 %tmp0, -256 ; ~0U << 8
393   ret i1 %tmp1
396 define i1 @add_ugecmp_i64_i32(i64 %x) nounwind {
397 ; RV32-LABEL: add_ugecmp_i64_i32:
398 ; RV32:       # %bb.0:
399 ; RV32-NEXT:    srai a0, a0, 31
400 ; RV32-NEXT:    xor a0, a0, a1
401 ; RV32-NEXT:    seqz a0, a0
402 ; RV32-NEXT:    ret
404 ; RV64-LABEL: add_ugecmp_i64_i32:
405 ; RV64:       # %bb.0:
406 ; RV64-NEXT:    sext.w a1, a0
407 ; RV64-NEXT:    xor a0, a1, a0
408 ; RV64-NEXT:    seqz a0, a0
409 ; RV64-NEXT:    ret
410   %tmp0 = add i64 %x, -2147483648 ; ~0U << (32-1)
411   %tmp1 = icmp uge i64 %tmp0, -4294967296 ; ~0U << 32
412   ret i1 %tmp1
415 define i1 @add_ugecmp_i64_i16(i64 %x) nounwind {
416 ; RV32I-LABEL: add_ugecmp_i64_i16:
417 ; RV32I:       # %bb.0:
418 ; RV32I-NEXT:    lui a2, 1048568
419 ; RV32I-NEXT:    add a2, a0, a2
420 ; RV32I-NEXT:    sltu a0, a2, a0
421 ; RV32I-NEXT:    add a0, a1, a0
422 ; RV32I-NEXT:    lui a1, 1048560
423 ; RV32I-NEXT:    addi a1, a1, -1
424 ; RV32I-NEXT:    sltu a1, a1, a2
425 ; RV32I-NEXT:    seqz a0, a0
426 ; RV32I-NEXT:    and a0, a0, a1
427 ; RV32I-NEXT:    ret
429 ; RV64I-LABEL: add_ugecmp_i64_i16:
430 ; RV64I:       # %bb.0:
431 ; RV64I-NEXT:    lui a1, 1048568
432 ; RV64I-NEXT:    add a0, a0, a1
433 ; RV64I-NEXT:    lui a1, 1048560
434 ; RV64I-NEXT:    addiw a1, a1, -1
435 ; RV64I-NEXT:    sltu a0, a1, a0
436 ; RV64I-NEXT:    ret
438 ; RV32ZBB-LABEL: add_ugecmp_i64_i16:
439 ; RV32ZBB:       # %bb.0:
440 ; RV32ZBB-NEXT:    sext.h a2, a0
441 ; RV32ZBB-NEXT:    xor a0, a2, a0
442 ; RV32ZBB-NEXT:    srai a2, a2, 31
443 ; RV32ZBB-NEXT:    xor a1, a2, a1
444 ; RV32ZBB-NEXT:    or a0, a0, a1
445 ; RV32ZBB-NEXT:    seqz a0, a0
446 ; RV32ZBB-NEXT:    ret
448 ; RV64ZBB-LABEL: add_ugecmp_i64_i16:
449 ; RV64ZBB:       # %bb.0:
450 ; RV64ZBB-NEXT:    sext.h a1, a0
451 ; RV64ZBB-NEXT:    xor a0, a1, a0
452 ; RV64ZBB-NEXT:    seqz a0, a0
453 ; RV64ZBB-NEXT:    ret
454   %tmp0 = add i64 %x, -32768 ; ~0U << (16-1)
455   %tmp1 = icmp uge i64 %tmp0, -65536 ; ~0U << 16
456   ret i1 %tmp1
459 define i1 @add_ugecmp_i64_i8(i64 %x) nounwind {
460 ; RV32I-LABEL: add_ugecmp_i64_i8:
461 ; RV32I:       # %bb.0:
462 ; RV32I-NEXT:    addi a2, a0, -128
463 ; RV32I-NEXT:    sltu a0, a2, a0
464 ; RV32I-NEXT:    add a0, a1, a0
465 ; RV32I-NEXT:    seqz a0, a0
466 ; RV32I-NEXT:    sltiu a1, a2, -256
467 ; RV32I-NEXT:    xori a1, a1, 1
468 ; RV32I-NEXT:    and a0, a0, a1
469 ; RV32I-NEXT:    ret
471 ; RV64-LABEL: add_ugecmp_i64_i8:
472 ; RV64:       # %bb.0:
473 ; RV64-NEXT:    addi a0, a0, -128
474 ; RV64-NEXT:    sltiu a0, a0, -256
475 ; RV64-NEXT:    xori a0, a0, 1
476 ; RV64-NEXT:    ret
478 ; RV32ZBB-LABEL: add_ugecmp_i64_i8:
479 ; RV32ZBB:       # %bb.0:
480 ; RV32ZBB-NEXT:    sext.b a2, a0
481 ; RV32ZBB-NEXT:    xor a0, a2, a0
482 ; RV32ZBB-NEXT:    srai a2, a2, 31
483 ; RV32ZBB-NEXT:    xor a1, a2, a1
484 ; RV32ZBB-NEXT:    or a0, a0, a1
485 ; RV32ZBB-NEXT:    seqz a0, a0
486 ; RV32ZBB-NEXT:    ret
487   %tmp0 = add i64 %x, -128 ; ~0U << (8-1)
488   %tmp1 = icmp uge i64 %tmp0, -256 ; ~0U << 8
489   ret i1 %tmp1
492 ; Slightly more canonical variant
493 define i1 @add_ugtcmp_i16_i8(i16 %x) nounwind {
494 ; RV32I-LABEL: add_ugtcmp_i16_i8:
495 ; RV32I:       # %bb.0:
496 ; RV32I-NEXT:    slli a0, a0, 16
497 ; RV32I-NEXT:    srli a0, a0, 16
498 ; RV32I-NEXT:    addi a0, a0, -128
499 ; RV32I-NEXT:    srli a0, a0, 8
500 ; RV32I-NEXT:    sltiu a0, a0, 255
501 ; RV32I-NEXT:    xori a0, a0, 1
502 ; RV32I-NEXT:    ret
504 ; RV64I-LABEL: add_ugtcmp_i16_i8:
505 ; RV64I:       # %bb.0:
506 ; RV64I-NEXT:    slli a0, a0, 48
507 ; RV64I-NEXT:    srli a0, a0, 48
508 ; RV64I-NEXT:    addi a0, a0, -128
509 ; RV64I-NEXT:    srli a0, a0, 8
510 ; RV64I-NEXT:    sltiu a0, a0, 255
511 ; RV64I-NEXT:    xori a0, a0, 1
512 ; RV64I-NEXT:    ret
514 ; RV32ZBB-LABEL: add_ugtcmp_i16_i8:
515 ; RV32ZBB:       # %bb.0:
516 ; RV32ZBB-NEXT:    zext.h a0, a0
517 ; RV32ZBB-NEXT:    addi a0, a0, -128
518 ; RV32ZBB-NEXT:    srli a0, a0, 8
519 ; RV32ZBB-NEXT:    sltiu a0, a0, 255
520 ; RV32ZBB-NEXT:    xori a0, a0, 1
521 ; RV32ZBB-NEXT:    ret
523 ; RV64ZBB-LABEL: add_ugtcmp_i16_i8:
524 ; RV64ZBB:       # %bb.0:
525 ; RV64ZBB-NEXT:    zext.h a0, a0
526 ; RV64ZBB-NEXT:    addi a0, a0, -128
527 ; RV64ZBB-NEXT:    srli a0, a0, 8
528 ; RV64ZBB-NEXT:    sltiu a0, a0, 255
529 ; RV64ZBB-NEXT:    xori a0, a0, 1
530 ; RV64ZBB-NEXT:    ret
531   %tmp0 = add i16 %x, -128 ; ~0U << (8-1)
532   %tmp1 = icmp ugt i16 %tmp0, -257 ; ~0U << 8 - 1
533   ret i1 %tmp1
536 ; ---------------------------------------------------------------------------- ;
537 ; add + icmp ult
538 ; ---------------------------------------------------------------------------- ;
540 define i1 @add_ultcmp_i16_i8(i16 %x) nounwind {
541 ; RV32I-LABEL: add_ultcmp_i16_i8:
542 ; RV32I:       # %bb.0:
543 ; RV32I-NEXT:    addi a0, a0, 128
544 ; RV32I-NEXT:    slli a0, a0, 16
545 ; RV32I-NEXT:    srli a0, a0, 16
546 ; RV32I-NEXT:    sltiu a0, a0, 256
547 ; RV32I-NEXT:    ret
549 ; RV64I-LABEL: add_ultcmp_i16_i8:
550 ; RV64I:       # %bb.0:
551 ; RV64I-NEXT:    addi a0, a0, 128
552 ; RV64I-NEXT:    slli a0, a0, 48
553 ; RV64I-NEXT:    srli a0, a0, 48
554 ; RV64I-NEXT:    sltiu a0, a0, 256
555 ; RV64I-NEXT:    ret
557 ; RV32ZBB-LABEL: add_ultcmp_i16_i8:
558 ; RV32ZBB:       # %bb.0:
559 ; RV32ZBB-NEXT:    addi a0, a0, 128
560 ; RV32ZBB-NEXT:    zext.h a0, a0
561 ; RV32ZBB-NEXT:    sltiu a0, a0, 256
562 ; RV32ZBB-NEXT:    ret
564 ; RV64ZBB-LABEL: add_ultcmp_i16_i8:
565 ; RV64ZBB:       # %bb.0:
566 ; RV64ZBB-NEXT:    addi a0, a0, 128
567 ; RV64ZBB-NEXT:    zext.h a0, a0
568 ; RV64ZBB-NEXT:    sltiu a0, a0, 256
569 ; RV64ZBB-NEXT:    ret
570   %tmp0 = add i16 %x, 128 ; 1U << (8-1)
571   %tmp1 = icmp ult i16 %tmp0, 256 ; 1U << 8
572   ret i1 %tmp1
575 define i1 @add_ultcmp_i32_i16(i32 %x) nounwind {
576 ; RV32I-LABEL: add_ultcmp_i32_i16:
577 ; RV32I:       # %bb.0:
578 ; RV32I-NEXT:    lui a1, 8
579 ; RV32I-NEXT:    add a0, a0, a1
580 ; RV32I-NEXT:    srli a0, a0, 16
581 ; RV32I-NEXT:    seqz a0, a0
582 ; RV32I-NEXT:    ret
584 ; RV64I-LABEL: add_ultcmp_i32_i16:
585 ; RV64I:       # %bb.0:
586 ; RV64I-NEXT:    lui a1, 8
587 ; RV64I-NEXT:    add a0, a0, a1
588 ; RV64I-NEXT:    srliw a0, a0, 16
589 ; RV64I-NEXT:    seqz a0, a0
590 ; RV64I-NEXT:    ret
592 ; RV32ZBB-LABEL: add_ultcmp_i32_i16:
593 ; RV32ZBB:       # %bb.0:
594 ; RV32ZBB-NEXT:    sext.h a1, a0
595 ; RV32ZBB-NEXT:    xor a0, a1, a0
596 ; RV32ZBB-NEXT:    seqz a0, a0
597 ; RV32ZBB-NEXT:    ret
599 ; RV64ZBB-LABEL: add_ultcmp_i32_i16:
600 ; RV64ZBB:       # %bb.0:
601 ; RV64ZBB-NEXT:    sext.w a1, a0
602 ; RV64ZBB-NEXT:    sext.h a0, a0
603 ; RV64ZBB-NEXT:    xor a0, a0, a1
604 ; RV64ZBB-NEXT:    seqz a0, a0
605 ; RV64ZBB-NEXT:    ret
606   %tmp0 = add i32 %x, 32768 ; 1U << (16-1)
607   %tmp1 = icmp ult i32 %tmp0, 65536 ; 1U << 16
608   ret i1 %tmp1
611 define i1 @add_ultcmp_i32_i8(i32 %x) nounwind {
612 ; RV32-LABEL: add_ultcmp_i32_i8:
613 ; RV32:       # %bb.0:
614 ; RV32-NEXT:    addi a0, a0, 128
615 ; RV32-NEXT:    sltiu a0, a0, 256
616 ; RV32-NEXT:    ret
618 ; RV64-LABEL: add_ultcmp_i32_i8:
619 ; RV64:       # %bb.0:
620 ; RV64-NEXT:    addiw a0, a0, 128
621 ; RV64-NEXT:    sltiu a0, a0, 256
622 ; RV64-NEXT:    ret
623   %tmp0 = add i32 %x, 128 ; 1U << (8-1)
624   %tmp1 = icmp ult i32 %tmp0, 256 ; 1U << 8
625   ret i1 %tmp1
628 define i1 @add_ultcmp_i64_i32(i64 %x) nounwind {
629 ; RV32-LABEL: add_ultcmp_i64_i32:
630 ; RV32:       # %bb.0:
631 ; RV32-NEXT:    srai a0, a0, 31
632 ; RV32-NEXT:    xor a0, a0, a1
633 ; RV32-NEXT:    seqz a0, a0
634 ; RV32-NEXT:    ret
636 ; RV64-LABEL: add_ultcmp_i64_i32:
637 ; RV64:       # %bb.0:
638 ; RV64-NEXT:    sext.w a1, a0
639 ; RV64-NEXT:    xor a0, a1, a0
640 ; RV64-NEXT:    seqz a0, a0
641 ; RV64-NEXT:    ret
642   %tmp0 = add i64 %x, 2147483648 ; 1U << (32-1)
643   %tmp1 = icmp ult i64 %tmp0, 4294967296 ; 1U << 32
644   ret i1 %tmp1
647 define i1 @add_ultcmp_i64_i16(i64 %x) nounwind {
648 ; RV32I-LABEL: add_ultcmp_i64_i16:
649 ; RV32I:       # %bb.0:
650 ; RV32I-NEXT:    lui a2, 8
651 ; RV32I-NEXT:    add a2, a0, a2
652 ; RV32I-NEXT:    sltu a0, a2, a0
653 ; RV32I-NEXT:    add a0, a1, a0
654 ; RV32I-NEXT:    srli a2, a2, 16
655 ; RV32I-NEXT:    or a0, a0, a2
656 ; RV32I-NEXT:    seqz a0, a0
657 ; RV32I-NEXT:    ret
659 ; RV64I-LABEL: add_ultcmp_i64_i16:
660 ; RV64I:       # %bb.0:
661 ; RV64I-NEXT:    lui a1, 8
662 ; RV64I-NEXT:    add a0, a0, a1
663 ; RV64I-NEXT:    srli a0, a0, 16
664 ; RV64I-NEXT:    seqz a0, a0
665 ; RV64I-NEXT:    ret
667 ; RV32ZBB-LABEL: add_ultcmp_i64_i16:
668 ; RV32ZBB:       # %bb.0:
669 ; RV32ZBB-NEXT:    sext.h a2, a0
670 ; RV32ZBB-NEXT:    xor a0, a2, a0
671 ; RV32ZBB-NEXT:    srai a2, a2, 31
672 ; RV32ZBB-NEXT:    xor a1, a2, a1
673 ; RV32ZBB-NEXT:    or a0, a0, a1
674 ; RV32ZBB-NEXT:    seqz a0, a0
675 ; RV32ZBB-NEXT:    ret
677 ; RV64ZBB-LABEL: add_ultcmp_i64_i16:
678 ; RV64ZBB:       # %bb.0:
679 ; RV64ZBB-NEXT:    sext.h a1, a0
680 ; RV64ZBB-NEXT:    xor a0, a1, a0
681 ; RV64ZBB-NEXT:    seqz a0, a0
682 ; RV64ZBB-NEXT:    ret
683   %tmp0 = add i64 %x, 32768 ; 1U << (16-1)
684   %tmp1 = icmp ult i64 %tmp0, 65536 ; 1U << 16
685   ret i1 %tmp1
688 define i1 @add_ultcmp_i64_i8(i64 %x) nounwind {
689 ; RV32I-LABEL: add_ultcmp_i64_i8:
690 ; RV32I:       # %bb.0:
691 ; RV32I-NEXT:    addi a2, a0, 128
692 ; RV32I-NEXT:    sltu a0, a2, a0
693 ; RV32I-NEXT:    add a0, a1, a0
694 ; RV32I-NEXT:    seqz a0, a0
695 ; RV32I-NEXT:    sltiu a1, a2, 256
696 ; RV32I-NEXT:    and a0, a0, a1
697 ; RV32I-NEXT:    ret
699 ; RV64-LABEL: add_ultcmp_i64_i8:
700 ; RV64:       # %bb.0:
701 ; RV64-NEXT:    addi a0, a0, 128
702 ; RV64-NEXT:    sltiu a0, a0, 256
703 ; RV64-NEXT:    ret
705 ; RV32ZBB-LABEL: add_ultcmp_i64_i8:
706 ; RV32ZBB:       # %bb.0:
707 ; RV32ZBB-NEXT:    sext.b a2, a0
708 ; RV32ZBB-NEXT:    xor a0, a2, a0
709 ; RV32ZBB-NEXT:    srai a2, a2, 31
710 ; RV32ZBB-NEXT:    xor a1, a2, a1
711 ; RV32ZBB-NEXT:    or a0, a0, a1
712 ; RV32ZBB-NEXT:    seqz a0, a0
713 ; RV32ZBB-NEXT:    ret
714   %tmp0 = add i64 %x, 128 ; 1U << (8-1)
715   %tmp1 = icmp ult i64 %tmp0, 256 ; 1U << 8
716   ret i1 %tmp1
719 ; Slightly more canonical variant
720 define i1 @add_ulecmp_i16_i8(i16 %x) nounwind {
721 ; RV32I-LABEL: add_ulecmp_i16_i8:
722 ; RV32I:       # %bb.0:
723 ; RV32I-NEXT:    addi a0, a0, 128
724 ; RV32I-NEXT:    slli a0, a0, 16
725 ; RV32I-NEXT:    srli a0, a0, 16
726 ; RV32I-NEXT:    sltiu a0, a0, 256
727 ; RV32I-NEXT:    ret
729 ; RV64I-LABEL: add_ulecmp_i16_i8:
730 ; RV64I:       # %bb.0:
731 ; RV64I-NEXT:    addi a0, a0, 128
732 ; RV64I-NEXT:    slli a0, a0, 48
733 ; RV64I-NEXT:    srli a0, a0, 48
734 ; RV64I-NEXT:    sltiu a0, a0, 256
735 ; RV64I-NEXT:    ret
737 ; RV32ZBB-LABEL: add_ulecmp_i16_i8:
738 ; RV32ZBB:       # %bb.0:
739 ; RV32ZBB-NEXT:    addi a0, a0, 128
740 ; RV32ZBB-NEXT:    zext.h a0, a0
741 ; RV32ZBB-NEXT:    sltiu a0, a0, 256
742 ; RV32ZBB-NEXT:    ret
744 ; RV64ZBB-LABEL: add_ulecmp_i16_i8:
745 ; RV64ZBB:       # %bb.0:
746 ; RV64ZBB-NEXT:    addi a0, a0, 128
747 ; RV64ZBB-NEXT:    zext.h a0, a0
748 ; RV64ZBB-NEXT:    sltiu a0, a0, 256
749 ; RV64ZBB-NEXT:    ret
750   %tmp0 = add i16 %x, 128 ; 1U << (8-1)
751   %tmp1 = icmp ule i16 %tmp0, 255 ; (1U << 8) - 1
752   ret i1 %tmp1
755 ; Negative tests
756 ; ---------------------------------------------------------------------------- ;
758 ; Adding not a constant
759 define i1 @add_ultcmp_bad_i16_i8_add(i16 %x, i16 %y) nounwind {
760 ; RV32I-LABEL: add_ultcmp_bad_i16_i8_add:
761 ; RV32I:       # %bb.0:
762 ; RV32I-NEXT:    add a0, a0, a1
763 ; RV32I-NEXT:    slli a0, a0, 16
764 ; RV32I-NEXT:    srli a0, a0, 16
765 ; RV32I-NEXT:    sltiu a0, a0, 256
766 ; RV32I-NEXT:    ret
768 ; RV64I-LABEL: add_ultcmp_bad_i16_i8_add:
769 ; RV64I:       # %bb.0:
770 ; RV64I-NEXT:    add a0, a0, a1
771 ; RV64I-NEXT:    slli a0, a0, 48
772 ; RV64I-NEXT:    srli a0, a0, 48
773 ; RV64I-NEXT:    sltiu a0, a0, 256
774 ; RV64I-NEXT:    ret
776 ; RV32ZBB-LABEL: add_ultcmp_bad_i16_i8_add:
777 ; RV32ZBB:       # %bb.0:
778 ; RV32ZBB-NEXT:    add a0, a0, a1
779 ; RV32ZBB-NEXT:    zext.h a0, a0
780 ; RV32ZBB-NEXT:    sltiu a0, a0, 256
781 ; RV32ZBB-NEXT:    ret
783 ; RV64ZBB-LABEL: add_ultcmp_bad_i16_i8_add:
784 ; RV64ZBB:       # %bb.0:
785 ; RV64ZBB-NEXT:    add a0, a0, a1
786 ; RV64ZBB-NEXT:    zext.h a0, a0
787 ; RV64ZBB-NEXT:    sltiu a0, a0, 256
788 ; RV64ZBB-NEXT:    ret
789   %tmp0 = add i16 %x, %y
790   %tmp1 = icmp ult i16 %tmp0, 256 ; 1U << 8
791   ret i1 %tmp1
794 ; Comparing not with a constant
795 define i1 @add_ultcmp_bad_i16_i8_cmp(i16 %x, i16 %y) nounwind {
796 ; RV32I-LABEL: add_ultcmp_bad_i16_i8_cmp:
797 ; RV32I:       # %bb.0:
798 ; RV32I-NEXT:    lui a2, 16
799 ; RV32I-NEXT:    addi a2, a2, -1
800 ; RV32I-NEXT:    and a1, a1, a2
801 ; RV32I-NEXT:    addi a0, a0, 128
802 ; RV32I-NEXT:    and a0, a0, a2
803 ; RV32I-NEXT:    sltu a0, a0, a1
804 ; RV32I-NEXT:    ret
806 ; RV64I-LABEL: add_ultcmp_bad_i16_i8_cmp:
807 ; RV64I:       # %bb.0:
808 ; RV64I-NEXT:    lui a2, 16
809 ; RV64I-NEXT:    addiw a2, a2, -1
810 ; RV64I-NEXT:    and a1, a1, a2
811 ; RV64I-NEXT:    addi a0, a0, 128
812 ; RV64I-NEXT:    and a0, a0, a2
813 ; RV64I-NEXT:    sltu a0, a0, a1
814 ; RV64I-NEXT:    ret
816 ; RV32ZBB-LABEL: add_ultcmp_bad_i16_i8_cmp:
817 ; RV32ZBB:       # %bb.0:
818 ; RV32ZBB-NEXT:    zext.h a1, a1
819 ; RV32ZBB-NEXT:    addi a0, a0, 128
820 ; RV32ZBB-NEXT:    zext.h a0, a0
821 ; RV32ZBB-NEXT:    sltu a0, a0, a1
822 ; RV32ZBB-NEXT:    ret
824 ; RV64ZBB-LABEL: add_ultcmp_bad_i16_i8_cmp:
825 ; RV64ZBB:       # %bb.0:
826 ; RV64ZBB-NEXT:    zext.h a1, a1
827 ; RV64ZBB-NEXT:    addi a0, a0, 128
828 ; RV64ZBB-NEXT:    zext.h a0, a0
829 ; RV64ZBB-NEXT:    sltu a0, a0, a1
830 ; RV64ZBB-NEXT:    ret
831   %tmp0 = add i16 %x, 128 ; 1U << (8-1)
832   %tmp1 = icmp ult i16 %tmp0, %y
833   ret i1 %tmp1
836 ; Second constant is not larger than the first one
837 define i1 @add_ultcmp_bad_i8_i16(i16 %x) nounwind {
838 ; RV32I-LABEL: add_ultcmp_bad_i8_i16:
839 ; RV32I:       # %bb.0:
840 ; RV32I-NEXT:    addi a0, a0, 128
841 ; RV32I-NEXT:    slli a0, a0, 16
842 ; RV32I-NEXT:    srli a0, a0, 16
843 ; RV32I-NEXT:    sltiu a0, a0, 128
844 ; RV32I-NEXT:    ret
846 ; RV64I-LABEL: add_ultcmp_bad_i8_i16:
847 ; RV64I:       # %bb.0:
848 ; RV64I-NEXT:    addi a0, a0, 128
849 ; RV64I-NEXT:    slli a0, a0, 48
850 ; RV64I-NEXT:    srli a0, a0, 48
851 ; RV64I-NEXT:    sltiu a0, a0, 128
852 ; RV64I-NEXT:    ret
854 ; RV32ZBB-LABEL: add_ultcmp_bad_i8_i16:
855 ; RV32ZBB:       # %bb.0:
856 ; RV32ZBB-NEXT:    addi a0, a0, 128
857 ; RV32ZBB-NEXT:    zext.h a0, a0
858 ; RV32ZBB-NEXT:    sltiu a0, a0, 128
859 ; RV32ZBB-NEXT:    ret
861 ; RV64ZBB-LABEL: add_ultcmp_bad_i8_i16:
862 ; RV64ZBB:       # %bb.0:
863 ; RV64ZBB-NEXT:    addi a0, a0, 128
864 ; RV64ZBB-NEXT:    zext.h a0, a0
865 ; RV64ZBB-NEXT:    sltiu a0, a0, 128
866 ; RV64ZBB-NEXT:    ret
867   %tmp0 = add i16 %x, 128 ; 1U << (8-1)
868   %tmp1 = icmp ult i16 %tmp0, 128 ; 1U << (8-1)
869   ret i1 %tmp1
872 ; First constant is not power of two
873 define i1 @add_ultcmp_bad_i16_i8_c0notpoweroftwo(i16 %x) nounwind {
874 ; RV32I-LABEL: add_ultcmp_bad_i16_i8_c0notpoweroftwo:
875 ; RV32I:       # %bb.0:
876 ; RV32I-NEXT:    addi a0, a0, 192
877 ; RV32I-NEXT:    slli a0, a0, 16
878 ; RV32I-NEXT:    srli a0, a0, 16
879 ; RV32I-NEXT:    sltiu a0, a0, 256
880 ; RV32I-NEXT:    ret
882 ; RV64I-LABEL: add_ultcmp_bad_i16_i8_c0notpoweroftwo:
883 ; RV64I:       # %bb.0:
884 ; RV64I-NEXT:    addi a0, a0, 192
885 ; RV64I-NEXT:    slli a0, a0, 48
886 ; RV64I-NEXT:    srli a0, a0, 48
887 ; RV64I-NEXT:    sltiu a0, a0, 256
888 ; RV64I-NEXT:    ret
890 ; RV32ZBB-LABEL: add_ultcmp_bad_i16_i8_c0notpoweroftwo:
891 ; RV32ZBB:       # %bb.0:
892 ; RV32ZBB-NEXT:    addi a0, a0, 192
893 ; RV32ZBB-NEXT:    zext.h a0, a0
894 ; RV32ZBB-NEXT:    sltiu a0, a0, 256
895 ; RV32ZBB-NEXT:    ret
897 ; RV64ZBB-LABEL: add_ultcmp_bad_i16_i8_c0notpoweroftwo:
898 ; RV64ZBB:       # %bb.0:
899 ; RV64ZBB-NEXT:    addi a0, a0, 192
900 ; RV64ZBB-NEXT:    zext.h a0, a0
901 ; RV64ZBB-NEXT:    sltiu a0, a0, 256
902 ; RV64ZBB-NEXT:    ret
903   %tmp0 = add i16 %x, 192 ; (1U << (8-1)) + (1U << (8-1-1))
904   %tmp1 = icmp ult i16 %tmp0, 256 ; 1U << 8
905   ret i1 %tmp1
908 ; Second constant is not power of two
909 define i1 @add_ultcmp_bad_i16_i8_c1notpoweroftwo(i16 %x) nounwind {
910 ; RV32I-LABEL: add_ultcmp_bad_i16_i8_c1notpoweroftwo:
911 ; RV32I:       # %bb.0:
912 ; RV32I-NEXT:    addi a0, a0, 128
913 ; RV32I-NEXT:    slli a0, a0, 16
914 ; RV32I-NEXT:    srli a0, a0, 16
915 ; RV32I-NEXT:    sltiu a0, a0, 768
916 ; RV32I-NEXT:    ret
918 ; RV64I-LABEL: add_ultcmp_bad_i16_i8_c1notpoweroftwo:
919 ; RV64I:       # %bb.0:
920 ; RV64I-NEXT:    addi a0, a0, 128
921 ; RV64I-NEXT:    slli a0, a0, 48
922 ; RV64I-NEXT:    srli a0, a0, 48
923 ; RV64I-NEXT:    sltiu a0, a0, 768
924 ; RV64I-NEXT:    ret
926 ; RV32ZBB-LABEL: add_ultcmp_bad_i16_i8_c1notpoweroftwo:
927 ; RV32ZBB:       # %bb.0:
928 ; RV32ZBB-NEXT:    addi a0, a0, 128
929 ; RV32ZBB-NEXT:    zext.h a0, a0
930 ; RV32ZBB-NEXT:    sltiu a0, a0, 768
931 ; RV32ZBB-NEXT:    ret
933 ; RV64ZBB-LABEL: add_ultcmp_bad_i16_i8_c1notpoweroftwo:
934 ; RV64ZBB:       # %bb.0:
935 ; RV64ZBB-NEXT:    addi a0, a0, 128
936 ; RV64ZBB-NEXT:    zext.h a0, a0
937 ; RV64ZBB-NEXT:    sltiu a0, a0, 768
938 ; RV64ZBB-NEXT:    ret
939   %tmp0 = add i16 %x, 128 ; 1U << (8-1)
940   %tmp1 = icmp ult i16 %tmp0, 768 ; (1U << 8)) + (1U << (8+1))
941   ret i1 %tmp1
944 ; Magic check fails, 64 << 1 != 256
945 define i1 @add_ultcmp_bad_i16_i8_magic(i16 %x) nounwind {
946 ; RV32I-LABEL: add_ultcmp_bad_i16_i8_magic:
947 ; RV32I:       # %bb.0:
948 ; RV32I-NEXT:    addi a0, a0, 64
949 ; RV32I-NEXT:    slli a0, a0, 16
950 ; RV32I-NEXT:    srli a0, a0, 16
951 ; RV32I-NEXT:    sltiu a0, a0, 256
952 ; RV32I-NEXT:    ret
954 ; RV64I-LABEL: add_ultcmp_bad_i16_i8_magic:
955 ; RV64I:       # %bb.0:
956 ; RV64I-NEXT:    addi a0, a0, 64
957 ; RV64I-NEXT:    slli a0, a0, 48
958 ; RV64I-NEXT:    srli a0, a0, 48
959 ; RV64I-NEXT:    sltiu a0, a0, 256
960 ; RV64I-NEXT:    ret
962 ; RV32ZBB-LABEL: add_ultcmp_bad_i16_i8_magic:
963 ; RV32ZBB:       # %bb.0:
964 ; RV32ZBB-NEXT:    addi a0, a0, 64
965 ; RV32ZBB-NEXT:    zext.h a0, a0
966 ; RV32ZBB-NEXT:    sltiu a0, a0, 256
967 ; RV32ZBB-NEXT:    ret
969 ; RV64ZBB-LABEL: add_ultcmp_bad_i16_i8_magic:
970 ; RV64ZBB:       # %bb.0:
971 ; RV64ZBB-NEXT:    addi a0, a0, 64
972 ; RV64ZBB-NEXT:    zext.h a0, a0
973 ; RV64ZBB-NEXT:    sltiu a0, a0, 256
974 ; RV64ZBB-NEXT:    ret
975   %tmp0 = add i16 %x, 64 ; 1U << (8-1-1)
976   %tmp1 = icmp ult i16 %tmp0, 256 ; 1U << 8
977   ret i1 %tmp1
980 ; Bad 'destination type'
981 define i1 @add_ultcmp_bad_i16_i4(i16 %x) nounwind {
982 ; RV32I-LABEL: add_ultcmp_bad_i16_i4:
983 ; RV32I:       # %bb.0:
984 ; RV32I-NEXT:    addi a0, a0, 8
985 ; RV32I-NEXT:    slli a0, a0, 16
986 ; RV32I-NEXT:    srli a0, a0, 16
987 ; RV32I-NEXT:    sltiu a0, a0, 16
988 ; RV32I-NEXT:    ret
990 ; RV64I-LABEL: add_ultcmp_bad_i16_i4:
991 ; RV64I:       # %bb.0:
992 ; RV64I-NEXT:    addi a0, a0, 8
993 ; RV64I-NEXT:    slli a0, a0, 48
994 ; RV64I-NEXT:    srli a0, a0, 48
995 ; RV64I-NEXT:    sltiu a0, a0, 16
996 ; RV64I-NEXT:    ret
998 ; RV32ZBB-LABEL: add_ultcmp_bad_i16_i4:
999 ; RV32ZBB:       # %bb.0:
1000 ; RV32ZBB-NEXT:    addi a0, a0, 8
1001 ; RV32ZBB-NEXT:    zext.h a0, a0
1002 ; RV32ZBB-NEXT:    sltiu a0, a0, 16
1003 ; RV32ZBB-NEXT:    ret
1005 ; RV64ZBB-LABEL: add_ultcmp_bad_i16_i4:
1006 ; RV64ZBB:       # %bb.0:
1007 ; RV64ZBB-NEXT:    addi a0, a0, 8
1008 ; RV64ZBB-NEXT:    zext.h a0, a0
1009 ; RV64ZBB-NEXT:    sltiu a0, a0, 16
1010 ; RV64ZBB-NEXT:    ret
1011   %tmp0 = add i16 %x, 8 ; 1U << (4-1)
1012   %tmp1 = icmp ult i16 %tmp0, 16 ; 1U << 4
1013   ret i1 %tmp1
1016 ; Bad storage type
1017 define i1 @add_ultcmp_bad_i24_i8(i24 %x) nounwind {
1018 ; RV32-LABEL: add_ultcmp_bad_i24_i8:
1019 ; RV32:       # %bb.0:
1020 ; RV32-NEXT:    addi a0, a0, 128
1021 ; RV32-NEXT:    slli a0, a0, 8
1022 ; RV32-NEXT:    srli a0, a0, 8
1023 ; RV32-NEXT:    sltiu a0, a0, 256
1024 ; RV32-NEXT:    ret
1026 ; RV64-LABEL: add_ultcmp_bad_i24_i8:
1027 ; RV64:       # %bb.0:
1028 ; RV64-NEXT:    addi a0, a0, 128
1029 ; RV64-NEXT:    slli a0, a0, 40
1030 ; RV64-NEXT:    srli a0, a0, 40
1031 ; RV64-NEXT:    sltiu a0, a0, 256
1032 ; RV64-NEXT:    ret
1033   %tmp0 = add i24 %x, 128 ; 1U << (8-1)
1034   %tmp1 = icmp ult i24 %tmp0, 256 ; 1U << 8
1035   ret i1 %tmp1
1038 define i1 @add_ulecmp_bad_i16_i8(i16 %x) nounwind {
1039 ; CHECK-LABEL: add_ulecmp_bad_i16_i8:
1040 ; CHECK:       # %bb.0:
1041 ; CHECK-NEXT:    li a0, 1
1042 ; CHECK-NEXT:    ret
1043   %tmp0 = add i16 %x, 128 ; 1U << (8-1)
1044   %tmp1 = icmp ule i16 %tmp0, -1 ; when we +1 it, it will wrap to 0
1045   ret i1 %tmp1