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 6 define 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 17 define 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 28 define 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 39 define 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 52 define 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 67 define 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 78 define 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 89 define 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 100 define 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 113 define 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 128 define 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 138 define 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 151 define 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 167 define 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 177 define 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 190 define 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 205 define 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 216 define 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 230 define 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 248 define 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 259 define 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 273 define 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 290 define 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 300 define 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 310 define 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 321 define 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 335 define 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 353 define 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 364 define 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 378 define 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 396 define 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 406 define 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 419 define 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 435 define 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 445 define 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 458 define 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 473 define 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 483 define 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 496 define 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 512 define 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 522 define 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 535 define 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 550 define 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 560 define 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 573 define 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 589 define 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 599 define 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 612 define 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 627 define 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 638 define 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 652 define 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 670 define 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 681 define 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 695 define 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 713 define 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 724 define 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 739 define 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 757 define 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 768 define 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 783 define 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 801 define 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 812 define 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 827 define 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 845 define 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 856 define 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 871 define 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 889 define 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 894 entry: 895 %and = and i64 %x, 4611686018427387903 896 ret i64 %and 897 } 898 899 define 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 904 entry: 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 911 define 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