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 20define void @test2(i32 %x, i32 %n) nounwind { 21entry: 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 30bb: ; preds = %entry 31 call void @foo() 32 ret void 33 34UnifiedReturnBlock: ; preds = %entry 35 ret void 36} 37 38define void @test2b(i32 %x, i32 %n) nounwind { 39entry: 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 48bb: ; preds = %entry 49 call void @foo() 50 ret void 51 52UnifiedReturnBlock: ; preds = %entry 53 ret void 54} 55 56define void @atest2(i32 %x, i32 %n) nounwind { 57entry: 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 66bb: ; preds = %entry 67 call void @foo() 68 ret void 69 70UnifiedReturnBlock: ; preds = %entry 71 ret void 72} 73 74define void @atest2b(i32 %x, i32 %n) nounwind { 75entry: 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 83bb: ; preds = %entry 84 call void @foo() 85 ret void 86 87UnifiedReturnBlock: ; preds = %entry 88 ret void 89} 90 91define void @test3(i32 %x, i32 %n) nounwind { 92entry: 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 101bb: ; preds = %entry 102 call void @foo() 103 ret void 104 105UnifiedReturnBlock: ; preds = %entry 106 ret void 107} 108 109define void @test3b(i32 %x, i32 %n) nounwind { 110entry: 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 119bb: ; preds = %entry 120 call void @foo() 121 ret void 122 123UnifiedReturnBlock: ; preds = %entry 124 ret void 125} 126 127define void @testne2(i32 %x, i32 %n) nounwind { 128entry: 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 137bb: ; preds = %entry 138 call void @foo() 139 ret void 140 141UnifiedReturnBlock: ; preds = %entry 142 ret void 143} 144 145define void @testne2b(i32 %x, i32 %n) nounwind { 146entry: 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 155bb: ; preds = %entry 156 call void @foo() 157 ret void 158 159UnifiedReturnBlock: ; preds = %entry 160 ret void 161} 162 163define void @atestne2(i32 %x, i32 %n) nounwind { 164entry: 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 173bb: ; preds = %entry 174 call void @foo() 175 ret void 176 177UnifiedReturnBlock: ; preds = %entry 178 ret void 179} 180 181define void @atestne2b(i32 %x, i32 %n) nounwind { 182entry: 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 191bb: ; preds = %entry 192 call void @foo() 193 ret void 194 195UnifiedReturnBlock: ; preds = %entry 196 ret void 197} 198 199define void @testne3(i32 %x, i32 %n) nounwind { 200entry: 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 209bb: ; preds = %entry 210 call void @foo() 211 ret void 212 213UnifiedReturnBlock: ; preds = %entry 214 ret void 215} 216 217define void @testne3b(i32 %x, i32 %n) nounwind { 218entry: 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 227bb: ; preds = %entry 228 call void @foo() 229 ret void 230 231UnifiedReturnBlock: ; preds = %entry 232 ret void 233} 234 235define void @query2(i32 %x, i32 %n) nounwind { 236entry: 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 245bb: ; preds = %entry 246 call void @foo() 247 ret void 248 249UnifiedReturnBlock: ; preds = %entry 250 ret void 251} 252 253define void @query2b(i32 %x, i32 %n) nounwind { 254entry: 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 263bb: ; preds = %entry 264 call void @foo() 265 ret void 266 267UnifiedReturnBlock: ; preds = %entry 268 ret void 269} 270 271define void @aquery2(i32 %x, i32 %n) nounwind { 272entry: 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 281bb: ; preds = %entry 282 call void @foo() 283 ret void 284 285UnifiedReturnBlock: ; preds = %entry 286 ret void 287} 288 289define void @aquery2b(i32 %x, i32 %n) nounwind { 290entry: 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 299bb: ; preds = %entry 300 call void @foo() 301 ret void 302 303UnifiedReturnBlock: ; preds = %entry 304 ret void 305} 306 307define void @query3(i32 %x, i32 %n) nounwind { 308entry: 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 317bb: ; preds = %entry 318 call void @foo() 319 ret void 320 321UnifiedReturnBlock: ; preds = %entry 322 ret void 323} 324 325define void @query3b(i32 %x, i32 %n) nounwind { 326entry: 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 335bb: ; preds = %entry 336 call void @foo() 337 ret void 338 339UnifiedReturnBlock: ; preds = %entry 340 ret void 341} 342 343define void @query3x(i32 %x, i32 %n) nounwind { 344entry: 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 353bb: ; preds = %entry 354 call void @foo() 355 ret void 356 357UnifiedReturnBlock: ; preds = %entry 358 ret void 359} 360 361define void @query3bx(i32 %x, i32 %n) nounwind { 362entry: 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 371bb: ; preds = %entry 372 call void @foo() 373 ret void 374 375UnifiedReturnBlock: ; preds = %entry 376 ret void 377} 378 379define void @queryne2(i32 %x, i32 %n) nounwind { 380entry: 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 389bb: ; preds = %entry 390 call void @foo() 391 ret void 392 393UnifiedReturnBlock: ; preds = %entry 394 ret void 395} 396 397define void @queryne2b(i32 %x, i32 %n) nounwind { 398entry: 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 407bb: ; preds = %entry 408 call void @foo() 409 ret void 410 411UnifiedReturnBlock: ; preds = %entry 412 ret void 413} 414 415define void @aqueryne2(i32 %x, i32 %n) nounwind { 416entry: 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 425bb: ; preds = %entry 426 call void @foo() 427 ret void 428 429UnifiedReturnBlock: ; preds = %entry 430 ret void 431} 432 433define void @aqueryne2b(i32 %x, i32 %n) nounwind { 434entry: 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 443bb: ; preds = %entry 444 call void @foo() 445 ret void 446 447UnifiedReturnBlock: ; preds = %entry 448 ret void 449} 450 451define void @queryne3(i32 %x, i32 %n) nounwind { 452entry: 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 461bb: ; preds = %entry 462 call void @foo() 463 ret void 464 465UnifiedReturnBlock: ; preds = %entry 466 ret void 467} 468 469define void @queryne3b(i32 %x, i32 %n) nounwind { 470entry: 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 479bb: ; preds = %entry 480 call void @foo() 481 ret void 482 483UnifiedReturnBlock: ; preds = %entry 484 ret void 485} 486 487define void @queryne3x(i32 %x, i32 %n) nounwind { 488entry: 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 497bb: ; preds = %entry 498 call void @foo() 499 ret void 500 501UnifiedReturnBlock: ; preds = %entry 502 ret void 503} 504 505define void @queryne3bx(i32 %x, i32 %n) nounwind { 506entry: 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 515bb: ; preds = %entry 516 call void @foo() 517 ret void 518 519UnifiedReturnBlock: ; preds = %entry 520 ret void 521} 522 523declare void @foo() 524 525define zeroext i1 @invert(i32 %flags, i32 %flag) nounwind { 526; CHECK: btl 527entry: 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