574 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc -mtriple=aarch64-unknown-linux-gnu < %s | FileCheck %s --check-prefixes=CHECK,CHECK-SD3; RUN: llc -mtriple=aarch64-unknown-linux-gnu -global-isel < %s | FileCheck %s --check-prefixes=CHECK,CHECK-GI4 5; https://bugs.llvm.org/show_bug.cgi?id=381496 7; We are truncating from wider width, and then sign-extending8; back to the original width. Then we equality-comparing orig and src.9; If they don't match, then we had signed truncation during truncation.10 11; This can be expressed in a several ways in IR:12; trunc + sext + icmp eq <- not canonical13; shl + ashr + icmp eq14; add + icmp uge/ugt15; add + icmp ult/ule16; However only the simplest form (with two shifts) gets lowered best.17 18; ---------------------------------------------------------------------------- ;19; shl + ashr + icmp eq20; ---------------------------------------------------------------------------- ;21 22define i1 @shifts_eqcmp_i16_i8(i16 %x) nounwind {23; CHECK-SD-LABEL: shifts_eqcmp_i16_i8:24; CHECK-SD: // %bb.0:25; CHECK-SD-NEXT: sxtb w8, w026; CHECK-SD-NEXT: and w8, w8, #0xffff27; CHECK-SD-NEXT: cmp w8, w0, uxth28; CHECK-SD-NEXT: cset w0, eq29; CHECK-SD-NEXT: ret30;31; CHECK-GI-LABEL: shifts_eqcmp_i16_i8:32; CHECK-GI: // %bb.0:33; CHECK-GI-NEXT: lsl w8, w0, #834; CHECK-GI-NEXT: sbfx w8, w8, #8, #835; CHECK-GI-NEXT: and w8, w8, #0xffff36; CHECK-GI-NEXT: cmp w8, w0, uxth37; CHECK-GI-NEXT: cset w0, eq38; CHECK-GI-NEXT: ret39 %tmp0 = shl i16 %x, 8 ; 16-840 %tmp1 = ashr exact i16 %tmp0, 8 ; 16-841 %tmp2 = icmp eq i16 %tmp1, %x42 ret i1 %tmp243}44 45define i1 @shifts_eqcmp_i32_i16(i32 %x) nounwind {46; CHECK-LABEL: shifts_eqcmp_i32_i16:47; CHECK: // %bb.0:48; CHECK-NEXT: cmp w0, w0, sxth49; CHECK-NEXT: cset w0, eq50; CHECK-NEXT: ret51 %tmp0 = shl i32 %x, 16 ; 32-1652 %tmp1 = ashr exact i32 %tmp0, 16 ; 32-1653 %tmp2 = icmp eq i32 %tmp1, %x54 ret i1 %tmp255}56 57define i1 @shifts_eqcmp_i32_i8(i32 %x) nounwind {58; CHECK-LABEL: shifts_eqcmp_i32_i8:59; CHECK: // %bb.0:60; CHECK-NEXT: cmp w0, w0, sxtb61; CHECK-NEXT: cset w0, eq62; CHECK-NEXT: ret63 %tmp0 = shl i32 %x, 24 ; 32-864 %tmp1 = ashr exact i32 %tmp0, 24 ; 32-865 %tmp2 = icmp eq i32 %tmp1, %x66 ret i1 %tmp267}68 69define i1 @shifts_eqcmp_i64_i32(i64 %x) nounwind {70; CHECK-LABEL: shifts_eqcmp_i64_i32:71; CHECK: // %bb.0:72; CHECK-NEXT: cmp x0, w0, sxtw73; CHECK-NEXT: cset w0, eq74; CHECK-NEXT: ret75 %tmp0 = shl i64 %x, 32 ; 64-3276 %tmp1 = ashr exact i64 %tmp0, 32 ; 64-3277 %tmp2 = icmp eq i64 %tmp1, %x78 ret i1 %tmp279}80 81define i1 @shifts_eqcmp_i64_i16(i64 %x) nounwind {82; CHECK-LABEL: shifts_eqcmp_i64_i16:83; CHECK: // %bb.0:84; CHECK-NEXT: cmp x0, w0, sxth85; CHECK-NEXT: cset w0, eq86; CHECK-NEXT: ret87 %tmp0 = shl i64 %x, 48 ; 64-1688 %tmp1 = ashr exact i64 %tmp0, 48 ; 64-1689 %tmp2 = icmp eq i64 %tmp1, %x90 ret i1 %tmp291}92 93define i1 @shifts_eqcmp_i64_i8(i64 %x) nounwind {94; CHECK-LABEL: shifts_eqcmp_i64_i8:95; CHECK: // %bb.0:96; CHECK-NEXT: cmp x0, w0, sxtb97; CHECK-NEXT: cset w0, eq98; CHECK-NEXT: ret99 %tmp0 = shl i64 %x, 56 ; 64-8100 %tmp1 = ashr exact i64 %tmp0, 56 ; 64-8101 %tmp2 = icmp eq i64 %tmp1, %x102 ret i1 %tmp2103}104 105; ---------------------------------------------------------------------------- ;106; add + icmp uge107; ---------------------------------------------------------------------------- ;108 109define i1 @add_ugecmp_i16_i8(i16 %x) nounwind {110; CHECK-SD-LABEL: add_ugecmp_i16_i8:111; CHECK-SD: // %bb.0:112; CHECK-SD-NEXT: and w8, w0, #0xffff113; CHECK-SD-NEXT: sub w8, w8, #128114; CHECK-SD-NEXT: lsr w8, w8, #8115; CHECK-SD-NEXT: cmp w8, #254116; CHECK-SD-NEXT: cset w0, hi117; CHECK-SD-NEXT: ret118;119; CHECK-GI-LABEL: add_ugecmp_i16_i8:120; CHECK-GI: // %bb.0:121; CHECK-GI-NEXT: mov w8, #-128 // =0xffffff80122; CHECK-GI-NEXT: mov w9, #65280 // =0xff00123; CHECK-GI-NEXT: add w8, w8, w0, uxth124; CHECK-GI-NEXT: cmp w8, w9125; CHECK-GI-NEXT: cset w0, hs126; CHECK-GI-NEXT: ret127 %tmp0 = add i16 %x, -128 ; ~0U << (8-1)128 %tmp1 = icmp uge i16 %tmp0, -256 ; ~0U << 8129 ret i1 %tmp1130}131 132define i1 @add_ugecmp_i32_i16_i8(i16 %xx) nounwind {133; CHECK-SD-LABEL: add_ugecmp_i32_i16_i8:134; CHECK-SD: // %bb.0:135; CHECK-SD-NEXT: and w8, w0, #0xffff136; CHECK-SD-NEXT: cmp w8, w8, sxtb137; CHECK-SD-NEXT: cset w0, eq138; CHECK-SD-NEXT: ret139;140; CHECK-GI-LABEL: add_ugecmp_i32_i16_i8:141; CHECK-GI: // %bb.0:142; CHECK-GI-NEXT: mov w8, #-128 // =0xffffff80143; CHECK-GI-NEXT: add w8, w8, w0, uxth144; CHECK-GI-NEXT: cmn w8, #256145; CHECK-GI-NEXT: cset w0, hs146; CHECK-GI-NEXT: ret147 %x = zext i16 %xx to i32148 %tmp0 = add i32 %x, -128 ; ~0U << (8-1)149 %tmp1 = icmp uge i32 %tmp0, -256 ; ~0U << 8150 ret i1 %tmp1151}152 153define i1 @add_ugecmp_i32_i16(i32 %x) nounwind {154; CHECK-SD-LABEL: add_ugecmp_i32_i16:155; CHECK-SD: // %bb.0:156; CHECK-SD-NEXT: cmp w0, w0, sxth157; CHECK-SD-NEXT: cset w0, eq158; CHECK-SD-NEXT: ret159;160; CHECK-GI-LABEL: add_ugecmp_i32_i16:161; CHECK-GI: // %bb.0:162; CHECK-GI-NEXT: sub w8, w0, #8, lsl #12 // =32768163; CHECK-GI-NEXT: cmn w8, #16, lsl #12 // =65536164; CHECK-GI-NEXT: cset w0, hs165; CHECK-GI-NEXT: ret166 %tmp0 = add i32 %x, -32768 ; ~0U << (16-1)167 %tmp1 = icmp uge i32 %tmp0, -65536 ; ~0U << 16168 ret i1 %tmp1169}170 171define i1 @add_ugecmp_i32_i8(i32 %x) nounwind {172; CHECK-SD-LABEL: add_ugecmp_i32_i8:173; CHECK-SD: // %bb.0:174; CHECK-SD-NEXT: cmp w0, w0, sxtb175; CHECK-SD-NEXT: cset w0, eq176; CHECK-SD-NEXT: ret177;178; CHECK-GI-LABEL: add_ugecmp_i32_i8:179; CHECK-GI: // %bb.0:180; CHECK-GI-NEXT: sub w8, w0, #128181; CHECK-GI-NEXT: cmn w8, #256182; CHECK-GI-NEXT: cset w0, hs183; CHECK-GI-NEXT: ret184 %tmp0 = add i32 %x, -128 ; ~0U << (8-1)185 %tmp1 = icmp uge i32 %tmp0, -256 ; ~0U << 8186 ret i1 %tmp1187}188 189define i1 @add_ugecmp_i64_i32(i64 %x) nounwind {190; CHECK-SD-LABEL: add_ugecmp_i64_i32:191; CHECK-SD: // %bb.0:192; CHECK-SD-NEXT: cmp x0, w0, sxtw193; CHECK-SD-NEXT: cset w0, eq194; CHECK-SD-NEXT: ret195;196; CHECK-GI-LABEL: add_ugecmp_i64_i32:197; CHECK-GI: // %bb.0:198; CHECK-GI-NEXT: mov x8, #-2147483648 // =0xffffffff80000000199; CHECK-GI-NEXT: mov x9, #-4294967296 // =0xffffffff00000000200; CHECK-GI-NEXT: add x8, x0, x8201; CHECK-GI-NEXT: cmp x8, x9202; CHECK-GI-NEXT: cset w0, hs203; CHECK-GI-NEXT: ret204 %tmp0 = add i64 %x, -2147483648 ; ~0U << (32-1)205 %tmp1 = icmp uge i64 %tmp0, -4294967296 ; ~0U << 32206 ret i1 %tmp1207}208 209define i1 @add_ugecmp_i64_i16(i64 %x) nounwind {210; CHECK-SD-LABEL: add_ugecmp_i64_i16:211; CHECK-SD: // %bb.0:212; CHECK-SD-NEXT: cmp x0, w0, sxth213; CHECK-SD-NEXT: cset w0, eq214; CHECK-SD-NEXT: ret215;216; CHECK-GI-LABEL: add_ugecmp_i64_i16:217; CHECK-GI: // %bb.0:218; CHECK-GI-NEXT: sub x8, x0, #8, lsl #12 // =32768219; CHECK-GI-NEXT: cmn x8, #16, lsl #12 // =65536220; CHECK-GI-NEXT: cset w0, hs221; CHECK-GI-NEXT: ret222 %tmp0 = add i64 %x, -32768 ; ~0U << (16-1)223 %tmp1 = icmp uge i64 %tmp0, -65536 ; ~0U << 16224 ret i1 %tmp1225}226 227define i1 @add_ugecmp_i64_i8(i64 %x) nounwind {228; CHECK-SD-LABEL: add_ugecmp_i64_i8:229; CHECK-SD: // %bb.0:230; CHECK-SD-NEXT: cmp x0, w0, sxtb231; CHECK-SD-NEXT: cset w0, eq232; CHECK-SD-NEXT: ret233;234; CHECK-GI-LABEL: add_ugecmp_i64_i8:235; CHECK-GI: // %bb.0:236; CHECK-GI-NEXT: sub x8, x0, #128237; CHECK-GI-NEXT: cmn x8, #256238; CHECK-GI-NEXT: cset w0, hs239; CHECK-GI-NEXT: ret240 %tmp0 = add i64 %x, -128 ; ~0U << (8-1)241 %tmp1 = icmp uge i64 %tmp0, -256 ; ~0U << 8242 ret i1 %tmp1243}244 245; Slightly more canonical variant246define i1 @add_ugtcmp_i16_i8(i16 %x) nounwind {247; CHECK-SD-LABEL: add_ugtcmp_i16_i8:248; CHECK-SD: // %bb.0:249; CHECK-SD-NEXT: and w8, w0, #0xffff250; CHECK-SD-NEXT: sub w8, w8, #128251; CHECK-SD-NEXT: lsr w8, w8, #8252; CHECK-SD-NEXT: cmp w8, #254253; CHECK-SD-NEXT: cset w0, hi254; CHECK-SD-NEXT: ret255;256; CHECK-GI-LABEL: add_ugtcmp_i16_i8:257; CHECK-GI: // %bb.0:258; CHECK-GI-NEXT: mov w8, #-128 // =0xffffff80259; CHECK-GI-NEXT: mov w9, #65279 // =0xfeff260; CHECK-GI-NEXT: add w8, w8, w0, uxth261; CHECK-GI-NEXT: cmp w8, w9262; CHECK-GI-NEXT: cset w0, hi263; CHECK-GI-NEXT: ret264 %tmp0 = add i16 %x, -128 ; ~0U << (8-1)265 %tmp1 = icmp ugt i16 %tmp0, -257 ; ~0U << 8 - 1266 ret i1 %tmp1267}268 269; ---------------------------------------------------------------------------- ;270; add + icmp ult271; ---------------------------------------------------------------------------- ;272 273define i1 @add_ultcmp_i16_i8(i16 %x) nounwind {274; CHECK-SD-LABEL: add_ultcmp_i16_i8:275; CHECK-SD: // %bb.0:276; CHECK-SD-NEXT: sxtb w8, w0277; CHECK-SD-NEXT: and w8, w8, #0xffff278; CHECK-SD-NEXT: cmp w8, w0, uxth279; CHECK-SD-NEXT: cset w0, eq280; CHECK-SD-NEXT: ret281;282; CHECK-GI-LABEL: add_ultcmp_i16_i8:283; CHECK-GI: // %bb.0:284; CHECK-GI-NEXT: add w8, w0, #128285; CHECK-GI-NEXT: and w8, w8, #0xffff286; CHECK-GI-NEXT: cmp w8, #256287; CHECK-GI-NEXT: cset w0, lo288; CHECK-GI-NEXT: ret289 %tmp0 = add i16 %x, 128 ; 1U << (8-1)290 %tmp1 = icmp ult i16 %tmp0, 256 ; 1U << 8291 ret i1 %tmp1292}293 294define i1 @add_ultcmp_i32_i16(i32 %x) nounwind {295; CHECK-SD-LABEL: add_ultcmp_i32_i16:296; CHECK-SD: // %bb.0:297; CHECK-SD-NEXT: cmp w0, w0, sxth298; CHECK-SD-NEXT: cset w0, eq299; CHECK-SD-NEXT: ret300;301; CHECK-GI-LABEL: add_ultcmp_i32_i16:302; CHECK-GI: // %bb.0:303; CHECK-GI-NEXT: add w8, w0, #8, lsl #12 // =32768304; CHECK-GI-NEXT: cmp w8, #16, lsl #12 // =65536305; CHECK-GI-NEXT: cset w0, lo306; CHECK-GI-NEXT: ret307 %tmp0 = add i32 %x, 32768 ; 1U << (16-1)308 %tmp1 = icmp ult i32 %tmp0, 65536 ; 1U << 16309 ret i1 %tmp1310}311 312define i1 @add_ultcmp_i32_i8(i32 %x) nounwind {313; CHECK-SD-LABEL: add_ultcmp_i32_i8:314; CHECK-SD: // %bb.0:315; CHECK-SD-NEXT: cmp w0, w0, sxtb316; CHECK-SD-NEXT: cset w0, eq317; CHECK-SD-NEXT: ret318;319; CHECK-GI-LABEL: add_ultcmp_i32_i8:320; CHECK-GI: // %bb.0:321; CHECK-GI-NEXT: add w8, w0, #128322; CHECK-GI-NEXT: cmp w8, #256323; CHECK-GI-NEXT: cset w0, lo324; CHECK-GI-NEXT: ret325 %tmp0 = add i32 %x, 128 ; 1U << (8-1)326 %tmp1 = icmp ult i32 %tmp0, 256 ; 1U << 8327 ret i1 %tmp1328}329 330define i1 @add_ultcmp_i64_i32(i64 %x) nounwind {331; CHECK-SD-LABEL: add_ultcmp_i64_i32:332; CHECK-SD: // %bb.0:333; CHECK-SD-NEXT: cmp x0, w0, sxtw334; CHECK-SD-NEXT: cset w0, eq335; CHECK-SD-NEXT: ret336;337; CHECK-GI-LABEL: add_ultcmp_i64_i32:338; CHECK-GI: // %bb.0:339; CHECK-GI-NEXT: mov w8, #-2147483648 // =0x80000000340; CHECK-GI-NEXT: mov x9, #4294967296 // =0x100000000341; CHECK-GI-NEXT: add x8, x0, x8342; CHECK-GI-NEXT: cmp x8, x9343; CHECK-GI-NEXT: cset w0, lo344; CHECK-GI-NEXT: ret345 %tmp0 = add i64 %x, 2147483648 ; 1U << (32-1)346 %tmp1 = icmp ult i64 %tmp0, 4294967296 ; 1U << 32347 ret i1 %tmp1348}349 350define i1 @add_ultcmp_i64_i16(i64 %x) nounwind {351; CHECK-SD-LABEL: add_ultcmp_i64_i16:352; CHECK-SD: // %bb.0:353; CHECK-SD-NEXT: cmp x0, w0, sxth354; CHECK-SD-NEXT: cset w0, eq355; CHECK-SD-NEXT: ret356;357; CHECK-GI-LABEL: add_ultcmp_i64_i16:358; CHECK-GI: // %bb.0:359; CHECK-GI-NEXT: add x8, x0, #8, lsl #12 // =32768360; CHECK-GI-NEXT: cmp x8, #16, lsl #12 // =65536361; CHECK-GI-NEXT: cset w0, lo362; CHECK-GI-NEXT: ret363 %tmp0 = add i64 %x, 32768 ; 1U << (16-1)364 %tmp1 = icmp ult i64 %tmp0, 65536 ; 1U << 16365 ret i1 %tmp1366}367 368define i1 @add_ultcmp_i64_i8(i64 %x) nounwind {369; CHECK-SD-LABEL: add_ultcmp_i64_i8:370; CHECK-SD: // %bb.0:371; CHECK-SD-NEXT: cmp x0, w0, sxtb372; CHECK-SD-NEXT: cset w0, eq373; CHECK-SD-NEXT: ret374;375; CHECK-GI-LABEL: add_ultcmp_i64_i8:376; CHECK-GI: // %bb.0:377; CHECK-GI-NEXT: add x8, x0, #128378; CHECK-GI-NEXT: cmp x8, #256379; CHECK-GI-NEXT: cset w0, lo380; CHECK-GI-NEXT: ret381 %tmp0 = add i64 %x, 128 ; 1U << (8-1)382 %tmp1 = icmp ult i64 %tmp0, 256 ; 1U << 8383 ret i1 %tmp1384}385 386; Slightly more canonical variant387define i1 @add_ulecmp_i16_i8(i16 %x) nounwind {388; CHECK-SD-LABEL: add_ulecmp_i16_i8:389; CHECK-SD: // %bb.0:390; CHECK-SD-NEXT: sxtb w8, w0391; CHECK-SD-NEXT: and w8, w8, #0xffff392; CHECK-SD-NEXT: cmp w8, w0, uxth393; CHECK-SD-NEXT: cset w0, eq394; CHECK-SD-NEXT: ret395;396; CHECK-GI-LABEL: add_ulecmp_i16_i8:397; CHECK-GI: // %bb.0:398; CHECK-GI-NEXT: add w8, w0, #128399; CHECK-GI-NEXT: and w8, w8, #0xffff400; CHECK-GI-NEXT: cmp w8, #255401; CHECK-GI-NEXT: cset w0, ls402; CHECK-GI-NEXT: ret403 %tmp0 = add i16 %x, 128 ; 1U << (8-1)404 %tmp1 = icmp ule i16 %tmp0, 255 ; (1U << 8) - 1405 ret i1 %tmp1406}407 408; Negative tests409; ---------------------------------------------------------------------------- ;410 411; Adding not a constant412define i1 @add_ultcmp_bad_i16_i8_add(i16 %x, i16 %y) nounwind {413; CHECK-SD-LABEL: add_ultcmp_bad_i16_i8_add:414; CHECK-SD: // %bb.0:415; CHECK-SD-NEXT: add w8, w0, w1416; CHECK-SD-NEXT: tst w8, #0xff00417; CHECK-SD-NEXT: cset w0, eq418; CHECK-SD-NEXT: ret419;420; CHECK-GI-LABEL: add_ultcmp_bad_i16_i8_add:421; CHECK-GI: // %bb.0:422; CHECK-GI-NEXT: add w8, w0, w1423; CHECK-GI-NEXT: and w8, w8, #0xffff424; CHECK-GI-NEXT: cmp w8, #256425; CHECK-GI-NEXT: cset w0, lo426; CHECK-GI-NEXT: ret427 %tmp0 = add i16 %x, %y428 %tmp1 = icmp ult i16 %tmp0, 256 ; 1U << 8429 ret i1 %tmp1430}431 432; Comparing not with a constant433define i1 @add_ultcmp_bad_i16_i8_cmp(i16 %x, i16 %y) nounwind {434; CHECK-LABEL: add_ultcmp_bad_i16_i8_cmp:435; CHECK: // %bb.0:436; CHECK-NEXT: add w8, w0, #128437; CHECK-NEXT: and w8, w8, #0xffff438; CHECK-NEXT: cmp w8, w1, uxth439; CHECK-NEXT: cset w0, lo440; CHECK-NEXT: ret441 %tmp0 = add i16 %x, 128 ; 1U << (8-1)442 %tmp1 = icmp ult i16 %tmp0, %y443 ret i1 %tmp1444}445 446; Second constant is not larger than the first one447define i1 @add_ultcmp_bad_i8_i16(i16 %x) nounwind {448; CHECK-SD-LABEL: add_ultcmp_bad_i8_i16:449; CHECK-SD: // %bb.0:450; CHECK-SD-NEXT: and w8, w0, #0xffff451; CHECK-SD-NEXT: add w8, w8, #128452; CHECK-SD-NEXT: lsr w0, w8, #16453; CHECK-SD-NEXT: ret454;455; CHECK-GI-LABEL: add_ultcmp_bad_i8_i16:456; CHECK-GI: // %bb.0:457; CHECK-GI-NEXT: and w8, w0, #0xffff458; CHECK-GI-NEXT: add w8, w8, #128459; CHECK-GI-NEXT: cmp w8, w8, uxth460; CHECK-GI-NEXT: cset w0, ne461; CHECK-GI-NEXT: ret462 %tmp0 = add i16 %x, 128 ; 1U << (8-1)463 %tmp1 = icmp ult i16 %tmp0, 128 ; 1U << (8-1)464 ret i1 %tmp1465}466 467; First constant is not power of two468define i1 @add_ultcmp_bad_i16_i8_c0notpoweroftwo(i16 %x) nounwind {469; CHECK-SD-LABEL: add_ultcmp_bad_i16_i8_c0notpoweroftwo:470; CHECK-SD: // %bb.0:471; CHECK-SD-NEXT: add w8, w0, #192472; CHECK-SD-NEXT: tst w8, #0xff00473; CHECK-SD-NEXT: cset w0, eq474; CHECK-SD-NEXT: ret475;476; CHECK-GI-LABEL: add_ultcmp_bad_i16_i8_c0notpoweroftwo:477; CHECK-GI: // %bb.0:478; CHECK-GI-NEXT: add w8, w0, #192479; CHECK-GI-NEXT: and w8, w8, #0xffff480; CHECK-GI-NEXT: cmp w8, #256481; CHECK-GI-NEXT: cset w0, lo482; CHECK-GI-NEXT: ret483 %tmp0 = add i16 %x, 192 ; (1U << (8-1)) + (1U << (8-1-1))484 %tmp1 = icmp ult i16 %tmp0, 256 ; 1U << 8485 ret i1 %tmp1486}487 488; Second constant is not power of two489define i1 @add_ultcmp_bad_i16_i8_c1notpoweroftwo(i16 %x) nounwind {490; CHECK-LABEL: add_ultcmp_bad_i16_i8_c1notpoweroftwo:491; CHECK: // %bb.0:492; CHECK-NEXT: add w8, w0, #128493; CHECK-NEXT: and w8, w8, #0xffff494; CHECK-NEXT: cmp w8, #768495; CHECK-NEXT: cset w0, lo496; CHECK-NEXT: ret497 %tmp0 = add i16 %x, 128 ; 1U << (8-1)498 %tmp1 = icmp ult i16 %tmp0, 768 ; (1U << 8)) + (1U << (8+1))499 ret i1 %tmp1500}501 502; Magic check fails, 64 << 1 != 256503define i1 @add_ultcmp_bad_i16_i8_magic(i16 %x) nounwind {504; CHECK-SD-LABEL: add_ultcmp_bad_i16_i8_magic:505; CHECK-SD: // %bb.0:506; CHECK-SD-NEXT: add w8, w0, #64507; CHECK-SD-NEXT: tst w8, #0xff00508; CHECK-SD-NEXT: cset w0, eq509; CHECK-SD-NEXT: ret510;511; CHECK-GI-LABEL: add_ultcmp_bad_i16_i8_magic:512; CHECK-GI: // %bb.0:513; CHECK-GI-NEXT: add w8, w0, #64514; CHECK-GI-NEXT: and w8, w8, #0xffff515; CHECK-GI-NEXT: cmp w8, #256516; CHECK-GI-NEXT: cset w0, lo517; CHECK-GI-NEXT: ret518 %tmp0 = add i16 %x, 64 ; 1U << (8-1-1)519 %tmp1 = icmp ult i16 %tmp0, 256 ; 1U << 8520 ret i1 %tmp1521}522 523; Bad 'destination type'524define i1 @add_ultcmp_bad_i16_i4(i16 %x) nounwind {525; CHECK-SD-LABEL: add_ultcmp_bad_i16_i4:526; CHECK-SD: // %bb.0:527; CHECK-SD-NEXT: add w8, w0, #8528; CHECK-SD-NEXT: tst w8, #0xfff0529; CHECK-SD-NEXT: cset w0, eq530; CHECK-SD-NEXT: ret531;532; CHECK-GI-LABEL: add_ultcmp_bad_i16_i4:533; CHECK-GI: // %bb.0:534; CHECK-GI-NEXT: add w8, w0, #8535; CHECK-GI-NEXT: and w8, w8, #0xffff536; CHECK-GI-NEXT: cmp w8, #16537; CHECK-GI-NEXT: cset w0, lo538; CHECK-GI-NEXT: ret539 %tmp0 = add i16 %x, 8 ; 1U << (4-1)540 %tmp1 = icmp ult i16 %tmp0, 16 ; 1U << 4541 ret i1 %tmp1542}543 544; Bad storage type545define i1 @add_ultcmp_bad_i24_i8(i24 %x) nounwind {546; CHECK-SD-LABEL: add_ultcmp_bad_i24_i8:547; CHECK-SD: // %bb.0:548; CHECK-SD-NEXT: add w8, w0, #128549; CHECK-SD-NEXT: tst w8, #0xffff00550; CHECK-SD-NEXT: cset w0, eq551; CHECK-SD-NEXT: ret552;553; CHECK-GI-LABEL: add_ultcmp_bad_i24_i8:554; CHECK-GI: // %bb.0:555; CHECK-GI-NEXT: add w8, w0, #128556; CHECK-GI-NEXT: and w8, w8, #0xffffff557; CHECK-GI-NEXT: cmp w8, #256558; CHECK-GI-NEXT: cset w0, lo559; CHECK-GI-NEXT: ret560 %tmp0 = add i24 %x, 128 ; 1U << (8-1)561 %tmp1 = icmp ult i24 %tmp0, 256 ; 1U << 8562 ret i1 %tmp1563}564 565define i1 @add_ulecmp_bad_i16_i8(i16 %x) nounwind {566; CHECK-LABEL: add_ulecmp_bad_i16_i8:567; CHECK: // %bb.0:568; CHECK-NEXT: mov w0, #1 // =0x1569; CHECK-NEXT: ret570 %tmp0 = add i16 %x, 128 ; 1U << (8-1)571 %tmp1 = icmp ule i16 %tmp0, -1 ; when we +1 it, it will wrap to 0572 ret i1 %tmp1573}574