1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 2; RUN: opt < %s -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s 3 4define void @ucmp_gt1(i32 %a, i32 %b) { 5; CHECK-LABEL: define void @ucmp_gt1( 6; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) { 7; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[A]], [[B]] 8; CHECK-NEXT: br i1 [[TMP1]], label %[[BB1:.*]], label %[[BB2:.*]] 9; CHECK: [[BB1]]: 10; CHECK-NEXT: call void @foo() 11; CHECK-NEXT: br label %[[BB2]] 12; CHECK: [[BB2]]: 13; CHECK-NEXT: ret void 14; 15 %res = call i8 @llvm.ucmp.i8.i32(i32 %a, i32 %b) 16 switch i8 %res, label %bb1 [ 17 i8 -1, label %bb2 18 i8 0, label %bb2 19 ] 20 21bb1: 22 call void @foo() 23 br label %bb2 24 25bb2: 26 ret void 27} 28 29define void @ucmp_gt2(i32 %a, i32 %b) { 30; CHECK-LABEL: define void @ucmp_gt2( 31; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) { 32; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[A]], [[B]] 33; CHECK-NEXT: br i1 [[TMP1]], label %[[BB1:.*]], label %[[BB2:.*]] 34; CHECK: [[BB1]]: 35; CHECK-NEXT: call void @foo() 36; CHECK-NEXT: br label %[[BB2]] 37; CHECK: [[BB2]]: 38; CHECK-NEXT: ret void 39; 40 %res = call i8 @llvm.ucmp.i8.i32(i32 %a, i32 %b) 41 switch i8 %res, label %bb1 [ 42 i8 0, label %bb2 43 i8 -1, label %bb2 44 ] 45 46bb1: 47 call void @foo() 48 br label %bb2 49 50bb2: 51 ret void 52} 53 54define void @ucmp_lt1(i32 %a, i32 %b) { 55; CHECK-LABEL: define void @ucmp_lt1( 56; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) { 57; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[A]], [[B]] 58; CHECK-NEXT: br i1 [[TMP1]], label %[[BB2:.*]], label %[[BB1:.*]] 59; CHECK: [[BB1]]: 60; CHECK-NEXT: call void @foo() 61; CHECK-NEXT: br label %[[BB2]] 62; CHECK: [[BB2]]: 63; CHECK-NEXT: ret void 64; 65 %res = call i8 @llvm.ucmp.i8.i32(i32 %a, i32 %b) 66 switch i8 %res, label %bb2 [ 67 i8 1, label %bb1 68 i8 0, label %bb1 69 ] 70 71bb1: 72 call void @foo() 73 br label %bb2 74 75bb2: 76 ret void 77} 78 79define void @ucmp_lt2(i32 %a, i32 %b) { 80; CHECK-LABEL: define void @ucmp_lt2( 81; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) { 82; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[A]], [[B]] 83; CHECK-NEXT: br i1 [[TMP1]], label %[[BB2:.*]], label %[[BB1:.*]] 84; CHECK: [[BB1]]: 85; CHECK-NEXT: call void @foo() 86; CHECK-NEXT: br label %[[BB2]] 87; CHECK: [[BB2]]: 88; CHECK-NEXT: ret void 89; 90 %res = call i8 @llvm.ucmp.i8.i32(i32 %a, i32 %b) 91 switch i8 %res, label %bb2 [ 92 i8 0, label %bb1 93 i8 1, label %bb1 94 ] 95 96bb1: 97 call void @foo() 98 br label %bb2 99 100bb2: 101 ret void 102} 103 104define void @ucmp_eq1(i32 %a, i32 %b) { 105; CHECK-LABEL: define void @ucmp_eq1( 106; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) { 107; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[A]], [[B]] 108; CHECK-NEXT: br i1 [[TMP1]], label %[[BB1:.*]], label %[[BB2:.*]] 109; CHECK: [[BB1]]: 110; CHECK-NEXT: call void @foo() 111; CHECK-NEXT: br label %[[BB2]] 112; CHECK: [[BB2]]: 113; CHECK-NEXT: ret void 114; 115 %res = call i8 @llvm.ucmp.i8.i32(i32 %a, i32 %b) 116 switch i8 %res, label %bb1 [ 117 i8 -1, label %bb2 118 i8 1, label %bb2 119 ] 120 121bb1: 122 call void @foo() 123 br label %bb2 124 125bb2: 126 ret void 127} 128 129define void @ucmp_eq2(i32 %a, i32 %b) { 130; CHECK-LABEL: define void @ucmp_eq2( 131; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) { 132; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[A]], [[B]] 133; CHECK-NEXT: br i1 [[TMP1]], label %[[BB1:.*]], label %[[BB2:.*]] 134; CHECK: [[BB1]]: 135; CHECK-NEXT: call void @foo() 136; CHECK-NEXT: br label %[[BB2]] 137; CHECK: [[BB2]]: 138; CHECK-NEXT: ret void 139; 140 %res = call i8 @llvm.ucmp.i8.i32(i32 %a, i32 %b) 141 switch i8 %res, label %bb1 [ 142 i8 1, label %bb2 143 i8 -1, label %bb2 144 ] 145 146bb1: 147 call void @foo() 148 br label %bb2 149 150bb2: 151 ret void 152} 153 154define void @scmp_gt1(i32 %a, i32 %b) { 155; CHECK-LABEL: define void @scmp_gt1( 156; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) { 157; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[A]], [[B]] 158; CHECK-NEXT: br i1 [[TMP1]], label %[[BB1:.*]], label %[[BB2:.*]] 159; CHECK: [[BB1]]: 160; CHECK-NEXT: call void @foo() 161; CHECK-NEXT: br label %[[BB2]] 162; CHECK: [[BB2]]: 163; CHECK-NEXT: ret void 164; 165 %res = call i8 @llvm.scmp.i8.i32(i32 %a, i32 %b) 166 switch i8 %res, label %bb1 [ 167 i8 -1, label %bb2 168 i8 0, label %bb2 169 ] 170 171bb1: 172 call void @foo() 173 br label %bb2 174 175bb2: 176 ret void 177} 178 179define void @scmp_gt2(i32 %a, i32 %b) { 180; CHECK-LABEL: define void @scmp_gt2( 181; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) { 182; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[A]], [[B]] 183; CHECK-NEXT: br i1 [[TMP1]], label %[[BB1:.*]], label %[[BB2:.*]] 184; CHECK: [[BB1]]: 185; CHECK-NEXT: call void @foo() 186; CHECK-NEXT: br label %[[BB2]] 187; CHECK: [[BB2]]: 188; CHECK-NEXT: ret void 189; 190 %res = call i8 @llvm.scmp.i8.i32(i32 %a, i32 %b) 191 switch i8 %res, label %bb1 [ 192 i8 0, label %bb2 193 i8 -1, label %bb2 194 ] 195 196bb1: 197 call void @foo() 198 br label %bb2 199 200bb2: 201 ret void 202} 203 204define void @ucmp_gt_multiuse(i32 %a, i32 %b) { 205; CHECK-LABEL: define void @ucmp_gt_multiuse( 206; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) { 207; CHECK-NEXT: [[RES:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[A]], i32 [[B]]) 208; CHECK-NEXT: call void @use(i8 [[RES]]) 209; CHECK-NEXT: switch i8 [[RES]], label %[[BB1:.*]] [ 210; CHECK-NEXT: i8 -1, label %[[BB2:.*]] 211; CHECK-NEXT: i8 0, label %[[BB2]] 212; CHECK-NEXT: ] 213; CHECK: [[BB1]]: 214; CHECK-NEXT: call void @foo() 215; CHECK-NEXT: br label %[[BB2]] 216; CHECK: [[BB2]]: 217; CHECK-NEXT: ret void 218; 219 %res = call i8 @llvm.ucmp.i8.i32(i32 %a, i32 %b) 220 call void @use(i8 %res) 221 switch i8 %res, label %bb1 [ 222 i8 -1, label %bb2 223 i8 0, label %bb2 224 ] 225 226bb1: 227 call void @foo() 228 br label %bb2 229 230bb2: 231 ret void 232} 233 234define i32 @ucmp_gt_phi(i32 %a, i32 %b) { 235; CHECK-LABEL: define i32 @ucmp_gt_phi( 236; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) { 237; CHECK-NEXT: [[ENTRY:.*]]: 238; CHECK-NEXT: [[TMP0:%.*]] = icmp ugt i32 [[A]], [[B]] 239; CHECK-NEXT: br i1 [[TMP0]], label %[[BB1:.*]], label %[[BB2:.*]] 240; CHECK: [[BB1]]: 241; CHECK-NEXT: call void @foo() 242; CHECK-NEXT: br label %[[BB2]] 243; CHECK: [[BB2]]: 244; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ 0, %[[BB1]] ], [ 1, %[[ENTRY]] ] 245; CHECK-NEXT: ret i32 [[PHI]] 246; 247entry: 248 %res = call i8 @llvm.ucmp.i8.i32(i32 %a, i32 %b) 249 switch i8 %res, label %bb1 [ 250 i8 -1, label %bb2 251 i8 0, label %bb2 252 ] 253 254bb1: 255 call void @foo() 256 br label %bb2 257 258bb2: 259 %phi = phi i32 [ 0, %bb1 ], [ 1, %entry ], [ 1, %entry ] 260 ret i32 %phi 261} 262 263define void @ucmp_gt_extra_case(i32 %a, i32 %b) { 264; CHECK-LABEL: define void @ucmp_gt_extra_case( 265; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) { 266; CHECK-NEXT: [[RES:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[A]], i32 [[B]]) 267; CHECK-NEXT: switch i8 [[RES]], label %[[BB1:.*]] [ 268; CHECK-NEXT: i8 -1, label %[[BB2:.*]] 269; CHECK-NEXT: i8 0, label %[[BB2]] 270; CHECK-NEXT: i8 1, label %[[BB2]] 271; CHECK-NEXT: ] 272; CHECK: [[BB1]]: 273; CHECK-NEXT: call void @foo() 274; CHECK-NEXT: br label %[[BB2]] 275; CHECK: [[BB2]]: 276; CHECK-NEXT: ret void 277; 278 %res = call i8 @llvm.ucmp.i8.i32(i32 %a, i32 %b) 279 switch i8 %res, label %bb1 [ 280 i8 -1, label %bb2 281 i8 0, label %bb2 282 i8 1, label %bb2 283 ] 284 285bb1: 286 call void @foo() 287 br label %bb2 288 289bb2: 290 ret void 291} 292 293define void @ucmp_gt_wrong_case(i32 %a, i32 %b) { 294; CHECK-LABEL: define void @ucmp_gt_wrong_case( 295; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) { 296; CHECK-NEXT: [[RES:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[A]], i32 [[B]]) 297; CHECK-NEXT: switch i8 [[RES]], label %[[BB1:.*]] [ 298; CHECK-NEXT: i8 -2, label %[[BB2:.*]] 299; CHECK-NEXT: i8 0, label %[[BB2]] 300; CHECK-NEXT: ] 301; CHECK: [[BB1]]: 302; CHECK-NEXT: call void @foo() 303; CHECK-NEXT: br label %[[BB2]] 304; CHECK: [[BB2]]: 305; CHECK-NEXT: ret void 306; 307 %res = call i8 @llvm.ucmp.i8.i32(i32 %a, i32 %b) 308 switch i8 %res, label %bb1 [ 309 i8 -2, label %bb2 310 i8 0, label %bb2 311 ] 312 313bb1: 314 call void @foo() 315 br label %bb2 316 317bb2: 318 ret void 319} 320 321define void @ucmp_gt_not_same_succ(i32 %a, i32 %b) { 322; CHECK-LABEL: define void @ucmp_gt_not_same_succ( 323; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) { 324; CHECK-NEXT: [[RES:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[A]], i32 [[B]]) 325; CHECK-NEXT: switch i8 [[RES]], label %[[BB1:.*]] [ 326; CHECK-NEXT: i8 -1, label %[[BB2:.*]] 327; CHECK-NEXT: i8 0, label %[[BB3:.*]] 328; CHECK-NEXT: ] 329; CHECK: [[BB1]]: 330; CHECK-NEXT: call void @foo() 331; CHECK-NEXT: br label %[[BB2]] 332; CHECK: [[BB3]]: 333; CHECK-NEXT: call void @foo() 334; CHECK-NEXT: br label %[[BB2]] 335; CHECK: [[BB2]]: 336; CHECK-NEXT: ret void 337; 338 %res = call i8 @llvm.ucmp.i8.i32(i32 %a, i32 %b) 339 switch i8 %res, label %bb1 [ 340 i8 -1, label %bb2 341 i8 0, label %bb3 342 ] 343 344bb1: 345 call void @foo() 346 br label %bb2 347 348bb3: 349 call void @foo() 350 br label %bb2 351 352bb2: 353 ret void 354} 355 356define void @ucmp_gt_unpredictable(i32 %a, i32 %b) { 357; CHECK-LABEL: define void @ucmp_gt_unpredictable( 358; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) { 359; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[A]], [[B]] 360; CHECK-NEXT: br i1 [[TMP1]], label %[[BB1:.*]], label %[[BB2:.*]], !unpredictable [[META0:![0-9]+]] 361; CHECK: [[BB1]]: 362; CHECK-NEXT: call void @foo() 363; CHECK-NEXT: br label %[[BB2]] 364; CHECK: [[BB2]]: 365; CHECK-NEXT: ret void 366; 367 %res = call i8 @llvm.ucmp.i8.i32(i32 %a, i32 %b) 368 switch i8 %res, label %bb1 [ 369 i8 -1, label %bb2 370 i8 0, label %bb2 371 ], !unpredictable !{} 372 373bb1: 374 call void @foo() 375 br label %bb2 376 377bb2: 378 ret void 379} 380 381define void @ucmp_gt_weights(i32 %a, i32 %b) { 382; CHECK-LABEL: define void @ucmp_gt_weights( 383; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) { 384; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[A]], [[B]] 385; CHECK-NEXT: br i1 [[TMP1]], label %[[BB1:.*]], label %[[BB2:.*]], !prof [[PROF1:![0-9]+]] 386; CHECK: [[BB1]]: 387; CHECK-NEXT: call void @foo() 388; CHECK-NEXT: br label %[[BB2]] 389; CHECK: [[BB2]]: 390; CHECK-NEXT: ret void 391; 392 %res = call i8 @llvm.ucmp.i8.i32(i32 %a, i32 %b) 393 switch i8 %res, label %bb1 [ 394 i8 -1, label %bb2 395 i8 0, label %bb2 396 ], !prof !{!"branch_weights", i32 5, i32 10, i32 20} 397 398bb1: 399 call void @foo() 400 br label %bb2 401 402bb2: 403 ret void 404} 405 406define void @ucmp_gt_unreachable(i32 %a, i32 %b) { 407; CHECK-LABEL: define void @ucmp_gt_unreachable( 408; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) { 409; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[A]], [[B]] 410; CHECK-NEXT: br i1 [[TMP1]], label %[[BB1:.*]], label %[[BB2:.*]] 411; CHECK: [[BB1]]: 412; CHECK-NEXT: call void @foo() 413; CHECK-NEXT: br label %[[BB2]] 414; CHECK: [[BB2]]: 415; CHECK-NEXT: ret void 416; 417 %res = call i8 @llvm.ucmp.i8.i32(i32 %a, i32 %b) 418 switch i8 %res, label %unreachable [ 419 i8 -1, label %bb2 420 i8 0, label %bb2 421 i8 1, label %bb1 422 ] 423 424bb1: 425 call void @foo() 426 br label %bb2 427 428bb2: 429 ret void 430 431unreachable: 432 unreachable 433} 434 435define void @ucmp_lt_unreachable(i32 %a, i32 %b) { 436; CHECK-LABEL: define void @ucmp_lt_unreachable( 437; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) { 438; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[A]], [[B]] 439; CHECK-NEXT: br i1 [[TMP1]], label %[[BB1:.*]], label %[[BB2:.*]] 440; CHECK: [[BB1]]: 441; CHECK-NEXT: call void @foo() 442; CHECK-NEXT: br label %[[BB2]] 443; CHECK: [[BB2]]: 444; CHECK-NEXT: ret void 445; 446 %res = call i8 @llvm.ucmp.i8.i32(i32 %a, i32 %b) 447 switch i8 %res, label %unreachable [ 448 i8 -1, label %bb1 449 i8 0, label %bb2 450 i8 1, label %bb2 451 ] 452 453bb1: 454 call void @foo() 455 br label %bb2 456 457bb2: 458 ret void 459 460unreachable: 461 unreachable 462} 463 464define void @ucmp_eq_unreachable(i32 %a, i32 %b) { 465; CHECK-LABEL: define void @ucmp_eq_unreachable( 466; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) { 467; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[A]], [[B]] 468; CHECK-NEXT: br i1 [[TMP1]], label %[[BB1:.*]], label %[[BB2:.*]] 469; CHECK: [[BB1]]: 470; CHECK-NEXT: call void @foo() 471; CHECK-NEXT: br label %[[BB2]] 472; CHECK: [[BB2]]: 473; CHECK-NEXT: ret void 474; 475 %res = call i8 @llvm.ucmp.i8.i32(i32 %a, i32 %b) 476 switch i8 %res, label %unreachable [ 477 i8 -1, label %bb2 478 i8 0, label %bb1 479 i8 1, label %bb2 480 ] 481 482bb1: 483 call void @foo() 484 br label %bb2 485 486bb2: 487 ret void 488 489unreachable: 490 unreachable 491} 492 493define void @ucmp_gt_unreachable_multi_edge(i8 %x, i32 %a, i32 %b) { 494; CHECK-LABEL: define void @ucmp_gt_unreachable_multi_edge( 495; CHECK-SAME: i8 [[X:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]) { 496; CHECK-NEXT: [[ENTRY:.*:]] 497; CHECK-NEXT: switch i8 [[X]], label %[[UNREACHABLE:.*]] [ 498; CHECK-NEXT: i8 0, label %[[SW:.*]] 499; CHECK-NEXT: i8 1, label %[[BB1:.*]] 500; CHECK-NEXT: ] 501; CHECK: [[SW]]: 502; CHECK-NEXT: [[TMP0:%.*]] = icmp ugt i32 [[A]], [[B]] 503; CHECK-NEXT: br i1 [[TMP0]], label %[[BB1]], label %[[BB2:.*]] 504; CHECK: [[BB1]]: 505; CHECK-NEXT: call void @foo() 506; CHECK-NEXT: br label %[[BB2]] 507; CHECK: [[BB2]]: 508; CHECK-NEXT: ret void 509; CHECK: [[UNREACHABLE]]: 510; CHECK-NEXT: unreachable 511; 512entry: 513 switch i8 %x, label %unreachable [ 514 i8 0, label %sw 515 i8 1, label %bb1 516 ] 517 518sw: 519 %res = call i8 @llvm.ucmp.i8.i32(i32 %a, i32 %b) 520 switch i8 %res, label %unreachable [ 521 i8 -1, label %bb2 522 i8 0, label %bb2 523 i8 1, label %bb1 524 ] 525 526bb1: 527 call void @foo() 528 br label %bb2 529 530bb2: 531 ret void 532 533unreachable: 534 %phi = phi i32 [ 0, %entry ], [ 1, %sw ] 535 unreachable 536} 537 538define void @ucmp_gt_unreachable_wrong_case(i32 %a, i32 %b) { 539; CHECK-LABEL: define void @ucmp_gt_unreachable_wrong_case( 540; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) { 541; CHECK-NEXT: [[RES:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[A]], i32 [[B]]) 542; CHECK-NEXT: switch i8 [[RES]], label %[[UNREACHABLE:.*]] [ 543; CHECK-NEXT: i8 -2, label %[[BB2:.*]] 544; CHECK-NEXT: i8 0, label %[[BB2]] 545; CHECK-NEXT: i8 1, label %[[BB1:.*]] 546; CHECK-NEXT: ] 547; CHECK: [[BB1]]: 548; CHECK-NEXT: call void @foo() 549; CHECK-NEXT: br label %[[BB2]] 550; CHECK: [[BB2]]: 551; CHECK-NEXT: ret void 552; CHECK: [[UNREACHABLE]]: 553; CHECK-NEXT: unreachable 554; 555 %res = call i8 @llvm.ucmp.i8.i32(i32 %a, i32 %b) 556 switch i8 %res, label %unreachable [ 557 i8 -2, label %bb2 558 i8 0, label %bb2 559 i8 1, label %bb1 560 ] 561 562bb1: 563 call void @foo() 564 br label %bb2 565 566bb2: 567 ret void 568 569unreachable: 570 unreachable 571} 572 573define void @ucmp_gt_unreachable_no_two_equal_cases(i32 %a, i32 %b) { 574; CHECK-LABEL: define void @ucmp_gt_unreachable_no_two_equal_cases( 575; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) { 576; CHECK-NEXT: [[RES:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[A]], i32 [[B]]) 577; CHECK-NEXT: switch i8 [[RES]], label %[[UNREACHABLE:.*]] [ 578; CHECK-NEXT: i8 -1, label %[[BB3:.*]] 579; CHECK-NEXT: i8 0, label %[[BB2:.*]] 580; CHECK-NEXT: i8 1, label %[[BB1:.*]] 581; CHECK-NEXT: ] 582; CHECK: [[BB1]]: 583; CHECK-NEXT: call void @foo() 584; CHECK-NEXT: br label %[[BB2]] 585; CHECK: [[BB3]]: 586; CHECK-NEXT: call void @foo() 587; CHECK-NEXT: br label %[[BB2]] 588; CHECK: [[BB2]]: 589; CHECK-NEXT: ret void 590; CHECK: [[UNREACHABLE]]: 591; CHECK-NEXT: unreachable 592; 593 %res = call i8 @llvm.ucmp.i8.i32(i32 %a, i32 %b) 594 switch i8 %res, label %unreachable [ 595 i8 -1, label %bb3 596 i8 0, label %bb2 597 i8 1, label %bb1 598 ] 599 600bb1: 601 call void @foo() 602 br label %bb2 603 604bb3: 605 call void @foo() 606 br label %bb2 607 608bb2: 609 ret void 610 611unreachable: 612 unreachable 613} 614 615define void @ucmp_gt_unreachable_three_equal_cases(i32 %a, i32 %b) { 616; CHECK-LABEL: define void @ucmp_gt_unreachable_three_equal_cases( 617; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) { 618; CHECK-NEXT: [[BB1:.*:]] 619; CHECK-NEXT: call void @foo() 620; CHECK-NEXT: ret void 621; 622 %res = call i8 @llvm.ucmp.i8.i32(i32 %a, i32 %b) 623 switch i8 %res, label %unreachable [ 624 i8 -1, label %bb1 625 i8 0, label %bb1 626 i8 1, label %bb1 627 ] 628 629bb1: 630 call void @foo() 631 ret void 632 633unreachable: 634 unreachable 635} 636 637define void @ucmp_gt_unreachable_default_not_unreachable(i32 %a, i32 %b) { 638; CHECK-LABEL: define void @ucmp_gt_unreachable_default_not_unreachable( 639; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) { 640; CHECK-NEXT: [[RES:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[A]], i32 [[B]]) 641; CHECK-NEXT: switch i8 [[RES]], label %[[NOT_UNREACHABLE:.*]] [ 642; CHECK-NEXT: i8 -1, label %[[BB2:.*]] 643; CHECK-NEXT: i8 0, label %[[BB2]] 644; CHECK-NEXT: i8 1, label %[[BB1:.*]] 645; CHECK-NEXT: ] 646; CHECK: [[BB1]]: 647; CHECK-NEXT: call void @foo() 648; CHECK-NEXT: br label %[[BB2]] 649; CHECK: [[BB2]]: 650; CHECK-NEXT: ret void 651; CHECK: [[NOT_UNREACHABLE]]: 652; CHECK-NEXT: call void @foo() 653; CHECK-NEXT: br label %[[BB2]] 654; 655 %res = call i8 @llvm.ucmp.i8.i32(i32 %a, i32 %b) 656 switch i8 %res, label %not.unreachable [ 657 i8 -1, label %bb2 658 i8 0, label %bb2 659 i8 1, label %bb1 660 ] 661 662bb1: 663 call void @foo() 664 br label %bb2 665 666bb2: 667 ret void 668 669not.unreachable: 670 call void @foo() 671 br label %bb2 672} 673 674define void @ucmp_gt_unreachable_weights(i32 %a, i32 %b) { 675; CHECK-LABEL: define void @ucmp_gt_unreachable_weights( 676; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) { 677; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[A]], [[B]] 678; CHECK-NEXT: br i1 [[TMP1]], label %[[BB1:.*]], label %[[BB2:.*]], !prof [[PROF1]] 679; CHECK: [[BB1]]: 680; CHECK-NEXT: call void @foo() 681; CHECK-NEXT: br label %[[BB2]] 682; CHECK: [[BB2]]: 683; CHECK-NEXT: ret void 684; 685 %res = call i8 @llvm.ucmp.i8.i32(i32 %a, i32 %b) 686 switch i8 %res, label %unreachable [ 687 i8 -1, label %bb2 688 i8 0, label %bb2 689 i8 1, label %bb1 690 ], !prof !{!"branch_weights", i32 0, i32 10, i32 20, i32 5} 691 692bb1: 693 call void @foo() 694 br label %bb2 695 696bb2: 697 ret void 698 699unreachable: 700 unreachable 701} 702 703declare void @use(i8) 704declare void @foo() 705;. 706; CHECK: [[META0]] = !{} 707; CHECK: [[PROF1]] = !{!"branch_weights", i32 5, i32 30} 708;. 709