1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -canon-freeze -S | FileCheck %s 3; A set of tests that have one phi node 4declare void @call(i32) 5declare i32 @get_step() 6 7define void @add(i32 %init, i32 %n) { 8; CHECK-LABEL: @add( 9; CHECK-NEXT: entry: 10; CHECK-NEXT: [[INIT_FROZEN:%.*]] = freeze i32 [[INIT:%.*]] 11; CHECK-NEXT: br label [[LOOP:%.*]] 12; CHECK: loop: 13; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[INIT_FROZEN]], [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ] 14; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1 15; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[I_NEXT]], [[N:%.*]] 16; CHECK-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]] 17; CHECK: exit: 18; CHECK-NEXT: ret void 19; 20entry: 21 br label %loop 22 23loop: 24 %i = phi i32 [ %init, %entry], [%i.next, %loop ] 25 %i.next = add i32 %i, 1 26 %i.next.fr = freeze i32 %i.next 27 %cond = icmp eq i32 %i.next.fr, %n 28 br i1 %cond, label %loop, label %exit 29 30exit: 31 ret void 32} 33 34define void @add_comm(i32 %init, i32 %n) { 35; CHECK-LABEL: @add_comm( 36; CHECK-NEXT: entry: 37; CHECK-NEXT: [[INIT_FROZEN:%.*]] = freeze i32 [[INIT:%.*]] 38; CHECK-NEXT: br label [[LOOP:%.*]] 39; CHECK: loop: 40; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[INIT_FROZEN]], [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ] 41; CHECK-NEXT: [[I_NEXT]] = add i32 1, [[I]] 42; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[I_NEXT]], [[N:%.*]] 43; CHECK-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]] 44; CHECK: exit: 45; CHECK-NEXT: ret void 46; 47entry: 48 br label %loop 49 50loop: 51 %i = phi i32 [ %init, %entry ], [ %i.next, %loop ] 52 %i.next = add i32 1, %i 53 %i.next.fr = freeze i32 %i.next 54 %cond = icmp eq i32 %i.next.fr, %n 55 br i1 %cond, label %loop, label %exit 56 57exit: 58 ret void 59} 60 61define void @add_multiuses(i32 %init, i32 %n) { 62; CHECK-LABEL: @add_multiuses( 63; CHECK-NEXT: entry: 64; CHECK-NEXT: [[INIT_FROZEN:%.*]] = freeze i32 [[INIT:%.*]] 65; CHECK-NEXT: br label [[LOOP:%.*]] 66; CHECK: loop: 67; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[INIT_FROZEN]], [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ] 68; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1 69; CHECK-NEXT: call void @call(i32 [[I_NEXT]]) 70; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[I_NEXT]], [[N:%.*]] 71; CHECK-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]] 72; CHECK: exit: 73; CHECK-NEXT: ret void 74; 75entry: 76 br label %loop 77 78loop: 79 %i = phi i32 [ %init, %entry ], [ %i.next, %loop ] 80 %i.next = add i32 %i, 1 81 %i.next.fr = freeze i32 %i.next 82 call void @call(i32 %i.next.fr) 83 %cond = icmp eq i32 %i.next.fr, %n 84 br i1 %cond, label %loop, label %exit 85 86exit: 87 ret void 88} 89 90define void @add_multiuses2(i32 %init, i32 %n) { 91; CHECK-LABEL: @add_multiuses2( 92; CHECK-NEXT: entry: 93; CHECK-NEXT: [[INIT_FROZEN:%.*]] = freeze i32 [[INIT:%.*]] 94; CHECK-NEXT: br label [[LOOP:%.*]] 95; CHECK: loop: 96; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[INIT_FROZEN]], [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ] 97; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1 98; CHECK-NEXT: call void @call(i32 [[I_NEXT]]) 99; CHECK-NEXT: call void @call(i32 [[I_NEXT]]) 100; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[I_NEXT]], [[N:%.*]] 101; CHECK-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]] 102; CHECK: exit: 103; CHECK-NEXT: ret void 104; 105entry: 106 br label %loop 107 108loop: 109 %i = phi i32 [ %init, %entry ], [ %i.next, %loop ] 110 %i.next = add i32 %i, 1 111 %i.next.fr = freeze i32 %i.next 112 call void @call(i32 %i.next.fr) 113 %i.next.fr2 = freeze i32 %i.next 114 call void @call(i32 %i.next.fr2) 115 %cond = icmp eq i32 %i.next.fr, %n 116 br i1 %cond, label %loop, label %exit 117 118exit: 119 ret void 120} 121 122define void @add_flags(i32 %init, i32 %n) { 123; CHECK-LABEL: @add_flags( 124; CHECK-NEXT: entry: 125; CHECK-NEXT: [[INIT_FROZEN:%.*]] = freeze i32 [[INIT:%.*]] 126; CHECK-NEXT: br label [[LOOP:%.*]] 127; CHECK: loop: 128; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[INIT_FROZEN]], [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ] 129; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1 130; CHECK-NEXT: call void @call(i32 [[I_NEXT]]) 131; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[I_NEXT]], [[N:%.*]] 132; CHECK-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]] 133; CHECK: exit: 134; CHECK-NEXT: ret void 135; 136entry: 137 br label %loop 138 139loop: 140 %i = phi i32 [ %init, %entry ], [ %i.next, %loop ] 141 %i.next = add nuw nsw i32 %i, 1 142 %i.next.fr = freeze i32 %i.next 143 call void @call(i32 %i.next.fr) 144 %cond = icmp eq i32 %i.next.fr, %n 145 br i1 %cond, label %loop, label %exit 146 147exit: 148 ret void 149} 150 151define void @add_ind(i32 %init, i32 %n) { 152; CHECK-LABEL: @add_ind( 153; CHECK-NEXT: entry: 154; CHECK-NEXT: [[INIT_FROZEN:%.*]] = freeze i32 [[INIT:%.*]] 155; CHECK-NEXT: br label [[LOOP:%.*]] 156; CHECK: loop: 157; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[INIT_FROZEN]], [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ] 158; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1 159; CHECK-NEXT: [[I_FR_NEXT:%.*]] = add nuw nsw i32 [[I]], 1 160; CHECK-NEXT: call void @call(i32 [[I_FR_NEXT]]) 161; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[I_FR_NEXT]], [[N:%.*]] 162; CHECK-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]] 163; CHECK: exit: 164; CHECK-NEXT: ret void 165; 166entry: 167 br label %loop 168 169loop: 170 %i = phi i32 [ %init, %entry ], [ %i.next, %loop ] 171 %i.next = add nuw nsw i32 %i, 1 172 %i.fr = freeze i32 %i 173 %i.fr.next = add nuw nsw i32 %i.fr, 1 174 call void @call(i32 %i.fr.next) 175 %cond = icmp eq i32 %i.fr.next, %n 176 br i1 %cond, label %loop, label %exit 177 178exit: 179 ret void 180} 181 182; Negative test 183define void @add_ind_frozen(i32 %init, i32 %n) { 184; CHECK-LABEL: @add_ind_frozen( 185; CHECK-NEXT: entry: 186; CHECK-NEXT: br label [[LOOP:%.*]] 187; CHECK: loop: 188; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[INIT:%.*]], [[ENTRY:%.*]] ], [ [[I_NEXT_FR:%.*]], [[LOOP]] ] 189; CHECK-NEXT: [[I_FR:%.*]] = freeze i32 [[I]] 190; CHECK-NEXT: [[I_NEXT_FR]] = add nuw nsw i32 [[I_FR]], 1 191; CHECK-NEXT: call void @call(i32 [[I_NEXT_FR]]) 192; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[I_NEXT_FR]], [[N:%.*]] 193; CHECK-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]] 194; CHECK: exit: 195; CHECK-NEXT: ret void 196; 197entry: 198 br label %loop 199 200loop: 201 %i = phi i32 [%init, %entry], [%i.next.fr, %loop] 202 %i.fr = freeze i32 %i 203 %i.next.fr = add nuw nsw i32 %i.fr, 1 204 call void @call(i32 %i.next.fr) 205 %cond = icmp eq i32 %i.next.fr, %n 206 br i1 %cond, label %loop, label %exit 207 208exit: 209 ret void 210} 211 212define void @add_flags_not_compared(i32 %init, i32 %n) { 213; CHECK-LABEL: @add_flags_not_compared( 214; CHECK-NEXT: entry: 215; CHECK-NEXT: [[INIT_FROZEN:%.*]] = freeze i32 [[INIT:%.*]] 216; CHECK-NEXT: br label [[LOOP:%.*]] 217; CHECK: loop: 218; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[INIT_FROZEN]], [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ] 219; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1 220; CHECK-NEXT: call void @call(i32 [[I_NEXT]]) 221; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[I_NEXT]], [[N:%.*]] 222; CHECK-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]] 223; CHECK: exit: 224; CHECK-NEXT: ret void 225; 226entry: 227 br label %loop 228 229loop: 230 %i = phi i32 [ %init, %entry ], [ %i.next, %loop ] 231 %i.next = add nuw nsw i32 %i, 1 232 %i.next.fr = freeze i32 %i.next 233 call void @call(i32 %i.next.fr) 234 %cond = icmp eq i32 %i.next, %n 235 br i1 %cond, label %loop, label %exit 236 237exit: 238 ret void 239} 240 241; Negative test 242define void @add_flags_not_compared_stepinst(i32 %init, i32 %n) { 243; CHECK-LABEL: @add_flags_not_compared_stepinst( 244; CHECK-NEXT: entry: 245; CHECK-NEXT: br label [[LOOP:%.*]] 246; CHECK: loop: 247; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[INIT:%.*]], [[ENTRY:%.*]] ], [ [[I_NEXT_FR:%.*]], [[LOOP]] ] 248; CHECK-NEXT: [[I_NEXT:%.*]] = add nuw nsw i32 [[I]], 1 249; CHECK-NEXT: [[I_NEXT_FR]] = freeze i32 [[I_NEXT]] 250; CHECK-NEXT: call void @call(i32 [[I_NEXT_FR]]) 251; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[I_NEXT]], [[N:%.*]] 252; CHECK-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]] 253; CHECK: exit: 254; CHECK-NEXT: ret void 255; 256entry: 257 br label %loop 258 259loop: 260 %i = phi i32 [ %init, %entry ], [ %i.next.fr, %loop ] 261 %i.next = add nuw nsw i32 %i, 1 262 %i.next.fr = freeze i32 %i.next 263 call void @call(i32 %i.next.fr) 264 %cond = icmp eq i32 %i.next, %n 265 br i1 %cond, label %loop, label %exit 266 267exit: 268 ret void 269} 270 271; Negative test 272; If pushing freeze through icmp is needed, this should be enabled. 273; There is no correctness issue in pushing freeze into icmp here, just it's 274; being conservative right now. 275define void @add_flags_stepinst_frozen(i32 %init, i32 %n) { 276; CHECK-LABEL: @add_flags_stepinst_frozen( 277; CHECK-NEXT: entry: 278; CHECK-NEXT: br label [[LOOP:%.*]] 279; CHECK: loop: 280; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[INIT:%.*]], [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ] 281; CHECK-NEXT: [[I_NEXT]] = add nuw nsw i32 [[I]], 1 282; CHECK-NEXT: call void @call(i32 [[I_NEXT]]) 283; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[I_NEXT]], [[N:%.*]] 284; CHECK-NEXT: [[COND_FR:%.*]] = freeze i1 [[COND]] 285; CHECK-NEXT: br i1 [[COND_FR]], label [[LOOP]], label [[EXIT:%.*]] 286; CHECK: exit: 287; CHECK-NEXT: ret void 288; 289entry: 290 br label %loop 291 292loop: 293 %i = phi i32 [ %init, %entry ], [ %i.next, %loop ] 294 %i.next = add nuw nsw i32 %i, 1 295 call void @call(i32 %i.next) 296 %cond = icmp eq i32 %i.next, %n 297 %cond.fr = freeze i1 %cond 298 br i1 %cond.fr, label %loop, label %exit 299 300exit: 301 ret void 302} 303 304define void @sub(i32 %init, i32 %n) { 305; CHECK-LABEL: @sub( 306; CHECK-NEXT: entry: 307; CHECK-NEXT: [[INIT_FROZEN:%.*]] = freeze i32 [[INIT:%.*]] 308; CHECK-NEXT: br label [[LOOP:%.*]] 309; CHECK: loop: 310; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[INIT_FROZEN]], [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ] 311; CHECK-NEXT: [[I_NEXT]] = sub i32 [[I]], 1 312; CHECK-NEXT: call void @call(i32 [[I_NEXT]]) 313; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[I_NEXT]], [[N:%.*]] 314; CHECK-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]] 315; CHECK: exit: 316; CHECK-NEXT: ret void 317; 318entry: 319 br label %loop 320 321loop: 322 %i = phi i32 [%init, %entry], [%i.next, %loop] 323 %i.next = sub nuw nsw i32 %i, 1 324 %i.next.fr = freeze i32 %i.next 325 call void @call(i32 %i.next.fr) 326 %cond = icmp eq i32 %i.next.fr, %n 327 br i1 %cond, label %loop, label %exit 328 329exit: 330 ret void 331} 332 333define void @init_const(i32 %n) { 334; CHECK-LABEL: @init_const( 335; CHECK-NEXT: entry: 336; CHECK-NEXT: br label [[LOOP:%.*]] 337; CHECK: loop: 338; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ] 339; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1 340; CHECK-NEXT: call void @call(i32 [[I_NEXT]]) 341; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[I_NEXT]], [[N:%.*]] 342; CHECK-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]] 343; CHECK: exit: 344; CHECK-NEXT: ret void 345; 346entry: 347 br label %loop 348 349loop: 350 %i = phi i32 [ 0, %entry ], [ %i.next, %loop ] 351 %i.next = add nuw nsw i32 %i, 1 352 %i.next.fr = freeze i32 %i.next 353 call void @call(i32 %i.next.fr) 354 %cond = icmp eq i32 %i.next.fr, %n 355 br i1 %cond, label %loop, label %exit 356 357exit: 358 ret void 359} 360 361define void @step_init_arg(i32 %init, i32 %n, i32 %step) { 362; CHECK-LABEL: @step_init_arg( 363; CHECK-NEXT: entry: 364; CHECK-NEXT: [[STEP_FROZEN:%.*]] = freeze i32 [[STEP:%.*]] 365; CHECK-NEXT: [[INIT_FROZEN:%.*]] = freeze i32 [[INIT:%.*]] 366; CHECK-NEXT: br label [[LOOP:%.*]] 367; CHECK: loop: 368; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[INIT_FROZEN]], [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ] 369; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], [[STEP_FROZEN]] 370; CHECK-NEXT: call void @call(i32 [[I_NEXT]]) 371; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[I_NEXT]], [[N:%.*]] 372; CHECK-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]] 373; CHECK: exit: 374; CHECK-NEXT: ret void 375; 376entry: 377 br label %loop 378 379loop: 380 %i = phi i32 [%init, %entry], [%i.next, %loop] 381 %i.next = add nuw nsw i32 %i, %step 382 %i.next.fr = freeze i32 %i.next 383 call void @call(i32 %i.next.fr) 384 %cond = icmp eq i32 %i.next.fr, %n 385 br i1 %cond, label %loop, label %exit 386 387exit: 388 ret void 389} 390 391define void @step_init_arg_multiuses(i32 %init, i32 %n, i32 %step) { 392; CHECK-LABEL: @step_init_arg_multiuses( 393; CHECK-NEXT: entry: 394; CHECK-NEXT: [[STEP_FROZEN:%.*]] = freeze i32 [[STEP:%.*]] 395; CHECK-NEXT: [[INIT_FROZEN:%.*]] = freeze i32 [[INIT:%.*]] 396; CHECK-NEXT: br label [[LOOP:%.*]] 397; CHECK: loop: 398; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[INIT_FROZEN]], [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ] 399; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], [[STEP_FROZEN]] 400; CHECK-NEXT: call void @call(i32 [[I_NEXT]]) 401; CHECK-NEXT: call void @call(i32 [[I_NEXT]]) 402; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[I_NEXT]], [[N:%.*]] 403; CHECK-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]] 404; CHECK: exit: 405; CHECK-NEXT: ret void 406; 407entry: 408 br label %loop 409 410loop: 411 %i = phi i32 [ %init, %entry ], [ %i.next, %loop ] 412 %i.next = add nsw nuw i32 %i, %step 413 %i.next.fr1 = freeze i32 %i.next 414 call void @call(i32 %i.next.fr1) 415 %i.next.fr2 = freeze i32 %i.next 416 call void @call(i32 %i.next.fr2) 417 %cond = icmp eq i32 %i.next, %n 418 br i1 %cond, label %loop, label %exit 419 420exit: 421 ret void 422} 423 424define void @step_init_arg_multiuses2(i32 %init, i32 %n, i32 %step) { 425; CHECK-LABEL: @step_init_arg_multiuses2( 426; CHECK-NEXT: entry: 427; CHECK-NEXT: [[STEP_FROZEN:%.*]] = freeze i32 [[STEP:%.*]] 428; CHECK-NEXT: [[INIT_FROZEN:%.*]] = freeze i32 [[INIT:%.*]] 429; CHECK-NEXT: br label [[LOOP:%.*]] 430; CHECK: loop: 431; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[INIT_FROZEN]], [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ] 432; CHECK-NEXT: call void @call(i32 [[I]]) 433; CHECK-NEXT: call void @call(i32 [[I]]) 434; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], [[STEP_FROZEN]] 435; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[I_NEXT]], [[N:%.*]] 436; CHECK-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]] 437; CHECK: exit: 438; CHECK-NEXT: ret void 439; 440entry: 441 br label %loop 442 443loop: 444 %i = phi i32 [ %init, %entry ], [ %i.next, %loop ] 445 %i.fr1 = freeze i32 %i 446 call void @call(i32 %i.fr1) 447 %i.fr2 = freeze i32 %i 448 call void @call(i32 %i.fr2) 449 %i.next = add nsw nuw i32 %i, %step 450 %cond = icmp eq i32 %i.next, %n 451 br i1 %cond, label %loop, label %exit 452 453exit: 454 ret void 455} 456 457define void @step_init_inst(i32 %n) { 458; CHECK-LABEL: @step_init_inst( 459; CHECK-NEXT: entry: 460; CHECK-NEXT: [[STEP:%.*]] = call i32 @get_step() 461; CHECK-NEXT: [[INIT:%.*]] = call i32 @get_step() 462; CHECK-NEXT: [[STEP_FROZEN:%.*]] = freeze i32 [[STEP]] 463; CHECK-NEXT: [[INIT_FROZEN:%.*]] = freeze i32 [[INIT]] 464; CHECK-NEXT: br label [[LOOP:%.*]] 465; CHECK: loop: 466; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[INIT_FROZEN]], [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ] 467; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], [[STEP_FROZEN]] 468; CHECK-NEXT: call void @call(i32 [[I_NEXT]]) 469; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[I_NEXT]], [[N:%.*]] 470; CHECK-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]] 471; CHECK: exit: 472; CHECK-NEXT: ret void 473; 474entry: 475 %step = call i32 @get_step() 476 %init = call i32 @get_step() 477 br label %loop 478 479loop: 480 %i = phi i32 [%init, %entry], [%i.next, %loop] 481 %i.next = add nuw nsw i32 %i, %step 482 %i.next.fr = freeze i32 %i.next 483 call void @call(i32 %i.next.fr) 484 %cond = icmp eq i32 %i.next.fr, %n 485 br i1 %cond, label %loop, label %exit 486 487exit: 488 ret void 489} 490 491; Negative test 492define void @step_inst(i32 %init, i32 %n) { 493; CHECK-LABEL: @step_inst( 494; CHECK-NEXT: entry: 495; CHECK-NEXT: br label [[LOOP:%.*]] 496; CHECK: loop: 497; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[INIT:%.*]], [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ] 498; CHECK-NEXT: [[I_NEXT]] = add nuw nsw i32 [[I]], [[I]] 499; CHECK-NEXT: [[I_NEXT_FR:%.*]] = freeze i32 [[I_NEXT]] 500; CHECK-NEXT: call void @call(i32 [[I_NEXT_FR]]) 501; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[I_NEXT_FR]], [[N:%.*]] 502; CHECK-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]] 503; CHECK: exit: 504; CHECK-NEXT: ret void 505; 506entry: 507 br label %loop 508 509loop: 510 %i = phi i32 [%init, %entry], [%i.next, %loop] 511 %i.next = add nuw nsw i32 %i, %i 512 %i.next.fr = freeze i32 %i.next 513 call void @call(i32 %i.next.fr) 514 %cond = icmp eq i32 %i.next.fr, %n 515 br i1 %cond, label %loop, label %exit 516 517exit: 518 ret void 519} 520 521; Negative test 522define void @gep(i8* %init, i8* %end) { 523; CHECK-LABEL: @gep( 524; CHECK-NEXT: entry: 525; CHECK-NEXT: br label [[LOOP:%.*]] 526; CHECK: loop: 527; CHECK-NEXT: [[I:%.*]] = phi i8* [ [[INIT:%.*]], [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ] 528; CHECK-NEXT: [[I_NEXT]] = getelementptr inbounds i8, i8* [[I]], i64 1 529; CHECK-NEXT: [[I_NEXT_FR:%.*]] = freeze i8* [[I_NEXT]] 530; CHECK-NEXT: [[COND:%.*]] = icmp eq i8* [[I_NEXT_FR]], [[END:%.*]] 531; CHECK-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]] 532; CHECK: exit: 533; CHECK-NEXT: ret void 534; 535entry: 536 br label %loop 537 538loop: 539 %i = phi i8* [ %init, %entry], [%i.next, %loop ] 540 %i.next = getelementptr inbounds i8, i8* %i, i64 1 541 %i.next.fr = freeze i8* %i.next 542 %cond = icmp eq i8* %i.next.fr, %end 543 br i1 %cond, label %loop, label %exit 544 545exit: 546 ret void 547} 548