1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple=i686-unknown-linux-gnu < %s | FileCheck %s --check-prefixes=CHECK,X86 3; RUN: llc -mtriple=x86_64-unknown-linux-gnu < %s | FileCheck %s --check-prefixes=CHECK,X64 4 5; https://bugs.llvm.org/show_bug.cgi?id=38149 6 7; We are truncating from wider width, and then sign-extending 8; 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 canonical 13; shl + ashr + icmp eq 14; add + icmp uge/ugt 15; add + icmp ult/ule 16; However only the simplest form (with two shifts) gets lowered best. 17 18; ---------------------------------------------------------------------------- ; 19; shl + ashr + icmp eq 20; ---------------------------------------------------------------------------- ; 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), %eax 26; X86-NEXT: movsbl %al, %ecx 27; X86-NEXT: cmpw %ax, %cx 28; X86-NEXT: sete %al 29; X86-NEXT: retl 30; 31; X64-LABEL: shifts_eqcmp_i16_i8: 32; X64: # %bb.0: 33; X64-NEXT: movsbl %dil, %eax 34; X64-NEXT: cmpw %di, %ax 35; X64-NEXT: sete %al 36; X64-NEXT: retq 37 %tmp0 = shl i16 %x, 8 ; 16-8 38 %tmp1 = ashr exact i16 %tmp0, 8 ; 16-8 39 %tmp2 = icmp eq i16 %tmp1, %x 40 ret i1 %tmp2 41} 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), %eax 47; X86-NEXT: movswl %ax, %ecx 48; X86-NEXT: cmpl %eax, %ecx 49; X86-NEXT: sete %al 50; X86-NEXT: retl 51; 52; X64-LABEL: shifts_eqcmp_i32_i16: 53; X64: # %bb.0: 54; X64-NEXT: movswl %di, %eax 55; X64-NEXT: cmpl %edi, %eax 56; X64-NEXT: sete %al 57; X64-NEXT: retq 58 %tmp0 = shl i32 %x, 16 ; 32-16 59 %tmp1 = ashr exact i32 %tmp0, 16 ; 32-16 60 %tmp2 = icmp eq i32 %tmp1, %x 61 ret i1 %tmp2 62} 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), %eax 68; X86-NEXT: movsbl %al, %ecx 69; X86-NEXT: cmpl %eax, %ecx 70; X86-NEXT: sete %al 71; X86-NEXT: retl 72; 73; X64-LABEL: shifts_eqcmp_i32_i8: 74; X64: # %bb.0: 75; X64-NEXT: movsbl %dil, %eax 76; X64-NEXT: cmpl %edi, %eax 77; X64-NEXT: sete %al 78; X64-NEXT: retq 79 %tmp0 = shl i32 %x, 24 ; 32-8 80 %tmp1 = ashr exact i32 %tmp0, 24 ; 32-8 81 %tmp2 = icmp eq i32 %tmp1, %x 82 ret i1 %tmp2 83} 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), %eax 89; X86-NEXT: sarl $31, %eax 90; X86-NEXT: xorl {{[0-9]+}}(%esp), %eax 91; X86-NEXT: sete %al 92; X86-NEXT: retl 93; 94; X64-LABEL: shifts_eqcmp_i64_i32: 95; X64: # %bb.0: 96; X64-NEXT: movslq %edi, %rax 97; X64-NEXT: cmpq %rdi, %rax 98; X64-NEXT: sete %al 99; X64-NEXT: retq 100 %tmp0 = shl i64 %x, 32 ; 64-32 101 %tmp1 = ashr exact i64 %tmp0, 32 ; 64-32 102 %tmp2 = icmp eq i64 %tmp1, %x 103 ret i1 %tmp2 104} 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), %eax 110; X86-NEXT: movswl %ax, %ecx 111; X86-NEXT: movl %ecx, %edx 112; X86-NEXT: sarl $31, %edx 113; X86-NEXT: xorl %eax, %ecx 114; X86-NEXT: xorl {{[0-9]+}}(%esp), %edx 115; X86-NEXT: orl %ecx, %edx 116; X86-NEXT: sete %al 117; X86-NEXT: retl 118; 119; X64-LABEL: shifts_eqcmp_i64_i16: 120; X64: # %bb.0: 121; X64-NEXT: movswq %di, %rax 122; X64-NEXT: cmpq %rdi, %rax 123; X64-NEXT: sete %al 124; X64-NEXT: retq 125 %tmp0 = shl i64 %x, 48 ; 64-16 126 %tmp1 = ashr exact i64 %tmp0, 48 ; 64-16 127 %tmp2 = icmp eq i64 %tmp1, %x 128 ret i1 %tmp2 129} 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), %eax 135; X86-NEXT: movsbl %al, %ecx 136; X86-NEXT: movl %ecx, %edx 137; X86-NEXT: sarl $31, %edx 138; X86-NEXT: xorl %eax, %ecx 139; X86-NEXT: xorl {{[0-9]+}}(%esp), %edx 140; X86-NEXT: orl %ecx, %edx 141; X86-NEXT: sete %al 142; X86-NEXT: retl 143; 144; X64-LABEL: shifts_eqcmp_i64_i8: 145; X64: # %bb.0: 146; X64-NEXT: movsbq %dil, %rax 147; X64-NEXT: cmpq %rdi, %rax 148; X64-NEXT: sete %al 149; X64-NEXT: retq 150 %tmp0 = shl i64 %x, 56 ; 64-8 151 %tmp1 = ashr exact i64 %tmp0, 56 ; 64-8 152 %tmp2 = icmp eq i64 %tmp1, %x 153 ret i1 %tmp2 154} 155 156; ---------------------------------------------------------------------------- ; 157; add + icmp uge 158; ---------------------------------------------------------------------------- ; 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), %eax 164; X86-NEXT: movsbl %al, %ecx 165; X86-NEXT: cmpw %ax, %cx 166; X86-NEXT: sete %al 167; X86-NEXT: retl 168; 169; X64-LABEL: add_ugecmp_i16_i8: 170; X64: # %bb.0: 171; X64-NEXT: movsbl %dil, %eax 172; X64-NEXT: cmpw %di, %ax 173; X64-NEXT: sete %al 174; X64-NEXT: retq 175 %tmp0 = add i16 %x, -128 ; ~0U << (8-1) 176 %tmp1 = icmp uge i16 %tmp0, -256 ; ~0U << 8 177 ret i1 %tmp1 178} 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), %eax 184; X86-NEXT: movswl %ax, %ecx 185; X86-NEXT: cmpl %eax, %ecx 186; X86-NEXT: sete %al 187; X86-NEXT: retl 188; 189; X64-LABEL: add_ugecmp_i32_i16: 190; X64: # %bb.0: 191; X64-NEXT: movswl %di, %eax 192; X64-NEXT: cmpl %edi, %eax 193; X64-NEXT: sete %al 194; X64-NEXT: retq 195 %tmp0 = add i32 %x, -32768 ; ~0U << (16-1) 196 %tmp1 = icmp uge i32 %tmp0, -65536 ; ~0U << 16 197 ret i1 %tmp1 198} 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), %eax 204; X86-NEXT: movsbl %al, %ecx 205; X86-NEXT: cmpl %eax, %ecx 206; X86-NEXT: sete %al 207; X86-NEXT: retl 208; 209; X64-LABEL: add_ugecmp_i32_i8: 210; X64: # %bb.0: 211; X64-NEXT: movsbl %dil, %eax 212; X64-NEXT: cmpl %edi, %eax 213; X64-NEXT: sete %al 214; X64-NEXT: retq 215 %tmp0 = add i32 %x, -128 ; ~0U << (8-1) 216 %tmp1 = icmp uge i32 %tmp0, -256 ; ~0U << 8 217 ret i1 %tmp1 218} 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), %eax 224; X86-NEXT: sarl $31, %eax 225; X86-NEXT: xorl {{[0-9]+}}(%esp), %eax 226; X86-NEXT: sete %al 227; X86-NEXT: retl 228; 229; X64-LABEL: add_ugecmp_i64_i32: 230; X64: # %bb.0: 231; X64-NEXT: movslq %edi, %rax 232; X64-NEXT: cmpq %rdi, %rax 233; X64-NEXT: sete %al 234; X64-NEXT: retq 235 %tmp0 = add i64 %x, -2147483648 ; ~0U << (32-1) 236 %tmp1 = icmp uge i64 %tmp0, -4294967296 ; ~0U << 32 237 ret i1 %tmp1 238} 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), %eax 244; X86-NEXT: movswl %ax, %ecx 245; X86-NEXT: xorl %ecx, %eax 246; X86-NEXT: sarl $31, %ecx 247; X86-NEXT: xorl {{[0-9]+}}(%esp), %ecx 248; X86-NEXT: orl %eax, %ecx 249; X86-NEXT: sete %al 250; X86-NEXT: retl 251; 252; X64-LABEL: add_ugecmp_i64_i16: 253; X64: # %bb.0: 254; X64-NEXT: movswq %di, %rax 255; X64-NEXT: cmpq %rdi, %rax 256; X64-NEXT: sete %al 257; X64-NEXT: retq 258 %tmp0 = add i64 %x, -32768 ; ~0U << (16-1) 259 %tmp1 = icmp uge i64 %tmp0, -65536 ; ~0U << 16 260 ret i1 %tmp1 261} 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), %eax 267; X86-NEXT: movsbl %al, %ecx 268; X86-NEXT: xorl %ecx, %eax 269; X86-NEXT: sarl $31, %ecx 270; X86-NEXT: xorl {{[0-9]+}}(%esp), %ecx 271; X86-NEXT: orl %eax, %ecx 272; X86-NEXT: sete %al 273; X86-NEXT: retl 274; 275; X64-LABEL: add_ugecmp_i64_i8: 276; X64: # %bb.0: 277; X64-NEXT: movsbq %dil, %rax 278; X64-NEXT: cmpq %rdi, %rax 279; X64-NEXT: sete %al 280; X64-NEXT: retq 281 %tmp0 = add i64 %x, -128 ; ~0U << (8-1) 282 %tmp1 = icmp uge i64 %tmp0, -256 ; ~0U << 8 283 ret i1 %tmp1 284} 285 286; Slightly more canonical variant 287define 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), %eax 291; X86-NEXT: movsbl %al, %ecx 292; X86-NEXT: cmpw %ax, %cx 293; X86-NEXT: sete %al 294; X86-NEXT: retl 295; 296; X64-LABEL: add_ugtcmp_i16_i8: 297; X64: # %bb.0: 298; X64-NEXT: movsbl %dil, %eax 299; X64-NEXT: cmpw %di, %ax 300; X64-NEXT: sete %al 301; X64-NEXT: retq 302 %tmp0 = add i16 %x, -128 ; ~0U << (8-1) 303 %tmp1 = icmp ugt i16 %tmp0, -257 ; ~0U << 8 - 1 304 ret i1 %tmp1 305} 306 307; ---------------------------------------------------------------------------- ; 308; add + icmp ult 309; ---------------------------------------------------------------------------- ; 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), %eax 315; X86-NEXT: movsbl %al, %ecx 316; X86-NEXT: cmpw %ax, %cx 317; X86-NEXT: sete %al 318; X86-NEXT: retl 319; 320; X64-LABEL: add_ultcmp_i16_i8: 321; X64: # %bb.0: 322; X64-NEXT: movsbl %dil, %eax 323; X64-NEXT: cmpw %di, %ax 324; X64-NEXT: sete %al 325; X64-NEXT: retq 326 %tmp0 = add i16 %x, 128 ; 1U << (8-1) 327 %tmp1 = icmp ult i16 %tmp0, 256 ; 1U << 8 328 ret i1 %tmp1 329} 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), %eax 335; X86-NEXT: movswl %ax, %ecx 336; X86-NEXT: cmpl %eax, %ecx 337; X86-NEXT: sete %al 338; X86-NEXT: retl 339; 340; X64-LABEL: add_ultcmp_i32_i16: 341; X64: # %bb.0: 342; X64-NEXT: movswl %di, %eax 343; X64-NEXT: cmpl %edi, %eax 344; X64-NEXT: sete %al 345; X64-NEXT: retq 346 %tmp0 = add i32 %x, 32768 ; 1U << (16-1) 347 %tmp1 = icmp ult i32 %tmp0, 65536 ; 1U << 16 348 ret i1 %tmp1 349} 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), %eax 355; X86-NEXT: movsbl %al, %ecx 356; X86-NEXT: cmpl %eax, %ecx 357; X86-NEXT: sete %al 358; X86-NEXT: retl 359; 360; X64-LABEL: add_ultcmp_i32_i8: 361; X64: # %bb.0: 362; X64-NEXT: movsbl %dil, %eax 363; X64-NEXT: cmpl %edi, %eax 364; X64-NEXT: sete %al 365; X64-NEXT: retq 366 %tmp0 = add i32 %x, 128 ; 1U << (8-1) 367 %tmp1 = icmp ult i32 %tmp0, 256 ; 1U << 8 368 ret i1 %tmp1 369} 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), %eax 375; X86-NEXT: sarl $31, %eax 376; X86-NEXT: xorl {{[0-9]+}}(%esp), %eax 377; X86-NEXT: sete %al 378; X86-NEXT: retl 379; 380; X64-LABEL: add_ultcmp_i64_i32: 381; X64: # %bb.0: 382; X64-NEXT: movslq %edi, %rax 383; X64-NEXT: cmpq %rdi, %rax 384; X64-NEXT: sete %al 385; X64-NEXT: retq 386 %tmp0 = add i64 %x, 2147483648 ; 1U << (32-1) 387 %tmp1 = icmp ult i64 %tmp0, 4294967296 ; 1U << 32 388 ret i1 %tmp1 389} 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), %eax 395; X86-NEXT: movswl %ax, %ecx 396; X86-NEXT: xorl %ecx, %eax 397; X86-NEXT: sarl $31, %ecx 398; X86-NEXT: xorl {{[0-9]+}}(%esp), %ecx 399; X86-NEXT: orl %eax, %ecx 400; X86-NEXT: sete %al 401; X86-NEXT: retl 402; 403; X64-LABEL: add_ultcmp_i64_i16: 404; X64: # %bb.0: 405; X64-NEXT: movswq %di, %rax 406; X64-NEXT: cmpq %rdi, %rax 407; X64-NEXT: sete %al 408; X64-NEXT: retq 409 %tmp0 = add i64 %x, 32768 ; 1U << (16-1) 410 %tmp1 = icmp ult i64 %tmp0, 65536 ; 1U << 16 411 ret i1 %tmp1 412} 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), %eax 418; X86-NEXT: movsbl %al, %ecx 419; X86-NEXT: xorl %ecx, %eax 420; X86-NEXT: sarl $31, %ecx 421; X86-NEXT: xorl {{[0-9]+}}(%esp), %ecx 422; X86-NEXT: orl %eax, %ecx 423; X86-NEXT: sete %al 424; X86-NEXT: retl 425; 426; X64-LABEL: add_ultcmp_i64_i8: 427; X64: # %bb.0: 428; X64-NEXT: movsbq %dil, %rax 429; X64-NEXT: cmpq %rdi, %rax 430; X64-NEXT: sete %al 431; X64-NEXT: retq 432 %tmp0 = add i64 %x, 128 ; 1U << (8-1) 433 %tmp1 = icmp ult i64 %tmp0, 256 ; 1U << 8 434 ret i1 %tmp1 435} 436 437; Slightly more canonical variant 438define 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), %eax 442; X86-NEXT: movsbl %al, %ecx 443; X86-NEXT: cmpw %ax, %cx 444; X86-NEXT: sete %al 445; X86-NEXT: retl 446; 447; X64-LABEL: add_ulecmp_i16_i8: 448; X64: # %bb.0: 449; X64-NEXT: movsbl %dil, %eax 450; X64-NEXT: cmpw %di, %ax 451; X64-NEXT: sete %al 452; X64-NEXT: retq 453 %tmp0 = add i16 %x, 128 ; 1U << (8-1) 454 %tmp1 = icmp ule i16 %tmp0, 255 ; (1U << 8) - 1 455 ret i1 %tmp1 456} 457 458; Negative tests 459; ---------------------------------------------------------------------------- ; 460 461; Adding not a constant 462define 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), %eax 466; X86-NEXT: addw {{[0-9]+}}(%esp), %ax 467; X86-NEXT: movzwl %ax, %eax 468; X86-NEXT: cmpl $256, %eax # imm = 0x100 469; X86-NEXT: setb %al 470; X86-NEXT: retl 471; 472; X64-LABEL: add_ultcmp_bad_i16_i8_add: 473; X64: # %bb.0: 474; X64-NEXT: addl %esi, %edi 475; X64-NEXT: movzwl %di, %eax 476; X64-NEXT: cmpl $256, %eax # imm = 0x100 477; X64-NEXT: setb %al 478; X64-NEXT: retq 479 %tmp0 = add i16 %x, %y 480 %tmp1 = icmp ult i16 %tmp0, 256 ; 1U << 8 481 ret i1 %tmp1 482} 483 484; Comparing not with a constant 485define 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), %eax 489; X86-NEXT: subl $-128, %eax 490; X86-NEXT: cmpw {{[0-9]+}}(%esp), %ax 491; X86-NEXT: setb %al 492; X86-NEXT: retl 493; 494; X64-LABEL: add_ultcmp_bad_i16_i8_cmp: 495; X64: # %bb.0: 496; X64-NEXT: subl $-128, %edi 497; X64-NEXT: cmpw %si, %di 498; X64-NEXT: setb %al 499; X64-NEXT: retq 500 %tmp0 = add i16 %x, 128 ; 1U << (8-1) 501 %tmp1 = icmp ult i16 %tmp0, %y 502 ret i1 %tmp1 503} 504 505; Second constant is not larger than the first one 506define 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, %ax 510; X86-NEXT: addw {{[0-9]+}}(%esp), %ax 511; X86-NEXT: setb %al 512; X86-NEXT: retl 513; 514; X64-LABEL: add_ultcmp_bad_i8_i16: 515; X64: # %bb.0: 516; X64-NEXT: addw $128, %di 517; X64-NEXT: setb %al 518; X64-NEXT: retq 519 %tmp0 = add i16 %x, 128 ; 1U << (8-1) 520 %tmp1 = icmp ult i16 %tmp0, 128 ; 1U << (8-1) 521 ret i1 %tmp1 522} 523 524; First constant is not power of two 525define 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, %eax 529; X86-NEXT: addl {{[0-9]+}}(%esp), %eax 530; X86-NEXT: movzwl %ax, %eax 531; X86-NEXT: cmpl $256, %eax # imm = 0x100 532; X86-NEXT: setb %al 533; X86-NEXT: retl 534; 535; X64-LABEL: add_ultcmp_bad_i16_i8_c0notpoweroftwo: 536; X64: # %bb.0: 537; X64-NEXT: addl $192, %edi 538; X64-NEXT: movzwl %di, %eax 539; X64-NEXT: cmpl $256, %eax # imm = 0x100 540; X64-NEXT: setb %al 541; X64-NEXT: retq 542 %tmp0 = add i16 %x, 192 ; (1U << (8-1)) + (1U << (8-1-1)) 543 %tmp1 = icmp ult i16 %tmp0, 256 ; 1U << 8 544 ret i1 %tmp1 545} 546 547; Second constant is not power of two 548define 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), %eax 552; X86-NEXT: subl $-128, %eax 553; X86-NEXT: movzwl %ax, %eax 554; X86-NEXT: cmpl $768, %eax # imm = 0x300 555; X86-NEXT: setb %al 556; X86-NEXT: retl 557; 558; X64-LABEL: add_ultcmp_bad_i16_i8_c1notpoweroftwo: 559; X64: # %bb.0: 560; X64-NEXT: subl $-128, %edi 561; X64-NEXT: movzwl %di, %eax 562; X64-NEXT: cmpl $768, %eax # imm = 0x300 563; X64-NEXT: setb %al 564; X64-NEXT: retq 565 %tmp0 = add i16 %x, 128 ; 1U << (8-1) 566 %tmp1 = icmp ult i16 %tmp0, 768 ; (1U << 8)) + (1U << (8+1)) 567 ret i1 %tmp1 568} 569 570; Magic check fails, 64 << 1 != 256 571define 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), %eax 575; X86-NEXT: addl $64, %eax 576; X86-NEXT: movzwl %ax, %eax 577; X86-NEXT: cmpl $256, %eax # imm = 0x100 578; X86-NEXT: setb %al 579; X86-NEXT: retl 580; 581; X64-LABEL: add_ultcmp_bad_i16_i8_magic: 582; X64: # %bb.0: 583; X64-NEXT: addl $64, %edi 584; X64-NEXT: movzwl %di, %eax 585; X64-NEXT: cmpl $256, %eax # imm = 0x100 586; X64-NEXT: setb %al 587; X64-NEXT: retq 588 %tmp0 = add i16 %x, 64 ; 1U << (8-1-1) 589 %tmp1 = icmp ult i16 %tmp0, 256 ; 1U << 8 590 ret i1 %tmp1 591} 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), %eax 598; X86-NEXT: addl $8, %eax 599; X86-NEXT: cmpw $16, %ax 600; X86-NEXT: setb %al 601; X86-NEXT: retl 602; 603; X64-LABEL: add_ultcmp_bad_i16_i4: 604; X64: # %bb.0: 605; X64-NEXT: addl $8, %edi 606; X64-NEXT: cmpw $16, %di 607; X64-NEXT: setb %al 608; X64-NEXT: retq 609 %tmp0 = add i16 %x, 8 ; 1U << (4-1) 610 %tmp1 = icmp ult i16 %tmp0, 16 ; 1U << 4 611 ret i1 %tmp1 612} 613 614; Bad storage type 615define 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), %eax 619; X86-NEXT: subl $-128, %eax 620; X86-NEXT: andl $16777215, %eax # imm = 0xFFFFFF 621; X86-NEXT: cmpl $256, %eax # imm = 0x100 622; X86-NEXT: setb %al 623; X86-NEXT: retl 624; 625; X64-LABEL: add_ultcmp_bad_i24_i8: 626; X64: # %bb.0: 627; X64-NEXT: subl $-128, %edi 628; X64-NEXT: andl $16777215, %edi # imm = 0xFFFFFF 629; X64-NEXT: cmpl $256, %edi # imm = 0x100 630; X64-NEXT: setb %al 631; X64-NEXT: retq 632 %tmp0 = add i24 %x, 128 ; 1U << (8-1) 633 %tmp1 = icmp ult i24 %tmp0, 256 ; 1U << 8 634 ret i1 %tmp1 635} 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, %al 641; 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 0 644 ret i1 %tmp1 645} 646