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