1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s --check-prefixes=CHECK,NOBMI 3; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+bmi | FileCheck %s --check-prefixes=CHECK,BMI 4 5define zeroext i1 @all_bits_clear(i32 %P, i32 %Q) nounwind { 6; CHECK-LABEL: all_bits_clear: 7; CHECK: # %bb.0: 8; CHECK-NEXT: orl %esi, %edi 9; CHECK-NEXT: sete %al 10; CHECK-NEXT: retq 11 %a = icmp eq i32 %P, 0 12 %b = icmp eq i32 %Q, 0 13 %c = and i1 %a, %b 14 ret i1 %c 15} 16 17define zeroext i1 @all_sign_bits_clear(i32 %P, i32 %Q) nounwind { 18; CHECK-LABEL: all_sign_bits_clear: 19; CHECK: # %bb.0: 20; CHECK-NEXT: orl %esi, %edi 21; CHECK-NEXT: setns %al 22; CHECK-NEXT: retq 23 %a = icmp sgt i32 %P, -1 24 %b = icmp sgt i32 %Q, -1 25 %c = and i1 %a, %b 26 ret i1 %c 27} 28 29define zeroext i1 @all_bits_set(i32 %P, i32 %Q) nounwind { 30; CHECK-LABEL: all_bits_set: 31; CHECK: # %bb.0: 32; CHECK-NEXT: andl %esi, %edi 33; CHECK-NEXT: cmpl $-1, %edi 34; CHECK-NEXT: sete %al 35; CHECK-NEXT: retq 36 %a = icmp eq i32 %P, -1 37 %b = icmp eq i32 %Q, -1 38 %c = and i1 %a, %b 39 ret i1 %c 40} 41 42define zeroext i1 @all_sign_bits_set(i32 %P, i32 %Q) nounwind { 43; CHECK-LABEL: all_sign_bits_set: 44; CHECK: # %bb.0: 45; CHECK-NEXT: movl %edi, %eax 46; CHECK-NEXT: andl %esi, %eax 47; CHECK-NEXT: shrl $31, %eax 48; CHECK-NEXT: # kill: def $al killed $al killed $eax 49; CHECK-NEXT: retq 50 %a = icmp slt i32 %P, 0 51 %b = icmp slt i32 %Q, 0 52 %c = and i1 %a, %b 53 ret i1 %c 54} 55 56define zeroext i1 @any_bits_set(i32 %P, i32 %Q) nounwind { 57; CHECK-LABEL: any_bits_set: 58; CHECK: # %bb.0: 59; CHECK-NEXT: orl %esi, %edi 60; CHECK-NEXT: setne %al 61; CHECK-NEXT: retq 62 %a = icmp ne i32 %P, 0 63 %b = icmp ne i32 %Q, 0 64 %c = or i1 %a, %b 65 ret i1 %c 66} 67 68define zeroext i1 @any_sign_bits_set(i32 %P, i32 %Q) nounwind { 69; CHECK-LABEL: any_sign_bits_set: 70; CHECK: # %bb.0: 71; CHECK-NEXT: movl %edi, %eax 72; CHECK-NEXT: orl %esi, %eax 73; CHECK-NEXT: shrl $31, %eax 74; CHECK-NEXT: # kill: def $al killed $al killed $eax 75; CHECK-NEXT: retq 76 %a = icmp slt i32 %P, 0 77 %b = icmp slt i32 %Q, 0 78 %c = or i1 %a, %b 79 ret i1 %c 80} 81 82define zeroext i1 @any_bits_clear(i32 %P, i32 %Q) nounwind { 83; CHECK-LABEL: any_bits_clear: 84; CHECK: # %bb.0: 85; CHECK-NEXT: andl %esi, %edi 86; CHECK-NEXT: cmpl $-1, %edi 87; CHECK-NEXT: setne %al 88; CHECK-NEXT: retq 89 %a = icmp ne i32 %P, -1 90 %b = icmp ne i32 %Q, -1 91 %c = or i1 %a, %b 92 ret i1 %c 93} 94 95define zeroext i1 @any_sign_bits_clear(i32 %P, i32 %Q) nounwind { 96; CHECK-LABEL: any_sign_bits_clear: 97; CHECK: # %bb.0: 98; CHECK-NEXT: testl %esi, %edi 99; CHECK-NEXT: setns %al 100; CHECK-NEXT: retq 101 %a = icmp sgt i32 %P, -1 102 %b = icmp sgt i32 %Q, -1 103 %c = or i1 %a, %b 104 ret i1 %c 105} 106 107; PR3351 - (P == 0) & (Q == 0) -> (P|Q) == 0 108define i32 @all_bits_clear_branch(ptr %P, ptr %Q) nounwind { 109; CHECK-LABEL: all_bits_clear_branch: 110; CHECK: # %bb.0: # %entry 111; CHECK-NEXT: orq %rsi, %rdi 112; CHECK-NEXT: jne .LBB8_2 113; CHECK-NEXT: # %bb.1: # %bb1 114; CHECK-NEXT: movl $4, %eax 115; CHECK-NEXT: retq 116; CHECK-NEXT: .LBB8_2: # %return 117; CHECK-NEXT: movl $192, %eax 118; CHECK-NEXT: retq 119entry: 120 %a = icmp eq ptr %P, null 121 %b = icmp eq ptr %Q, null 122 %c = and i1 %a, %b 123 br i1 %c, label %bb1, label %return 124 125bb1: 126 ret i32 4 127 128return: 129 ret i32 192 130} 131 132define i32 @all_sign_bits_clear_branch(i32 %P, i32 %Q) nounwind { 133; CHECK-LABEL: all_sign_bits_clear_branch: 134; CHECK: # %bb.0: # %entry 135; CHECK-NEXT: orl %esi, %edi 136; CHECK-NEXT: js .LBB9_2 137; CHECK-NEXT: # %bb.1: # %bb1 138; CHECK-NEXT: movl $4, %eax 139; CHECK-NEXT: retq 140; CHECK-NEXT: .LBB9_2: # %return 141; CHECK-NEXT: movl $192, %eax 142; CHECK-NEXT: retq 143entry: 144 %a = icmp sgt i32 %P, -1 145 %b = icmp sgt i32 %Q, -1 146 %c = and i1 %a, %b 147 br i1 %c, label %bb1, label %return 148 149bb1: 150 ret i32 4 151 152return: 153 ret i32 192 154} 155 156define i32 @all_bits_set_branch(i32 %P, i32 %Q) nounwind { 157; CHECK-LABEL: all_bits_set_branch: 158; CHECK: # %bb.0: # %entry 159; CHECK-NEXT: andl %esi, %edi 160; CHECK-NEXT: cmpl $-1, %edi 161; CHECK-NEXT: jne .LBB10_2 162; CHECK-NEXT: # %bb.1: # %bb1 163; CHECK-NEXT: movl $4, %eax 164; CHECK-NEXT: retq 165; CHECK-NEXT: .LBB10_2: # %return 166; CHECK-NEXT: movl $192, %eax 167; CHECK-NEXT: retq 168entry: 169 %a = icmp eq i32 %P, -1 170 %b = icmp eq i32 %Q, -1 171 %c = and i1 %a, %b 172 br i1 %c, label %bb1, label %return 173 174bb1: 175 ret i32 4 176 177return: 178 ret i32 192 179} 180 181define i32 @all_sign_bits_set_branch(i32 %P, i32 %Q) nounwind { 182; CHECK-LABEL: all_sign_bits_set_branch: 183; CHECK: # %bb.0: # %entry 184; CHECK-NEXT: testl %esi, %edi 185; CHECK-NEXT: jns .LBB11_2 186; CHECK-NEXT: # %bb.1: # %bb1 187; CHECK-NEXT: movl $4, %eax 188; CHECK-NEXT: retq 189; CHECK-NEXT: .LBB11_2: # %return 190; CHECK-NEXT: movl $192, %eax 191; CHECK-NEXT: retq 192entry: 193 %a = icmp slt i32 %P, 0 194 %b = icmp slt i32 %Q, 0 195 %c = and i1 %a, %b 196 br i1 %c, label %bb1, label %return 197 198bb1: 199 ret i32 4 200 201return: 202 ret i32 192 203} 204 205; PR3351 - (P != 0) | (Q != 0) -> (P|Q) != 0 206define i32 @any_bits_set_branch(ptr %P, ptr %Q) nounwind { 207; CHECK-LABEL: any_bits_set_branch: 208; CHECK: # %bb.0: # %entry 209; CHECK-NEXT: orq %rsi, %rdi 210; CHECK-NEXT: je .LBB12_2 211; CHECK-NEXT: # %bb.1: # %bb1 212; CHECK-NEXT: movl $4, %eax 213; CHECK-NEXT: retq 214; CHECK-NEXT: .LBB12_2: # %return 215; CHECK-NEXT: movl $192, %eax 216; CHECK-NEXT: retq 217entry: 218 %a = icmp ne ptr %P, null 219 %b = icmp ne ptr %Q, null 220 %c = or i1 %a, %b 221 br i1 %c, label %bb1, label %return 222 223bb1: 224 ret i32 4 225 226return: 227 ret i32 192 228} 229 230define i32 @any_sign_bits_set_branch(i32 %P, i32 %Q) nounwind { 231; CHECK-LABEL: any_sign_bits_set_branch: 232; CHECK: # %bb.0: # %entry 233; CHECK-NEXT: orl %esi, %edi 234; CHECK-NEXT: jns .LBB13_2 235; CHECK-NEXT: # %bb.1: # %bb1 236; CHECK-NEXT: movl $4, %eax 237; CHECK-NEXT: retq 238; CHECK-NEXT: .LBB13_2: # %return 239; CHECK-NEXT: movl $192, %eax 240; CHECK-NEXT: retq 241entry: 242 %a = icmp slt i32 %P, 0 243 %b = icmp slt i32 %Q, 0 244 %c = or i1 %a, %b 245 br i1 %c, label %bb1, label %return 246 247bb1: 248 ret i32 4 249 250return: 251 ret i32 192 252} 253 254define i32 @any_bits_clear_branch(i32 %P, i32 %Q) nounwind { 255; CHECK-LABEL: any_bits_clear_branch: 256; CHECK: # %bb.0: # %entry 257; CHECK-NEXT: andl %esi, %edi 258; CHECK-NEXT: cmpl $-1, %edi 259; CHECK-NEXT: je .LBB14_2 260; CHECK-NEXT: # %bb.1: # %bb1 261; CHECK-NEXT: movl $4, %eax 262; CHECK-NEXT: retq 263; CHECK-NEXT: .LBB14_2: # %return 264; CHECK-NEXT: movl $192, %eax 265; CHECK-NEXT: retq 266entry: 267 %a = icmp ne i32 %P, -1 268 %b = icmp ne i32 %Q, -1 269 %c = or i1 %a, %b 270 br i1 %c, label %bb1, label %return 271 272bb1: 273 ret i32 4 274 275return: 276 ret i32 192 277} 278 279define i32 @any_sign_bits_clear_branch(i32 %P, i32 %Q) nounwind { 280; CHECK-LABEL: any_sign_bits_clear_branch: 281; CHECK: # %bb.0: # %entry 282; CHECK-NEXT: testl %esi, %edi 283; CHECK-NEXT: js .LBB15_2 284; CHECK-NEXT: # %bb.1: # %bb1 285; CHECK-NEXT: movl $4, %eax 286; CHECK-NEXT: retq 287; CHECK-NEXT: .LBB15_2: # %return 288; CHECK-NEXT: movl $192, %eax 289; CHECK-NEXT: retq 290entry: 291 %a = icmp sgt i32 %P, -1 292 %b = icmp sgt i32 %Q, -1 293 %c = or i1 %a, %b 294 br i1 %c, label %bb1, label %return 295 296bb1: 297 ret i32 4 298 299return: 300 ret i32 192 301} 302 303; PR44565 - https://bugs.llvm.org/show_bug.cgi?id=44565 304 305define i32 @vec_extract_branch(<2 x double> %x) { 306; CHECK-LABEL: vec_extract_branch: 307; CHECK: # %bb.0: 308; CHECK-NEXT: xorpd %xmm1, %xmm1 309; CHECK-NEXT: cmpltpd %xmm0, %xmm1 310; CHECK-NEXT: movmskpd %xmm1, %eax 311; CHECK-NEXT: cmpl $3, %eax 312; CHECK-NEXT: jne .LBB16_2 313; CHECK-NEXT: # %bb.1: # %true 314; CHECK-NEXT: movl $42, %eax 315; CHECK-NEXT: retq 316; CHECK-NEXT: .LBB16_2: # %false 317; CHECK-NEXT: movl $88, %eax 318; CHECK-NEXT: retq 319 %t1 = fcmp ogt <2 x double> %x, zeroinitializer 320 %t2 = extractelement <2 x i1> %t1, i32 0 321 %t3 = extractelement <2 x i1> %t1, i32 1 322 %t4 = and i1 %t2, %t3 323 br i1 %t4, label %true, label %false 324true: 325 ret i32 42 326false: 327 ret i32 88 328} 329 330define <4 x i1> @all_bits_clear_vec(<4 x i32> %P, <4 x i32> %Q) nounwind { 331; CHECK-LABEL: all_bits_clear_vec: 332; CHECK: # %bb.0: 333; CHECK-NEXT: por %xmm1, %xmm0 334; CHECK-NEXT: pxor %xmm1, %xmm1 335; CHECK-NEXT: pcmpeqd %xmm1, %xmm0 336; CHECK-NEXT: retq 337 %a = icmp eq <4 x i32> %P, zeroinitializer 338 %b = icmp eq <4 x i32> %Q, zeroinitializer 339 %c = and <4 x i1> %a, %b 340 ret <4 x i1> %c 341} 342 343define <4 x i1> @all_sign_bits_clear_vec(<4 x i32> %P, <4 x i32> %Q) nounwind { 344; CHECK-LABEL: all_sign_bits_clear_vec: 345; CHECK: # %bb.0: 346; CHECK-NEXT: por %xmm1, %xmm0 347; CHECK-NEXT: pcmpeqd %xmm1, %xmm1 348; CHECK-NEXT: pcmpgtd %xmm1, %xmm0 349; CHECK-NEXT: retq 350 %a = icmp sgt <4 x i32> %P, <i32 -1, i32 -1, i32 -1, i32 -1> 351 %b = icmp sgt <4 x i32> %Q, <i32 -1, i32 -1, i32 -1, i32 -1> 352 %c = and <4 x i1> %a, %b 353 ret <4 x i1> %c 354} 355 356define <4 x i1> @all_bits_set_vec(<4 x i32> %P, <4 x i32> %Q) nounwind { 357; CHECK-LABEL: all_bits_set_vec: 358; CHECK: # %bb.0: 359; CHECK-NEXT: pand %xmm1, %xmm0 360; CHECK-NEXT: pcmpeqd %xmm1, %xmm1 361; CHECK-NEXT: pcmpeqd %xmm1, %xmm0 362; CHECK-NEXT: retq 363 %a = icmp eq <4 x i32> %P, <i32 -1, i32 -1, i32 -1, i32 -1> 364 %b = icmp eq <4 x i32> %Q, <i32 -1, i32 -1, i32 -1, i32 -1> 365 %c = and <4 x i1> %a, %b 366 ret <4 x i1> %c 367} 368 369define <4 x i1> @all_sign_bits_set_vec(<4 x i32> %P, <4 x i32> %Q) nounwind { 370; CHECK-LABEL: all_sign_bits_set_vec: 371; CHECK: # %bb.0: 372; CHECK-NEXT: pand %xmm1, %xmm0 373; CHECK-NEXT: pxor %xmm1, %xmm1 374; CHECK-NEXT: pcmpgtd %xmm0, %xmm1 375; CHECK-NEXT: movdqa %xmm1, %xmm0 376; CHECK-NEXT: retq 377 %a = icmp slt <4 x i32> %P, zeroinitializer 378 %b = icmp slt <4 x i32> %Q, zeroinitializer 379 %c = and <4 x i1> %a, %b 380 ret <4 x i1> %c 381} 382 383define <4 x i1> @any_bits_set_vec(<4 x i32> %P, <4 x i32> %Q) nounwind { 384; CHECK-LABEL: any_bits_set_vec: 385; CHECK: # %bb.0: 386; CHECK-NEXT: por %xmm1, %xmm0 387; CHECK-NEXT: pxor %xmm1, %xmm1 388; CHECK-NEXT: pcmpeqd %xmm1, %xmm0 389; CHECK-NEXT: pcmpeqd %xmm1, %xmm1 390; CHECK-NEXT: pxor %xmm1, %xmm0 391; CHECK-NEXT: retq 392 %a = icmp ne <4 x i32> %P, zeroinitializer 393 %b = icmp ne <4 x i32> %Q, zeroinitializer 394 %c = or <4 x i1> %a, %b 395 ret <4 x i1> %c 396} 397 398define <4 x i1> @any_sign_bits_set_vec(<4 x i32> %P, <4 x i32> %Q) nounwind { 399; CHECK-LABEL: any_sign_bits_set_vec: 400; CHECK: # %bb.0: 401; CHECK-NEXT: por %xmm1, %xmm0 402; CHECK-NEXT: pxor %xmm1, %xmm1 403; CHECK-NEXT: pcmpgtd %xmm0, %xmm1 404; CHECK-NEXT: movdqa %xmm1, %xmm0 405; CHECK-NEXT: retq 406 %a = icmp slt <4 x i32> %P, zeroinitializer 407 %b = icmp slt <4 x i32> %Q, zeroinitializer 408 %c = or <4 x i1> %a, %b 409 ret <4 x i1> %c 410} 411 412define <4 x i1> @any_bits_clear_vec(<4 x i32> %P, <4 x i32> %Q) nounwind { 413; CHECK-LABEL: any_bits_clear_vec: 414; CHECK: # %bb.0: 415; CHECK-NEXT: pand %xmm1, %xmm0 416; CHECK-NEXT: pcmpeqd %xmm1, %xmm1 417; CHECK-NEXT: pcmpeqd %xmm1, %xmm0 418; CHECK-NEXT: pxor %xmm1, %xmm0 419; CHECK-NEXT: retq 420 %a = icmp ne <4 x i32> %P, <i32 -1, i32 -1, i32 -1, i32 -1> 421 %b = icmp ne <4 x i32> %Q, <i32 -1, i32 -1, i32 -1, i32 -1> 422 %c = or <4 x i1> %a, %b 423 ret <4 x i1> %c 424} 425 426define <4 x i1> @any_sign_bits_clear_vec(<4 x i32> %P, <4 x i32> %Q) nounwind { 427; CHECK-LABEL: any_sign_bits_clear_vec: 428; CHECK: # %bb.0: 429; CHECK-NEXT: pand %xmm1, %xmm0 430; CHECK-NEXT: pcmpeqd %xmm1, %xmm1 431; CHECK-NEXT: pcmpgtd %xmm1, %xmm0 432; CHECK-NEXT: retq 433 %a = icmp sgt <4 x i32> %P, <i32 -1, i32 -1, i32 -1, i32 -1> 434 %b = icmp sgt <4 x i32> %Q, <i32 -1, i32 -1, i32 -1, i32 -1> 435 %c = or <4 x i1> %a, %b 436 ret <4 x i1> %c 437} 438 439define zeroext i1 @ne_neg1_and_ne_zero(i64 %x) nounwind { 440; CHECK-LABEL: ne_neg1_and_ne_zero: 441; CHECK: # %bb.0: 442; CHECK-NEXT: incq %rdi 443; CHECK-NEXT: testq $-2, %rdi 444; CHECK-NEXT: setne %al 445; CHECK-NEXT: retq 446 %cmp1 = icmp ne i64 %x, -1 447 %cmp2 = icmp ne i64 %x, 0 448 %and = and i1 %cmp1, %cmp2 449 ret i1 %and 450} 451 452; PR32401 - https://bugs.llvm.org/show_bug.cgi?id=32401 453 454define zeroext i1 @and_eq(i8 %a, i8 %b, i8 %c, i8 %d) nounwind { 455; CHECK-LABEL: and_eq: 456; CHECK: # %bb.0: 457; CHECK-NEXT: xorl %esi, %edi 458; CHECK-NEXT: xorl %ecx, %edx 459; CHECK-NEXT: orb %dl, %dil 460; CHECK-NEXT: sete %al 461; CHECK-NEXT: retq 462 %cmp1 = icmp eq i8 %a, %b 463 %cmp2 = icmp eq i8 %c, %d 464 %and = and i1 %cmp1, %cmp2 465 ret i1 %and 466} 467 468define zeroext i1 @or_ne(i8 %a, i8 %b, i8 %c, i8 %d) nounwind { 469; CHECK-LABEL: or_ne: 470; CHECK: # %bb.0: 471; CHECK-NEXT: xorl %esi, %edi 472; CHECK-NEXT: xorl %ecx, %edx 473; CHECK-NEXT: orb %dl, %dil 474; CHECK-NEXT: setne %al 475; CHECK-NEXT: retq 476 %cmp1 = icmp ne i8 %a, %b 477 %cmp2 = icmp ne i8 %c, %d 478 %or = or i1 %cmp1, %cmp2 479 ret i1 %or 480} 481 482; This should not be transformed because vector compares + bitwise logic are faster. 483 484define <4 x i1> @and_eq_vec(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c, <4 x i32> %d) nounwind { 485; CHECK-LABEL: and_eq_vec: 486; CHECK: # %bb.0: 487; CHECK-NEXT: pcmpeqd %xmm1, %xmm0 488; CHECK-NEXT: pcmpeqd %xmm3, %xmm2 489; CHECK-NEXT: pand %xmm2, %xmm0 490; CHECK-NEXT: retq 491 %cmp1 = icmp eq <4 x i32> %a, %b 492 %cmp2 = icmp eq <4 x i32> %c, %d 493 %and = and <4 x i1> %cmp1, %cmp2 494 ret <4 x i1> %and 495} 496 497define i1 @or_icmps_const_1bit_diff(i8 %x) { 498; CHECK-LABEL: or_icmps_const_1bit_diff: 499; CHECK: # %bb.0: 500; CHECK-NEXT: addb $-43, %dil 501; CHECK-NEXT: testb $-3, %dil 502; CHECK-NEXT: sete %al 503; CHECK-NEXT: retq 504 %a = icmp eq i8 %x, 43 505 %b = icmp eq i8 %x, 45 506 %r = or i1 %a, %b 507 ret i1 %r 508} 509 510define <4 x i32> @or_icmps_const_1bit_diff_vec(<4 x i32> %x) { 511; CHECK-LABEL: or_icmps_const_1bit_diff_vec: 512; CHECK: # %bb.0: 513; CHECK-NEXT: movdqa {{.*#+}} xmm1 = [43,45,43,45] 514; CHECK-NEXT: pcmpeqd %xmm0, %xmm1 515; CHECK-NEXT: pcmpeqd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 516; CHECK-NEXT: por %xmm1, %xmm0 517; CHECK-NEXT: retq 518 %a = icmp eq <4 x i32> %x, <i32 43, i32 45, i32 43, i32 45> 519 %b = icmp eq <4 x i32> %x, <i32 45, i32 43, i32 45, i32 43> 520 %t = or <4 x i1> %a, %b 521 %r = sext <4 x i1> %t to <4 x i32> 522 ret <4 x i32> %r 523} 524 525define i1 @and_icmps_const_1bit_diff(i32 %x) { 526; CHECK-LABEL: and_icmps_const_1bit_diff: 527; CHECK: # %bb.0: 528; CHECK-NEXT: addl $-44, %edi 529; CHECK-NEXT: testl $-17, %edi 530; CHECK-NEXT: setne %al 531; CHECK-NEXT: retq 532 %a = icmp ne i32 %x, 44 533 %b = icmp ne i32 %x, 60 534 %r = and i1 %a, %b 535 ret i1 %r 536} 537 538define <4 x i32> @and_icmps_const_1bit_diff_vec(<4 x i32> %x) { 539; CHECK-LABEL: and_icmps_const_1bit_diff_vec: 540; CHECK: # %bb.0: 541; CHECK-NEXT: movdqa {{.*#+}} xmm1 = [44,60,44,60] 542; CHECK-NEXT: pcmpeqd %xmm0, %xmm1 543; CHECK-NEXT: pcmpeqd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 544; CHECK-NEXT: por %xmm1, %xmm0 545; CHECK-NEXT: pcmpeqd %xmm1, %xmm1 546; CHECK-NEXT: pxor %xmm1, %xmm0 547; CHECK-NEXT: retq 548 %a = icmp ne <4 x i32> %x, <i32 44, i32 60, i32 44, i32 60> 549 %b = icmp ne <4 x i32> %x, <i32 60, i32 44, i32 60, i32 44> 550 %t = and <4 x i1> %a, %b 551 %r = sext <4 x i1> %t to <4 x i32> 552 ret <4 x i32> %r 553} 554 555; Negative test - extra use prevents optimization 556 557define i1 @or_icmps_const_1bit_diff_extra_use(i8 %x, ptr %p) { 558; CHECK-LABEL: or_icmps_const_1bit_diff_extra_use: 559; CHECK: # %bb.0: 560; CHECK-NEXT: cmpb $45, %dil 561; CHECK-NEXT: sete %cl 562; CHECK-NEXT: cmpb $43, %dil 563; CHECK-NEXT: sete %al 564; CHECK-NEXT: sete (%rsi) 565; CHECK-NEXT: orb %cl, %al 566; CHECK-NEXT: retq 567 %a = icmp eq i8 %x, 43 568 %b = icmp eq i8 %x, 45 569 %r = or i1 %a, %b 570 %z = zext i1 %a to i8 571 store i8 %z, ptr %p 572 ret i1 %r 573} 574 575; Negative test - constant diff is >1 bit 576 577define i1 @and_icmps_const_not1bit_diff(i32 %x) { 578; CHECK-LABEL: and_icmps_const_not1bit_diff: 579; CHECK: # %bb.0: 580; CHECK-NEXT: cmpl $44, %edi 581; CHECK-NEXT: setne %cl 582; CHECK-NEXT: cmpl $92, %edi 583; CHECK-NEXT: setne %al 584; CHECK-NEXT: andb %cl, %al 585; CHECK-NEXT: retq 586 %a = icmp ne i32 %x, 44 587 %b = icmp ne i32 %x, 92 588 %r = and i1 %a, %b 589 ret i1 %r 590} 591 592; Negative test - wrong comparison 593 594define i1 @and_icmps_const_1bit_diff_wrong_pred(i32 %x) { 595; CHECK-LABEL: and_icmps_const_1bit_diff_wrong_pred: 596; CHECK: # %bb.0: 597; CHECK-NEXT: cmpl $43, %edi 598; CHECK-NEXT: sete %cl 599; CHECK-NEXT: cmpl $45, %edi 600; CHECK-NEXT: setl %al 601; CHECK-NEXT: orb %cl, %al 602; CHECK-NEXT: retq 603 %a = icmp eq i32 %x, 43 604 %b = icmp slt i32 %x, 45 605 %r = or i1 %a, %b 606 ret i1 %r 607} 608 609; Negative test - no common operand 610 611define i1 @and_icmps_const_1bit_diff_common_op(i32 %x, i32 %y) { 612; CHECK-LABEL: and_icmps_const_1bit_diff_common_op: 613; CHECK: # %bb.0: 614; CHECK-NEXT: cmpl $43, %edi 615; CHECK-NEXT: sete %cl 616; CHECK-NEXT: cmpl $45, %esi 617; CHECK-NEXT: sete %al 618; CHECK-NEXT: orb %cl, %al 619; CHECK-NEXT: retq 620 %a = icmp eq i32 %x, 43 621 %b = icmp eq i32 %y, 45 622 %r = or i1 %a, %b 623 ret i1 %r 624} 625 626; PR44136 - fold cmpeq(or(X,Y),X) --> cmpeq(and(~X,Y),0) 627 628define i1 @or_cmp_eq_i64(i64 %x, i64 %y) { 629; NOBMI-LABEL: or_cmp_eq_i64: 630; NOBMI: # %bb.0: 631; NOBMI-NEXT: notq %rdi 632; NOBMI-NEXT: testq %rsi, %rdi 633; NOBMI-NEXT: sete %al 634; NOBMI-NEXT: retq 635; 636; BMI-LABEL: or_cmp_eq_i64: 637; BMI: # %bb.0: 638; BMI-NEXT: andnq %rsi, %rdi, %rax 639; BMI-NEXT: sete %al 640; BMI-NEXT: retq 641 %o = or i64 %x, %y 642 %c = icmp eq i64 %o, %x 643 ret i1 %c 644} 645 646define i1 @or_cmp_ne_i32(i32 %x, i32 %y) { 647; NOBMI-LABEL: or_cmp_ne_i32: 648; NOBMI: # %bb.0: 649; NOBMI-NEXT: notl %esi 650; NOBMI-NEXT: testl %edi, %esi 651; NOBMI-NEXT: setne %al 652; NOBMI-NEXT: retq 653; 654; BMI-LABEL: or_cmp_ne_i32: 655; BMI: # %bb.0: 656; BMI-NEXT: andnl %edi, %esi, %eax 657; BMI-NEXT: setne %al 658; BMI-NEXT: retq 659 %o = or i32 %x, %y 660 %c = icmp ne i32 %o, %y 661 ret i1 %c 662} 663 664define i1 @or_cmp_eq_i16(i16 zeroext %x, i16 zeroext %y) { 665; NOBMI-LABEL: or_cmp_eq_i16: 666; NOBMI: # %bb.0: 667; NOBMI-NEXT: notl %edi 668; NOBMI-NEXT: testl %esi, %edi 669; NOBMI-NEXT: sete %al 670; NOBMI-NEXT: retq 671; 672; BMI-LABEL: or_cmp_eq_i16: 673; BMI: # %bb.0: 674; BMI-NEXT: andnl %esi, %edi, %eax 675; BMI-NEXT: sete %al 676; BMI-NEXT: retq 677 %o = or i16 %x, %y 678 %c = icmp eq i16 %x, %o 679 ret i1 %c 680} 681 682define i1 @or_cmp_ne_i8(i8 zeroext %x, i8 zeroext %y) { 683; CHECK-LABEL: or_cmp_ne_i8: 684; CHECK: # %bb.0: 685; CHECK-NEXT: notb %sil 686; CHECK-NEXT: testb %dil, %sil 687; CHECK-NEXT: setne %al 688; CHECK-NEXT: retq 689 %o = or i8 %x, %y 690 %c = icmp ne i8 %y, %o 691 ret i1 %c 692} 693 694; Don't fold vectors. 695define <4 x i32> @or_cmp_eq_v4i32(<4 x i32> %x, <4 x i32> %y) { 696; CHECK-LABEL: or_cmp_eq_v4i32: 697; CHECK: # %bb.0: 698; CHECK-NEXT: por %xmm0, %xmm1 699; CHECK-NEXT: pcmpeqd %xmm1, %xmm0 700; CHECK-NEXT: retq 701 %o = or <4 x i32> %x, %y 702 %c = icmp eq <4 x i32> %o, %x 703 %s = sext <4 x i1> %c to <4 x i32> 704 ret <4 x i32> %s 705} 706 707define <16 x i8> @or_cmp_ne_v4i32(<16 x i8> %x, <16 x i8> %y) { 708; CHECK-LABEL: or_cmp_ne_v4i32: 709; CHECK: # %bb.0: 710; CHECK-NEXT: por %xmm0, %xmm1 711; CHECK-NEXT: pcmpeqb %xmm1, %xmm0 712; CHECK-NEXT: pcmpeqd %xmm1, %xmm1 713; CHECK-NEXT: pxor %xmm1, %xmm0 714; CHECK-NEXT: retq 715 %o = or <16 x i8> %x, %y 716 %c = icmp ne <16 x i8> %o, %x 717 %s = sext <16 x i1> %c to <16 x i8> 718 ret <16 x i8> %s 719} 720