1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -S -passes=simplifycfg < %s | FileCheck %s 3 4; This used to infinitely thread between loop and loop.latch without reaching a 5; fixed point. 6 7declare void @dummy() 8 9define i32 @main(i1 %c1, i1 %c2, i32 %y) { 10; CHECK-LABEL: @main( 11; CHECK-NEXT: br i1 [[C1:%.*]], label [[EXIT:%.*]], label [[LOOP_PRE_PREHEADER:%.*]] 12; CHECK: loop.pre.preheader: 13; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[Y:%.*]], -1 14; CHECK-NEXT: br i1 [[CMP]], label [[LOOP_PREHEADER:%.*]], label [[EXIT]] 15; CHECK: loop.preheader: 16; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[Y]], 0 17; CHECK-NEXT: br label [[LOOP:%.*]] 18; CHECK: loop: 19; CHECK-NEXT: br i1 [[C1]], label [[LOOP2:%.*]], label [[LOOP_LATCH:%.*]] 20; CHECK: loop.latch: 21; CHECK-NEXT: br i1 [[CMP]], label [[LOOP]], label [[EXIT]] 22; CHECK: loop2: 23; CHECK-NEXT: br i1 [[CMP2]], label [[JOIN:%.*]], label [[IF:%.*]] 24; CHECK: if: 25; CHECK-NEXT: call void @dummy() 26; CHECK-NEXT: br label [[JOIN]] 27; CHECK: join: 28; CHECK-NEXT: br i1 [[C2:%.*]], label [[LOOP2]], label [[LOOP_LATCH]] 29; CHECK: exit: 30; CHECK-NEXT: ret i32 0 31; 32 br i1 %c1, label %exit, label %loop.pre.preheader 33 34loop.pre.preheader: 35 %cmp = icmp sgt i32 %y, -1 36 br i1 %cmp, label %loop.preheader, label %exit 37 38loop.preheader: 39 %cmp2 = icmp eq i32 %y, 0 40 br label %loop 41 42loop: 43 br i1 %c1, label %loop2, label %loop.latch 44 45loop.latch: 46 br i1 %cmp, label %loop, label %exit 47 48loop2: 49 br i1 %cmp2, label %join, label %if 50 51if: 52 call void @dummy() 53 br label %join 54 55join: 56 br i1 %c2, label %loop2, label %loop.latch 57 58exit: 59 ret i32 0 60 61; uselistorder directives 62 uselistorder label %loop2, { 1, 0 } 63} 64