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