646 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc -mtriple=i686-unknown-linux-gnu < %s | FileCheck %s --check-prefixes=CHECK,X863; RUN: llc -mtriple=x86_64-unknown-linux-gnu < %s | FileCheck %s --check-prefixes=CHECK,X644 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; X86-LABEL: shifts_eqcmp_i16_i8:24; X86: # %bb.0:25; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax26; X86-NEXT: movsbl %al, %ecx27; X86-NEXT: cmpw %ax, %cx28; X86-NEXT: sete %al29; X86-NEXT: retl30;31; X64-LABEL: shifts_eqcmp_i16_i8:32; X64: # %bb.0:33; X64-NEXT: movsbl %dil, %eax34; X64-NEXT: cmpw %di, %ax35; X64-NEXT: sete %al36; X64-NEXT: retq37 %tmp0 = shl i16 %x, 8 ; 16-838 %tmp1 = ashr exact i16 %tmp0, 8 ; 16-839 %tmp2 = icmp eq i16 %tmp1, %x40 ret i1 %tmp241}42 43define i1 @shifts_eqcmp_i32_i16(i32 %x) nounwind {44; X86-LABEL: shifts_eqcmp_i32_i16:45; X86: # %bb.0:46; X86-NEXT: movl {{[0-9]+}}(%esp), %eax47; X86-NEXT: movswl %ax, %ecx48; X86-NEXT: cmpl %eax, %ecx49; X86-NEXT: sete %al50; X86-NEXT: retl51;52; X64-LABEL: shifts_eqcmp_i32_i16:53; X64: # %bb.0:54; X64-NEXT: movswl %di, %eax55; X64-NEXT: cmpl %edi, %eax56; X64-NEXT: sete %al57; X64-NEXT: retq58 %tmp0 = shl i32 %x, 16 ; 32-1659 %tmp1 = ashr exact i32 %tmp0, 16 ; 32-1660 %tmp2 = icmp eq i32 %tmp1, %x61 ret i1 %tmp262}63 64define i1 @shifts_eqcmp_i32_i8(i32 %x) nounwind {65; X86-LABEL: shifts_eqcmp_i32_i8:66; X86: # %bb.0:67; X86-NEXT: movl {{[0-9]+}}(%esp), %eax68; X86-NEXT: movsbl %al, %ecx69; X86-NEXT: cmpl %eax, %ecx70; X86-NEXT: sete %al71; X86-NEXT: retl72;73; X64-LABEL: shifts_eqcmp_i32_i8:74; X64: # %bb.0:75; X64-NEXT: movsbl %dil, %eax76; X64-NEXT: cmpl %edi, %eax77; X64-NEXT: sete %al78; X64-NEXT: retq79 %tmp0 = shl i32 %x, 24 ; 32-880 %tmp1 = ashr exact i32 %tmp0, 24 ; 32-881 %tmp2 = icmp eq i32 %tmp1, %x82 ret i1 %tmp283}84 85define i1 @shifts_eqcmp_i64_i32(i64 %x) nounwind {86; X86-LABEL: shifts_eqcmp_i64_i32:87; X86: # %bb.0:88; X86-NEXT: movl {{[0-9]+}}(%esp), %eax89; X86-NEXT: sarl $31, %eax90; X86-NEXT: xorl {{[0-9]+}}(%esp), %eax91; X86-NEXT: sete %al92; X86-NEXT: retl93;94; X64-LABEL: shifts_eqcmp_i64_i32:95; X64: # %bb.0:96; X64-NEXT: movslq %edi, %rax97; X64-NEXT: cmpq %rdi, %rax98; X64-NEXT: sete %al99; X64-NEXT: retq100 %tmp0 = shl i64 %x, 32 ; 64-32101 %tmp1 = ashr exact i64 %tmp0, 32 ; 64-32102 %tmp2 = icmp eq i64 %tmp1, %x103 ret i1 %tmp2104}105 106define i1 @shifts_eqcmp_i64_i16(i64 %x) nounwind {107; X86-LABEL: shifts_eqcmp_i64_i16:108; X86: # %bb.0:109; X86-NEXT: movl {{[0-9]+}}(%esp), %eax110; X86-NEXT: movswl %ax, %ecx111; X86-NEXT: movl %ecx, %edx112; X86-NEXT: sarl $31, %edx113; X86-NEXT: xorl %eax, %ecx114; X86-NEXT: xorl {{[0-9]+}}(%esp), %edx115; X86-NEXT: orl %ecx, %edx116; X86-NEXT: sete %al117; X86-NEXT: retl118;119; X64-LABEL: shifts_eqcmp_i64_i16:120; X64: # %bb.0:121; X64-NEXT: movswq %di, %rax122; X64-NEXT: cmpq %rdi, %rax123; X64-NEXT: sete %al124; X64-NEXT: retq125 %tmp0 = shl i64 %x, 48 ; 64-16126 %tmp1 = ashr exact i64 %tmp0, 48 ; 64-16127 %tmp2 = icmp eq i64 %tmp1, %x128 ret i1 %tmp2129}130 131define i1 @shifts_eqcmp_i64_i8(i64 %x) nounwind {132; X86-LABEL: shifts_eqcmp_i64_i8:133; X86: # %bb.0:134; X86-NEXT: movl {{[0-9]+}}(%esp), %eax135; X86-NEXT: movsbl %al, %ecx136; X86-NEXT: movl %ecx, %edx137; X86-NEXT: sarl $31, %edx138; X86-NEXT: xorl %eax, %ecx139; X86-NEXT: xorl {{[0-9]+}}(%esp), %edx140; X86-NEXT: orl %ecx, %edx141; X86-NEXT: sete %al142; X86-NEXT: retl143;144; X64-LABEL: shifts_eqcmp_i64_i8:145; X64: # %bb.0:146; X64-NEXT: movsbq %dil, %rax147; X64-NEXT: cmpq %rdi, %rax148; X64-NEXT: sete %al149; X64-NEXT: retq150 %tmp0 = shl i64 %x, 56 ; 64-8151 %tmp1 = ashr exact i64 %tmp0, 56 ; 64-8152 %tmp2 = icmp eq i64 %tmp1, %x153 ret i1 %tmp2154}155 156; ---------------------------------------------------------------------------- ;157; add + icmp uge158; ---------------------------------------------------------------------------- ;159 160define i1 @add_ugecmp_i16_i8(i16 %x) nounwind {161; X86-LABEL: add_ugecmp_i16_i8:162; X86: # %bb.0:163; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax164; X86-NEXT: movsbl %al, %ecx165; X86-NEXT: cmpw %ax, %cx166; X86-NEXT: sete %al167; X86-NEXT: retl168;169; X64-LABEL: add_ugecmp_i16_i8:170; X64: # %bb.0:171; X64-NEXT: movsbl %dil, %eax172; X64-NEXT: cmpw %di, %ax173; X64-NEXT: sete %al174; X64-NEXT: retq175 %tmp0 = add i16 %x, -128 ; ~0U << (8-1)176 %tmp1 = icmp uge i16 %tmp0, -256 ; ~0U << 8177 ret i1 %tmp1178}179 180define i1 @add_ugecmp_i32_i16(i32 %x) nounwind {181; X86-LABEL: add_ugecmp_i32_i16:182; X86: # %bb.0:183; X86-NEXT: movl {{[0-9]+}}(%esp), %eax184; X86-NEXT: movswl %ax, %ecx185; X86-NEXT: cmpl %eax, %ecx186; X86-NEXT: sete %al187; X86-NEXT: retl188;189; X64-LABEL: add_ugecmp_i32_i16:190; X64: # %bb.0:191; X64-NEXT: movswl %di, %eax192; X64-NEXT: cmpl %edi, %eax193; X64-NEXT: sete %al194; X64-NEXT: retq195 %tmp0 = add i32 %x, -32768 ; ~0U << (16-1)196 %tmp1 = icmp uge i32 %tmp0, -65536 ; ~0U << 16197 ret i1 %tmp1198}199 200define i1 @add_ugecmp_i32_i8(i32 %x) nounwind {201; X86-LABEL: add_ugecmp_i32_i8:202; X86: # %bb.0:203; X86-NEXT: movl {{[0-9]+}}(%esp), %eax204; X86-NEXT: movsbl %al, %ecx205; X86-NEXT: cmpl %eax, %ecx206; X86-NEXT: sete %al207; X86-NEXT: retl208;209; X64-LABEL: add_ugecmp_i32_i8:210; X64: # %bb.0:211; X64-NEXT: movsbl %dil, %eax212; X64-NEXT: cmpl %edi, %eax213; X64-NEXT: sete %al214; X64-NEXT: retq215 %tmp0 = add i32 %x, -128 ; ~0U << (8-1)216 %tmp1 = icmp uge i32 %tmp0, -256 ; ~0U << 8217 ret i1 %tmp1218}219 220define i1 @add_ugecmp_i64_i32(i64 %x) nounwind {221; X86-LABEL: add_ugecmp_i64_i32:222; X86: # %bb.0:223; X86-NEXT: movl {{[0-9]+}}(%esp), %eax224; X86-NEXT: sarl $31, %eax225; X86-NEXT: xorl {{[0-9]+}}(%esp), %eax226; X86-NEXT: sete %al227; X86-NEXT: retl228;229; X64-LABEL: add_ugecmp_i64_i32:230; X64: # %bb.0:231; X64-NEXT: movslq %edi, %rax232; X64-NEXT: cmpq %rdi, %rax233; X64-NEXT: sete %al234; X64-NEXT: retq235 %tmp0 = add i64 %x, -2147483648 ; ~0U << (32-1)236 %tmp1 = icmp uge i64 %tmp0, -4294967296 ; ~0U << 32237 ret i1 %tmp1238}239 240define i1 @add_ugecmp_i64_i16(i64 %x) nounwind {241; X86-LABEL: add_ugecmp_i64_i16:242; X86: # %bb.0:243; X86-NEXT: movl {{[0-9]+}}(%esp), %eax244; X86-NEXT: movswl %ax, %ecx245; X86-NEXT: xorl %ecx, %eax246; X86-NEXT: sarl $31, %ecx247; X86-NEXT: xorl {{[0-9]+}}(%esp), %ecx248; X86-NEXT: orl %eax, %ecx249; X86-NEXT: sete %al250; X86-NEXT: retl251;252; X64-LABEL: add_ugecmp_i64_i16:253; X64: # %bb.0:254; X64-NEXT: movswq %di, %rax255; X64-NEXT: cmpq %rdi, %rax256; X64-NEXT: sete %al257; X64-NEXT: retq258 %tmp0 = add i64 %x, -32768 ; ~0U << (16-1)259 %tmp1 = icmp uge i64 %tmp0, -65536 ; ~0U << 16260 ret i1 %tmp1261}262 263define i1 @add_ugecmp_i64_i8(i64 %x) nounwind {264; X86-LABEL: add_ugecmp_i64_i8:265; X86: # %bb.0:266; X86-NEXT: movl {{[0-9]+}}(%esp), %eax267; X86-NEXT: movsbl %al, %ecx268; X86-NEXT: xorl %ecx, %eax269; X86-NEXT: sarl $31, %ecx270; X86-NEXT: xorl {{[0-9]+}}(%esp), %ecx271; X86-NEXT: orl %eax, %ecx272; X86-NEXT: sete %al273; X86-NEXT: retl274;275; X64-LABEL: add_ugecmp_i64_i8:276; X64: # %bb.0:277; X64-NEXT: movsbq %dil, %rax278; X64-NEXT: cmpq %rdi, %rax279; X64-NEXT: sete %al280; X64-NEXT: retq281 %tmp0 = add i64 %x, -128 ; ~0U << (8-1)282 %tmp1 = icmp uge i64 %tmp0, -256 ; ~0U << 8283 ret i1 %tmp1284}285 286; Slightly more canonical variant287define i1 @add_ugtcmp_i16_i8(i16 %x) nounwind {288; X86-LABEL: add_ugtcmp_i16_i8:289; X86: # %bb.0:290; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax291; X86-NEXT: movsbl %al, %ecx292; X86-NEXT: cmpw %ax, %cx293; X86-NEXT: sete %al294; X86-NEXT: retl295;296; X64-LABEL: add_ugtcmp_i16_i8:297; X64: # %bb.0:298; X64-NEXT: movsbl %dil, %eax299; X64-NEXT: cmpw %di, %ax300; X64-NEXT: sete %al301; X64-NEXT: retq302 %tmp0 = add i16 %x, -128 ; ~0U << (8-1)303 %tmp1 = icmp ugt i16 %tmp0, -257 ; ~0U << 8 - 1304 ret i1 %tmp1305}306 307; ---------------------------------------------------------------------------- ;308; add + icmp ult309; ---------------------------------------------------------------------------- ;310 311define i1 @add_ultcmp_i16_i8(i16 %x) nounwind {312; X86-LABEL: add_ultcmp_i16_i8:313; X86: # %bb.0:314; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax315; X86-NEXT: movsbl %al, %ecx316; X86-NEXT: cmpw %ax, %cx317; X86-NEXT: sete %al318; X86-NEXT: retl319;320; X64-LABEL: add_ultcmp_i16_i8:321; X64: # %bb.0:322; X64-NEXT: movsbl %dil, %eax323; X64-NEXT: cmpw %di, %ax324; X64-NEXT: sete %al325; X64-NEXT: retq326 %tmp0 = add i16 %x, 128 ; 1U << (8-1)327 %tmp1 = icmp ult i16 %tmp0, 256 ; 1U << 8328 ret i1 %tmp1329}330 331define i1 @add_ultcmp_i32_i16(i32 %x) nounwind {332; X86-LABEL: add_ultcmp_i32_i16:333; X86: # %bb.0:334; X86-NEXT: movl {{[0-9]+}}(%esp), %eax335; X86-NEXT: movswl %ax, %ecx336; X86-NEXT: cmpl %eax, %ecx337; X86-NEXT: sete %al338; X86-NEXT: retl339;340; X64-LABEL: add_ultcmp_i32_i16:341; X64: # %bb.0:342; X64-NEXT: movswl %di, %eax343; X64-NEXT: cmpl %edi, %eax344; X64-NEXT: sete %al345; X64-NEXT: retq346 %tmp0 = add i32 %x, 32768 ; 1U << (16-1)347 %tmp1 = icmp ult i32 %tmp0, 65536 ; 1U << 16348 ret i1 %tmp1349}350 351define i1 @add_ultcmp_i32_i8(i32 %x) nounwind {352; X86-LABEL: add_ultcmp_i32_i8:353; X86: # %bb.0:354; X86-NEXT: movl {{[0-9]+}}(%esp), %eax355; X86-NEXT: movsbl %al, %ecx356; X86-NEXT: cmpl %eax, %ecx357; X86-NEXT: sete %al358; X86-NEXT: retl359;360; X64-LABEL: add_ultcmp_i32_i8:361; X64: # %bb.0:362; X64-NEXT: movsbl %dil, %eax363; X64-NEXT: cmpl %edi, %eax364; X64-NEXT: sete %al365; X64-NEXT: retq366 %tmp0 = add i32 %x, 128 ; 1U << (8-1)367 %tmp1 = icmp ult i32 %tmp0, 256 ; 1U << 8368 ret i1 %tmp1369}370 371define i1 @add_ultcmp_i64_i32(i64 %x) nounwind {372; X86-LABEL: add_ultcmp_i64_i32:373; X86: # %bb.0:374; X86-NEXT: movl {{[0-9]+}}(%esp), %eax375; X86-NEXT: sarl $31, %eax376; X86-NEXT: xorl {{[0-9]+}}(%esp), %eax377; X86-NEXT: sete %al378; X86-NEXT: retl379;380; X64-LABEL: add_ultcmp_i64_i32:381; X64: # %bb.0:382; X64-NEXT: movslq %edi, %rax383; X64-NEXT: cmpq %rdi, %rax384; X64-NEXT: sete %al385; X64-NEXT: retq386 %tmp0 = add i64 %x, 2147483648 ; 1U << (32-1)387 %tmp1 = icmp ult i64 %tmp0, 4294967296 ; 1U << 32388 ret i1 %tmp1389}390 391define i1 @add_ultcmp_i64_i16(i64 %x) nounwind {392; X86-LABEL: add_ultcmp_i64_i16:393; X86: # %bb.0:394; X86-NEXT: movl {{[0-9]+}}(%esp), %eax395; X86-NEXT: movswl %ax, %ecx396; X86-NEXT: xorl %ecx, %eax397; X86-NEXT: sarl $31, %ecx398; X86-NEXT: xorl {{[0-9]+}}(%esp), %ecx399; X86-NEXT: orl %eax, %ecx400; X86-NEXT: sete %al401; X86-NEXT: retl402;403; X64-LABEL: add_ultcmp_i64_i16:404; X64: # %bb.0:405; X64-NEXT: movswq %di, %rax406; X64-NEXT: cmpq %rdi, %rax407; X64-NEXT: sete %al408; X64-NEXT: retq409 %tmp0 = add i64 %x, 32768 ; 1U << (16-1)410 %tmp1 = icmp ult i64 %tmp0, 65536 ; 1U << 16411 ret i1 %tmp1412}413 414define i1 @add_ultcmp_i64_i8(i64 %x) nounwind {415; X86-LABEL: add_ultcmp_i64_i8:416; X86: # %bb.0:417; X86-NEXT: movl {{[0-9]+}}(%esp), %eax418; X86-NEXT: movsbl %al, %ecx419; X86-NEXT: xorl %ecx, %eax420; X86-NEXT: sarl $31, %ecx421; X86-NEXT: xorl {{[0-9]+}}(%esp), %ecx422; X86-NEXT: orl %eax, %ecx423; X86-NEXT: sete %al424; X86-NEXT: retl425;426; X64-LABEL: add_ultcmp_i64_i8:427; X64: # %bb.0:428; X64-NEXT: movsbq %dil, %rax429; X64-NEXT: cmpq %rdi, %rax430; X64-NEXT: sete %al431; X64-NEXT: retq432 %tmp0 = add i64 %x, 128 ; 1U << (8-1)433 %tmp1 = icmp ult i64 %tmp0, 256 ; 1U << 8434 ret i1 %tmp1435}436 437; Slightly more canonical variant438define i1 @add_ulecmp_i16_i8(i16 %x) nounwind {439; X86-LABEL: add_ulecmp_i16_i8:440; X86: # %bb.0:441; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax442; X86-NEXT: movsbl %al, %ecx443; X86-NEXT: cmpw %ax, %cx444; X86-NEXT: sete %al445; X86-NEXT: retl446;447; X64-LABEL: add_ulecmp_i16_i8:448; X64: # %bb.0:449; X64-NEXT: movsbl %dil, %eax450; X64-NEXT: cmpw %di, %ax451; X64-NEXT: sete %al452; X64-NEXT: retq453 %tmp0 = add i16 %x, 128 ; 1U << (8-1)454 %tmp1 = icmp ule i16 %tmp0, 255 ; (1U << 8) - 1455 ret i1 %tmp1456}457 458; Negative tests459; ---------------------------------------------------------------------------- ;460 461; Adding not a constant462define i1 @add_ultcmp_bad_i16_i8_add(i16 %x, i16 %y) nounwind {463; X86-LABEL: add_ultcmp_bad_i16_i8_add:464; X86: # %bb.0:465; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax466; X86-NEXT: addw {{[0-9]+}}(%esp), %ax467; X86-NEXT: movzwl %ax, %eax468; X86-NEXT: cmpl $256, %eax # imm = 0x100469; X86-NEXT: setb %al470; X86-NEXT: retl471;472; X64-LABEL: add_ultcmp_bad_i16_i8_add:473; X64: # %bb.0:474; X64-NEXT: addl %esi, %edi475; X64-NEXT: movzwl %di, %eax476; X64-NEXT: cmpl $256, %eax # imm = 0x100477; X64-NEXT: setb %al478; X64-NEXT: retq479 %tmp0 = add i16 %x, %y480 %tmp1 = icmp ult i16 %tmp0, 256 ; 1U << 8481 ret i1 %tmp1482}483 484; Comparing not with a constant485define i1 @add_ultcmp_bad_i16_i8_cmp(i16 %x, i16 %y) nounwind {486; X86-LABEL: add_ultcmp_bad_i16_i8_cmp:487; X86: # %bb.0:488; X86-NEXT: movl {{[0-9]+}}(%esp), %eax489; X86-NEXT: subl $-128, %eax490; X86-NEXT: cmpw {{[0-9]+}}(%esp), %ax491; X86-NEXT: setb %al492; X86-NEXT: retl493;494; X64-LABEL: add_ultcmp_bad_i16_i8_cmp:495; X64: # %bb.0:496; X64-NEXT: subl $-128, %edi497; X64-NEXT: cmpw %si, %di498; X64-NEXT: setb %al499; X64-NEXT: retq500 %tmp0 = add i16 %x, 128 ; 1U << (8-1)501 %tmp1 = icmp ult i16 %tmp0, %y502 ret i1 %tmp1503}504 505; Second constant is not larger than the first one506define i1 @add_ultcmp_bad_i8_i16(i16 %x) nounwind {507; X86-LABEL: add_ultcmp_bad_i8_i16:508; X86: # %bb.0:509; X86-NEXT: movw $128, %ax510; X86-NEXT: addw {{[0-9]+}}(%esp), %ax511; X86-NEXT: setb %al512; X86-NEXT: retl513;514; X64-LABEL: add_ultcmp_bad_i8_i16:515; X64: # %bb.0:516; X64-NEXT: addw $128, %di517; X64-NEXT: setb %al518; X64-NEXT: retq519 %tmp0 = add i16 %x, 128 ; 1U << (8-1)520 %tmp1 = icmp ult i16 %tmp0, 128 ; 1U << (8-1)521 ret i1 %tmp1522}523 524; First constant is not power of two525define i1 @add_ultcmp_bad_i16_i8_c0notpoweroftwo(i16 %x) nounwind {526; X86-LABEL: add_ultcmp_bad_i16_i8_c0notpoweroftwo:527; X86: # %bb.0:528; X86-NEXT: movl $192, %eax529; X86-NEXT: addl {{[0-9]+}}(%esp), %eax530; X86-NEXT: movzwl %ax, %eax531; X86-NEXT: cmpl $256, %eax # imm = 0x100532; X86-NEXT: setb %al533; X86-NEXT: retl534;535; X64-LABEL: add_ultcmp_bad_i16_i8_c0notpoweroftwo:536; X64: # %bb.0:537; X64-NEXT: addl $192, %edi538; X64-NEXT: movzwl %di, %eax539; X64-NEXT: cmpl $256, %eax # imm = 0x100540; X64-NEXT: setb %al541; X64-NEXT: retq542 %tmp0 = add i16 %x, 192 ; (1U << (8-1)) + (1U << (8-1-1))543 %tmp1 = icmp ult i16 %tmp0, 256 ; 1U << 8544 ret i1 %tmp1545}546 547; Second constant is not power of two548define i1 @add_ultcmp_bad_i16_i8_c1notpoweroftwo(i16 %x) nounwind {549; X86-LABEL: add_ultcmp_bad_i16_i8_c1notpoweroftwo:550; X86: # %bb.0:551; X86-NEXT: movl {{[0-9]+}}(%esp), %eax552; X86-NEXT: subl $-128, %eax553; X86-NEXT: movzwl %ax, %eax554; X86-NEXT: cmpl $768, %eax # imm = 0x300555; X86-NEXT: setb %al556; X86-NEXT: retl557;558; X64-LABEL: add_ultcmp_bad_i16_i8_c1notpoweroftwo:559; X64: # %bb.0:560; X64-NEXT: subl $-128, %edi561; X64-NEXT: movzwl %di, %eax562; X64-NEXT: cmpl $768, %eax # imm = 0x300563; X64-NEXT: setb %al564; X64-NEXT: retq565 %tmp0 = add i16 %x, 128 ; 1U << (8-1)566 %tmp1 = icmp ult i16 %tmp0, 768 ; (1U << 8)) + (1U << (8+1))567 ret i1 %tmp1568}569 570; Magic check fails, 64 << 1 != 256571define i1 @add_ultcmp_bad_i16_i8_magic(i16 %x) nounwind {572; X86-LABEL: add_ultcmp_bad_i16_i8_magic:573; X86: # %bb.0:574; X86-NEXT: movl {{[0-9]+}}(%esp), %eax575; X86-NEXT: addl $64, %eax576; X86-NEXT: movzwl %ax, %eax577; X86-NEXT: cmpl $256, %eax # imm = 0x100578; X86-NEXT: setb %al579; X86-NEXT: retl580;581; X64-LABEL: add_ultcmp_bad_i16_i8_magic:582; X64: # %bb.0:583; X64-NEXT: addl $64, %edi584; X64-NEXT: movzwl %di, %eax585; X64-NEXT: cmpl $256, %eax # imm = 0x100586; X64-NEXT: setb %al587; X64-NEXT: retq588 %tmp0 = add i16 %x, 64 ; 1U << (8-1-1)589 %tmp1 = icmp ult i16 %tmp0, 256 ; 1U << 8590 ret i1 %tmp1591}592 593; Bad 'destination type'594define i1 @add_ultcmp_bad_i16_i4(i16 %x) nounwind {595; X86-LABEL: add_ultcmp_bad_i16_i4:596; X86: # %bb.0:597; X86-NEXT: movl {{[0-9]+}}(%esp), %eax598; X86-NEXT: addl $8, %eax599; X86-NEXT: cmpw $16, %ax600; X86-NEXT: setb %al601; X86-NEXT: retl602;603; X64-LABEL: add_ultcmp_bad_i16_i4:604; X64: # %bb.0:605; X64-NEXT: addl $8, %edi606; X64-NEXT: cmpw $16, %di607; X64-NEXT: setb %al608; X64-NEXT: retq609 %tmp0 = add i16 %x, 8 ; 1U << (4-1)610 %tmp1 = icmp ult i16 %tmp0, 16 ; 1U << 4611 ret i1 %tmp1612}613 614; Bad storage type615define i1 @add_ultcmp_bad_i24_i8(i24 %x) nounwind {616; X86-LABEL: add_ultcmp_bad_i24_i8:617; X86: # %bb.0:618; X86-NEXT: movl {{[0-9]+}}(%esp), %eax619; X86-NEXT: subl $-128, %eax620; X86-NEXT: andl $16777215, %eax # imm = 0xFFFFFF621; X86-NEXT: cmpl $256, %eax # imm = 0x100622; X86-NEXT: setb %al623; X86-NEXT: retl624;625; X64-LABEL: add_ultcmp_bad_i24_i8:626; X64: # %bb.0:627; X64-NEXT: subl $-128, %edi628; X64-NEXT: andl $16777215, %edi # imm = 0xFFFFFF629; X64-NEXT: cmpl $256, %edi # imm = 0x100630; X64-NEXT: setb %al631; X64-NEXT: retq632 %tmp0 = add i24 %x, 128 ; 1U << (8-1)633 %tmp1 = icmp ult i24 %tmp0, 256 ; 1U << 8634 ret i1 %tmp1635}636 637define i1 @add_ulecmp_bad_i16_i8(i16 %x) nounwind {638; CHECK-LABEL: add_ulecmp_bad_i16_i8:639; CHECK: # %bb.0:640; CHECK-NEXT: movb $1, %al641; CHECK-NEXT: ret{{[l|q]}}642 %tmp0 = add i16 %x, 128 ; 1U << (8-1)643 %tmp1 = icmp ule i16 %tmp0, -1 ; when we +1 it, it will wrap to 0644 ret i1 %tmp1645}646