1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple=x86_64-unknown-unknown -mattr=+tbm < %s | FileCheck %s 3 4; TODO - Patterns fail to fold with ZF flags and prevents TBM instruction selection. 5 6define i32 @test_x86_tbm_bextri_u32(i32 %a) nounwind { 7; CHECK-LABEL: test_x86_tbm_bextri_u32: 8; CHECK: # %bb.0: 9; CHECK-NEXT: bextrl $3076, %edi, %eax # imm = 0xC04 10; CHECK-NEXT: retq 11 %t0 = lshr i32 %a, 4 12 %t1 = and i32 %t0, 4095 13 ret i32 %t1 14} 15 16; Make sure we still use AH subreg trick for extracting bits 15:8 17define i32 @test_x86_tbm_bextri_u32_subreg(i32 %a) nounwind { 18; CHECK-LABEL: test_x86_tbm_bextri_u32_subreg: 19; CHECK: # %bb.0: 20; CHECK-NEXT: movl %edi, %eax 21; CHECK-NEXT: movzbl %ah, %eax 22; CHECK-NEXT: retq 23 %t0 = lshr i32 %a, 8 24 %t1 = and i32 %t0, 255 25 ret i32 %t1 26} 27 28define i32 @test_x86_tbm_bextri_u32_m(i32* nocapture %a) nounwind { 29; CHECK-LABEL: test_x86_tbm_bextri_u32_m: 30; CHECK: # %bb.0: 31; CHECK-NEXT: bextrl $3076, (%rdi), %eax # imm = 0xC04 32; CHECK-NEXT: retq 33 %t0 = load i32, i32* %a 34 %t1 = lshr i32 %t0, 4 35 %t2 = and i32 %t1, 4095 36 ret i32 %t2 37} 38 39define i32 @test_x86_tbm_bextri_u32_z(i32 %a, i32 %b) nounwind { 40; CHECK-LABEL: test_x86_tbm_bextri_u32_z: 41; CHECK: # %bb.0: 42; CHECK-NEXT: bextrl $3076, %edi, %eax # imm = 0xC04 43; CHECK-NEXT: cmovel %esi, %eax 44; CHECK-NEXT: retq 45 %t0 = lshr i32 %a, 4 46 %t1 = and i32 %t0, 4095 47 %t2 = icmp eq i32 %t1, 0 48 %t3 = select i1 %t2, i32 %b, i32 %t1 49 ret i32 %t3 50} 51 52define i32 @test_x86_tbm_bextri_u32_z2(i32 %a, i32 %b, i32 %c) nounwind { 53; CHECK-LABEL: test_x86_tbm_bextri_u32_z2: 54; CHECK: # %bb.0: 55; CHECK-NEXT: shrl $4, %edi 56; CHECK-NEXT: testl $4095, %edi # imm = 0xFFF 57; CHECK-NEXT: cmovnel %edx, %esi 58; CHECK-NEXT: movl %esi, %eax 59; CHECK-NEXT: retq 60 %t0 = lshr i32 %a, 4 61 %t1 = and i32 %t0, 4095 62 %t2 = icmp eq i32 %t1, 0 63 %t3 = select i1 %t2, i32 %b, i32 %c 64 ret i32 %t3 65} 66 67define i64 @test_x86_tbm_bextri_u64(i64 %a) nounwind { 68; CHECK-LABEL: test_x86_tbm_bextri_u64: 69; CHECK: # %bb.0: 70; CHECK-NEXT: bextrl $3076, %edi, %eax # imm = 0xC04 71; CHECK-NEXT: retq 72 %t0 = lshr i64 %a, 4 73 %t1 = and i64 %t0, 4095 74 ret i64 %t1 75} 76 77; Make sure we still use AH subreg trick for extracting bits 15:8 78define i64 @test_x86_tbm_bextri_u64_subreg(i64 %a) nounwind { 79; CHECK-LABEL: test_x86_tbm_bextri_u64_subreg: 80; CHECK: # %bb.0: 81; CHECK-NEXT: movq %rdi, %rax 82; CHECK-NEXT: movzbl %ah, %eax 83; CHECK-NEXT: retq 84 %t0 = lshr i64 %a, 8 85 %t1 = and i64 %t0, 255 86 ret i64 %t1 87} 88 89define i64 @test_x86_tbm_bextri_u64_m(i64* nocapture %a) nounwind { 90; CHECK-LABEL: test_x86_tbm_bextri_u64_m: 91; CHECK: # %bb.0: 92; CHECK-NEXT: bextrl $3076, (%rdi), %eax # imm = 0xC04 93; CHECK-NEXT: retq 94 %t0 = load i64, i64* %a 95 %t1 = lshr i64 %t0, 4 96 %t2 = and i64 %t1, 4095 97 ret i64 %t2 98} 99 100define i64 @test_x86_tbm_bextri_u64_z(i64 %a, i64 %b) nounwind { 101; CHECK-LABEL: test_x86_tbm_bextri_u64_z: 102; CHECK: # %bb.0: 103; CHECK-NEXT: bextrl $3076, %edi, %eax # imm = 0xC04 104; CHECK-NEXT: cmoveq %rsi, %rax 105; CHECK-NEXT: retq 106 %t0 = lshr i64 %a, 4 107 %t1 = and i64 %t0, 4095 108 %t2 = icmp eq i64 %t1, 0 109 %t3 = select i1 %t2, i64 %b, i64 %t1 110 ret i64 %t3 111} 112 113define i64 @test_x86_tbm_bextri_u64_z2(i64 %a, i64 %b, i64 %c) nounwind { 114; CHECK-LABEL: test_x86_tbm_bextri_u64_z2: 115; CHECK: # %bb.0: 116; CHECK-NEXT: shrl $4, %edi 117; CHECK-NEXT: testl $4095, %edi # imm = 0xFFF 118; CHECK-NEXT: cmovneq %rdx, %rsi 119; CHECK-NEXT: movq %rsi, %rax 120; CHECK-NEXT: retq 121 %t0 = lshr i64 %a, 4 122 %t1 = and i64 %t0, 4095 123 %t2 = icmp eq i64 %t1, 0 124 %t3 = select i1 %t2, i64 %b, i64 %c 125 ret i64 %t3 126} 127 128define i32 @test_x86_tbm_blcfill_u32(i32 %a) nounwind { 129; CHECK-LABEL: test_x86_tbm_blcfill_u32: 130; CHECK: # %bb.0: 131; CHECK-NEXT: blcfilll %edi, %eax 132; CHECK-NEXT: retq 133 %t0 = add i32 %a, 1 134 %t1 = and i32 %t0, %a 135 ret i32 %t1 136} 137 138define i32 @test_x86_tbm_blcfill_u32_z(i32 %a, i32 %b) nounwind { 139; CHECK-LABEL: test_x86_tbm_blcfill_u32_z: 140; CHECK: # %bb.0: 141; CHECK-NEXT: blcfilll %edi, %eax 142; CHECK-NEXT: cmovel %esi, %eax 143; CHECK-NEXT: retq 144 %t0 = add i32 %a, 1 145 %t1 = and i32 %t0, %a 146 %t2 = icmp eq i32 %t1, 0 147 %t3 = select i1 %t2, i32 %b, i32 %t1 148 ret i32 %t3 149} 150 151define i32 @test_x86_tbm_blcfill_u32_z2(i32 %a, i32 %b, i32 %c) nounwind { 152; CHECK-LABEL: test_x86_tbm_blcfill_u32_z2: 153; CHECK: # %bb.0: 154; CHECK-NEXT: # kill: def $edi killed $edi def $rdi 155; CHECK-NEXT: leal 1(%rdi), %eax 156; CHECK-NEXT: testl %edi, %eax 157; CHECK-NEXT: cmovnel %edx, %esi 158; CHECK-NEXT: movl %esi, %eax 159; CHECK-NEXT: retq 160 %t0 = add i32 %a, 1 161 %t1 = and i32 %t0, %a 162 %t2 = icmp eq i32 %t1, 0 163 %t3 = select i1 %t2, i32 %b, i32 %c 164 ret i32 %t3 165} 166 167define i64 @test_x86_tbm_blcfill_u64(i64 %a) nounwind { 168; CHECK-LABEL: test_x86_tbm_blcfill_u64: 169; CHECK: # %bb.0: 170; CHECK-NEXT: blcfillq %rdi, %rax 171; CHECK-NEXT: retq 172 %t0 = add i64 %a, 1 173 %t1 = and i64 %t0, %a 174 ret i64 %t1 175} 176 177define i64 @test_x86_tbm_blcfill_u64_z(i64 %a, i64 %b) nounwind { 178; CHECK-LABEL: test_x86_tbm_blcfill_u64_z: 179; CHECK: # %bb.0: 180; CHECK-NEXT: blcfillq %rdi, %rax 181; CHECK-NEXT: cmoveq %rsi, %rax 182; CHECK-NEXT: retq 183 %t0 = add i64 %a, 1 184 %t1 = and i64 %t0, %a 185 %t2 = icmp eq i64 %t1, 0 186 %t3 = select i1 %t2, i64 %b, i64 %t1 187 ret i64 %t3 188} 189 190define i64 @test_x86_tbm_blcfill_u64_z2(i64 %a, i64 %b, i64 %c) nounwind { 191; CHECK-LABEL: test_x86_tbm_blcfill_u64_z2: 192; CHECK: # %bb.0: 193; CHECK-NEXT: leaq 1(%rdi), %rax 194; CHECK-NEXT: testq %rdi, %rax 195; CHECK-NEXT: cmovneq %rdx, %rsi 196; CHECK-NEXT: movq %rsi, %rax 197; CHECK-NEXT: retq 198 %t0 = add i64 %a, 1 199 %t1 = and i64 %t0, %a 200 %t2 = icmp eq i64 %t1, 0 201 %t3 = select i1 %t2, i64 %b, i64 %c 202 ret i64 %t3 203} 204 205define i32 @test_x86_tbm_blci_u32(i32 %a) nounwind { 206; CHECK-LABEL: test_x86_tbm_blci_u32: 207; CHECK: # %bb.0: 208; CHECK-NEXT: blcil %edi, %eax 209; CHECK-NEXT: retq 210 %t0 = add i32 1, %a 211 %t1 = xor i32 %t0, -1 212 %t2 = or i32 %t1, %a 213 ret i32 %t2 214} 215 216define i32 @test_x86_tbm_blci_u32_z(i32 %a, i32 %b) nounwind { 217; CHECK-LABEL: test_x86_tbm_blci_u32_z: 218; CHECK: # %bb.0: 219; CHECK-NEXT: blcil %edi, %eax 220; CHECK-NEXT: cmovel %esi, %eax 221; CHECK-NEXT: retq 222 %t0 = add i32 1, %a 223 %t1 = xor i32 %t0, -1 224 %t2 = or i32 %t1, %a 225 %t3 = icmp eq i32 %t2, 0 226 %t4 = select i1 %t3, i32 %b, i32 %t2 227 ret i32 %t4 228} 229 230define i32 @test_x86_tbm_blci_u32_z2(i32 %a, i32 %b, i32 %c) nounwind { 231; CHECK-LABEL: test_x86_tbm_blci_u32_z2: 232; CHECK: # %bb.0: 233; CHECK-NEXT: # kill: def $edi killed $edi def $rdi 234; CHECK-NEXT: leal 1(%rdi), %eax 235; CHECK-NEXT: notl %eax 236; CHECK-NEXT: orl %edi, %eax 237; CHECK-NEXT: cmovnel %edx, %esi 238; CHECK-NEXT: movl %esi, %eax 239; CHECK-NEXT: retq 240 %t0 = add i32 1, %a 241 %t1 = xor i32 %t0, -1 242 %t2 = or i32 %t1, %a 243 %t3 = icmp eq i32 %t2, 0 244 %t4 = select i1 %t3, i32 %b, i32 %c 245 ret i32 %t4 246} 247 248define i64 @test_x86_tbm_blci_u64(i64 %a) nounwind { 249; CHECK-LABEL: test_x86_tbm_blci_u64: 250; CHECK: # %bb.0: 251; CHECK-NEXT: blciq %rdi, %rax 252; CHECK-NEXT: retq 253 %t0 = add i64 1, %a 254 %t1 = xor i64 %t0, -1 255 %t2 = or i64 %t1, %a 256 ret i64 %t2 257} 258 259define i64 @test_x86_tbm_blci_u64_z(i64 %a, i64 %b) nounwind { 260; CHECK-LABEL: test_x86_tbm_blci_u64_z: 261; CHECK: # %bb.0: 262; CHECK-NEXT: blciq %rdi, %rax 263; CHECK-NEXT: cmoveq %rsi, %rax 264; CHECK-NEXT: retq 265 %t0 = add i64 1, %a 266 %t1 = xor i64 %t0, -1 267 %t2 = or i64 %t1, %a 268 %t3 = icmp eq i64 %t2, 0 269 %t4 = select i1 %t3, i64 %b, i64 %t2 270 ret i64 %t4 271} 272 273define i64 @test_x86_tbm_blci_u64_z2(i64 %a, i64 %b, i64 %c) nounwind { 274; CHECK-LABEL: test_x86_tbm_blci_u64_z2: 275; CHECK: # %bb.0: 276; CHECK-NEXT: leaq 1(%rdi), %rax 277; CHECK-NEXT: notq %rax 278; CHECK-NEXT: orq %rdi, %rax 279; CHECK-NEXT: cmovneq %rdx, %rsi 280; CHECK-NEXT: movq %rsi, %rax 281; CHECK-NEXT: retq 282 %t0 = add i64 1, %a 283 %t1 = xor i64 %t0, -1 284 %t2 = or i64 %t1, %a 285 %t3 = icmp eq i64 %t2, 0 286 %t4 = select i1 %t3, i64 %b, i64 %c 287 ret i64 %t4 288} 289 290define i32 @test_x86_tbm_blci_u32_b(i32 %a) nounwind { 291; CHECK-LABEL: test_x86_tbm_blci_u32_b: 292; CHECK: # %bb.0: 293; CHECK-NEXT: blcil %edi, %eax 294; CHECK-NEXT: retq 295 %t0 = sub i32 -2, %a 296 %t1 = or i32 %t0, %a 297 ret i32 %t1 298} 299 300define i64 @test_x86_tbm_blci_u64_b(i64 %a) nounwind { 301; CHECK-LABEL: test_x86_tbm_blci_u64_b: 302; CHECK: # %bb.0: 303; CHECK-NEXT: blciq %rdi, %rax 304; CHECK-NEXT: retq 305 %t0 = sub i64 -2, %a 306 %t1 = or i64 %t0, %a 307 ret i64 %t1 308} 309 310define i32 @test_x86_tbm_blcic_u32(i32 %a) nounwind { 311; CHECK-LABEL: test_x86_tbm_blcic_u32: 312; CHECK: # %bb.0: 313; CHECK-NEXT: blcicl %edi, %eax 314; CHECK-NEXT: retq 315 %t0 = xor i32 %a, -1 316 %t1 = add i32 %a, 1 317 %t2 = and i32 %t1, %t0 318 ret i32 %t2 319} 320 321define i32 @test_x86_tbm_blcic_u32_z(i32 %a, i32 %b) nounwind { 322; CHECK-LABEL: test_x86_tbm_blcic_u32_z: 323; CHECK: # %bb.0: 324; CHECK-NEXT: blcicl %edi, %eax 325; CHECK-NEXT: cmovel %esi, %eax 326; CHECK-NEXT: retq 327 %t0 = xor i32 %a, -1 328 %t1 = add i32 %a, 1 329 %t2 = and i32 %t1, %t0 330 %t3 = icmp eq i32 %t2, 0 331 %t4 = select i1 %t3, i32 %b, i32 %t2 332 ret i32 %t4 333} 334 335define i32 @test_x86_tbm_blcic_u32_z2(i32 %a, i32 %b, i32 %c) nounwind { 336; CHECK-LABEL: test_x86_tbm_blcic_u32_z2: 337; CHECK: # %bb.0: 338; CHECK-NEXT: movl %edi, %eax 339; CHECK-NEXT: notl %eax 340; CHECK-NEXT: incl %edi 341; CHECK-NEXT: testl %eax, %edi 342; CHECK-NEXT: cmovnel %edx, %esi 343; CHECK-NEXT: movl %esi, %eax 344; CHECK-NEXT: retq 345 %t0 = xor i32 %a, -1 346 %t1 = add i32 %a, 1 347 %t2 = and i32 %t1, %t0 348 %t3 = icmp eq i32 %t2, 0 349 %t4 = select i1 %t3, i32 %b, i32 %c 350 ret i32 %t4 351} 352 353define i64 @test_x86_tbm_blcic_u64(i64 %a) nounwind { 354; CHECK-LABEL: test_x86_tbm_blcic_u64: 355; CHECK: # %bb.0: 356; CHECK-NEXT: blcicq %rdi, %rax 357; CHECK-NEXT: retq 358 %t0 = xor i64 %a, -1 359 %t1 = add i64 %a, 1 360 %t2 = and i64 %t1, %t0 361 ret i64 %t2 362} 363 364define i64 @test_x86_tbm_blcic_u64_z(i64 %a, i64 %b) nounwind { 365; CHECK-LABEL: test_x86_tbm_blcic_u64_z: 366; CHECK: # %bb.0: 367; CHECK-NEXT: blcicq %rdi, %rax 368; CHECK-NEXT: cmoveq %rsi, %rax 369; CHECK-NEXT: retq 370 %t0 = xor i64 %a, -1 371 %t1 = add i64 %a, 1 372 %t2 = and i64 %t1, %t0 373 %t3 = icmp eq i64 %t2, 0 374 %t4 = select i1 %t3, i64 %b, i64 %t2 375 ret i64 %t4 376} 377 378define i64 @test_x86_tbm_blcic_u64_z2(i64 %a, i64 %b, i64 %c) nounwind { 379; CHECK-LABEL: test_x86_tbm_blcic_u64_z2: 380; CHECK: # %bb.0: 381; CHECK-NEXT: movq %rdi, %rax 382; CHECK-NEXT: notq %rax 383; CHECK-NEXT: incq %rdi 384; CHECK-NEXT: testq %rax, %rdi 385; CHECK-NEXT: cmovneq %rdx, %rsi 386; CHECK-NEXT: movq %rsi, %rax 387; CHECK-NEXT: retq 388 %t0 = xor i64 %a, -1 389 %t1 = add i64 %a, 1 390 %t2 = and i64 %t1, %t0 391 %t3 = icmp eq i64 %t2, 0 392 %t4 = select i1 %t3, i64 %b, i64 %c 393 ret i64 %t4 394} 395 396define i32 @test_x86_tbm_blcmsk_u32(i32 %a) nounwind { 397; CHECK-LABEL: test_x86_tbm_blcmsk_u32: 398; CHECK: # %bb.0: 399; CHECK-NEXT: blcmskl %edi, %eax 400; CHECK-NEXT: retq 401 %t0 = add i32 %a, 1 402 %t1 = xor i32 %t0, %a 403 ret i32 %t1 404} 405 406define i32 @test_x86_tbm_blcmsk_u32_z(i32 %a, i32 %b) nounwind { 407; CHECK-LABEL: test_x86_tbm_blcmsk_u32_z: 408; CHECK: # %bb.0: 409; CHECK-NEXT: blcmskl %edi, %eax 410; CHECK-NEXT: cmovel %esi, %eax 411; CHECK-NEXT: retq 412 %t0 = add i32 %a, 1 413 %t1 = xor i32 %t0, %a 414 %t2 = icmp eq i32 %t1, 0 415 %t3 = select i1 %t2, i32 %b, i32 %t1 416 ret i32 %t3 417} 418 419define i32 @test_x86_tbm_blcmsk_u32_z2(i32 %a, i32 %b, i32 %c) nounwind { 420; CHECK-LABEL: test_x86_tbm_blcmsk_u32_z2: 421; CHECK: # %bb.0: 422; CHECK-NEXT: # kill: def $edi killed $edi def $rdi 423; CHECK-NEXT: leal 1(%rdi), %eax 424; CHECK-NEXT: xorl %edi, %eax 425; CHECK-NEXT: cmovnel %edx, %esi 426; CHECK-NEXT: movl %esi, %eax 427; CHECK-NEXT: retq 428 %t0 = add i32 %a, 1 429 %t1 = xor i32 %t0, %a 430 %t2 = icmp eq i32 %t1, 0 431 %t3 = select i1 %t2, i32 %b, i32 %c 432 ret i32 %t3 433} 434 435define i64 @test_x86_tbm_blcmsk_u64(i64 %a) nounwind { 436; CHECK-LABEL: test_x86_tbm_blcmsk_u64: 437; CHECK: # %bb.0: 438; CHECK-NEXT: blcmskq %rdi, %rax 439; CHECK-NEXT: retq 440 %t0 = add i64 %a, 1 441 %t1 = xor i64 %t0, %a 442 ret i64 %t1 443} 444 445define i64 @test_x86_tbm_blcmsk_u64_z(i64 %a, i64 %b) nounwind { 446; CHECK-LABEL: test_x86_tbm_blcmsk_u64_z: 447; CHECK: # %bb.0: 448; CHECK-NEXT: blcmskq %rdi, %rax 449; CHECK-NEXT: cmoveq %rsi, %rax 450; CHECK-NEXT: retq 451 %t0 = add i64 %a, 1 452 %t1 = xor i64 %t0, %a 453 %t2 = icmp eq i64 %t1, 0 454 %t3 = select i1 %t2, i64 %b, i64 %t1 455 ret i64 %t3 456} 457 458define i64 @test_x86_tbm_blcmsk_u64_z2(i64 %a, i64 %b, i64 %c) nounwind { 459; CHECK-LABEL: test_x86_tbm_blcmsk_u64_z2: 460; CHECK: # %bb.0: 461; CHECK-NEXT: leaq 1(%rdi), %rax 462; CHECK-NEXT: xorq %rdi, %rax 463; CHECK-NEXT: cmovneq %rdx, %rsi 464; CHECK-NEXT: movq %rsi, %rax 465; CHECK-NEXT: retq 466 %t0 = add i64 %a, 1 467 %t1 = xor i64 %t0, %a 468 %t2 = icmp eq i64 %t1, 0 469 %t3 = select i1 %t2, i64 %b, i64 %c 470 ret i64 %t3 471} 472 473define i32 @test_x86_tbm_blcs_u32(i32 %a) nounwind { 474; CHECK-LABEL: test_x86_tbm_blcs_u32: 475; CHECK: # %bb.0: 476; CHECK-NEXT: blcsl %edi, %eax 477; CHECK-NEXT: retq 478 %t0 = add i32 %a, 1 479 %t1 = or i32 %t0, %a 480 ret i32 %t1 481} 482 483define i32 @test_x86_tbm_blcs_u32_z(i32 %a, i32 %b) nounwind { 484; CHECK-LABEL: test_x86_tbm_blcs_u32_z: 485; CHECK: # %bb.0: 486; CHECK-NEXT: blcsl %edi, %eax 487; CHECK-NEXT: cmovel %esi, %eax 488; CHECK-NEXT: retq 489 %t0 = add i32 %a, 1 490 %t1 = or i32 %t0, %a 491 %t2 = icmp eq i32 %t1, 0 492 %t3 = select i1 %t2, i32 %b, i32 %t1 493 ret i32 %t3 494} 495 496define i32 @test_x86_tbm_blcs_u32_z2(i32 %a, i32 %b, i32 %c) nounwind { 497; CHECK-LABEL: test_x86_tbm_blcs_u32_z2: 498; CHECK: # %bb.0: 499; CHECK-NEXT: # kill: def $edi killed $edi def $rdi 500; CHECK-NEXT: leal 1(%rdi), %eax 501; CHECK-NEXT: orl %edi, %eax 502; CHECK-NEXT: cmovnel %edx, %esi 503; CHECK-NEXT: movl %esi, %eax 504; CHECK-NEXT: retq 505 %t0 = add i32 %a, 1 506 %t1 = or i32 %t0, %a 507 %t2 = icmp eq i32 %t1, 0 508 %t3 = select i1 %t2, i32 %b, i32 %c 509 ret i32 %t3 510} 511 512define i64 @test_x86_tbm_blcs_u64(i64 %a) nounwind { 513; CHECK-LABEL: test_x86_tbm_blcs_u64: 514; CHECK: # %bb.0: 515; CHECK-NEXT: blcsq %rdi, %rax 516; CHECK-NEXT: retq 517 %t0 = add i64 %a, 1 518 %t1 = or i64 %t0, %a 519 ret i64 %t1 520} 521 522define i64 @test_x86_tbm_blcs_u64_z(i64 %a, i64 %b) nounwind { 523; CHECK-LABEL: test_x86_tbm_blcs_u64_z: 524; CHECK: # %bb.0: 525; CHECK-NEXT: blcsq %rdi, %rax 526; CHECK-NEXT: cmoveq %rsi, %rax 527; CHECK-NEXT: retq 528 %t0 = add i64 %a, 1 529 %t1 = or i64 %t0, %a 530 %t2 = icmp eq i64 %t1, 0 531 %t3 = select i1 %t2, i64 %b, i64 %t1 532 ret i64 %t3 533} 534 535define i64 @test_x86_tbm_blcs_u64_z2(i64 %a, i64 %b, i64 %c) nounwind { 536; CHECK-LABEL: test_x86_tbm_blcs_u64_z2: 537; CHECK: # %bb.0: 538; CHECK-NEXT: leaq 1(%rdi), %rax 539; CHECK-NEXT: orq %rdi, %rax 540; CHECK-NEXT: cmovneq %rdx, %rsi 541; CHECK-NEXT: movq %rsi, %rax 542; CHECK-NEXT: retq 543 %t0 = add i64 %a, 1 544 %t1 = or i64 %t0, %a 545 %t2 = icmp eq i64 %t1, 0 546 %t3 = select i1 %t2, i64 %b, i64 %c 547 ret i64 %t3 548} 549 550define i32 @test_x86_tbm_blsfill_u32(i32 %a) nounwind { 551; CHECK-LABEL: test_x86_tbm_blsfill_u32: 552; CHECK: # %bb.0: 553; CHECK-NEXT: blsfilll %edi, %eax 554; CHECK-NEXT: retq 555 %t0 = add i32 %a, -1 556 %t1 = or i32 %t0, %a 557 ret i32 %t1 558} 559 560define i32 @test_x86_tbm_blsfill_u32_z(i32 %a, i32 %b) nounwind { 561; CHECK-LABEL: test_x86_tbm_blsfill_u32_z: 562; CHECK: # %bb.0: 563; CHECK-NEXT: blsfilll %edi, %eax 564; CHECK-NEXT: cmovel %esi, %eax 565; CHECK-NEXT: retq 566 %t0 = add i32 %a, -1 567 %t1 = or i32 %t0, %a 568 %t2 = icmp eq i32 %t1, 0 569 %t3 = select i1 %t2, i32 %b, i32 %t1 570 ret i32 %t3 571} 572 573define i32 @test_x86_tbm_blsfill_u32_z2(i32 %a, i32 %b, i32 %c) nounwind { 574; CHECK-LABEL: test_x86_tbm_blsfill_u32_z2: 575; CHECK: # %bb.0: 576; CHECK-NEXT: # kill: def $edi killed $edi def $rdi 577; CHECK-NEXT: leal -1(%rdi), %eax 578; CHECK-NEXT: orl %edi, %eax 579; CHECK-NEXT: cmovnel %edx, %esi 580; CHECK-NEXT: movl %esi, %eax 581; CHECK-NEXT: retq 582 %t0 = add i32 %a, -1 583 %t1 = or i32 %t0, %a 584 %t2 = icmp eq i32 %t1, 0 585 %t3 = select i1 %t2, i32 %b, i32 %c 586 ret i32 %t3 587} 588 589define i64 @test_x86_tbm_blsfill_u64(i64 %a) nounwind { 590; CHECK-LABEL: test_x86_tbm_blsfill_u64: 591; CHECK: # %bb.0: 592; CHECK-NEXT: blsfillq %rdi, %rax 593; CHECK-NEXT: retq 594 %t0 = add i64 %a, -1 595 %t1 = or i64 %t0, %a 596 ret i64 %t1 597} 598 599define i64 @test_x86_tbm_blsfill_u64_z(i64 %a, i64 %b) nounwind { 600; CHECK-LABEL: test_x86_tbm_blsfill_u64_z: 601; CHECK: # %bb.0: 602; CHECK-NEXT: blsfillq %rdi, %rax 603; CHECK-NEXT: cmoveq %rsi, %rax 604; CHECK-NEXT: retq 605 %t0 = add i64 %a, -1 606 %t1 = or i64 %t0, %a 607 %t2 = icmp eq i64 %t1, 0 608 %t3 = select i1 %t2, i64 %b, i64 %t1 609 ret i64 %t3 610} 611 612define i64 @test_x86_tbm_blsfill_u64_z2(i64 %a, i64 %b, i64 %c) nounwind { 613; CHECK-LABEL: test_x86_tbm_blsfill_u64_z2: 614; CHECK: # %bb.0: 615; CHECK-NEXT: leaq -1(%rdi), %rax 616; CHECK-NEXT: orq %rdi, %rax 617; CHECK-NEXT: cmovneq %rdx, %rsi 618; CHECK-NEXT: movq %rsi, %rax 619; CHECK-NEXT: retq 620 %t0 = add i64 %a, -1 621 %t1 = or i64 %t0, %a 622 %t2 = icmp eq i64 %t1, 0 623 %t3 = select i1 %t2, i64 %b, i64 %c 624 ret i64 %t3 625} 626 627define i32 @test_x86_tbm_blsic_u32(i32 %a) nounwind { 628; CHECK-LABEL: test_x86_tbm_blsic_u32: 629; CHECK: # %bb.0: 630; CHECK-NEXT: blsicl %edi, %eax 631; CHECK-NEXT: retq 632 %t0 = xor i32 %a, -1 633 %t1 = add i32 %a, -1 634 %t2 = or i32 %t0, %t1 635 ret i32 %t2 636} 637 638define i32 @test_x86_tbm_blsic_u32_z(i32 %a, i32 %b) nounwind { 639; CHECK-LABEL: test_x86_tbm_blsic_u32_z: 640; CHECK: # %bb.0: 641; CHECK-NEXT: blsicl %edi, %eax 642; CHECK-NEXT: cmovel %esi, %eax 643; CHECK-NEXT: retq 644 %t0 = xor i32 %a, -1 645 %t1 = add i32 %a, -1 646 %t2 = or i32 %t0, %t1 647 %t3 = icmp eq i32 %t2, 0 648 %t4 = select i1 %t3, i32 %b, i32 %t2 649 ret i32 %t4 650} 651 652define i32 @test_x86_tbm_blsic_u32_z2(i32 %a, i32 %b, i32 %c) nounwind { 653; CHECK-LABEL: test_x86_tbm_blsic_u32_z2: 654; CHECK: # %bb.0: 655; CHECK-NEXT: movl %edi, %eax 656; CHECK-NEXT: notl %eax 657; CHECK-NEXT: decl %edi 658; CHECK-NEXT: orl %eax, %edi 659; CHECK-NEXT: cmovnel %edx, %esi 660; CHECK-NEXT: movl %esi, %eax 661; CHECK-NEXT: retq 662 %t0 = xor i32 %a, -1 663 %t1 = add i32 %a, -1 664 %t2 = or i32 %t0, %t1 665 %t3 = icmp eq i32 %t2, 0 666 %t4 = select i1 %t3, i32 %b, i32 %c 667 ret i32 %t4 668} 669 670define i64 @test_x86_tbm_blsic_u64(i64 %a) nounwind { 671; CHECK-LABEL: test_x86_tbm_blsic_u64: 672; CHECK: # %bb.0: 673; CHECK-NEXT: blsicq %rdi, %rax 674; CHECK-NEXT: retq 675 %t0 = xor i64 %a, -1 676 %t1 = add i64 %a, -1 677 %t2 = or i64 %t0, %t1 678 ret i64 %t2 679} 680 681define i64 @test_x86_tbm_blsic_u64_z(i64 %a, i64 %b) nounwind { 682; CHECK-LABEL: test_x86_tbm_blsic_u64_z: 683; CHECK: # %bb.0: 684; CHECK-NEXT: blsicq %rdi, %rax 685; CHECK-NEXT: cmoveq %rsi, %rax 686; CHECK-NEXT: retq 687 %t0 = xor i64 %a, -1 688 %t1 = add i64 %a, -1 689 %t2 = or i64 %t0, %t1 690 %t3 = icmp eq i64 %t2, 0 691 %t4 = select i1 %t3, i64 %b, i64 %t2 692 ret i64 %t4 693} 694 695define i64 @test_x86_tbm_blsic_u64_z2(i64 %a, i64 %b, i64 %c) nounwind { 696; CHECK-LABEL: test_x86_tbm_blsic_u64_z2: 697; CHECK: # %bb.0: 698; CHECK-NEXT: movq %rdi, %rax 699; CHECK-NEXT: notq %rax 700; CHECK-NEXT: decq %rdi 701; CHECK-NEXT: orq %rax, %rdi 702; CHECK-NEXT: cmovneq %rdx, %rsi 703; CHECK-NEXT: movq %rsi, %rax 704; CHECK-NEXT: retq 705 %t0 = xor i64 %a, -1 706 %t1 = add i64 %a, -1 707 %t2 = or i64 %t0, %t1 708 %t3 = icmp eq i64 %t2, 0 709 %t4 = select i1 %t3, i64 %b, i64 %c 710 ret i64 %t4 711} 712 713define i32 @test_x86_tbm_t1mskc_u32(i32 %a) nounwind { 714; CHECK-LABEL: test_x86_tbm_t1mskc_u32: 715; CHECK: # %bb.0: 716; CHECK-NEXT: t1mskcl %edi, %eax 717; CHECK-NEXT: retq 718 %t0 = xor i32 %a, -1 719 %t1 = add i32 %a, 1 720 %t2 = or i32 %t0, %t1 721 ret i32 %t2 722} 723 724define i32 @test_x86_tbm_t1mskc_u32_z(i32 %a, i32 %b) nounwind { 725; CHECK-LABEL: test_x86_tbm_t1mskc_u32_z: 726; CHECK: # %bb.0: 727; CHECK-NEXT: t1mskcl %edi, %eax 728; CHECK-NEXT: testl %eax, %eax 729; CHECK-NEXT: cmovel %esi, %eax 730; CHECK-NEXT: retq 731 %t0 = xor i32 %a, -1 732 %t1 = add i32 %a, 1 733 %t2 = or i32 %t0, %t1 734 %t3 = icmp eq i32 %t2, 0 735 %t4 = select i1 %t3, i32 %b, i32 %t2 736 ret i32 %t4 737} 738 739define i32 @test_x86_tbm_t1mskc_u32_z2(i32 %a, i32 %b, i32 %c) nounwind { 740; CHECK-LABEL: test_x86_tbm_t1mskc_u32_z2: 741; CHECK: # %bb.0: 742; CHECK-NEXT: movl %edi, %eax 743; CHECK-NEXT: notl %eax 744; CHECK-NEXT: incl %edi 745; CHECK-NEXT: orl %eax, %edi 746; CHECK-NEXT: cmovnel %edx, %esi 747; CHECK-NEXT: movl %esi, %eax 748; CHECK-NEXT: retq 749 %t0 = xor i32 %a, -1 750 %t1 = add i32 %a, 1 751 %t2 = or i32 %t0, %t1 752 %t3 = icmp eq i32 %t2, 0 753 %t4 = select i1 %t3, i32 %b, i32 %c 754 ret i32 %t4 755} 756 757define i64 @test_x86_tbm_t1mskc_u64(i64 %a) nounwind { 758; CHECK-LABEL: test_x86_tbm_t1mskc_u64: 759; CHECK: # %bb.0: 760; CHECK-NEXT: t1mskcq %rdi, %rax 761; CHECK-NEXT: retq 762 %t0 = xor i64 %a, -1 763 %t1 = add i64 %a, 1 764 %t2 = or i64 %t0, %t1 765 ret i64 %t2 766} 767 768define i64 @test_x86_tbm_t1mskc_u64_z(i64 %a, i64 %b) nounwind { 769; CHECK-LABEL: test_x86_tbm_t1mskc_u64_z: 770; CHECK: # %bb.0: 771; CHECK-NEXT: t1mskcq %rdi, %rax 772; CHECK-NEXT: testq %rax, %rax 773; CHECK-NEXT: cmoveq %rsi, %rax 774; CHECK-NEXT: retq 775 %t0 = xor i64 %a, -1 776 %t1 = add i64 %a, 1 777 %t2 = or i64 %t0, %t1 778 %t3 = icmp eq i64 %t2, 0 779 %t4 = select i1 %t3, i64 %b, i64 %t2 780 ret i64 %t4 781} 782 783define i64 @test_x86_tbm_t1mskc_u64_z2(i64 %a, i64 %b, i64 %c) nounwind { 784; CHECK-LABEL: test_x86_tbm_t1mskc_u64_z2: 785; CHECK: # %bb.0: 786; CHECK-NEXT: movq %rdi, %rax 787; CHECK-NEXT: notq %rax 788; CHECK-NEXT: incq %rdi 789; CHECK-NEXT: orq %rax, %rdi 790; CHECK-NEXT: cmovneq %rdx, %rsi 791; CHECK-NEXT: movq %rsi, %rax 792; CHECK-NEXT: retq 793 %t0 = xor i64 %a, -1 794 %t1 = add i64 %a, 1 795 %t2 = or i64 %t0, %t1 796 %t3 = icmp eq i64 %t2, 0 797 %t4 = select i1 %t3, i64 %b, i64 %c 798 ret i64 %t4 799} 800 801define i32 @test_x86_tbm_tzmsk_u32(i32 %a) nounwind { 802; CHECK-LABEL: test_x86_tbm_tzmsk_u32: 803; CHECK: # %bb.0: 804; CHECK-NEXT: tzmskl %edi, %eax 805; CHECK-NEXT: retq 806 %t0 = xor i32 %a, -1 807 %t1 = add i32 %a, -1 808 %t2 = and i32 %t0, %t1 809 ret i32 %t2 810} 811 812define i32 @test_x86_tbm_tzmsk_u32_z(i32 %a, i32 %b) nounwind { 813; CHECK-LABEL: test_x86_tbm_tzmsk_u32_z: 814; CHECK: # %bb.0: 815; CHECK-NEXT: tzmskl %edi, %eax 816; CHECK-NEXT: testl %eax, %eax 817; CHECK-NEXT: cmovel %esi, %eax 818; CHECK-NEXT: retq 819 %t0 = xor i32 %a, -1 820 %t1 = add i32 %a, -1 821 %t2 = and i32 %t0, %t1 822 %t3 = icmp eq i32 %t2, 0 823 %t4 = select i1 %t3, i32 %b, i32 %t2 824 ret i32 %t4 825} 826 827define i32 @test_x86_tbm_tzmsk_u32_z2(i32 %a, i32 %b, i32 %c) nounwind { 828; CHECK-LABEL: test_x86_tbm_tzmsk_u32_z2: 829; CHECK: # %bb.0: 830; CHECK-NEXT: movl %edi, %eax 831; CHECK-NEXT: notl %eax 832; CHECK-NEXT: decl %edi 833; CHECK-NEXT: testl %edi, %eax 834; CHECK-NEXT: cmovnel %edx, %esi 835; CHECK-NEXT: movl %esi, %eax 836; CHECK-NEXT: retq 837 %t0 = xor i32 %a, -1 838 %t1 = add i32 %a, -1 839 %t2 = and i32 %t0, %t1 840 %t3 = icmp eq i32 %t2, 0 841 %t4 = select i1 %t3, i32 %b, i32 %c 842 ret i32 %t4 843} 844 845define i64 @test_x86_tbm_tzmsk_u64(i64 %a) nounwind { 846; CHECK-LABEL: test_x86_tbm_tzmsk_u64: 847; CHECK: # %bb.0: 848; CHECK-NEXT: tzmskq %rdi, %rax 849; CHECK-NEXT: retq 850 %t0 = xor i64 %a, -1 851 %t1 = add i64 %a, -1 852 %t2 = and i64 %t0, %t1 853 ret i64 %t2 854} 855 856define i64 @test_x86_tbm_tzmsk_u64_z(i64 %a, i64 %b) nounwind { 857; CHECK-LABEL: test_x86_tbm_tzmsk_u64_z: 858; CHECK: # %bb.0: 859; CHECK-NEXT: tzmskq %rdi, %rax 860; CHECK-NEXT: testq %rax, %rax 861; CHECK-NEXT: cmoveq %rsi, %rax 862; CHECK-NEXT: retq 863 %t0 = xor i64 %a, -1 864 %t1 = add i64 %a, -1 865 %t2 = and i64 %t0, %t1 866 %t3 = icmp eq i64 %t2, 0 867 %t4 = select i1 %t3, i64 %b, i64 %t2 868 ret i64 %t4 869} 870 871define i64 @test_x86_tbm_tzmsk_u64_z2(i64 %a, i64 %b, i64 %c) nounwind { 872; CHECK-LABEL: test_x86_tbm_tzmsk_u64_z2: 873; CHECK: # %bb.0: 874; CHECK-NEXT: movq %rdi, %rax 875; CHECK-NEXT: notq %rax 876; CHECK-NEXT: decq %rdi 877; CHECK-NEXT: testq %rdi, %rax 878; CHECK-NEXT: cmovneq %rdx, %rsi 879; CHECK-NEXT: movq %rsi, %rax 880; CHECK-NEXT: retq 881 %t0 = xor i64 %a, -1 882 %t1 = add i64 %a, -1 883 %t2 = and i64 %t0, %t1 884 %t3 = icmp eq i64 %t2, 0 885 %t4 = select i1 %t3, i64 %b, i64 %c 886 ret i64 %t4 887} 888 889define i64 @test_and_large_constant_mask(i64 %x) { 890; CHECK-LABEL: test_and_large_constant_mask: 891; CHECK: # %bb.0: # %entry 892; CHECK-NEXT: bextrq $15872, %rdi, %rax # imm = 0x3E00 893; CHECK-NEXT: retq 894entry: 895 %and = and i64 %x, 4611686018427387903 896 ret i64 %and 897} 898 899define i64 @test_and_large_constant_mask_load(i64* %x) { 900; CHECK-LABEL: test_and_large_constant_mask_load: 901; CHECK: # %bb.0: # %entry 902; CHECK-NEXT: bextrq $15872, (%rdi), %rax # imm = 0x3E00 903; CHECK-NEXT: retq 904entry: 905 %x1 = load i64, i64* %x 906 %and = and i64 %x1, 4611686018427387903 907 ret i64 %and 908} 909 910; Make sure the mask doesn't break our matching of blcic 911define i64 @masked_blcic(i64) { 912; CHECK-LABEL: masked_blcic: 913; CHECK: # %bb.0: 914; CHECK-NEXT: movzwl %di, %eax 915; CHECK-NEXT: blcicl %eax, %eax 916; CHECK-NEXT: retq 917 %2 = and i64 %0, 65535 918 %3 = xor i64 %2, -1 919 %4 = add nuw nsw i64 %2, 1 920 %5 = and i64 %4, %3 921 ret i64 %5 922} 923