Re-land [openmp] Fix warnings when building on Windows with latest MSVC or Clang...
[llvm-project.git] / llvm / test / CodeGen / RISCV / signed-truncation-check.ll
blob0860853ae9c0af9e8e30c73ea1d7b04b1007933a
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 ; RV32-LABEL: add_ugecmp_i16_i8:
258 ; RV32:       # %bb.0:
259 ; RV32-NEXT:    addi a0, a0, -128
260 ; RV32-NEXT:    slli a0, a0, 16
261 ; RV32-NEXT:    srli a0, a0, 24
262 ; RV32-NEXT:    sltiu a0, a0, 255
263 ; RV32-NEXT:    xori a0, a0, 1
264 ; RV32-NEXT:    ret
266 ; RV64-LABEL: add_ugecmp_i16_i8:
267 ; RV64:       # %bb.0:
268 ; RV64-NEXT:    addi a0, a0, -128
269 ; RV64-NEXT:    slli a0, a0, 48
270 ; RV64-NEXT:    srli a0, a0, 56
271 ; RV64-NEXT:    sltiu a0, a0, 255
272 ; RV64-NEXT:    xori a0, a0, 1
273 ; RV64-NEXT:    ret
274   %tmp0 = add i16 %x, -128 ; ~0U << (8-1)
275   %tmp1 = icmp uge i16 %tmp0, -256 ; ~0U << 8
276   ret i1 %tmp1
279 define i1 @add_ugecmp_i32_i16_i8(i16 %xx) nounwind {
280 ; RV32I-LABEL: add_ugecmp_i32_i16_i8:
281 ; RV32I:       # %bb.0:
282 ; RV32I-NEXT:    slli a0, a0, 16
283 ; RV32I-NEXT:    srli a0, a0, 16
284 ; RV32I-NEXT:    addi a0, a0, -128
285 ; RV32I-NEXT:    sltiu a0, a0, -256
286 ; RV32I-NEXT:    xori a0, a0, 1
287 ; RV32I-NEXT:    ret
289 ; RV64I-LABEL: add_ugecmp_i32_i16_i8:
290 ; RV64I:       # %bb.0:
291 ; RV64I-NEXT:    slli a0, a0, 48
292 ; RV64I-NEXT:    srli a0, a0, 48
293 ; RV64I-NEXT:    addi a0, a0, -128
294 ; RV64I-NEXT:    sltiu a0, a0, -256
295 ; RV64I-NEXT:    xori a0, a0, 1
296 ; RV64I-NEXT:    ret
298 ; RV32ZBB-LABEL: add_ugecmp_i32_i16_i8:
299 ; RV32ZBB:       # %bb.0:
300 ; RV32ZBB-NEXT:    zext.h a0, a0
301 ; RV32ZBB-NEXT:    addi a0, a0, -128
302 ; RV32ZBB-NEXT:    sltiu a0, a0, -256
303 ; RV32ZBB-NEXT:    xori a0, a0, 1
304 ; RV32ZBB-NEXT:    ret
306 ; RV64ZBB-LABEL: add_ugecmp_i32_i16_i8:
307 ; RV64ZBB:       # %bb.0:
308 ; RV64ZBB-NEXT:    zext.h a0, a0
309 ; RV64ZBB-NEXT:    addi a0, a0, -128
310 ; RV64ZBB-NEXT:    sltiu a0, a0, -256
311 ; RV64ZBB-NEXT:    xori a0, a0, 1
312 ; RV64ZBB-NEXT:    ret
313   %x = zext i16 %xx to i32
314   %tmp0 = add i32 %x, -128 ; ~0U << (8-1)
315   %tmp1 = icmp uge i32 %tmp0, -256 ; ~0U << 8
316   ret i1 %tmp1
319 define i1 @add_ugecmp_i32_i16(i32 %x) nounwind {
320 ; RV32I-LABEL: add_ugecmp_i32_i16:
321 ; RV32I:       # %bb.0:
322 ; RV32I-NEXT:    lui a1, 1048568
323 ; RV32I-NEXT:    add a0, a0, a1
324 ; RV32I-NEXT:    lui a1, 1048560
325 ; RV32I-NEXT:    addi a1, a1, -1
326 ; RV32I-NEXT:    sltu a0, a1, a0
327 ; RV32I-NEXT:    ret
329 ; RV64I-LABEL: add_ugecmp_i32_i16:
330 ; RV64I:       # %bb.0:
331 ; RV64I-NEXT:    lui a1, 1048568
332 ; RV64I-NEXT:    addw a0, a0, a1
333 ; RV64I-NEXT:    lui a1, 1048560
334 ; RV64I-NEXT:    addiw a1, a1, -1
335 ; RV64I-NEXT:    sltu a0, a1, a0
336 ; RV64I-NEXT:    ret
338 ; RV32ZBB-LABEL: add_ugecmp_i32_i16:
339 ; RV32ZBB:       # %bb.0:
340 ; RV32ZBB-NEXT:    sext.h a1, a0
341 ; RV32ZBB-NEXT:    xor a0, a1, a0
342 ; RV32ZBB-NEXT:    seqz a0, a0
343 ; RV32ZBB-NEXT:    ret
345 ; RV64ZBB-LABEL: add_ugecmp_i32_i16:
346 ; RV64ZBB:       # %bb.0:
347 ; RV64ZBB-NEXT:    sext.w a1, a0
348 ; RV64ZBB-NEXT:    sext.h a0, a0
349 ; RV64ZBB-NEXT:    xor a0, a0, a1
350 ; RV64ZBB-NEXT:    seqz a0, a0
351 ; RV64ZBB-NEXT:    ret
352   %tmp0 = add i32 %x, -32768 ; ~0U << (16-1)
353   %tmp1 = icmp uge i32 %tmp0, -65536 ; ~0U << 16
354   ret i1 %tmp1
357 define i1 @add_ugecmp_i32_i8(i32 %x) nounwind {
358 ; RV32-LABEL: add_ugecmp_i32_i8:
359 ; RV32:       # %bb.0:
360 ; RV32-NEXT:    addi a0, a0, -128
361 ; RV32-NEXT:    sltiu a0, a0, -256
362 ; RV32-NEXT:    xori a0, a0, 1
363 ; RV32-NEXT:    ret
365 ; RV64-LABEL: add_ugecmp_i32_i8:
366 ; RV64:       # %bb.0:
367 ; RV64-NEXT:    addiw a0, a0, -128
368 ; RV64-NEXT:    sltiu a0, a0, -256
369 ; RV64-NEXT:    xori a0, a0, 1
370 ; RV64-NEXT:    ret
371   %tmp0 = add i32 %x, -128 ; ~0U << (8-1)
372   %tmp1 = icmp uge i32 %tmp0, -256 ; ~0U << 8
373   ret i1 %tmp1
376 define i1 @add_ugecmp_i64_i32(i64 %x) nounwind {
377 ; RV32-LABEL: add_ugecmp_i64_i32:
378 ; RV32:       # %bb.0:
379 ; RV32-NEXT:    srai a0, a0, 31
380 ; RV32-NEXT:    xor a0, a0, a1
381 ; RV32-NEXT:    seqz a0, a0
382 ; RV32-NEXT:    ret
384 ; RV64-LABEL: add_ugecmp_i64_i32:
385 ; RV64:       # %bb.0:
386 ; RV64-NEXT:    sext.w a1, a0
387 ; RV64-NEXT:    xor a0, a1, a0
388 ; RV64-NEXT:    seqz a0, a0
389 ; RV64-NEXT:    ret
390   %tmp0 = add i64 %x, -2147483648 ; ~0U << (32-1)
391   %tmp1 = icmp uge i64 %tmp0, -4294967296 ; ~0U << 32
392   ret i1 %tmp1
395 define i1 @add_ugecmp_i64_i16(i64 %x) nounwind {
396 ; RV32I-LABEL: add_ugecmp_i64_i16:
397 ; RV32I:       # %bb.0:
398 ; RV32I-NEXT:    lui a2, 1048568
399 ; RV32I-NEXT:    add a2, a0, a2
400 ; RV32I-NEXT:    sltu a0, a2, a0
401 ; RV32I-NEXT:    add a0, a1, a0
402 ; RV32I-NEXT:    lui a1, 1048560
403 ; RV32I-NEXT:    addi a1, a1, -1
404 ; RV32I-NEXT:    sltu a1, a1, a2
405 ; RV32I-NEXT:    seqz a0, a0
406 ; RV32I-NEXT:    and a0, a0, a1
407 ; RV32I-NEXT:    ret
409 ; RV64I-LABEL: add_ugecmp_i64_i16:
410 ; RV64I:       # %bb.0:
411 ; RV64I-NEXT:    lui a1, 1048568
412 ; RV64I-NEXT:    add a0, a0, a1
413 ; RV64I-NEXT:    lui a1, 1048560
414 ; RV64I-NEXT:    addiw a1, a1, -1
415 ; RV64I-NEXT:    sltu a0, a1, a0
416 ; RV64I-NEXT:    ret
418 ; RV32ZBB-LABEL: add_ugecmp_i64_i16:
419 ; RV32ZBB:       # %bb.0:
420 ; RV32ZBB-NEXT:    sext.h a2, a0
421 ; RV32ZBB-NEXT:    xor a0, a2, a0
422 ; RV32ZBB-NEXT:    srai a2, a2, 31
423 ; RV32ZBB-NEXT:    xor a1, a2, a1
424 ; RV32ZBB-NEXT:    or a0, a0, a1
425 ; RV32ZBB-NEXT:    seqz a0, a0
426 ; RV32ZBB-NEXT:    ret
428 ; RV64ZBB-LABEL: add_ugecmp_i64_i16:
429 ; RV64ZBB:       # %bb.0:
430 ; RV64ZBB-NEXT:    sext.h a1, a0
431 ; RV64ZBB-NEXT:    xor a0, a1, a0
432 ; RV64ZBB-NEXT:    seqz a0, a0
433 ; RV64ZBB-NEXT:    ret
434   %tmp0 = add i64 %x, -32768 ; ~0U << (16-1)
435   %tmp1 = icmp uge i64 %tmp0, -65536 ; ~0U << 16
436   ret i1 %tmp1
439 define i1 @add_ugecmp_i64_i8(i64 %x) nounwind {
440 ; RV32I-LABEL: add_ugecmp_i64_i8:
441 ; RV32I:       # %bb.0:
442 ; RV32I-NEXT:    addi a2, a0, -128
443 ; RV32I-NEXT:    sltu a0, a2, a0
444 ; RV32I-NEXT:    add a0, a1, a0
445 ; RV32I-NEXT:    seqz a0, a0
446 ; RV32I-NEXT:    sltiu a1, a2, -256
447 ; RV32I-NEXT:    xori a1, a1, 1
448 ; RV32I-NEXT:    and a0, a0, a1
449 ; RV32I-NEXT:    ret
451 ; RV64-LABEL: add_ugecmp_i64_i8:
452 ; RV64:       # %bb.0:
453 ; RV64-NEXT:    addi a0, a0, -128
454 ; RV64-NEXT:    sltiu a0, a0, -256
455 ; RV64-NEXT:    xori a0, a0, 1
456 ; RV64-NEXT:    ret
458 ; RV32ZBB-LABEL: add_ugecmp_i64_i8:
459 ; RV32ZBB:       # %bb.0:
460 ; RV32ZBB-NEXT:    sext.b a2, a0
461 ; RV32ZBB-NEXT:    xor a0, a2, a0
462 ; RV32ZBB-NEXT:    srai a2, a2, 31
463 ; RV32ZBB-NEXT:    xor a1, a2, a1
464 ; RV32ZBB-NEXT:    or a0, a0, a1
465 ; RV32ZBB-NEXT:    seqz a0, a0
466 ; RV32ZBB-NEXT:    ret
467   %tmp0 = add i64 %x, -128 ; ~0U << (8-1)
468   %tmp1 = icmp uge i64 %tmp0, -256 ; ~0U << 8
469   ret i1 %tmp1
472 ; Slightly more canonical variant
473 define i1 @add_ugtcmp_i16_i8(i16 %x) nounwind {
474 ; RV32-LABEL: add_ugtcmp_i16_i8:
475 ; RV32:       # %bb.0:
476 ; RV32-NEXT:    addi a0, a0, -128
477 ; RV32-NEXT:    slli a0, a0, 16
478 ; RV32-NEXT:    srli a0, a0, 24
479 ; RV32-NEXT:    sltiu a0, a0, 255
480 ; RV32-NEXT:    xori a0, a0, 1
481 ; RV32-NEXT:    ret
483 ; RV64-LABEL: add_ugtcmp_i16_i8:
484 ; RV64:       # %bb.0:
485 ; RV64-NEXT:    addi a0, a0, -128
486 ; RV64-NEXT:    slli a0, a0, 48
487 ; RV64-NEXT:    srli a0, a0, 56
488 ; RV64-NEXT:    sltiu a0, a0, 255
489 ; RV64-NEXT:    xori a0, a0, 1
490 ; RV64-NEXT:    ret
491   %tmp0 = add i16 %x, -128 ; ~0U << (8-1)
492   %tmp1 = icmp ugt i16 %tmp0, -257 ; ~0U << 8 - 1
493   ret i1 %tmp1
496 ; ---------------------------------------------------------------------------- ;
497 ; add + icmp ult
498 ; ---------------------------------------------------------------------------- ;
500 define i1 @add_ultcmp_i16_i8(i16 %x) nounwind {
501 ; RV32I-LABEL: add_ultcmp_i16_i8:
502 ; RV32I:       # %bb.0:
503 ; RV32I-NEXT:    addi a0, a0, 128
504 ; RV32I-NEXT:    slli a0, a0, 16
505 ; RV32I-NEXT:    srli a0, a0, 16
506 ; RV32I-NEXT:    sltiu a0, a0, 256
507 ; RV32I-NEXT:    ret
509 ; RV64I-LABEL: add_ultcmp_i16_i8:
510 ; RV64I:       # %bb.0:
511 ; RV64I-NEXT:    addi a0, a0, 128
512 ; RV64I-NEXT:    slli a0, a0, 48
513 ; RV64I-NEXT:    srli a0, a0, 48
514 ; RV64I-NEXT:    sltiu a0, a0, 256
515 ; RV64I-NEXT:    ret
517 ; RV32ZBB-LABEL: add_ultcmp_i16_i8:
518 ; RV32ZBB:       # %bb.0:
519 ; RV32ZBB-NEXT:    addi a0, a0, 128
520 ; RV32ZBB-NEXT:    zext.h a0, a0
521 ; RV32ZBB-NEXT:    sltiu a0, a0, 256
522 ; RV32ZBB-NEXT:    ret
524 ; RV64ZBB-LABEL: add_ultcmp_i16_i8:
525 ; RV64ZBB:       # %bb.0:
526 ; RV64ZBB-NEXT:    addi a0, a0, 128
527 ; RV64ZBB-NEXT:    zext.h a0, a0
528 ; RV64ZBB-NEXT:    sltiu a0, a0, 256
529 ; RV64ZBB-NEXT:    ret
530   %tmp0 = add i16 %x, 128 ; 1U << (8-1)
531   %tmp1 = icmp ult i16 %tmp0, 256 ; 1U << 8
532   ret i1 %tmp1
535 define i1 @add_ultcmp_i32_i16(i32 %x) nounwind {
536 ; RV32I-LABEL: add_ultcmp_i32_i16:
537 ; RV32I:       # %bb.0:
538 ; RV32I-NEXT:    lui a1, 8
539 ; RV32I-NEXT:    add a0, a0, a1
540 ; RV32I-NEXT:    srli a0, a0, 16
541 ; RV32I-NEXT:    seqz a0, a0
542 ; RV32I-NEXT:    ret
544 ; RV64I-LABEL: add_ultcmp_i32_i16:
545 ; RV64I:       # %bb.0:
546 ; RV64I-NEXT:    lui a1, 8
547 ; RV64I-NEXT:    add a0, a0, a1
548 ; RV64I-NEXT:    srliw a0, a0, 16
549 ; RV64I-NEXT:    seqz a0, a0
550 ; RV64I-NEXT:    ret
552 ; RV32ZBB-LABEL: add_ultcmp_i32_i16:
553 ; RV32ZBB:       # %bb.0:
554 ; RV32ZBB-NEXT:    sext.h a1, a0
555 ; RV32ZBB-NEXT:    xor a0, a1, a0
556 ; RV32ZBB-NEXT:    seqz a0, a0
557 ; RV32ZBB-NEXT:    ret
559 ; RV64ZBB-LABEL: add_ultcmp_i32_i16:
560 ; RV64ZBB:       # %bb.0:
561 ; RV64ZBB-NEXT:    sext.w a1, a0
562 ; RV64ZBB-NEXT:    sext.h a0, a0
563 ; RV64ZBB-NEXT:    xor a0, a0, a1
564 ; RV64ZBB-NEXT:    seqz a0, a0
565 ; RV64ZBB-NEXT:    ret
566   %tmp0 = add i32 %x, 32768 ; 1U << (16-1)
567   %tmp1 = icmp ult i32 %tmp0, 65536 ; 1U << 16
568   ret i1 %tmp1
571 define i1 @add_ultcmp_i32_i8(i32 %x) nounwind {
572 ; RV32-LABEL: add_ultcmp_i32_i8:
573 ; RV32:       # %bb.0:
574 ; RV32-NEXT:    addi a0, a0, 128
575 ; RV32-NEXT:    sltiu a0, a0, 256
576 ; RV32-NEXT:    ret
578 ; RV64-LABEL: add_ultcmp_i32_i8:
579 ; RV64:       # %bb.0:
580 ; RV64-NEXT:    addiw a0, a0, 128
581 ; RV64-NEXT:    sltiu a0, a0, 256
582 ; RV64-NEXT:    ret
583   %tmp0 = add i32 %x, 128 ; 1U << (8-1)
584   %tmp1 = icmp ult i32 %tmp0, 256 ; 1U << 8
585   ret i1 %tmp1
588 define i1 @add_ultcmp_i64_i32(i64 %x) nounwind {
589 ; RV32-LABEL: add_ultcmp_i64_i32:
590 ; RV32:       # %bb.0:
591 ; RV32-NEXT:    srai a0, a0, 31
592 ; RV32-NEXT:    xor a0, a0, a1
593 ; RV32-NEXT:    seqz a0, a0
594 ; RV32-NEXT:    ret
596 ; RV64-LABEL: add_ultcmp_i64_i32:
597 ; RV64:       # %bb.0:
598 ; RV64-NEXT:    sext.w a1, a0
599 ; RV64-NEXT:    xor a0, a1, a0
600 ; RV64-NEXT:    seqz a0, a0
601 ; RV64-NEXT:    ret
602   %tmp0 = add i64 %x, 2147483648 ; 1U << (32-1)
603   %tmp1 = icmp ult i64 %tmp0, 4294967296 ; 1U << 32
604   ret i1 %tmp1
607 define i1 @add_ultcmp_i64_i16(i64 %x) nounwind {
608 ; RV32I-LABEL: add_ultcmp_i64_i16:
609 ; RV32I:       # %bb.0:
610 ; RV32I-NEXT:    lui a2, 8
611 ; RV32I-NEXT:    add a2, a0, a2
612 ; RV32I-NEXT:    sltu a0, a2, a0
613 ; RV32I-NEXT:    add a0, a1, a0
614 ; RV32I-NEXT:    srli a2, a2, 16
615 ; RV32I-NEXT:    or a0, a0, a2
616 ; RV32I-NEXT:    seqz a0, a0
617 ; RV32I-NEXT:    ret
619 ; RV64I-LABEL: add_ultcmp_i64_i16:
620 ; RV64I:       # %bb.0:
621 ; RV64I-NEXT:    lui a1, 8
622 ; RV64I-NEXT:    add a0, a0, a1
623 ; RV64I-NEXT:    srli a0, a0, 16
624 ; RV64I-NEXT:    seqz a0, a0
625 ; RV64I-NEXT:    ret
627 ; RV32ZBB-LABEL: add_ultcmp_i64_i16:
628 ; RV32ZBB:       # %bb.0:
629 ; RV32ZBB-NEXT:    sext.h a2, a0
630 ; RV32ZBB-NEXT:    xor a0, a2, a0
631 ; RV32ZBB-NEXT:    srai a2, a2, 31
632 ; RV32ZBB-NEXT:    xor a1, a2, a1
633 ; RV32ZBB-NEXT:    or a0, a0, a1
634 ; RV32ZBB-NEXT:    seqz a0, a0
635 ; RV32ZBB-NEXT:    ret
637 ; RV64ZBB-LABEL: add_ultcmp_i64_i16:
638 ; RV64ZBB:       # %bb.0:
639 ; RV64ZBB-NEXT:    sext.h a1, a0
640 ; RV64ZBB-NEXT:    xor a0, a1, a0
641 ; RV64ZBB-NEXT:    seqz a0, a0
642 ; RV64ZBB-NEXT:    ret
643   %tmp0 = add i64 %x, 32768 ; 1U << (16-1)
644   %tmp1 = icmp ult i64 %tmp0, 65536 ; 1U << 16
645   ret i1 %tmp1
648 define i1 @add_ultcmp_i64_i8(i64 %x) nounwind {
649 ; RV32I-LABEL: add_ultcmp_i64_i8:
650 ; RV32I:       # %bb.0:
651 ; RV32I-NEXT:    addi a2, a0, 128
652 ; RV32I-NEXT:    sltu a0, a2, a0
653 ; RV32I-NEXT:    add a0, a1, a0
654 ; RV32I-NEXT:    seqz a0, a0
655 ; RV32I-NEXT:    sltiu a1, a2, 256
656 ; RV32I-NEXT:    and a0, a0, a1
657 ; RV32I-NEXT:    ret
659 ; RV64-LABEL: add_ultcmp_i64_i8:
660 ; RV64:       # %bb.0:
661 ; RV64-NEXT:    addi a0, a0, 128
662 ; RV64-NEXT:    sltiu a0, a0, 256
663 ; RV64-NEXT:    ret
665 ; RV32ZBB-LABEL: add_ultcmp_i64_i8:
666 ; RV32ZBB:       # %bb.0:
667 ; RV32ZBB-NEXT:    sext.b a2, a0
668 ; RV32ZBB-NEXT:    xor a0, a2, a0
669 ; RV32ZBB-NEXT:    srai a2, a2, 31
670 ; RV32ZBB-NEXT:    xor a1, a2, a1
671 ; RV32ZBB-NEXT:    or a0, a0, a1
672 ; RV32ZBB-NEXT:    seqz a0, a0
673 ; RV32ZBB-NEXT:    ret
674   %tmp0 = add i64 %x, 128 ; 1U << (8-1)
675   %tmp1 = icmp ult i64 %tmp0, 256 ; 1U << 8
676   ret i1 %tmp1
679 ; Slightly more canonical variant
680 define i1 @add_ulecmp_i16_i8(i16 %x) nounwind {
681 ; RV32I-LABEL: add_ulecmp_i16_i8:
682 ; RV32I:       # %bb.0:
683 ; RV32I-NEXT:    addi a0, a0, 128
684 ; RV32I-NEXT:    slli a0, a0, 16
685 ; RV32I-NEXT:    srli a0, a0, 16
686 ; RV32I-NEXT:    sltiu a0, a0, 256
687 ; RV32I-NEXT:    ret
689 ; RV64I-LABEL: add_ulecmp_i16_i8:
690 ; RV64I:       # %bb.0:
691 ; RV64I-NEXT:    addi a0, a0, 128
692 ; RV64I-NEXT:    slli a0, a0, 48
693 ; RV64I-NEXT:    srli a0, a0, 48
694 ; RV64I-NEXT:    sltiu a0, a0, 256
695 ; RV64I-NEXT:    ret
697 ; RV32ZBB-LABEL: add_ulecmp_i16_i8:
698 ; RV32ZBB:       # %bb.0:
699 ; RV32ZBB-NEXT:    addi a0, a0, 128
700 ; RV32ZBB-NEXT:    zext.h a0, a0
701 ; RV32ZBB-NEXT:    sltiu a0, a0, 256
702 ; RV32ZBB-NEXT:    ret
704 ; RV64ZBB-LABEL: add_ulecmp_i16_i8:
705 ; RV64ZBB:       # %bb.0:
706 ; RV64ZBB-NEXT:    addi a0, a0, 128
707 ; RV64ZBB-NEXT:    zext.h a0, a0
708 ; RV64ZBB-NEXT:    sltiu a0, a0, 256
709 ; RV64ZBB-NEXT:    ret
710   %tmp0 = add i16 %x, 128 ; 1U << (8-1)
711   %tmp1 = icmp ule i16 %tmp0, 255 ; (1U << 8) - 1
712   ret i1 %tmp1
715 ; Negative tests
716 ; ---------------------------------------------------------------------------- ;
718 ; Adding not a constant
719 define i1 @add_ultcmp_bad_i16_i8_add(i16 %x, i16 %y) nounwind {
720 ; RV32I-LABEL: add_ultcmp_bad_i16_i8_add:
721 ; RV32I:       # %bb.0:
722 ; RV32I-NEXT:    add a0, a0, a1
723 ; RV32I-NEXT:    slli a0, a0, 16
724 ; RV32I-NEXT:    srli a0, a0, 16
725 ; RV32I-NEXT:    sltiu a0, a0, 256
726 ; RV32I-NEXT:    ret
728 ; RV64I-LABEL: add_ultcmp_bad_i16_i8_add:
729 ; RV64I:       # %bb.0:
730 ; RV64I-NEXT:    add a0, a0, a1
731 ; RV64I-NEXT:    slli a0, a0, 48
732 ; RV64I-NEXT:    srli a0, a0, 48
733 ; RV64I-NEXT:    sltiu a0, a0, 256
734 ; RV64I-NEXT:    ret
736 ; RV32ZBB-LABEL: add_ultcmp_bad_i16_i8_add:
737 ; RV32ZBB:       # %bb.0:
738 ; RV32ZBB-NEXT:    add a0, a0, a1
739 ; RV32ZBB-NEXT:    zext.h a0, a0
740 ; RV32ZBB-NEXT:    sltiu a0, a0, 256
741 ; RV32ZBB-NEXT:    ret
743 ; RV64ZBB-LABEL: add_ultcmp_bad_i16_i8_add:
744 ; RV64ZBB:       # %bb.0:
745 ; RV64ZBB-NEXT:    add a0, a0, a1
746 ; RV64ZBB-NEXT:    zext.h a0, a0
747 ; RV64ZBB-NEXT:    sltiu a0, a0, 256
748 ; RV64ZBB-NEXT:    ret
749   %tmp0 = add i16 %x, %y
750   %tmp1 = icmp ult i16 %tmp0, 256 ; 1U << 8
751   ret i1 %tmp1
754 ; Comparing not with a constant
755 define i1 @add_ultcmp_bad_i16_i8_cmp(i16 %x, i16 %y) nounwind {
756 ; RV32I-LABEL: add_ultcmp_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:    ret
766 ; RV64I-LABEL: add_ultcmp_bad_i16_i8_cmp:
767 ; RV64I:       # %bb.0:
768 ; RV64I-NEXT:    lui a2, 16
769 ; RV64I-NEXT:    addiw a2, a2, -1
770 ; RV64I-NEXT:    and a1, a1, a2
771 ; RV64I-NEXT:    addi a0, a0, 128
772 ; RV64I-NEXT:    and a0, a0, a2
773 ; RV64I-NEXT:    sltu a0, a0, a1
774 ; RV64I-NEXT:    ret
776 ; RV32ZBB-LABEL: add_ultcmp_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:    ret
784 ; RV64ZBB-LABEL: add_ultcmp_bad_i16_i8_cmp:
785 ; RV64ZBB:       # %bb.0:
786 ; RV64ZBB-NEXT:    zext.h a1, a1
787 ; RV64ZBB-NEXT:    addi a0, a0, 128
788 ; RV64ZBB-NEXT:    zext.h a0, a0
789 ; RV64ZBB-NEXT:    sltu a0, a0, a1
790 ; RV64ZBB-NEXT:    ret
791   %tmp0 = add i16 %x, 128 ; 1U << (8-1)
792   %tmp1 = icmp ult i16 %tmp0, %y
793   ret i1 %tmp1
796 ; Second constant is not larger than the first one
797 define i1 @add_ultcmp_bad_i8_i16(i16 %x) nounwind {
798 ; RV32I-LABEL: add_ultcmp_bad_i8_i16:
799 ; RV32I:       # %bb.0:
800 ; RV32I-NEXT:    addi a0, a0, 128
801 ; RV32I-NEXT:    slli a0, a0, 16
802 ; RV32I-NEXT:    srli a0, a0, 16
803 ; RV32I-NEXT:    sltiu a0, a0, 128
804 ; RV32I-NEXT:    ret
806 ; RV64I-LABEL: add_ultcmp_bad_i8_i16:
807 ; RV64I:       # %bb.0:
808 ; RV64I-NEXT:    addi a0, a0, 128
809 ; RV64I-NEXT:    slli a0, a0, 48
810 ; RV64I-NEXT:    srli a0, a0, 48
811 ; RV64I-NEXT:    sltiu a0, a0, 128
812 ; RV64I-NEXT:    ret
814 ; RV32ZBB-LABEL: add_ultcmp_bad_i8_i16:
815 ; RV32ZBB:       # %bb.0:
816 ; RV32ZBB-NEXT:    addi a0, a0, 128
817 ; RV32ZBB-NEXT:    zext.h a0, a0
818 ; RV32ZBB-NEXT:    sltiu a0, a0, 128
819 ; RV32ZBB-NEXT:    ret
821 ; RV64ZBB-LABEL: add_ultcmp_bad_i8_i16:
822 ; RV64ZBB:       # %bb.0:
823 ; RV64ZBB-NEXT:    addi a0, a0, 128
824 ; RV64ZBB-NEXT:    zext.h a0, a0
825 ; RV64ZBB-NEXT:    sltiu a0, a0, 128
826 ; RV64ZBB-NEXT:    ret
827   %tmp0 = add i16 %x, 128 ; 1U << (8-1)
828   %tmp1 = icmp ult i16 %tmp0, 128 ; 1U << (8-1)
829   ret i1 %tmp1
832 ; First constant is not power of two
833 define i1 @add_ultcmp_bad_i16_i8_c0notpoweroftwo(i16 %x) nounwind {
834 ; RV32I-LABEL: add_ultcmp_bad_i16_i8_c0notpoweroftwo:
835 ; RV32I:       # %bb.0:
836 ; RV32I-NEXT:    addi a0, a0, 192
837 ; RV32I-NEXT:    slli a0, a0, 16
838 ; RV32I-NEXT:    srli a0, a0, 16
839 ; RV32I-NEXT:    sltiu a0, a0, 256
840 ; RV32I-NEXT:    ret
842 ; RV64I-LABEL: add_ultcmp_bad_i16_i8_c0notpoweroftwo:
843 ; RV64I:       # %bb.0:
844 ; RV64I-NEXT:    addi a0, a0, 192
845 ; RV64I-NEXT:    slli a0, a0, 48
846 ; RV64I-NEXT:    srli a0, a0, 48
847 ; RV64I-NEXT:    sltiu a0, a0, 256
848 ; RV64I-NEXT:    ret
850 ; RV32ZBB-LABEL: add_ultcmp_bad_i16_i8_c0notpoweroftwo:
851 ; RV32ZBB:       # %bb.0:
852 ; RV32ZBB-NEXT:    addi a0, a0, 192
853 ; RV32ZBB-NEXT:    zext.h a0, a0
854 ; RV32ZBB-NEXT:    sltiu a0, a0, 256
855 ; RV32ZBB-NEXT:    ret
857 ; RV64ZBB-LABEL: add_ultcmp_bad_i16_i8_c0notpoweroftwo:
858 ; RV64ZBB:       # %bb.0:
859 ; RV64ZBB-NEXT:    addi a0, a0, 192
860 ; RV64ZBB-NEXT:    zext.h a0, a0
861 ; RV64ZBB-NEXT:    sltiu a0, a0, 256
862 ; RV64ZBB-NEXT:    ret
863   %tmp0 = add i16 %x, 192 ; (1U << (8-1)) + (1U << (8-1-1))
864   %tmp1 = icmp ult i16 %tmp0, 256 ; 1U << 8
865   ret i1 %tmp1
868 ; Second constant is not power of two
869 define i1 @add_ultcmp_bad_i16_i8_c1notpoweroftwo(i16 %x) nounwind {
870 ; RV32I-LABEL: add_ultcmp_bad_i16_i8_c1notpoweroftwo:
871 ; RV32I:       # %bb.0:
872 ; RV32I-NEXT:    addi a0, a0, 128
873 ; RV32I-NEXT:    slli a0, a0, 16
874 ; RV32I-NEXT:    srli a0, a0, 16
875 ; RV32I-NEXT:    sltiu a0, a0, 768
876 ; RV32I-NEXT:    ret
878 ; RV64I-LABEL: add_ultcmp_bad_i16_i8_c1notpoweroftwo:
879 ; RV64I:       # %bb.0:
880 ; RV64I-NEXT:    addi a0, a0, 128
881 ; RV64I-NEXT:    slli a0, a0, 48
882 ; RV64I-NEXT:    srli a0, a0, 48
883 ; RV64I-NEXT:    sltiu a0, a0, 768
884 ; RV64I-NEXT:    ret
886 ; RV32ZBB-LABEL: add_ultcmp_bad_i16_i8_c1notpoweroftwo:
887 ; RV32ZBB:       # %bb.0:
888 ; RV32ZBB-NEXT:    addi a0, a0, 128
889 ; RV32ZBB-NEXT:    zext.h a0, a0
890 ; RV32ZBB-NEXT:    sltiu a0, a0, 768
891 ; RV32ZBB-NEXT:    ret
893 ; RV64ZBB-LABEL: add_ultcmp_bad_i16_i8_c1notpoweroftwo:
894 ; RV64ZBB:       # %bb.0:
895 ; RV64ZBB-NEXT:    addi a0, a0, 128
896 ; RV64ZBB-NEXT:    zext.h a0, a0
897 ; RV64ZBB-NEXT:    sltiu a0, a0, 768
898 ; RV64ZBB-NEXT:    ret
899   %tmp0 = add i16 %x, 128 ; 1U << (8-1)
900   %tmp1 = icmp ult i16 %tmp0, 768 ; (1U << 8)) + (1U << (8+1))
901   ret i1 %tmp1
904 ; Magic check fails, 64 << 1 != 256
905 define i1 @add_ultcmp_bad_i16_i8_magic(i16 %x) nounwind {
906 ; RV32I-LABEL: add_ultcmp_bad_i16_i8_magic:
907 ; RV32I:       # %bb.0:
908 ; RV32I-NEXT:    addi a0, a0, 64
909 ; RV32I-NEXT:    slli a0, a0, 16
910 ; RV32I-NEXT:    srli a0, a0, 16
911 ; RV32I-NEXT:    sltiu a0, a0, 256
912 ; RV32I-NEXT:    ret
914 ; RV64I-LABEL: add_ultcmp_bad_i16_i8_magic:
915 ; RV64I:       # %bb.0:
916 ; RV64I-NEXT:    addi a0, a0, 64
917 ; RV64I-NEXT:    slli a0, a0, 48
918 ; RV64I-NEXT:    srli a0, a0, 48
919 ; RV64I-NEXT:    sltiu a0, a0, 256
920 ; RV64I-NEXT:    ret
922 ; RV32ZBB-LABEL: add_ultcmp_bad_i16_i8_magic:
923 ; RV32ZBB:       # %bb.0:
924 ; RV32ZBB-NEXT:    addi a0, a0, 64
925 ; RV32ZBB-NEXT:    zext.h a0, a0
926 ; RV32ZBB-NEXT:    sltiu a0, a0, 256
927 ; RV32ZBB-NEXT:    ret
929 ; RV64ZBB-LABEL: add_ultcmp_bad_i16_i8_magic:
930 ; RV64ZBB:       # %bb.0:
931 ; RV64ZBB-NEXT:    addi a0, a0, 64
932 ; RV64ZBB-NEXT:    zext.h a0, a0
933 ; RV64ZBB-NEXT:    sltiu a0, a0, 256
934 ; RV64ZBB-NEXT:    ret
935   %tmp0 = add i16 %x, 64 ; 1U << (8-1-1)
936   %tmp1 = icmp ult i16 %tmp0, 256 ; 1U << 8
937   ret i1 %tmp1
940 ; Bad 'destination type'
941 define i1 @add_ultcmp_bad_i16_i4(i16 %x) nounwind {
942 ; RV32I-LABEL: add_ultcmp_bad_i16_i4:
943 ; RV32I:       # %bb.0:
944 ; RV32I-NEXT:    addi a0, a0, 8
945 ; RV32I-NEXT:    slli a0, a0, 16
946 ; RV32I-NEXT:    srli a0, a0, 16
947 ; RV32I-NEXT:    sltiu a0, a0, 16
948 ; RV32I-NEXT:    ret
950 ; RV64I-LABEL: add_ultcmp_bad_i16_i4:
951 ; RV64I:       # %bb.0:
952 ; RV64I-NEXT:    addi a0, a0, 8
953 ; RV64I-NEXT:    slli a0, a0, 48
954 ; RV64I-NEXT:    srli a0, a0, 48
955 ; RV64I-NEXT:    sltiu a0, a0, 16
956 ; RV64I-NEXT:    ret
958 ; RV32ZBB-LABEL: add_ultcmp_bad_i16_i4:
959 ; RV32ZBB:       # %bb.0:
960 ; RV32ZBB-NEXT:    addi a0, a0, 8
961 ; RV32ZBB-NEXT:    zext.h a0, a0
962 ; RV32ZBB-NEXT:    sltiu a0, a0, 16
963 ; RV32ZBB-NEXT:    ret
965 ; RV64ZBB-LABEL: add_ultcmp_bad_i16_i4:
966 ; RV64ZBB:       # %bb.0:
967 ; RV64ZBB-NEXT:    addi a0, a0, 8
968 ; RV64ZBB-NEXT:    zext.h a0, a0
969 ; RV64ZBB-NEXT:    sltiu a0, a0, 16
970 ; RV64ZBB-NEXT:    ret
971   %tmp0 = add i16 %x, 8 ; 1U << (4-1)
972   %tmp1 = icmp ult i16 %tmp0, 16 ; 1U << 4
973   ret i1 %tmp1
976 ; Bad storage type
977 define i1 @add_ultcmp_bad_i24_i8(i24 %x) nounwind {
978 ; RV32-LABEL: add_ultcmp_bad_i24_i8:
979 ; RV32:       # %bb.0:
980 ; RV32-NEXT:    addi a0, a0, 128
981 ; RV32-NEXT:    slli a0, a0, 8
982 ; RV32-NEXT:    srli a0, a0, 8
983 ; RV32-NEXT:    sltiu a0, a0, 256
984 ; RV32-NEXT:    ret
986 ; RV64-LABEL: add_ultcmp_bad_i24_i8:
987 ; RV64:       # %bb.0:
988 ; RV64-NEXT:    addi a0, a0, 128
989 ; RV64-NEXT:    slli a0, a0, 40
990 ; RV64-NEXT:    srli a0, a0, 40
991 ; RV64-NEXT:    sltiu a0, a0, 256
992 ; RV64-NEXT:    ret
993   %tmp0 = add i24 %x, 128 ; 1U << (8-1)
994   %tmp1 = icmp ult i24 %tmp0, 256 ; 1U << 8
995   ret i1 %tmp1
998 define i1 @add_ulecmp_bad_i16_i8(i16 %x) nounwind {
999 ; CHECK-LABEL: add_ulecmp_bad_i16_i8:
1000 ; CHECK:       # %bb.0:
1001 ; CHECK-NEXT:    li a0, 1
1002 ; CHECK-NEXT:    ret
1003   %tmp0 = add i16 %x, 128 ; 1U << (8-1)
1004   %tmp1 = icmp ule i16 %tmp0, -1 ; when we +1 it, it will wrap to 0
1005   ret i1 %tmp1