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