1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4 2; RUN: opt < %s -passes=correlated-propagation -S | FileCheck %s 3 4define void @test0(i32 %a) { 5; CHECK-LABEL: define void @test0( 6; CHECK-SAME: i32 [[A:%.*]]) { 7; CHECK-NEXT: entry: 8; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[A]], 100 9; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]] 10; CHECK: bb: 11; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], 1 12; CHECK-NEXT: br label [[EXIT]] 13; CHECK: exit: 14; CHECK-NEXT: ret void 15; 16entry: 17 %cmp = icmp slt i32 %a, 100 18 br i1 %cmp, label %bb, label %exit 19 20bb: 21 %add = add i32 %a, 1 22 br label %exit 23 24exit: 25 ret void 26} 27 28define void @test1(i32 %a) { 29; CHECK-LABEL: define void @test1( 30; CHECK-SAME: i32 [[A:%.*]]) { 31; CHECK-NEXT: entry: 32; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[A]], 100 33; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]] 34; CHECK: bb: 35; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i32 [[A]], 1 36; CHECK-NEXT: br label [[EXIT]] 37; CHECK: exit: 38; CHECK-NEXT: ret void 39; 40entry: 41 %cmp = icmp ult i32 %a, 100 42 br i1 %cmp, label %bb, label %exit 43 44bb: 45 %add = add i32 %a, 1 46 br label %exit 47 48exit: 49 ret void 50} 51 52define void @test2(i32 %a) { 53; CHECK-LABEL: define void @test2( 54; CHECK-SAME: i32 [[A:%.*]]) { 55; CHECK-NEXT: entry: 56; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[A]], -1 57; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]] 58; CHECK: bb: 59; CHECK-NEXT: [[ADD:%.*]] = add nuw i32 [[A]], 1 60; CHECK-NEXT: br label [[EXIT]] 61; CHECK: exit: 62; CHECK-NEXT: ret void 63; 64entry: 65 %cmp = icmp ult i32 %a, -1 66 br i1 %cmp, label %bb, label %exit 67 68bb: 69 %add = add i32 %a, 1 70 br label %exit 71 72exit: 73 ret void 74} 75 76define void @test3(i32 %a) { 77; CHECK-LABEL: define void @test3( 78; CHECK-SAME: i32 [[A:%.*]]) { 79; CHECK-NEXT: entry: 80; CHECK-NEXT: [[CMP:%.*]] = icmp ule i32 [[A]], -1 81; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]] 82; CHECK: bb: 83; CHECK-NEXT: [[ADD:%.*]] = add i32 [[A]], 1 84; CHECK-NEXT: br label [[EXIT]] 85; CHECK: exit: 86; CHECK-NEXT: ret void 87; 88entry: 89 %cmp = icmp ule i32 %a, -1 90 br i1 %cmp, label %bb, label %exit 91 92bb: 93 %add = add i32 %a, 1 94 br label %exit 95 96exit: 97 ret void 98} 99 100define void @test4(i32 %a) { 101; CHECK-LABEL: define void @test4( 102; CHECK-SAME: i32 [[A:%.*]]) { 103; CHECK-NEXT: entry: 104; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[A]], 2147483647 105; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]] 106; CHECK: bb: 107; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], 1 108; CHECK-NEXT: br label [[EXIT]] 109; CHECK: exit: 110; CHECK-NEXT: ret void 111; 112entry: 113 %cmp = icmp slt i32 %a, 2147483647 114 br i1 %cmp, label %bb, label %exit 115 116bb: 117 %add = add i32 %a, 1 118 br label %exit 119 120exit: 121 ret void 122} 123 124define void @test5(i32 %a) { 125; CHECK-LABEL: define void @test5( 126; CHECK-SAME: i32 [[A:%.*]]) { 127; CHECK-NEXT: entry: 128; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[A]], 2147483647 129; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]] 130; CHECK: bb: 131; CHECK-NEXT: [[ADD:%.*]] = add i32 [[A]], 1 132; CHECK-NEXT: br label [[EXIT]] 133; CHECK: exit: 134; CHECK-NEXT: ret void 135; 136entry: 137 %cmp = icmp sle i32 %a, 2147483647 138 br i1 %cmp, label %bb, label %exit 139 140bb: 141 %add = add i32 %a, 1 142 br label %exit 143 144exit: 145 ret void 146} 147 148; Check for a corner case where an integer value is represented with a constant 149; LVILatticeValue instead of constantrange. Check that we don't fail with an 150; assertion in this case. 151@b = global i32 0, align 4 152define void @test6(i32 %a) { 153; CHECK-LABEL: define void @test6( 154; CHECK-SAME: i32 [[A:%.*]]) { 155; CHECK-NEXT: bb: 156; CHECK-NEXT: [[ADD:%.*]] = add i32 [[A]], ptrtoint (ptr @b to i32) 157; CHECK-NEXT: ret void 158; 159bb: 160 %add = add i32 %a, ptrtoint (ptr @b to i32) 161 ret void 162} 163 164; Check that we can gather information for conditions is the form of 165; and ( i s< 100, Unknown ) 166define void @test7(i32 %a, i1 %flag) { 167; CHECK-LABEL: define void @test7( 168; CHECK-SAME: i32 [[A:%.*]], i1 [[FLAG:%.*]]) { 169; CHECK-NEXT: entry: 170; CHECK-NEXT: [[CMP_1:%.*]] = icmp slt i32 [[A]], 100 171; CHECK-NEXT: [[CMP:%.*]] = and i1 [[CMP_1]], [[FLAG]] 172; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]] 173; CHECK: bb: 174; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], 1 175; CHECK-NEXT: br label [[EXIT]] 176; CHECK: exit: 177; CHECK-NEXT: ret void 178; 179entry: 180 %cmp.1 = icmp slt i32 %a, 100 181 %cmp = and i1 %cmp.1, %flag 182 br i1 %cmp, label %bb, label %exit 183 184bb: 185 %add = add i32 %a, 1 186 br label %exit 187 188exit: 189 ret void 190} 191 192; Check that we can gather information for conditions is the form of 193; and ( i s< 100, i s> 0 ) 194define void @test8(i32 %a) { 195; CHECK-LABEL: define void @test8( 196; CHECK-SAME: i32 [[A:%.*]]) { 197; CHECK-NEXT: entry: 198; CHECK-NEXT: [[CMP_1:%.*]] = icmp slt i32 [[A]], 100 199; CHECK-NEXT: [[CMP_2:%.*]] = icmp sgt i32 [[A]], 0 200; CHECK-NEXT: [[CMP:%.*]] = and i1 [[CMP_1]], [[CMP_2]] 201; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]] 202; CHECK: bb: 203; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i32 [[A]], 1 204; CHECK-NEXT: br label [[EXIT]] 205; CHECK: exit: 206; CHECK-NEXT: ret void 207; 208entry: 209 %cmp.1 = icmp slt i32 %a, 100 210 %cmp.2 = icmp sgt i32 %a, 0 211 %cmp = and i1 %cmp.1, %cmp.2 212 br i1 %cmp, label %bb, label %exit 213 214bb: 215 %add = add i32 %a, 1 216 br label %exit 217 218exit: 219 ret void 220} 221 222; Check that for conditions is the form of cond1 && cond2 we don't mistakenly 223; assume that !cond1 && !cond2 holds down to false path. 224define void @test8_neg(i32 %a) { 225; CHECK-LABEL: define void @test8_neg( 226; CHECK-SAME: i32 [[A:%.*]]) { 227; CHECK-NEXT: entry: 228; CHECK-NEXT: [[CMP_1:%.*]] = icmp sge i32 [[A]], 100 229; CHECK-NEXT: [[CMP_2:%.*]] = icmp sle i32 [[A]], 0 230; CHECK-NEXT: [[CMP:%.*]] = and i1 [[CMP_1]], [[CMP_2]] 231; CHECK-NEXT: br i1 [[CMP]], label [[EXIT:%.*]], label [[BB:%.*]] 232; CHECK: bb: 233; CHECK-NEXT: [[ADD:%.*]] = add i32 [[A]], 1 234; CHECK-NEXT: br label [[EXIT]] 235; CHECK: exit: 236; CHECK-NEXT: ret void 237; 238entry: 239 %cmp.1 = icmp sge i32 %a, 100 240 %cmp.2 = icmp sle i32 %a, 0 241 %cmp = and i1 %cmp.1, %cmp.2 242 br i1 %cmp, label %exit, label %bb 243 244bb: 245 %add = add i32 %a, 1 246 br label %exit 247 248exit: 249 ret void 250} 251 252; Check that we can gather information for conditions is the form of 253; and ( i s< 100, and (i s> 0, Unknown ) 254define void @test9(i32 %a, i1 %flag) { 255; CHECK-LABEL: define void @test9( 256; CHECK-SAME: i32 [[A:%.*]], i1 [[FLAG:%.*]]) { 257; CHECK-NEXT: entry: 258; CHECK-NEXT: [[CMP_1:%.*]] = icmp slt i32 [[A]], 100 259; CHECK-NEXT: [[CMP_2:%.*]] = icmp sgt i32 [[A]], 0 260; CHECK-NEXT: [[CMP_3:%.*]] = and i1 [[CMP_2]], [[FLAG]] 261; CHECK-NEXT: [[CMP:%.*]] = and i1 [[CMP_1]], [[CMP_3]] 262; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]] 263; CHECK: bb: 264; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i32 [[A]], 1 265; CHECK-NEXT: br label [[EXIT]] 266; CHECK: exit: 267; CHECK-NEXT: ret void 268; 269entry: 270 %cmp.1 = icmp slt i32 %a, 100 271 %cmp.2 = icmp sgt i32 %a, 0 272 %cmp.3 = and i1 %cmp.2, %flag 273 %cmp = and i1 %cmp.1, %cmp.3 274 br i1 %cmp, label %bb, label %exit 275 276bb: 277 %add = add i32 %a, 1 278 br label %exit 279 280exit: 281 ret void 282} 283 284; Check that we can gather information for conditions is the form of 285; and ( i s< Unknown, ... ) 286define void @test10(i32 %a, i32 %b, i1 %flag) { 287; CHECK-LABEL: define void @test10( 288; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]], i1 [[FLAG:%.*]]) { 289; CHECK-NEXT: entry: 290; CHECK-NEXT: [[CMP_1:%.*]] = icmp slt i32 [[A]], [[B]] 291; CHECK-NEXT: [[CMP:%.*]] = and i1 [[CMP_1]], [[FLAG]] 292; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]] 293; CHECK: bb: 294; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], 1 295; CHECK-NEXT: br label [[EXIT]] 296; CHECK: exit: 297; CHECK-NEXT: ret void 298; 299entry: 300 %cmp.1 = icmp slt i32 %a, %b 301 %cmp = and i1 %cmp.1, %flag 302 br i1 %cmp, label %bb, label %exit 303 304bb: 305 %add = add i32 %a, 1 306 br label %exit 307 308exit: 309 ret void 310} 311 312@limit = external global i32 313define i32 @test11(ptr %p, i32 %i) { 314; CHECK-LABEL: define range(i32 0, 2147483645) i32 @test11( 315; CHECK-SAME: ptr [[P:%.*]], i32 [[I:%.*]]) { 316; CHECK-NEXT: [[LIMIT:%.*]] = load i32, ptr [[P]], align 4, !range [[RNG0:![0-9]+]] 317; CHECK-NEXT: [[WITHIN_1:%.*]] = icmp ugt i32 [[LIMIT]], [[I]] 318; CHECK-NEXT: [[I_PLUS_7:%.*]] = add i32 [[I]], 7 319; CHECK-NEXT: [[WITHIN_2:%.*]] = icmp ugt i32 [[LIMIT]], [[I_PLUS_7]] 320; CHECK-NEXT: [[WITHIN:%.*]] = and i1 [[WITHIN_1]], [[WITHIN_2]] 321; CHECK-NEXT: br i1 [[WITHIN]], label [[THEN:%.*]], label [[ELSE:%.*]] 322; CHECK: then: 323; CHECK-NEXT: [[I_PLUS_6:%.*]] = add nuw nsw i32 [[I]], 6 324; CHECK-NEXT: ret i32 [[I_PLUS_6]] 325; CHECK: else: 326; CHECK-NEXT: ret i32 0 327; 328 %limit = load i32, ptr %p, !range !{i32 0, i32 2147483647} 329 %within.1 = icmp ugt i32 %limit, %i 330 %i.plus.7 = add i32 %i, 7 331 %within.2 = icmp ugt i32 %limit, %i.plus.7 332 %within = and i1 %within.1, %within.2 333 br i1 %within, label %then, label %else 334 335then: 336 %i.plus.6 = add i32 %i, 6 337 ret i32 %i.plus.6 338 339else: 340 ret i32 0 341} 342 343; Check that we can gather information for conditions is the form of 344; or ( i s>= 100, Unknown ) 345define void @test12(i32 %a, i1 %flag) { 346; CHECK-LABEL: define void @test12( 347; CHECK-SAME: i32 [[A:%.*]], i1 [[FLAG:%.*]]) { 348; CHECK-NEXT: entry: 349; CHECK-NEXT: [[CMP_1:%.*]] = icmp sge i32 [[A]], 100 350; CHECK-NEXT: [[CMP:%.*]] = or i1 [[CMP_1]], [[FLAG]] 351; CHECK-NEXT: br i1 [[CMP]], label [[EXIT:%.*]], label [[BB:%.*]] 352; CHECK: bb: 353; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], 1 354; CHECK-NEXT: br label [[EXIT]] 355; CHECK: exit: 356; CHECK-NEXT: ret void 357; 358entry: 359 %cmp.1 = icmp sge i32 %a, 100 360 %cmp = or i1 %cmp.1, %flag 361 br i1 %cmp, label %exit, label %bb 362 363bb: 364 %add = add i32 %a, 1 365 br label %exit 366 367exit: 368 ret void 369} 370 371; Check that we can gather information for conditions is the form of 372; or ( i s>= 100, i s<= 0 ) 373define void @test13(i32 %a) { 374; CHECK-LABEL: define void @test13( 375; CHECK-SAME: i32 [[A:%.*]]) { 376; CHECK-NEXT: entry: 377; CHECK-NEXT: [[CMP_1:%.*]] = icmp sge i32 [[A]], 100 378; CHECK-NEXT: [[CMP_2:%.*]] = icmp sle i32 [[A]], 0 379; CHECK-NEXT: [[CMP:%.*]] = or i1 [[CMP_1]], [[CMP_2]] 380; CHECK-NEXT: br i1 [[CMP]], label [[EXIT:%.*]], label [[BB:%.*]] 381; CHECK: bb: 382; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i32 [[A]], 1 383; CHECK-NEXT: br label [[EXIT]] 384; CHECK: exit: 385; CHECK-NEXT: ret void 386; 387entry: 388 %cmp.1 = icmp sge i32 %a, 100 389 %cmp.2 = icmp sle i32 %a, 0 390 %cmp = or i1 %cmp.1, %cmp.2 391 br i1 %cmp, label %exit, label %bb 392 393bb: 394 %add = add i32 %a, 1 395 br label %exit 396 397exit: 398 ret void 399} 400 401; Check that for conditions is the form of cond1 || cond2 we don't mistakenly 402; assume that cond1 || cond2 holds down to true path. 403define void @test13_neg(i32 %a) { 404; CHECK-LABEL: define void @test13_neg( 405; CHECK-SAME: i32 [[A:%.*]]) { 406; CHECK-NEXT: entry: 407; CHECK-NEXT: [[CMP_1:%.*]] = icmp slt i32 [[A]], 100 408; CHECK-NEXT: [[CMP_2:%.*]] = icmp sgt i32 [[A]], 0 409; CHECK-NEXT: [[CMP:%.*]] = or i1 [[CMP_1]], [[CMP_2]] 410; CHECK-NEXT: br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]] 411; CHECK: bb: 412; CHECK-NEXT: [[ADD:%.*]] = add i32 [[A]], 1 413; CHECK-NEXT: br label [[EXIT]] 414; CHECK: exit: 415; CHECK-NEXT: ret void 416; 417entry: 418 %cmp.1 = icmp slt i32 %a, 100 419 %cmp.2 = icmp sgt i32 %a, 0 420 %cmp = or i1 %cmp.1, %cmp.2 421 br i1 %cmp, label %bb, label %exit 422 423bb: 424 %add = add i32 %a, 1 425 br label %exit 426 427exit: 428 ret void 429} 430 431; Check that we can gather information for conditions is the form of 432; or ( i s>=100, or (i s<= 0, Unknown ) 433define void @test14(i32 %a, i1 %flag) { 434; CHECK-LABEL: define void @test14( 435; CHECK-SAME: i32 [[A:%.*]], i1 [[FLAG:%.*]]) { 436; CHECK-NEXT: entry: 437; CHECK-NEXT: [[CMP_1:%.*]] = icmp sge i32 [[A]], 100 438; CHECK-NEXT: [[CMP_2:%.*]] = icmp sle i32 [[A]], 0 439; CHECK-NEXT: [[CMP_3:%.*]] = or i1 [[CMP_2]], [[FLAG]] 440; CHECK-NEXT: [[CMP:%.*]] = or i1 [[CMP_1]], [[CMP_3]] 441; CHECK-NEXT: br i1 [[CMP]], label [[EXIT:%.*]], label [[BB:%.*]] 442; CHECK: bb: 443; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i32 [[A]], 1 444; CHECK-NEXT: br label [[EXIT]] 445; CHECK: exit: 446; CHECK-NEXT: ret void 447; 448entry: 449 %cmp.1 = icmp sge i32 %a, 100 450 %cmp.2 = icmp sle i32 %a, 0 451 %cmp.3 = or i1 %cmp.2, %flag 452 %cmp = or i1 %cmp.1, %cmp.3 453 br i1 %cmp, label %exit, label %bb 454 455bb: 456 %add = add i32 %a, 1 457 br label %exit 458 459exit: 460 ret void 461} 462 463; Check that we can gather information for conditions is the form of 464; or ( i s>= Unknown, ... ) 465define void @test15(i32 %a, i32 %b, i1 %flag) { 466; CHECK-LABEL: define void @test15( 467; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]], i1 [[FLAG:%.*]]) { 468; CHECK-NEXT: entry: 469; CHECK-NEXT: [[CMP_1:%.*]] = icmp sge i32 [[A]], [[B]] 470; CHECK-NEXT: [[CMP:%.*]] = or i1 [[CMP_1]], [[FLAG]] 471; CHECK-NEXT: br i1 [[CMP]], label [[EXIT:%.*]], label [[BB:%.*]] 472; CHECK: bb: 473; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], 1 474; CHECK-NEXT: br label [[EXIT]] 475; CHECK: exit: 476; CHECK-NEXT: ret void 477; 478entry: 479 %cmp.1 = icmp sge i32 %a, %b 480 %cmp = or i1 %cmp.1, %flag 481 br i1 %cmp, label %exit, label %bb 482 483bb: 484 %add = add i32 %a, 1 485 br label %exit 486 487exit: 488 ret void 489} 490 491; single basic block loop 492; because the loop exit condition is SLT, we can supplement the iv add 493; (iv.next def) with an nsw. 494define i32 @test16(ptr %n, ptr %a) { 495; CHECK-LABEL: define i32 @test16( 496; CHECK-SAME: ptr [[N:%.*]], ptr [[A:%.*]]) { 497; CHECK-NEXT: preheader: 498; CHECK-NEXT: br label [[LOOP:%.*]] 499; CHECK: loop: 500; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ] 501; CHECK-NEXT: [[ACC:%.*]] = phi i32 [ 0, [[PREHEADER]] ], [ [[ACC_CURR:%.*]], [[LOOP]] ] 502; CHECK-NEXT: [[X:%.*]] = load atomic i32, ptr [[A]] unordered, align 8 503; CHECK-NEXT: fence acquire 504; CHECK-NEXT: [[ACC_CURR]] = add i32 [[ACC]], [[X]] 505; CHECK-NEXT: [[IV_NEXT]] = add nsw i32 [[IV]], 1 506; CHECK-NEXT: [[NVAL:%.*]] = load atomic i32, ptr [[N]] unordered, align 8 507; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[IV_NEXT]], [[NVAL]] 508; CHECK-NEXT: br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]] 509; CHECK: exit: 510; CHECK-NEXT: ret i32 [[ACC_CURR]] 511; 512preheader: 513 br label %loop 514 515loop: 516 %iv = phi i32 [ 0, %preheader ], [ %iv.next, %loop ] 517 %acc = phi i32 [ 0, %preheader ], [ %acc.curr, %loop ] 518 %x = load atomic i32, ptr %a unordered, align 8 519 fence acquire 520 %acc.curr = add i32 %acc, %x 521 %iv.next = add i32 %iv, 1 522 %nval = load atomic i32, ptr %n unordered, align 8 523 %cmp = icmp slt i32 %iv.next, %nval 524 br i1 %cmp, label %loop, label %exit 525 526exit: 527 ret i32 %acc.curr 528} 529 530define i32 @test_undef_range(i32 %x) { 531; CHECK-LABEL: define i32 @test_undef_range( 532; CHECK-SAME: i32 [[X:%.*]]) { 533; CHECK-NEXT: entry: 534; CHECK-NEXT: switch i32 [[X]], label [[JOIN:%.*]] [ 535; CHECK-NEXT: i32 1, label [[CASE1:%.*]] 536; CHECK-NEXT: i32 2, label [[CASE2:%.*]] 537; CHECK-NEXT: ] 538; CHECK: case1: 539; CHECK-NEXT: br label [[JOIN]] 540; CHECK: case2: 541; CHECK-NEXT: br label [[JOIN]] 542; CHECK: join: 543; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ 1, [[CASE1]] ], [ 2, [[CASE2]] ], [ undef, [[ENTRY:%.*]] ] 544; CHECK-NEXT: [[ADD:%.*]] = add i32 [[PHI]], 1 545; CHECK-NEXT: ret i32 [[ADD]] 546; 547entry: 548 switch i32 %x, label %join [ 549 i32 1, label %case1 550 i32 2, label %case2 551 ] 552 553case1: 554 br label %join 555 556case2: 557 br label %join 558 559join: 560 %phi = phi i32 [ 1, %case1 ], [ 2, %case2 ], [ undef, %entry ] 561 %add = add i32 %phi, 1 562 ret i32 %add 563} 564 565;. 566; CHECK: [[RNG0]] = !{i32 0, i32 2147483647} 567;. 568