1 ; RUN: llc < %s -mtriple=i386-apple-macosx -mcpu=penryn | FileCheck %s 2 ; PR3253 3 4 ; The register+memory form of the BT instruction should be usable on 5 ; pentium4, however it is currently disabled due to the register+memory 6 ; form having different semantics than the register+register form. 7 8 ; Test these patterns: 9 ; (X & (1 << N)) != 0 --> BT(X, N). 10 ; ((X >>u N) & 1) != 0 --> BT(X, N). 11 ; as well as several variations: 12 ; - The second form can use an arithmetic shift. 13 ; - Either form can use == instead of !=. 14 ; - Either form can compare with an operand of the & 15 ; instead of with 0. 16 ; - The comparison can be commuted (only cases where neither 17 ; operand is constant are included). 18 ; - The and can be commuted. 19 20 define void @test2(i32 %x, i32 %n) nounwind { 21 entry: 22 ; CHECK: test2 23 ; CHECK: btl %ecx, %eax 24 ; CHECK: jb 25 %tmp29 = lshr i32 %x, %n ; <i32> [#uses=1] 26 %tmp3 = and i32 %tmp29, 1 ; <i32> [#uses=1] 27 %tmp4 = icmp eq i32 %tmp3, 0 ; <i1> [#uses=1] 28 br i1 %tmp4, label %bb, label %UnifiedReturnBlock 29 30 bb: ; preds = %entry 31 call void @foo() 32 ret void 33 34 UnifiedReturnBlock: ; preds = %entry 35 ret void 36 } 37 38 define void @test2b(i32 %x, i32 %n) nounwind { 39 entry: 40 ; CHECK: test2b 41 ; CHECK: btl %e{{..}}, %e{{..}} 42 ; CHECK: jb 43 %tmp29 = lshr i32 %x, %n ; <i32> [#uses=1] 44 %tmp3 = and i32 1, %tmp29 45 %tmp4 = icmp eq i32 %tmp3, 0 ; <i1> [#uses=1] 46 br i1 %tmp4, label %bb, label %UnifiedReturnBlock 47 48 bb: ; preds = %entry 49 call void @foo() 50 ret void 51 52 UnifiedReturnBlock: ; preds = %entry 53 ret void 54 } 55 56 define void @atest2(i32 %x, i32 %n) nounwind { 57 entry: 58 ; CHECK: atest2 59 ; CHECK: btl %e{{..}}, %e{{..}} 60 ; CHECK: jb 61 %tmp29 = ashr i32 %x, %n ; <i32> [#uses=1] 62 %tmp3 = and i32 %tmp29, 1 ; <i32> [#uses=1] 63 %tmp4 = icmp eq i32 %tmp3, 0 ; <i1> [#uses=1] 64 br i1 %tmp4, label %bb, label %UnifiedReturnBlock 65 66 bb: ; preds = %entry 67 call void @foo() 68 ret void 69 70 UnifiedReturnBlock: ; preds = %entry 71 ret void 72 } 73 74 define void @atest2b(i32 %x, i32 %n) nounwind { 75 entry: 76 ; CHECK: atest2b 77 ; CHECK: btl %e{{..}}, %e{{..}} 78 %tmp29 = ashr i32 %x, %n ; <i32> [#uses=1] 79 %tmp3 = and i32 1, %tmp29 80 %tmp4 = icmp eq i32 %tmp3, 0 ; <i1> [#uses=1] 81 br i1 %tmp4, label %bb, label %UnifiedReturnBlock 82 83 bb: ; preds = %entry 84 call void @foo() 85 ret void 86 87 UnifiedReturnBlock: ; preds = %entry 88 ret void 89 } 90 91 define void @test3(i32 %x, i32 %n) nounwind { 92 entry: 93 ; CHECK: test3 94 ; CHECK: btl %e{{..}}, %e{{..}} 95 ; CHECK: jb 96 %tmp29 = shl i32 1, %n ; <i32> [#uses=1] 97 %tmp3 = and i32 %tmp29, %x ; <i32> [#uses=1] 98 %tmp4 = icmp eq i32 %tmp3, 0 ; <i1> [#uses=1] 99 br i1 %tmp4, label %bb, label %UnifiedReturnBlock 100 101 bb: ; preds = %entry 102 call void @foo() 103 ret void 104 105 UnifiedReturnBlock: ; preds = %entry 106 ret void 107 } 108 109 define void @test3b(i32 %x, i32 %n) nounwind { 110 entry: 111 ; CHECK: test3b 112 ; CHECK: btl %e{{..}}, %e{{..}} 113 ; CHECK: jb 114 %tmp29 = shl i32 1, %n ; <i32> [#uses=1] 115 %tmp3 = and i32 %x, %tmp29 116 %tmp4 = icmp eq i32 %tmp3, 0 ; <i1> [#uses=1] 117 br i1 %tmp4, label %bb, label %UnifiedReturnBlock 118 119 bb: ; preds = %entry 120 call void @foo() 121 ret void 122 123 UnifiedReturnBlock: ; preds = %entry 124 ret void 125 } 126 127 define void @testne2(i32 %x, i32 %n) nounwind { 128 entry: 129 ; CHECK: testne2 130 ; CHECK: btl %e{{..}}, %e{{..}} 131 ; CHECK: jae 132 %tmp29 = lshr i32 %x, %n ; <i32> [#uses=1] 133 %tmp3 = and i32 %tmp29, 1 ; <i32> [#uses=1] 134 %tmp4 = icmp ne i32 %tmp3, 0 ; <i1> [#uses=1] 135 br i1 %tmp4, label %bb, label %UnifiedReturnBlock 136 137 bb: ; preds = %entry 138 call void @foo() 139 ret void 140 141 UnifiedReturnBlock: ; preds = %entry 142 ret void 143 } 144 145 define void @testne2b(i32 %x, i32 %n) nounwind { 146 entry: 147 ; CHECK: testne2b 148 ; CHECK: btl %e{{..}}, %e{{..}} 149 ; CHECK: jae 150 %tmp29 = lshr i32 %x, %n ; <i32> [#uses=1] 151 %tmp3 = and i32 1, %tmp29 152 %tmp4 = icmp ne i32 %tmp3, 0 ; <i1> [#uses=1] 153 br i1 %tmp4, label %bb, label %UnifiedReturnBlock 154 155 bb: ; preds = %entry 156 call void @foo() 157 ret void 158 159 UnifiedReturnBlock: ; preds = %entry 160 ret void 161 } 162 163 define void @atestne2(i32 %x, i32 %n) nounwind { 164 entry: 165 ; CHECK: atestne2 166 ; CHECK: btl %e{{..}}, %e{{..}} 167 ; CHECK: jae 168 %tmp29 = ashr i32 %x, %n ; <i32> [#uses=1] 169 %tmp3 = and i32 %tmp29, 1 ; <i32> [#uses=1] 170 %tmp4 = icmp ne i32 %tmp3, 0 ; <i1> [#uses=1] 171 br i1 %tmp4, label %bb, label %UnifiedReturnBlock 172 173 bb: ; preds = %entry 174 call void @foo() 175 ret void 176 177 UnifiedReturnBlock: ; preds = %entry 178 ret void 179 } 180 181 define void @atestne2b(i32 %x, i32 %n) nounwind { 182 entry: 183 ; CHECK: atestne2b 184 ; CHECK: btl %e{{..}}, %e{{..}} 185 ; CHECK: jae 186 %tmp29 = ashr i32 %x, %n ; <i32> [#uses=1] 187 %tmp3 = and i32 1, %tmp29 188 %tmp4 = icmp ne i32 %tmp3, 0 ; <i1> [#uses=1] 189 br i1 %tmp4, label %bb, label %UnifiedReturnBlock 190 191 bb: ; preds = %entry 192 call void @foo() 193 ret void 194 195 UnifiedReturnBlock: ; preds = %entry 196 ret void 197 } 198 199 define void @testne3(i32 %x, i32 %n) nounwind { 200 entry: 201 ; CHECK: testne3 202 ; CHECK: btl %e{{..}}, %e{{..}} 203 ; CHECK: jae 204 %tmp29 = shl i32 1, %n ; <i32> [#uses=1] 205 %tmp3 = and i32 %tmp29, %x ; <i32> [#uses=1] 206 %tmp4 = icmp ne i32 %tmp3, 0 ; <i1> [#uses=1] 207 br i1 %tmp4, label %bb, label %UnifiedReturnBlock 208 209 bb: ; preds = %entry 210 call void @foo() 211 ret void 212 213 UnifiedReturnBlock: ; preds = %entry 214 ret void 215 } 216 217 define void @testne3b(i32 %x, i32 %n) nounwind { 218 entry: 219 ; CHECK: testne3b 220 ; CHECK: btl %e{{..}}, %e{{..}} 221 ; CHECK: jae 222 %tmp29 = shl i32 1, %n ; <i32> [#uses=1] 223 %tmp3 = and i32 %x, %tmp29 224 %tmp4 = icmp ne i32 %tmp3, 0 ; <i1> [#uses=1] 225 br i1 %tmp4, label %bb, label %UnifiedReturnBlock 226 227 bb: ; preds = %entry 228 call void @foo() 229 ret void 230 231 UnifiedReturnBlock: ; preds = %entry 232 ret void 233 } 234 235 define void @query2(i32 %x, i32 %n) nounwind { 236 entry: 237 ; CHECK: query2 238 ; CHECK: btl %e{{..}}, %e{{..}} 239 ; CHECK: jae 240 %tmp29 = lshr i32 %x, %n ; <i32> [#uses=1] 241 %tmp3 = and i32 %tmp29, 1 ; <i32> [#uses=1] 242 %tmp4 = icmp eq i32 %tmp3, 1 ; <i1> [#uses=1] 243 br i1 %tmp4, label %bb, label %UnifiedReturnBlock 244 245 bb: ; preds = %entry 246 call void @foo() 247 ret void 248 249 UnifiedReturnBlock: ; preds = %entry 250 ret void 251 } 252 253 define void @query2b(i32 %x, i32 %n) nounwind { 254 entry: 255 ; CHECK: query2b 256 ; CHECK: btl %e{{..}}, %e{{..}} 257 ; CHECK: jae 258 %tmp29 = lshr i32 %x, %n ; <i32> [#uses=1] 259 %tmp3 = and i32 1, %tmp29 260 %tmp4 = icmp eq i32 %tmp3, 1 ; <i1> [#uses=1] 261 br i1 %tmp4, label %bb, label %UnifiedReturnBlock 262 263 bb: ; preds = %entry 264 call void @foo() 265 ret void 266 267 UnifiedReturnBlock: ; preds = %entry 268 ret void 269 } 270 271 define void @aquery2(i32 %x, i32 %n) nounwind { 272 entry: 273 ; CHECK: aquery2 274 ; CHECK: btl %e{{..}}, %e{{..}} 275 ; CHECK: jae 276 %tmp29 = ashr i32 %x, %n ; <i32> [#uses=1] 277 %tmp3 = and i32 %tmp29, 1 ; <i32> [#uses=1] 278 %tmp4 = icmp eq i32 %tmp3, 1 ; <i1> [#uses=1] 279 br i1 %tmp4, label %bb, label %UnifiedReturnBlock 280 281 bb: ; preds = %entry 282 call void @foo() 283 ret void 284 285 UnifiedReturnBlock: ; preds = %entry 286 ret void 287 } 288 289 define void @aquery2b(i32 %x, i32 %n) nounwind { 290 entry: 291 ; CHECK: aquery2b 292 ; CHECK: btl %e{{..}}, %e{{..}} 293 ; CHECK: jae 294 %tmp29 = ashr i32 %x, %n ; <i32> [#uses=1] 295 %tmp3 = and i32 1, %tmp29 296 %tmp4 = icmp eq i32 %tmp3, 1 ; <i1> [#uses=1] 297 br i1 %tmp4, label %bb, label %UnifiedReturnBlock 298 299 bb: ; preds = %entry 300 call void @foo() 301 ret void 302 303 UnifiedReturnBlock: ; preds = %entry 304 ret void 305 } 306 307 define void @query3(i32 %x, i32 %n) nounwind { 308 entry: 309 ; CHECK: query3 310 ; CHECK: btl %e{{..}}, %e{{..}} 311 ; CHECK: jae 312 %tmp29 = shl i32 1, %n ; <i32> [#uses=1] 313 %tmp3 = and i32 %tmp29, %x ; <i32> [#uses=1] 314 %tmp4 = icmp eq i32 %tmp3, %tmp29 ; <i1> [#uses=1] 315 br i1 %tmp4, label %bb, label %UnifiedReturnBlock 316 317 bb: ; preds = %entry 318 call void @foo() 319 ret void 320 321 UnifiedReturnBlock: ; preds = %entry 322 ret void 323 } 324 325 define void @query3b(i32 %x, i32 %n) nounwind { 326 entry: 327 ; CHECK: query3b 328 ; CHECK: btl %e{{..}}, %e{{..}} 329 ; CHECK: jae 330 %tmp29 = shl i32 1, %n ; <i32> [#uses=1] 331 %tmp3 = and i32 %x, %tmp29 332 %tmp4 = icmp eq i32 %tmp3, %tmp29 ; <i1> [#uses=1] 333 br i1 %tmp4, label %bb, label %UnifiedReturnBlock 334 335 bb: ; preds = %entry 336 call void @foo() 337 ret void 338 339 UnifiedReturnBlock: ; preds = %entry 340 ret void 341 } 342 343 define void @query3x(i32 %x, i32 %n) nounwind { 344 entry: 345 ; CHECK: query3x 346 ; CHECK: btl %e{{..}}, %e{{..}} 347 ; CHECK: jae 348 %tmp29 = shl i32 1, %n ; <i32> [#uses=1] 349 %tmp3 = and i32 %tmp29, %x ; <i32> [#uses=1] 350 %tmp4 = icmp eq i32 %tmp29, %tmp3 ; <i1> [#uses=1] 351 br i1 %tmp4, label %bb, label %UnifiedReturnBlock 352 353 bb: ; preds = %entry 354 call void @foo() 355 ret void 356 357 UnifiedReturnBlock: ; preds = %entry 358 ret void 359 } 360 361 define void @query3bx(i32 %x, i32 %n) nounwind { 362 entry: 363 ; CHECK: query3bx 364 ; CHECK: btl %e{{..}}, %e{{..}} 365 ; CHECK: jae 366 %tmp29 = shl i32 1, %n ; <i32> [#uses=1] 367 %tmp3 = and i32 %x, %tmp29 368 %tmp4 = icmp eq i32 %tmp29, %tmp3 ; <i1> [#uses=1] 369 br i1 %tmp4, label %bb, label %UnifiedReturnBlock 370 371 bb: ; preds = %entry 372 call void @foo() 373 ret void 374 375 UnifiedReturnBlock: ; preds = %entry 376 ret void 377 } 378 379 define void @queryne2(i32 %x, i32 %n) nounwind { 380 entry: 381 ; CHECK: queryne2 382 ; CHECK: btl %e{{..}}, %e{{..}} 383 ; CHECK: jb 384 %tmp29 = lshr i32 %x, %n ; <i32> [#uses=1] 385 %tmp3 = and i32 %tmp29, 1 ; <i32> [#uses=1] 386 %tmp4 = icmp ne i32 %tmp3, 1 ; <i1> [#uses=1] 387 br i1 %tmp4, label %bb, label %UnifiedReturnBlock 388 389 bb: ; preds = %entry 390 call void @foo() 391 ret void 392 393 UnifiedReturnBlock: ; preds = %entry 394 ret void 395 } 396 397 define void @queryne2b(i32 %x, i32 %n) nounwind { 398 entry: 399 ; CHECK: queryne2b 400 ; CHECK: btl %e{{..}}, %e{{..}} 401 ; CHECK: jb 402 %tmp29 = lshr i32 %x, %n ; <i32> [#uses=1] 403 %tmp3 = and i32 1, %tmp29 404 %tmp4 = icmp ne i32 %tmp3, 1 ; <i1> [#uses=1] 405 br i1 %tmp4, label %bb, label %UnifiedReturnBlock 406 407 bb: ; preds = %entry 408 call void @foo() 409 ret void 410 411 UnifiedReturnBlock: ; preds = %entry 412 ret void 413 } 414 415 define void @aqueryne2(i32 %x, i32 %n) nounwind { 416 entry: 417 ; CHECK: aqueryne2 418 ; CHECK: btl %e{{..}}, %e{{..}} 419 ; CHECK: jb 420 %tmp29 = ashr i32 %x, %n ; <i32> [#uses=1] 421 %tmp3 = and i32 %tmp29, 1 ; <i32> [#uses=1] 422 %tmp4 = icmp ne i32 %tmp3, 1 ; <i1> [#uses=1] 423 br i1 %tmp4, label %bb, label %UnifiedReturnBlock 424 425 bb: ; preds = %entry 426 call void @foo() 427 ret void 428 429 UnifiedReturnBlock: ; preds = %entry 430 ret void 431 } 432 433 define void @aqueryne2b(i32 %x, i32 %n) nounwind { 434 entry: 435 ; CHECK: aqueryne2b 436 ; CHECK: btl %e{{..}}, %e{{..}} 437 ; CHECK: jb 438 %tmp29 = ashr i32 %x, %n ; <i32> [#uses=1] 439 %tmp3 = and i32 1, %tmp29 440 %tmp4 = icmp ne i32 %tmp3, 1 ; <i1> [#uses=1] 441 br i1 %tmp4, label %bb, label %UnifiedReturnBlock 442 443 bb: ; preds = %entry 444 call void @foo() 445 ret void 446 447 UnifiedReturnBlock: ; preds = %entry 448 ret void 449 } 450 451 define void @queryne3(i32 %x, i32 %n) nounwind { 452 entry: 453 ; CHECK: queryne3 454 ; CHECK: btl %e{{..}}, %e{{..}} 455 ; CHECK: jb 456 %tmp29 = shl i32 1, %n ; <i32> [#uses=1] 457 %tmp3 = and i32 %tmp29, %x ; <i32> [#uses=1] 458 %tmp4 = icmp ne i32 %tmp3, %tmp29 ; <i1> [#uses=1] 459 br i1 %tmp4, label %bb, label %UnifiedReturnBlock 460 461 bb: ; preds = %entry 462 call void @foo() 463 ret void 464 465 UnifiedReturnBlock: ; preds = %entry 466 ret void 467 } 468 469 define void @queryne3b(i32 %x, i32 %n) nounwind { 470 entry: 471 ; CHECK: queryne3b 472 ; CHECK: btl %e{{..}}, %e{{..}} 473 ; CHECK: jb 474 %tmp29 = shl i32 1, %n ; <i32> [#uses=1] 475 %tmp3 = and i32 %x, %tmp29 476 %tmp4 = icmp ne i32 %tmp3, %tmp29 ; <i1> [#uses=1] 477 br i1 %tmp4, label %bb, label %UnifiedReturnBlock 478 479 bb: ; preds = %entry 480 call void @foo() 481 ret void 482 483 UnifiedReturnBlock: ; preds = %entry 484 ret void 485 } 486 487 define void @queryne3x(i32 %x, i32 %n) nounwind { 488 entry: 489 ; CHECK: queryne3x 490 ; CHECK: btl %e{{..}}, %e{{..}} 491 ; CHECK: jb 492 %tmp29 = shl i32 1, %n ; <i32> [#uses=1] 493 %tmp3 = and i32 %tmp29, %x ; <i32> [#uses=1] 494 %tmp4 = icmp ne i32 %tmp29, %tmp3 ; <i1> [#uses=1] 495 br i1 %tmp4, label %bb, label %UnifiedReturnBlock 496 497 bb: ; preds = %entry 498 call void @foo() 499 ret void 500 501 UnifiedReturnBlock: ; preds = %entry 502 ret void 503 } 504 505 define void @queryne3bx(i32 %x, i32 %n) nounwind { 506 entry: 507 ; CHECK: queryne3bx 508 ; CHECK: btl %e{{..}}, %e{{..}} 509 ; CHECK: jb 510 %tmp29 = shl i32 1, %n ; <i32> [#uses=1] 511 %tmp3 = and i32 %x, %tmp29 512 %tmp4 = icmp ne i32 %tmp29, %tmp3 ; <i1> [#uses=1] 513 br i1 %tmp4, label %bb, label %UnifiedReturnBlock 514 515 bb: ; preds = %entry 516 call void @foo() 517 ret void 518 519 UnifiedReturnBlock: ; preds = %entry 520 ret void 521 } 522 523 declare void @foo() 524 525 define zeroext i1 @invert(i32 %flags, i32 %flag) nounwind { 526 ; CHECK: btl 527 entry: 528 %neg = xor i32 %flags, -1 529 %shl = shl i32 1, %flag 530 %and = and i32 %shl, %neg 531 %tobool = icmp ne i32 %and, 0 532 ret i1 %tobool 533 } 534