1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=instsimplify -S | FileCheck %s 3 4; A == B implies A >u B is false. 5 6define void @test1(i32 %a, i32 %b) { 7; CHECK-LABEL: @test1( 8; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]] 9; CHECK-NEXT: br i1 [[CMP1]], label [[TAKEN:%.*]], label [[END:%.*]] 10; CHECK: taken: 11; CHECK-NEXT: call void @foo(i32 10) 12; CHECK-NEXT: br label [[END]] 13; CHECK: end: 14; CHECK-NEXT: ret void 15; 16 %cmp1 = icmp eq i32 %a, %b 17 br i1 %cmp1, label %taken, label %end 18 19taken: 20 %cmp2 = icmp ugt i32 %a, %b 21 %c = select i1 %cmp2, i32 0, i32 10 22 call void @foo(i32 %c) 23 br label %end 24 25end: 26 ret void 27} 28 29; If A == B is false then A != B is true. 30 31define void @test2(i32 %a, i32 %b) { 32; CHECK-LABEL: @test2( 33; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]] 34; CHECK-NEXT: br i1 [[CMP1]], label [[END:%.*]], label [[TAKEN:%.*]] 35; CHECK: taken: 36; CHECK-NEXT: call void @foo(i32 20) 37; CHECK-NEXT: br label [[END]] 38; CHECK: end: 39; CHECK-NEXT: ret void 40; 41 %cmp1 = icmp eq i32 %a, %b 42 br i1 %cmp1, label %end, label %taken 43 44taken: 45 %cmp2 = icmp ne i32 %a, %b 46 %c = select i1 %cmp2, i32 20, i32 0 47 call void @foo(i32 %c) 48 br label %end 49 50end: 51 ret void 52} 53 54; A >u 10 implies A >u 10 is true. 55 56define void @test3(i32 %a) { 57; CHECK-LABEL: @test3( 58; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i32 [[A:%.*]], 10 59; CHECK-NEXT: br i1 [[CMP1]], label [[TAKEN:%.*]], label [[END:%.*]] 60; CHECK: taken: 61; CHECK-NEXT: call void @foo(i32 30) 62; CHECK-NEXT: br label [[END]] 63; CHECK: end: 64; CHECK-NEXT: ret void 65; 66 %cmp1 = icmp ugt i32 %a, 10 67 br i1 %cmp1, label %taken, label %end 68 69taken: 70 %cmp2 = icmp ugt i32 %a, 10 71 %c = select i1 %cmp2, i32 30, i32 0 72 call void @foo(i32 %c) 73 br label %end 74 75end: 76 ret void 77} 78 79define i8 @PR23333(i8 addrspace(1)* %ptr) { 80; CHECK-LABEL: @PR23333( 81; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 addrspace(1)* [[PTR:%.*]], null 82; CHECK-NEXT: br i1 [[CMP]], label [[TAKEN:%.*]], label [[END:%.*]] 83; CHECK: taken: 84; CHECK-NEXT: ret i8 1 85; CHECK: end: 86; CHECK-NEXT: ret i8 0 87; 88 %cmp = icmp eq i8 addrspace(1)* %ptr, null 89 br i1 %cmp, label %taken, label %end 90 91taken: 92 %cmp2 = icmp ne i8 addrspace(1)* %ptr, null 93 %res = select i1 %cmp2, i8 2, i8 1 94 ret i8 %res 95 96end: 97 ret i8 0 98} 99 100; We know the condition of the select is true based on a dominating condition. 101; Therefore, we can replace %cond with %len. 102; TODO: len == 8 is known false in bb. This is handled by other passes, but should it be handled here? 103 104define void @test4(i32 %len) { 105; CHECK-LABEL: @test4( 106; CHECK-NEXT: entry: 107; CHECK-NEXT: [[TMP0:%.*]] = call i32 @bar(i32 [[LEN:%.*]]) 108; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[LEN]], 4 109; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[B1:%.*]] 110; CHECK: bb: 111; CHECK-NEXT: [[CMP11:%.*]] = icmp eq i32 [[LEN]], 8 112; CHECK-NEXT: br i1 [[CMP11]], label [[B0:%.*]], label [[B1]] 113; CHECK: b0: 114; CHECK-NEXT: call void @foo(i32 [[LEN]]) 115; CHECK-NEXT: br label [[B1]] 116; CHECK: b1: 117; CHECK-NEXT: [[TMP1:%.*]] = phi i32 [ [[LEN]], [[BB]] ], [ undef, [[B0]] ], [ [[TMP0]], [[ENTRY:%.*]] ] 118; CHECK-NEXT: br label [[RET:%.*]] 119; CHECK: ret: 120; CHECK-NEXT: call void @foo(i32 [[TMP1]]) 121; CHECK-NEXT: ret void 122; 123entry: 124 %0 = call i32 @bar(i32 %len); 125 %cmp = icmp ult i32 %len, 4 126 br i1 %cmp, label %bb, label %b1 127bb: 128 %cond = select i1 %cmp, i32 %len, i32 8 129 %cmp11 = icmp eq i32 %cond, 8 130 br i1 %cmp11, label %b0, label %b1 131 132b0: 133 call void @foo(i32 %len) 134 br label %b1 135 136b1: 137 %1 = phi i32 [ %cond, %bb ], [ undef, %b0 ], [ %0, %entry ] 138 br label %ret 139 140ret: 141 call void @foo(i32 %1) 142 ret void 143} 144 145; A >u 10 implies A >u 9 is true. 146 147define void @test5(i32 %a) { 148; CHECK-LABEL: @test5( 149; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i32 [[A:%.*]], 10 150; CHECK-NEXT: br i1 [[CMP1]], label [[TAKEN:%.*]], label [[END:%.*]] 151; CHECK: taken: 152; CHECK-NEXT: call void @foo(i32 30) 153; CHECK-NEXT: br label [[END]] 154; CHECK: end: 155; CHECK-NEXT: ret void 156; 157 %cmp1 = icmp ugt i32 %a, 10 158 br i1 %cmp1, label %taken, label %end 159 160taken: 161 %cmp2 = icmp ugt i32 %a, 9 162 %c = select i1 %cmp2, i32 30, i32 0 163 call void @foo(i32 %c) 164 br label %end 165 166end: 167 ret void 168} 169 170declare void @foo(i32) 171declare i32 @bar(i32) 172 173define i32 @test_and(i32 %a, i32 %b) { 174; CHECK-LABEL: @test_and( 175; CHECK-NEXT: entry: 176; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i32 [[A:%.*]], 0 177; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i32 [[B:%.*]], 0 178; CHECK-NEXT: [[AND:%.*]] = and i1 [[CMP1]], [[CMP2]] 179; CHECK-NEXT: br i1 [[AND]], label [[TPATH:%.*]], label [[END:%.*]] 180; CHECK: tpath: 181; CHECK-NEXT: ret i32 313 182; CHECK: end: 183; CHECK-NEXT: ret i32 0 184; 185entry: 186 %cmp1 = icmp ne i32 %a, 0 187 %cmp2 = icmp ne i32 %b, 0 188 %and = and i1 %cmp1, %cmp2 189 br i1 %and, label %tpath, label %end 190 191tpath: 192 %cmp3 = icmp eq i32 %a, 0 ;; <-- implied false 193 %c = select i1 %cmp3, i32 0, i32 313 194 ret i32 %c 195 196end: 197 ret i32 0 198} 199 200; cmp1 and cmp2 are false on the 'fpath' path and thus cmp3 is true. 201 202define i32 @test_or1(i32 %a, i32 %b) { 203; CHECK-LABEL: @test_or1( 204; CHECK-NEXT: entry: 205; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[A:%.*]], 0 206; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[B:%.*]], 0 207; CHECK-NEXT: [[OR:%.*]] = or i1 [[CMP1]], [[CMP2]] 208; CHECK-NEXT: br i1 [[OR]], label [[END:%.*]], label [[FPATH:%.*]] 209; CHECK: fpath: 210; CHECK-NEXT: ret i32 37 211; CHECK: end: 212; CHECK-NEXT: ret i32 0 213; 214entry: 215 %cmp1 = icmp eq i32 %a, 0 216 %cmp2 = icmp eq i32 %b, 0 217 %or = or i1 %cmp1, %cmp2 218 br i1 %or, label %end, label %fpath 219 220fpath: 221 %cmp3 = icmp ne i32 %a, 0 ;; <-- implied true 222 %c = select i1 %cmp3, i32 37, i32 0 223 ret i32 %c 224 225end: 226 ret i32 0 227} 228 229; LHS ==> RHS by definition (true -> true) 230 231define void @test6(i32 %a, i32 %b) { 232; CHECK-LABEL: @test6( 233; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]] 234; CHECK-NEXT: br i1 [[CMP1]], label [[TAKEN:%.*]], label [[END:%.*]] 235; CHECK: taken: 236; CHECK-NEXT: call void @foo(i32 10) 237; CHECK-NEXT: br label [[END]] 238; CHECK: end: 239; CHECK-NEXT: ret void 240; 241 %cmp1 = icmp eq i32 %a, %b 242 br i1 %cmp1, label %taken, label %end 243 244taken: 245 %c = select i1 %cmp1, i32 10, i32 0 246 call void @foo(i32 %c) 247 br label %end 248 249end: 250 ret void 251} 252 253; LHS ==> RHS by definition (false -> false) 254 255define void @test7(i32 %a, i32 %b) { 256; CHECK-LABEL: @test7( 257; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]] 258; CHECK-NEXT: br i1 [[CMP1]], label [[END:%.*]], label [[TAKEN:%.*]] 259; CHECK: taken: 260; CHECK-NEXT: call void @foo(i32 11) 261; CHECK-NEXT: br label [[END]] 262; CHECK: end: 263; CHECK-NEXT: ret void 264; 265 %cmp1 = icmp eq i32 %a, %b 266 br i1 %cmp1, label %end, label %taken 267 268taken: 269 %c = select i1 %cmp1, i32 0, i32 11 270 call void @foo(i32 %c) 271 br label %end 272 273end: 274 ret void 275} 276 277define void @implies_or(i32 %a, i32 %b, i1 %x) { 278; CHECK-LABEL: @implies_or( 279; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]] 280; CHECK-NEXT: br i1 [[CMP1]], label [[END:%.*]], label [[TAKEN:%.*]] 281; CHECK: taken: 282; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i32 [[A]], [[B]] 283; CHECK-NEXT: [[OR:%.*]] = or i1 [[CMP2]], [[X:%.*]] 284; CHECK-NEXT: [[C:%.*]] = select i1 [[OR]], i32 20, i32 0 285; CHECK-NEXT: call void @foo(i32 [[C]]) 286; CHECK-NEXT: br label [[END]] 287; CHECK: end: 288; CHECK-NEXT: ret void 289; 290 %cmp1 = icmp eq i32 %a, %b 291 br i1 %cmp1, label %end, label %taken 292 293taken: 294 %cmp2 = icmp ne i32 %a, %b 295 %or = or i1 %cmp2, %x 296 %c = select i1 %or, i32 20, i32 0 297 call void @foo(i32 %c) 298 br label %end 299 300end: 301 ret void 302} 303 304define void @implies_or_comm(i32 %a, i32 %b, i1 %x) { 305; CHECK-LABEL: @implies_or_comm( 306; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]] 307; CHECK-NEXT: br i1 [[CMP1]], label [[END:%.*]], label [[TAKEN:%.*]] 308; CHECK: taken: 309; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i32 [[A]], [[B]] 310; CHECK-NEXT: [[OR:%.*]] = or i1 [[X:%.*]], [[CMP2]] 311; CHECK-NEXT: [[C:%.*]] = select i1 [[OR]], i32 20, i32 0 312; CHECK-NEXT: call void @foo(i32 [[C]]) 313; CHECK-NEXT: br label [[END]] 314; CHECK: end: 315; CHECK-NEXT: ret void 316; 317 %cmp1 = icmp eq i32 %a, %b 318 br i1 %cmp1, label %end, label %taken 319 320taken: 321 %cmp2 = icmp ne i32 %a, %b 322 %or = or i1 %x, %cmp2 323 %c = select i1 %or, i32 20, i32 0 324 call void @foo(i32 %c) 325 br label %end 326 327end: 328 ret void 329} 330 331define void @implies_or_branch_comm(i32 %a, i32 %b, i1 %x) { 332; CHECK-LABEL: @implies_or_branch_comm( 333; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i32 [[A:%.*]], [[B:%.*]] 334; CHECK-NEXT: br i1 [[CMP1]], label [[TAKEN:%.*]], label [[END:%.*]] 335; CHECK: taken: 336; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i32 [[A]], [[B]] 337; CHECK-NEXT: [[OR:%.*]] = or i1 [[CMP2]], [[X:%.*]] 338; CHECK-NEXT: [[C:%.*]] = select i1 [[OR]], i32 20, i32 0 339; CHECK-NEXT: call void @foo(i32 [[C]]) 340; CHECK-NEXT: br label [[END]] 341; CHECK: end: 342; CHECK-NEXT: ret void 343; 344 %cmp1 = icmp ne i32 %a, %b 345 br i1 %cmp1, label %taken, label %end 346 347taken: 348 %cmp2 = icmp ne i32 %a, %b 349 %or = or i1 %cmp2, %x 350 %c = select i1 %or, i32 20, i32 0 351 call void @foo(i32 %c) 352 br label %end 353 354end: 355 ret void 356} 357 358define void @implies_logical_or(i32 %a, i32 %b, i1 %x) { 359; CHECK-LABEL: @implies_logical_or( 360; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]] 361; CHECK-NEXT: br i1 [[CMP1]], label [[END:%.*]], label [[TAKEN:%.*]] 362; CHECK: taken: 363; CHECK-NEXT: call void @foo(i32 20) 364; CHECK-NEXT: br label [[END]] 365; CHECK: end: 366; CHECK-NEXT: ret void 367; 368 %cmp1 = icmp eq i32 %a, %b 369 br i1 %cmp1, label %end, label %taken 370 371taken: 372 %cmp2 = icmp ne i32 %a, %b 373 %or = select i1 %cmp2, i1 true, i1 %x 374 %c = select i1 %or, i32 20, i32 0 375 call void @foo(i32 %c) 376 br label %end 377 378end: 379 ret void 380} 381 382define void @implies_logical_or_comm(i32 %a, i32 %b, i1 %x) { 383; CHECK-LABEL: @implies_logical_or_comm( 384; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]] 385; CHECK-NEXT: br i1 [[CMP1]], label [[END:%.*]], label [[TAKEN:%.*]] 386; CHECK: taken: 387; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i32 [[A]], [[B]] 388; CHECK-NEXT: [[OR:%.*]] = select i1 [[X:%.*]], i1 true, i1 [[CMP2]] 389; CHECK-NEXT: [[C:%.*]] = select i1 [[OR]], i32 20, i32 0 390; CHECK-NEXT: call void @foo(i32 [[C]]) 391; CHECK-NEXT: br label [[END]] 392; CHECK: end: 393; CHECK-NEXT: ret void 394; 395 %cmp1 = icmp eq i32 %a, %b 396 br i1 %cmp1, label %end, label %taken 397 398taken: 399 %cmp2 = icmp ne i32 %a, %b 400 %or = select i1 %x, i1 true, i1 %cmp2 401 %c = select i1 %or, i32 20, i32 0 402 call void @foo(i32 %c) 403 br label %end 404 405end: 406 ret void 407} 408 409define void @doesnt_imply_and(i32 %a, i32 %b, i1 %x) { 410; CHECK-LABEL: @doesnt_imply_and( 411; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]] 412; CHECK-NEXT: br i1 [[CMP1]], label [[END:%.*]], label [[TAKEN:%.*]] 413; CHECK: taken: 414; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i32 [[A]], [[B]] 415; CHECK-NEXT: [[OR:%.*]] = and i1 [[CMP2]], [[X:%.*]] 416; CHECK-NEXT: [[C:%.*]] = select i1 [[OR]], i32 20, i32 0 417; CHECK-NEXT: call void @foo(i32 [[C]]) 418; CHECK-NEXT: br label [[END]] 419; CHECK: end: 420; CHECK-NEXT: ret void 421; 422 %cmp1 = icmp eq i32 %a, %b 423 br i1 %cmp1, label %end, label %taken 424 425taken: 426 %cmp2 = icmp ne i32 %a, %b 427 %or = and i1 %cmp2, %x 428 %c = select i1 %or, i32 20, i32 0 429 call void @foo(i32 %c) 430 br label %end 431 432end: 433 ret void 434} 435 436define void @implies_not_and(i32 %a, i32 %b, i1 %x) { 437; CHECK-LABEL: @implies_not_and( 438; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]] 439; CHECK-NEXT: br i1 [[CMP1]], label [[END:%.*]], label [[TAKEN:%.*]] 440; CHECK: taken: 441; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[A]], [[B]] 442; CHECK-NEXT: [[AND:%.*]] = and i1 [[CMP2]], [[X:%.*]] 443; CHECK-NEXT: [[C:%.*]] = select i1 [[AND]], i32 20, i32 0 444; CHECK-NEXT: call void @foo(i32 [[C]]) 445; CHECK-NEXT: br label [[END]] 446; CHECK: end: 447; CHECK-NEXT: ret void 448; 449 %cmp1 = icmp eq i32 %a, %b 450 br i1 %cmp1, label %end, label %taken 451 452taken: 453 %cmp2 = icmp eq i32 %a, %b 454 %and = and i1 %cmp2, %x 455 %c = select i1 %and, i32 20, i32 0 456 call void @foo(i32 %c) 457 br label %end 458 459end: 460 ret void 461} 462 463define void @implies_not_and_comm(i32 %a, i32 %b, i1 %x) { 464; CHECK-LABEL: @implies_not_and_comm( 465; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]] 466; CHECK-NEXT: br i1 [[CMP1]], label [[END:%.*]], label [[TAKEN:%.*]] 467; CHECK: taken: 468; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[A]], [[B]] 469; CHECK-NEXT: [[AND:%.*]] = and i1 [[X:%.*]], [[CMP2]] 470; CHECK-NEXT: [[C:%.*]] = select i1 [[AND]], i32 20, i32 0 471; CHECK-NEXT: call void @foo(i32 [[C]]) 472; CHECK-NEXT: br label [[END]] 473; CHECK: end: 474; CHECK-NEXT: ret void 475; 476 %cmp1 = icmp eq i32 %a, %b 477 br i1 %cmp1, label %end, label %taken 478 479taken: 480 %cmp2 = icmp eq i32 %a, %b 481 %and = and i1 %x, %cmp2 482 %c = select i1 %and, i32 20, i32 0 483 call void @foo(i32 %c) 484 br label %end 485 486end: 487 ret void 488} 489 490define void @implies_not_and_branch_comm(i32 %a, i32 %b, i1 %x) { 491; CHECK-LABEL: @implies_not_and_branch_comm( 492; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i32 [[A:%.*]], [[B:%.*]] 493; CHECK-NEXT: br i1 [[CMP1]], label [[TAKEN:%.*]], label [[END:%.*]] 494; CHECK: taken: 495; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[A]], [[B]] 496; CHECK-NEXT: [[AND:%.*]] = and i1 [[CMP2]], [[X:%.*]] 497; CHECK-NEXT: [[C:%.*]] = select i1 [[AND]], i32 20, i32 0 498; CHECK-NEXT: call void @foo(i32 [[C]]) 499; CHECK-NEXT: br label [[END]] 500; CHECK: end: 501; CHECK-NEXT: ret void 502; 503 %cmp1 = icmp ne i32 %a, %b 504 br i1 %cmp1, label %taken, label %end 505 506taken: 507 %cmp2 = icmp eq i32 %a, %b 508 %and = and i1 %cmp2, %x 509 %c = select i1 %and, i32 20, i32 0 510 call void @foo(i32 %c) 511 br label %end 512 513end: 514 ret void 515} 516 517define void @implies_not_logical_and(i32 %a, i32 %b, i1 %x) { 518; CHECK-LABEL: @implies_not_logical_and( 519; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]] 520; CHECK-NEXT: br i1 [[CMP1]], label [[END:%.*]], label [[TAKEN:%.*]] 521; CHECK: taken: 522; CHECK-NEXT: call void @foo(i32 0) 523; CHECK-NEXT: br label [[END]] 524; CHECK: end: 525; CHECK-NEXT: ret void 526; 527 %cmp1 = icmp eq i32 %a, %b 528 br i1 %cmp1, label %end, label %taken 529 530taken: 531 %cmp2 = icmp eq i32 %a, %b 532 %and = select i1 %cmp2, i1 %x, i1 false 533 %c = select i1 %and, i32 20, i32 0 534 call void @foo(i32 %c) 535 br label %end 536 537end: 538 ret void 539} 540 541define void @implies_not_logical_and_comm(i32 %a, i32 %b, i1 %x) { 542; CHECK-LABEL: @implies_not_logical_and_comm( 543; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]] 544; CHECK-NEXT: br i1 [[CMP1]], label [[END:%.*]], label [[TAKEN:%.*]] 545; CHECK: taken: 546; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[A]], [[B]] 547; CHECK-NEXT: [[AND:%.*]] = select i1 [[X:%.*]], i1 [[CMP2]], i1 false 548; CHECK-NEXT: [[C:%.*]] = select i1 [[AND]], i32 20, i32 0 549; CHECK-NEXT: call void @foo(i32 [[C]]) 550; CHECK-NEXT: br label [[END]] 551; CHECK: end: 552; CHECK-NEXT: ret void 553; 554 %cmp1 = icmp eq i32 %a, %b 555 br i1 %cmp1, label %end, label %taken 556 557taken: 558 %cmp2 = icmp eq i32 %a, %b 559 %and = select i1 %x, i1 %cmp2, i1 false 560 %c = select i1 %and, i32 20, i32 0 561 call void @foo(i32 %c) 562 br label %end 563 564end: 565 ret void 566} 567 568define void @doesnt_imply_or(i32 %a, i32 %b, i1 %x) { 569; CHECK-LABEL: @doesnt_imply_or( 570; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]] 571; CHECK-NEXT: br i1 [[CMP1]], label [[END:%.*]], label [[TAKEN:%.*]] 572; CHECK: taken: 573; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[A]], [[B]] 574; CHECK-NEXT: [[AND:%.*]] = or i1 [[CMP2]], [[X:%.*]] 575; CHECK-NEXT: [[C:%.*]] = select i1 [[AND]], i32 20, i32 0 576; CHECK-NEXT: call void @foo(i32 [[C]]) 577; CHECK-NEXT: br label [[END]] 578; CHECK: end: 579; CHECK-NEXT: ret void 580; 581 %cmp1 = icmp eq i32 %a, %b 582 br i1 %cmp1, label %end, label %taken 583 584taken: 585 %cmp2 = icmp eq i32 %a, %b 586 %and = or i1 %cmp2, %x 587 %c = select i1 %and, i32 20, i32 0 588 call void @foo(i32 %c) 589 br label %end 590 591end: 592 ret void 593} 594