| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py | |
| ; RUN: opt -passes=indvars -S < %s | FileCheck %s | |
| define void @ult(i64 %n, i64 %m) { | |
| ; CHECK-LABEL: @ult( | |
| ; CHECK-NEXT: entry: | |
| ; CHECK-NEXT: [[CMP0:%.*]] = icmp ult i64 [[N:%.*]], [[M:%.*]] | |
| ; CHECK-NEXT: br i1 [[CMP0]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]] | |
| ; CHECK: loop.preheader: | |
| ; CHECK-NEXT: br label [[LOOP:%.*]] | |
| ; CHECK: loop: | |
| ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[LATCH:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] | |
| ; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1 | |
| ; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i64 [[IV]], [[N]] | |
| ; CHECK-NEXT: br i1 [[CMP1]], label [[LATCH]], label [[EXIT_LOOPEXIT:%.*]] | |
| ; CHECK: latch: | |
| ; CHECK-NEXT: call void @side_effect() | |
| ; CHECK-NEXT: br i1 true, label [[LOOP]], label [[EXIT_LOOPEXIT]] | |
| ; CHECK: exit.loopexit: | |
| ; CHECK-NEXT: br label [[EXIT]] | |
| ; CHECK: exit: | |
| ; CHECK-NEXT: ret void | |
| ; | |
| entry: | |
| %cmp0 = icmp ult i64 %n, %m | |
| br i1 %cmp0, label %loop, label %exit | |
| loop: | |
| %iv = phi i64 [ 0, %entry ], [ %iv.next, %latch ] | |
| %iv.next = add i64 %iv, 1 | |
| %cmp1 = icmp ult i64 %iv, %n | |
| br i1 %cmp1, label %latch, label %exit | |
| latch: | |
| call void @side_effect() | |
| %cmp2 = icmp ult i64 %iv, %m | |
| br i1 %cmp2, label %loop, label %exit | |
| exit: | |
| ret void | |
| } | |
| define void @ugt(i64 %n, i64 %m) { | |
| ; CHECK-LABEL: @ugt( | |
| ; CHECK-NEXT: entry: | |
| ; CHECK-NEXT: [[CMP0:%.*]] = icmp ugt i64 [[N:%.*]], [[M:%.*]] | |
| ; CHECK-NEXT: br i1 [[CMP0]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]] | |
| ; CHECK: loop.preheader: | |
| ; CHECK-NEXT: br label [[LOOP:%.*]] | |
| ; CHECK: loop: | |
| ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[LATCH:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] | |
| ; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1 | |
| ; CHECK-NEXT: br i1 true, label [[LATCH]], label [[EXIT_LOOPEXIT:%.*]] | |
| ; CHECK: latch: | |
| ; CHECK-NEXT: call void @side_effect() | |
| ; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i64 [[IV]], [[M]] | |
| ; CHECK-NEXT: br i1 [[CMP2]], label [[LOOP]], label [[EXIT_LOOPEXIT]] | |
| ; CHECK: exit.loopexit: | |
| ; CHECK-NEXT: br label [[EXIT]] | |
| ; CHECK: exit: | |
| ; CHECK-NEXT: ret void | |
| ; | |
| entry: | |
| %cmp0 = icmp ugt i64 %n, %m | |
| br i1 %cmp0, label %loop, label %exit | |
| loop: | |
| %iv = phi i64 [ 0, %entry ], [ %iv.next, %latch ] | |
| %iv.next = add i64 %iv, 1 | |
| %cmp1 = icmp ult i64 %iv, %n | |
| br i1 %cmp1, label %latch, label %exit | |
| latch: | |
| call void @side_effect() | |
| %cmp2 = icmp ult i64 %iv, %m | |
| br i1 %cmp2, label %loop, label %exit | |
| exit: | |
| ret void | |
| } | |
| define void @ule(i64 %n, i64 %m) { | |
| ; CHECK-LABEL: @ule( | |
| ; CHECK-NEXT: entry: | |
| ; CHECK-NEXT: [[CMP0:%.*]] = icmp ule i64 [[N:%.*]], [[M:%.*]] | |
| ; CHECK-NEXT: br i1 [[CMP0]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]] | |
| ; CHECK: loop.preheader: | |
| ; CHECK-NEXT: br label [[LOOP:%.*]] | |
| ; CHECK: loop: | |
| ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[LATCH:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] | |
| ; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1 | |
| ; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i64 [[IV]], [[N]] | |
| ; CHECK-NEXT: br i1 [[CMP1]], label [[LATCH]], label [[EXIT_LOOPEXIT:%.*]] | |
| ; CHECK: latch: | |
| ; CHECK-NEXT: call void @side_effect() | |
| ; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i64 [[IV]], [[M]] | |
| ; CHECK-NEXT: br i1 [[CMP2]], label [[LOOP]], label [[EXIT_LOOPEXIT]] | |
| ; CHECK: exit.loopexit: | |
| ; CHECK-NEXT: br label [[EXIT]] | |
| ; CHECK: exit: | |
| ; CHECK-NEXT: ret void | |
| ; | |
| entry: | |
| %cmp0 = icmp ule i64 %n, %m | |
| br i1 %cmp0, label %loop, label %exit | |
| loop: | |
| %iv = phi i64 [ 0, %entry ], [ %iv.next, %latch ] | |
| %iv.next = add i64 %iv, 1 | |
| %cmp1 = icmp ult i64 %iv, %n | |
| br i1 %cmp1, label %latch, label %exit | |
| latch: | |
| call void @side_effect() | |
| %cmp2 = icmp ult i64 %iv, %m | |
| br i1 %cmp2, label %loop, label %exit | |
| exit: | |
| ret void | |
| } | |
| define void @uge(i64 %n, i64 %m) { | |
| ; CHECK-LABEL: @uge( | |
| ; CHECK-NEXT: entry: | |
| ; CHECK-NEXT: [[CMP0:%.*]] = icmp uge i64 [[N:%.*]], [[M:%.*]] | |
| ; CHECK-NEXT: br i1 [[CMP0]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]] | |
| ; CHECK: loop.preheader: | |
| ; CHECK-NEXT: br label [[LOOP:%.*]] | |
| ; CHECK: loop: | |
| ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[LATCH:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] | |
| ; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1 | |
| ; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i64 [[IV]], [[N]] | |
| ; CHECK-NEXT: br i1 [[CMP1]], label [[LATCH]], label [[EXIT_LOOPEXIT:%.*]] | |
| ; CHECK: latch: | |
| ; CHECK-NEXT: call void @side_effect() | |
| ; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i64 [[IV]], [[M]] | |
| ; CHECK-NEXT: br i1 [[CMP2]], label [[LOOP]], label [[EXIT_LOOPEXIT]] | |
| ; CHECK: exit.loopexit: | |
| ; CHECK-NEXT: br label [[EXIT]] | |
| ; CHECK: exit: | |
| ; CHECK-NEXT: ret void | |
| ; | |
| entry: | |
| %cmp0 = icmp uge i64 %n, %m | |
| br i1 %cmp0, label %loop, label %exit | |
| loop: | |
| %iv = phi i64 [ 0, %entry ], [ %iv.next, %latch ] | |
| %iv.next = add i64 %iv, 1 | |
| %cmp1 = icmp ult i64 %iv, %n | |
| br i1 %cmp1, label %latch, label %exit | |
| latch: | |
| call void @side_effect() | |
| %cmp2 = icmp ult i64 %iv, %m | |
| br i1 %cmp2, label %loop, label %exit | |
| exit: | |
| ret void | |
| } | |
| define void @ult_const_max(i64 %n) { | |
| ; CHECK-LABEL: @ult_const_max( | |
| ; CHECK-NEXT: entry: | |
| ; CHECK-NEXT: [[CMP0:%.*]] = icmp ult i64 [[N:%.*]], 20 | |
| ; CHECK-NEXT: br i1 [[CMP0]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]] | |
| ; CHECK: loop.preheader: | |
| ; CHECK-NEXT: br label [[LOOP:%.*]] | |
| ; CHECK: loop: | |
| ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[LATCH:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] | |
| ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1 | |
| ; CHECK-NEXT: br i1 true, label [[LATCH]], label [[EXIT_LOOPEXIT:%.*]] | |
| ; CHECK: latch: | |
| ; CHECK-NEXT: call void @side_effect() | |
| ; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i64 [[IV]], [[N]] | |
| ; CHECK-NEXT: br i1 [[CMP2]], label [[LOOP]], label [[EXIT_LOOPEXIT]] | |
| ; CHECK: exit.loopexit: | |
| ; CHECK-NEXT: br label [[EXIT]] | |
| ; CHECK: exit: | |
| ; CHECK-NEXT: ret void | |
| ; | |
| entry: | |
| %cmp0 = icmp ult i64 %n, 20 | |
| br i1 %cmp0, label %loop, label %exit | |
| loop: | |
| %iv = phi i64 [ 0, %entry ], [ %iv.next, %latch ] | |
| %iv.next = add i64 %iv, 1 | |
| %udiv = udiv i64 %iv, 10 | |
| %cmp1 = icmp ult i64 %udiv, 2 | |
| br i1 %cmp1, label %latch, label %exit | |
| latch: | |
| call void @side_effect() | |
| %cmp2 = icmp ult i64 %iv, %n | |
| br i1 %cmp2, label %loop, label %exit | |
| exit: | |
| ret void | |
| } | |
| define void @mixed_width(i32 %len) { | |
| ; CHECK-LABEL: @mixed_width( | |
| ; CHECK-NEXT: entry: | |
| ; CHECK-NEXT: [[LEN_ZEXT:%.*]] = zext i32 [[LEN:%.*]] to i64 | |
| ; CHECK-NEXT: br label [[LOOP:%.*]] | |
| ; CHECK: loop: | |
| ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ] | |
| ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1 | |
| ; CHECK-NEXT: [[CMP1:%.*]] = icmp samesign ult i64 [[IV]], [[LEN_ZEXT]] | |
| ; CHECK-NEXT: br i1 [[CMP1]], label [[BACKEDGE]], label [[EXIT:%.*]] | |
| ; CHECK: backedge: | |
| ; CHECK-NEXT: call void @side_effect() | |
| ; CHECK-NEXT: br i1 true, label [[LOOP]], label [[EXIT]] | |
| ; CHECK: exit: | |
| ; CHECK-NEXT: ret void | |
| ; | |
| entry: | |
| %len.zext = zext i32 %len to i64 | |
| br label %loop | |
| loop: | |
| %iv = phi i64 [0, %entry], [%iv.next, %backedge] | |
| %iv2 = phi i32 [0, %entry], [%iv2.next, %backedge] | |
| %iv.next = add i64 %iv, 1 | |
| %iv2.next = add i32 %iv2, 1 | |
| %cmp1 = icmp ult i64 %iv, %len.zext | |
| br i1 %cmp1, label %backedge, label %exit | |
| backedge: | |
| call void @side_effect() | |
| %cmp2 = icmp ult i32 %iv2, %len | |
| br i1 %cmp2, label %loop, label %exit | |
| exit: | |
| ret void | |
| } | |
| define void @many_exits([100 x i64] %len) { | |
| ; CHECK-LABEL: @many_exits( | |
| ; CHECK-NEXT: entry: | |
| ; CHECK-NEXT: [[LEN1:%.*]] = extractvalue [100 x i64] [[LEN:%.*]], 1 | |
| ; CHECK-NEXT: [[LEN2:%.*]] = extractvalue [100 x i64] [[LEN]], 2 | |
| ; CHECK-NEXT: [[LEN3:%.*]] = extractvalue [100 x i64] [[LEN]], 3 | |
| ; CHECK-NEXT: [[LEN4:%.*]] = extractvalue [100 x i64] [[LEN]], 4 | |
| ; CHECK-NEXT: [[LEN5:%.*]] = extractvalue [100 x i64] [[LEN]], 5 | |
| ; CHECK-NEXT: [[LEN6:%.*]] = extractvalue [100 x i64] [[LEN]], 6 | |
| ; CHECK-NEXT: [[LEN7:%.*]] = extractvalue [100 x i64] [[LEN]], 7 | |
| ; CHECK-NEXT: [[LEN8:%.*]] = extractvalue [100 x i64] [[LEN]], 8 | |
| ; CHECK-NEXT: [[LEN9:%.*]] = extractvalue [100 x i64] [[LEN]], 9 | |
| ; CHECK-NEXT: [[LEN10:%.*]] = extractvalue [100 x i64] [[LEN]], 10 | |
| ; CHECK-NEXT: [[LEN11:%.*]] = extractvalue [100 x i64] [[LEN]], 11 | |
| ; CHECK-NEXT: [[LEN12:%.*]] = extractvalue [100 x i64] [[LEN]], 12 | |
| ; CHECK-NEXT: [[LEN13:%.*]] = extractvalue [100 x i64] [[LEN]], 13 | |
| ; CHECK-NEXT: [[LEN14:%.*]] = extractvalue [100 x i64] [[LEN]], 14 | |
| ; CHECK-NEXT: [[LEN15:%.*]] = extractvalue [100 x i64] [[LEN]], 15 | |
| ; CHECK-NEXT: [[LEN16:%.*]] = extractvalue [100 x i64] [[LEN]], 16 | |
| ; CHECK-NEXT: [[LEN17:%.*]] = extractvalue [100 x i64] [[LEN]], 17 | |
| ; CHECK-NEXT: [[LEN18:%.*]] = extractvalue [100 x i64] [[LEN]], 18 | |
| ; CHECK-NEXT: [[LEN19:%.*]] = extractvalue [100 x i64] [[LEN]], 19 | |
| ; CHECK-NEXT: [[LEN20:%.*]] = extractvalue [100 x i64] [[LEN]], 20 | |
| ; CHECK-NEXT: [[LEN21:%.*]] = extractvalue [100 x i64] [[LEN]], 21 | |
| ; CHECK-NEXT: [[LEN22:%.*]] = extractvalue [100 x i64] [[LEN]], 22 | |
| ; CHECK-NEXT: [[LEN23:%.*]] = extractvalue [100 x i64] [[LEN]], 23 | |
| ; CHECK-NEXT: [[LEN24:%.*]] = extractvalue [100 x i64] [[LEN]], 24 | |
| ; CHECK-NEXT: [[LEN25:%.*]] = extractvalue [100 x i64] [[LEN]], 25 | |
| ; CHECK-NEXT: [[LEN26:%.*]] = extractvalue [100 x i64] [[LEN]], 26 | |
| ; CHECK-NEXT: [[LEN27:%.*]] = extractvalue [100 x i64] [[LEN]], 27 | |
| ; CHECK-NEXT: [[LEN28:%.*]] = extractvalue [100 x i64] [[LEN]], 28 | |
| ; CHECK-NEXT: [[LEN29:%.*]] = extractvalue [100 x i64] [[LEN]], 29 | |
| ; CHECK-NEXT: [[LEN30:%.*]] = extractvalue [100 x i64] [[LEN]], 30 | |
| ; CHECK-NEXT: [[LEN31:%.*]] = extractvalue [100 x i64] [[LEN]], 31 | |
| ; CHECK-NEXT: [[LEN32:%.*]] = extractvalue [100 x i64] [[LEN]], 32 | |
| ; CHECK-NEXT: [[LEN33:%.*]] = extractvalue [100 x i64] [[LEN]], 33 | |
| ; CHECK-NEXT: [[LEN34:%.*]] = extractvalue [100 x i64] [[LEN]], 34 | |
| ; CHECK-NEXT: [[LEN35:%.*]] = extractvalue [100 x i64] [[LEN]], 35 | |
| ; CHECK-NEXT: [[LEN36:%.*]] = extractvalue [100 x i64] [[LEN]], 36 | |
| ; CHECK-NEXT: [[LEN37:%.*]] = extractvalue [100 x i64] [[LEN]], 37 | |
| ; CHECK-NEXT: [[LEN38:%.*]] = extractvalue [100 x i64] [[LEN]], 38 | |
| ; CHECK-NEXT: [[LEN39:%.*]] = extractvalue [100 x i64] [[LEN]], 39 | |
| ; CHECK-NEXT: br label [[LOOP:%.*]] | |
| ; CHECK: loop: | |
| ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ] | |
| ; CHECK-NEXT: [[LEN0:%.*]] = extractvalue [100 x i64] [[LEN]], 0 | |
| ; CHECK-NEXT: [[EARLY0:%.*]] = icmp eq i64 [[IV]], [[LEN0]] | |
| ; CHECK-NEXT: call void @side_effect() | |
| ; CHECK-NEXT: br i1 [[EARLY0]], label [[EXIT:%.*]], label [[CONT0:%.*]] | |
| ; CHECK: cont0: | |
| ; CHECK-NEXT: [[EARLY1:%.*]] = icmp eq i64 [[IV]], [[LEN1]] | |
| ; CHECK-NEXT: call void @side_effect() | |
| ; CHECK-NEXT: br i1 [[EARLY1]], label [[EXIT]], label [[CONT1:%.*]] | |
| ; CHECK: cont1: | |
| ; CHECK-NEXT: [[EARLY2:%.*]] = icmp eq i64 [[IV]], [[LEN2]] | |
| ; CHECK-NEXT: call void @side_effect() | |
| ; CHECK-NEXT: br i1 [[EARLY2]], label [[EXIT]], label [[CONT2:%.*]] | |
| ; CHECK: cont2: | |
| ; CHECK-NEXT: [[EARLY3:%.*]] = icmp eq i64 [[IV]], [[LEN3]] | |
| ; CHECK-NEXT: call void @side_effect() | |
| ; CHECK-NEXT: br i1 [[EARLY3]], label [[EXIT]], label [[CONT3:%.*]] | |
| ; CHECK: cont3: | |
| ; CHECK-NEXT: [[EARLY4:%.*]] = icmp eq i64 [[IV]], [[LEN4]] | |
| ; CHECK-NEXT: call void @side_effect() | |
| ; CHECK-NEXT: br i1 [[EARLY4]], label [[EXIT]], label [[CONT4:%.*]] | |
| ; CHECK: cont4: | |
| ; CHECK-NEXT: [[EARLY5:%.*]] = icmp eq i64 [[IV]], [[LEN5]] | |
| ; CHECK-NEXT: call void @side_effect() | |
| ; CHECK-NEXT: br i1 [[EARLY5]], label [[EXIT]], label [[CONT5:%.*]] | |
| ; CHECK: cont5: | |
| ; CHECK-NEXT: [[EARLY6:%.*]] = icmp eq i64 [[IV]], [[LEN6]] | |
| ; CHECK-NEXT: call void @side_effect() | |
| ; CHECK-NEXT: br i1 [[EARLY6]], label [[EXIT]], label [[CONT6:%.*]] | |
| ; CHECK: cont6: | |
| ; CHECK-NEXT: [[EARLY7:%.*]] = icmp eq i64 [[IV]], [[LEN7]] | |
| ; CHECK-NEXT: call void @side_effect() | |
| ; CHECK-NEXT: br i1 [[EARLY7]], label [[EXIT]], label [[CONT7:%.*]] | |
| ; CHECK: cont7: | |
| ; CHECK-NEXT: [[EARLY8:%.*]] = icmp eq i64 [[IV]], [[LEN8]] | |
| ; CHECK-NEXT: call void @side_effect() | |
| ; CHECK-NEXT: br i1 [[EARLY8]], label [[EXIT]], label [[CONT8:%.*]] | |
| ; CHECK: cont8: | |
| ; CHECK-NEXT: [[EARLY9:%.*]] = icmp eq i64 [[IV]], [[LEN9]] | |
| ; CHECK-NEXT: call void @side_effect() | |
| ; CHECK-NEXT: br i1 [[EARLY9]], label [[EXIT]], label [[CONT9:%.*]] | |
| ; CHECK: cont9: | |
| ; CHECK-NEXT: [[EARLY10:%.*]] = icmp eq i64 [[IV]], [[LEN10]] | |
| ; CHECK-NEXT: call void @side_effect() | |
| ; CHECK-NEXT: br i1 [[EARLY10]], label [[EXIT]], label [[CONT10:%.*]] | |
| ; CHECK: cont10: | |
| ; CHECK-NEXT: [[EARLY11:%.*]] = icmp eq i64 [[IV]], [[LEN11]] | |
| ; CHECK-NEXT: call void @side_effect() | |
| ; CHECK-NEXT: br i1 [[EARLY11]], label [[EXIT]], label [[CONT11:%.*]] | |
| ; CHECK: cont11: | |
| ; CHECK-NEXT: [[EARLY12:%.*]] = icmp eq i64 [[IV]], [[LEN12]] | |
| ; CHECK-NEXT: call void @side_effect() | |
| ; CHECK-NEXT: br i1 [[EARLY12]], label [[EXIT]], label [[CONT12:%.*]] | |
| ; CHECK: cont12: | |
| ; CHECK-NEXT: [[EARLY13:%.*]] = icmp eq i64 [[IV]], [[LEN13]] | |
| ; CHECK-NEXT: call void @side_effect() | |
| ; CHECK-NEXT: br i1 [[EARLY13]], label [[EXIT]], label [[CONT13:%.*]] | |
| ; CHECK: cont13: | |
| ; CHECK-NEXT: [[EARLY14:%.*]] = icmp eq i64 [[IV]], [[LEN14]] | |
| ; CHECK-NEXT: call void @side_effect() | |
| ; CHECK-NEXT: br i1 [[EARLY14]], label [[EXIT]], label [[CONT14:%.*]] | |
| ; CHECK: cont14: | |
| ; CHECK-NEXT: [[EARLY15:%.*]] = icmp eq i64 [[IV]], [[LEN15]] | |
| ; CHECK-NEXT: call void @side_effect() | |
| ; CHECK-NEXT: br i1 [[EARLY15]], label [[EXIT]], label [[CONT15:%.*]] | |
| ; CHECK: cont15: | |
| ; CHECK-NEXT: [[EARLY16:%.*]] = icmp eq i64 [[IV]], [[LEN16]] | |
| ; CHECK-NEXT: call void @side_effect() | |
| ; CHECK-NEXT: br i1 [[EARLY16]], label [[EXIT]], label [[CONT16:%.*]] | |
| ; CHECK: cont16: | |
| ; CHECK-NEXT: [[EARLY17:%.*]] = icmp eq i64 [[IV]], [[LEN17]] | |
| ; CHECK-NEXT: call void @side_effect() | |
| ; CHECK-NEXT: br i1 [[EARLY17]], label [[EXIT]], label [[CONT17:%.*]] | |
| ; CHECK: cont17: | |
| ; CHECK-NEXT: [[EARLY18:%.*]] = icmp eq i64 [[IV]], [[LEN18]] | |
| ; CHECK-NEXT: call void @side_effect() | |
| ; CHECK-NEXT: br i1 [[EARLY18]], label [[EXIT]], label [[CONT18:%.*]] | |
| ; CHECK: cont18: | |
| ; CHECK-NEXT: [[EARLY19:%.*]] = icmp eq i64 [[IV]], [[LEN19]] | |
| ; CHECK-NEXT: call void @side_effect() | |
| ; CHECK-NEXT: br i1 [[EARLY19]], label [[EXIT]], label [[CONT19:%.*]] | |
| ; CHECK: cont19: | |
| ; CHECK-NEXT: [[EARLY20:%.*]] = icmp eq i64 [[IV]], [[LEN20]] | |
| ; CHECK-NEXT: call void @side_effect() | |
| ; CHECK-NEXT: br i1 [[EARLY20]], label [[EXIT]], label [[CONT20:%.*]] | |
| ; CHECK: cont20: | |
| ; CHECK-NEXT: [[EARLY21:%.*]] = icmp eq i64 [[IV]], [[LEN21]] | |
| ; CHECK-NEXT: call void @side_effect() | |
| ; CHECK-NEXT: br i1 [[EARLY21]], label [[EXIT]], label [[CONT21:%.*]] | |
| ; CHECK: cont21: | |
| ; CHECK-NEXT: [[EARLY22:%.*]] = icmp eq i64 [[IV]], [[LEN22]] | |
| ; CHECK-NEXT: call void @side_effect() | |
| ; CHECK-NEXT: br i1 [[EARLY22]], label [[EXIT]], label [[CONT22:%.*]] | |
| ; CHECK: cont22: | |
| ; CHECK-NEXT: [[EARLY23:%.*]] = icmp eq i64 [[IV]], [[LEN23]] | |
| ; CHECK-NEXT: call void @side_effect() | |
| ; CHECK-NEXT: br i1 [[EARLY23]], label [[EXIT]], label [[CONT23:%.*]] | |
| ; CHECK: cont23: | |
| ; CHECK-NEXT: [[EARLY24:%.*]] = icmp eq i64 [[IV]], [[LEN24]] | |
| ; CHECK-NEXT: call void @side_effect() | |
| ; CHECK-NEXT: br i1 [[EARLY24]], label [[EXIT]], label [[CONT24:%.*]] | |
| ; CHECK: cont24: | |
| ; CHECK-NEXT: [[EARLY25:%.*]] = icmp eq i64 [[IV]], [[LEN25]] | |
| ; CHECK-NEXT: call void @side_effect() | |
| ; CHECK-NEXT: br i1 [[EARLY25]], label [[EXIT]], label [[CONT25:%.*]] | |
| ; CHECK: cont25: | |
| ; CHECK-NEXT: [[EARLY26:%.*]] = icmp eq i64 [[IV]], [[LEN26]] | |
| ; CHECK-NEXT: call void @side_effect() | |
| ; CHECK-NEXT: br i1 [[EARLY26]], label [[EXIT]], label [[CONT26:%.*]] | |
| ; CHECK: cont26: | |
| ; CHECK-NEXT: [[EARLY27:%.*]] = icmp eq i64 [[IV]], [[LEN27]] | |
| ; CHECK-NEXT: call void @side_effect() | |
| ; CHECK-NEXT: br i1 [[EARLY27]], label [[EXIT]], label [[CONT27:%.*]] | |
| ; CHECK: cont27: | |
| ; CHECK-NEXT: [[EARLY28:%.*]] = icmp eq i64 [[IV]], [[LEN28]] | |
| ; CHECK-NEXT: call void @side_effect() | |
| ; CHECK-NEXT: br i1 [[EARLY28]], label [[EXIT]], label [[CONT28:%.*]] | |
| ; CHECK: cont28: | |
| ; CHECK-NEXT: [[EARLY29:%.*]] = icmp eq i64 [[IV]], [[LEN29]] | |
| ; CHECK-NEXT: call void @side_effect() | |
| ; CHECK-NEXT: br i1 [[EARLY29]], label [[EXIT]], label [[CONT29:%.*]] | |
| ; CHECK: cont29: | |
| ; CHECK-NEXT: [[EARLY30:%.*]] = icmp eq i64 [[IV]], [[LEN30]] | |
| ; CHECK-NEXT: call void @side_effect() | |
| ; CHECK-NEXT: br i1 [[EARLY30]], label [[EXIT]], label [[CONT30:%.*]] | |
| ; CHECK: cont30: | |
| ; CHECK-NEXT: [[EARLY31:%.*]] = icmp eq i64 [[IV]], [[LEN31]] | |
| ; CHECK-NEXT: call void @side_effect() | |
| ; CHECK-NEXT: br i1 [[EARLY31]], label [[EXIT]], label [[CONT31:%.*]] | |
| ; CHECK: cont31: | |
| ; CHECK-NEXT: [[EARLY32:%.*]] = icmp eq i64 [[IV]], [[LEN32]] | |
| ; CHECK-NEXT: call void @side_effect() | |
| ; CHECK-NEXT: br i1 [[EARLY32]], label [[EXIT]], label [[CONT32:%.*]] | |
| ; CHECK: cont32: | |
| ; CHECK-NEXT: [[EARLY33:%.*]] = icmp eq i64 [[IV]], [[LEN33]] | |
| ; CHECK-NEXT: call void @side_effect() | |
| ; CHECK-NEXT: br i1 [[EARLY33]], label [[EXIT]], label [[CONT33:%.*]] | |
| ; CHECK: cont33: | |
| ; CHECK-NEXT: [[EARLY34:%.*]] = icmp eq i64 [[IV]], [[LEN34]] | |
| ; CHECK-NEXT: call void @side_effect() | |
| ; CHECK-NEXT: br i1 [[EARLY34]], label [[EXIT]], label [[CONT34:%.*]] | |
| ; CHECK: cont34: | |
| ; CHECK-NEXT: [[EARLY35:%.*]] = icmp eq i64 [[IV]], [[LEN35]] | |
| ; CHECK-NEXT: call void @side_effect() | |
| ; CHECK-NEXT: br i1 [[EARLY35]], label [[EXIT]], label [[CONT35:%.*]] | |
| ; CHECK: cont35: | |
| ; CHECK-NEXT: [[EARLY36:%.*]] = icmp eq i64 [[IV]], [[LEN36]] | |
| ; CHECK-NEXT: call void @side_effect() | |
| ; CHECK-NEXT: br i1 [[EARLY36]], label [[EXIT]], label [[CONT36:%.*]] | |
| ; CHECK: cont36: | |
| ; CHECK-NEXT: [[EARLY37:%.*]] = icmp eq i64 [[IV]], [[LEN37]] | |
| ; CHECK-NEXT: call void @side_effect() | |
| ; CHECK-NEXT: br i1 [[EARLY37]], label [[EXIT]], label [[CONT37:%.*]] | |
| ; CHECK: cont37: | |
| ; CHECK-NEXT: [[EARLY38:%.*]] = icmp eq i64 [[IV]], [[LEN38]] | |
| ; CHECK-NEXT: call void @side_effect() | |
| ; CHECK-NEXT: br i1 [[EARLY38]], label [[EXIT]], label [[CONT38:%.*]] | |
| ; CHECK: cont38: | |
| ; CHECK-NEXT: [[EARLY39:%.*]] = icmp eq i64 [[IV]], [[LEN39]] | |
| ; CHECK-NEXT: call void @side_effect() | |
| ; CHECK-NEXT: br i1 [[EARLY39]], label [[EXIT]], label [[CONT39:%.*]] | |
| ; CHECK: cont39: | |
| ; CHECK-NEXT: br label [[BACKEDGE]] | |
| ; CHECK: backedge: | |
| ; CHECK-NEXT: call void @side_effect() | |
| ; CHECK-NEXT: [[CMP2:%.*]] = icmp samesign ult i64 [[IV]], 999 | |
| ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1 | |
| ; CHECK-NEXT: br i1 [[CMP2]], label [[LOOP]], label [[EXIT]] | |
| ; CHECK: exit: | |
| ; CHECK-NEXT: ret void | |
| ; | |
| entry: | |
| br label %loop | |
| loop: | |
| %iv = phi i64 [0, %entry], [%iv.next, %backedge] | |
| %len0 = extractvalue [100 x i64] %len, 0 | |
| %early0 = icmp eq i64 %iv, %len0 | |
| call void @side_effect() | |
| br i1 %early0, label %exit, label %cont0 | |
| cont0: | |
| %len1 = extractvalue [100 x i64] %len, 1 | |
| %early1 = icmp eq i64 %iv, %len1 | |
| call void @side_effect() | |
| br i1 %early1, label %exit, label %cont1 | |
| cont1: | |
| %len2 = extractvalue [100 x i64] %len, 2 | |
| %early2 = icmp eq i64 %iv, %len2 | |
| call void @side_effect() | |
| br i1 %early2, label %exit, label %cont2 | |
| cont2: | |
| %len3 = extractvalue [100 x i64] %len, 3 | |
| %early3 = icmp eq i64 %iv, %len3 | |
| call void @side_effect() | |
| br i1 %early3, label %exit, label %cont3 | |
| cont3: | |
| %len4 = extractvalue [100 x i64] %len, 4 | |
| %early4 = icmp eq i64 %iv, %len4 | |
| call void @side_effect() | |
| br i1 %early4, label %exit, label %cont4 | |
| cont4: | |
| %len5 = extractvalue [100 x i64] %len, 5 | |
| %early5 = icmp eq i64 %iv, %len5 | |
| call void @side_effect() | |
| br i1 %early5, label %exit, label %cont5 | |
| cont5: | |
| %len6 = extractvalue [100 x i64] %len, 6 | |
| %early6 = icmp eq i64 %iv, %len6 | |
| call void @side_effect() | |
| br i1 %early6, label %exit, label %cont6 | |
| cont6: | |
| %len7 = extractvalue [100 x i64] %len, 7 | |
| %early7 = icmp eq i64 %iv, %len7 | |
| call void @side_effect() | |
| br i1 %early7, label %exit, label %cont7 | |
| cont7: | |
| %len8 = extractvalue [100 x i64] %len, 8 | |
| %early8 = icmp eq i64 %iv, %len8 | |
| call void @side_effect() | |
| br i1 %early8, label %exit, label %cont8 | |
| cont8: | |
| %len9 = extractvalue [100 x i64] %len, 9 | |
| %early9 = icmp eq i64 %iv, %len9 | |
| call void @side_effect() | |
| br i1 %early9, label %exit, label %cont9 | |
| cont9: | |
| %len10 = extractvalue [100 x i64] %len, 10 | |
| %early10 = icmp eq i64 %iv, %len10 | |
| call void @side_effect() | |
| br i1 %early10, label %exit, label %cont10 | |
| cont10: | |
| %len11 = extractvalue [100 x i64] %len, 11 | |
| %early11 = icmp eq i64 %iv, %len11 | |
| call void @side_effect() | |
| br i1 %early11, label %exit, label %cont11 | |
| cont11: | |
| %len12 = extractvalue [100 x i64] %len, 12 | |
| %early12 = icmp eq i64 %iv, %len12 | |
| call void @side_effect() | |
| br i1 %early12, label %exit, label %cont12 | |
| cont12: | |
| %len13 = extractvalue [100 x i64] %len, 13 | |
| %early13 = icmp eq i64 %iv, %len13 | |
| call void @side_effect() | |
| br i1 %early13, label %exit, label %cont13 | |
| cont13: | |
| %len14 = extractvalue [100 x i64] %len, 14 | |
| %early14 = icmp eq i64 %iv, %len14 | |
| call void @side_effect() | |
| br i1 %early14, label %exit, label %cont14 | |
| cont14: | |
| %len15 = extractvalue [100 x i64] %len, 15 | |
| %early15 = icmp eq i64 %iv, %len15 | |
| call void @side_effect() | |
| br i1 %early15, label %exit, label %cont15 | |
| cont15: | |
| %len16 = extractvalue [100 x i64] %len, 16 | |
| %early16 = icmp eq i64 %iv, %len16 | |
| call void @side_effect() | |
| br i1 %early16, label %exit, label %cont16 | |
| cont16: | |
| %len17 = extractvalue [100 x i64] %len, 17 | |
| %early17 = icmp eq i64 %iv, %len17 | |
| call void @side_effect() | |
| br i1 %early17, label %exit, label %cont17 | |
| cont17: | |
| %len18 = extractvalue [100 x i64] %len, 18 | |
| %early18 = icmp eq i64 %iv, %len18 | |
| call void @side_effect() | |
| br i1 %early18, label %exit, label %cont18 | |
| cont18: | |
| %len19 = extractvalue [100 x i64] %len, 19 | |
| %early19 = icmp eq i64 %iv, %len19 | |
| call void @side_effect() | |
| br i1 %early19, label %exit, label %cont19 | |
| cont19: | |
| %len20 = extractvalue [100 x i64] %len, 20 | |
| %early20 = icmp eq i64 %iv, %len20 | |
| call void @side_effect() | |
| br i1 %early20, label %exit, label %cont20 | |
| cont20: | |
| %len21 = extractvalue [100 x i64] %len, 21 | |
| %early21 = icmp eq i64 %iv, %len21 | |
| call void @side_effect() | |
| br i1 %early21, label %exit, label %cont21 | |
| cont21: | |
| %len22 = extractvalue [100 x i64] %len, 22 | |
| %early22 = icmp eq i64 %iv, %len22 | |
| call void @side_effect() | |
| br i1 %early22, label %exit, label %cont22 | |
| cont22: | |
| %len23 = extractvalue [100 x i64] %len, 23 | |
| %early23 = icmp eq i64 %iv, %len23 | |
| call void @side_effect() | |
| br i1 %early23, label %exit, label %cont23 | |
| cont23: | |
| %len24 = extractvalue [100 x i64] %len, 24 | |
| %early24 = icmp eq i64 %iv, %len24 | |
| call void @side_effect() | |
| br i1 %early24, label %exit, label %cont24 | |
| cont24: | |
| %len25 = extractvalue [100 x i64] %len, 25 | |
| %early25 = icmp eq i64 %iv, %len25 | |
| call void @side_effect() | |
| br i1 %early25, label %exit, label %cont25 | |
| cont25: | |
| %len26 = extractvalue [100 x i64] %len, 26 | |
| %early26 = icmp eq i64 %iv, %len26 | |
| call void @side_effect() | |
| br i1 %early26, label %exit, label %cont26 | |
| cont26: | |
| %len27 = extractvalue [100 x i64] %len, 27 | |
| %early27 = icmp eq i64 %iv, %len27 | |
| call void @side_effect() | |
| br i1 %early27, label %exit, label %cont27 | |
| cont27: | |
| %len28 = extractvalue [100 x i64] %len, 28 | |
| %early28 = icmp eq i64 %iv, %len28 | |
| call void @side_effect() | |
| br i1 %early28, label %exit, label %cont28 | |
| cont28: | |
| %len29 = extractvalue [100 x i64] %len, 29 | |
| %early29 = icmp eq i64 %iv, %len29 | |
| call void @side_effect() | |
| br i1 %early29, label %exit, label %cont29 | |
| cont29: | |
| %len30 = extractvalue [100 x i64] %len, 30 | |
| %early30 = icmp eq i64 %iv, %len30 | |
| call void @side_effect() | |
| br i1 %early30, label %exit, label %cont30 | |
| cont30: | |
| %len31 = extractvalue [100 x i64] %len, 31 | |
| %early31 = icmp eq i64 %iv, %len31 | |
| call void @side_effect() | |
| br i1 %early31, label %exit, label %cont31 | |
| cont31: | |
| %len32 = extractvalue [100 x i64] %len, 32 | |
| %early32 = icmp eq i64 %iv, %len32 | |
| call void @side_effect() | |
| br i1 %early32, label %exit, label %cont32 | |
| cont32: | |
| %len33 = extractvalue [100 x i64] %len, 33 | |
| %early33 = icmp eq i64 %iv, %len33 | |
| call void @side_effect() | |
| br i1 %early33, label %exit, label %cont33 | |
| cont33: | |
| %len34 = extractvalue [100 x i64] %len, 34 | |
| %early34 = icmp eq i64 %iv, %len34 | |
| call void @side_effect() | |
| br i1 %early34, label %exit, label %cont34 | |
| cont34: | |
| %len35 = extractvalue [100 x i64] %len, 35 | |
| %early35 = icmp eq i64 %iv, %len35 | |
| call void @side_effect() | |
| br i1 %early35, label %exit, label %cont35 | |
| cont35: | |
| %len36 = extractvalue [100 x i64] %len, 36 | |
| %early36 = icmp eq i64 %iv, %len36 | |
| call void @side_effect() | |
| br i1 %early36, label %exit, label %cont36 | |
| cont36: | |
| %len37 = extractvalue [100 x i64] %len, 37 | |
| %early37 = icmp eq i64 %iv, %len37 | |
| call void @side_effect() | |
| br i1 %early37, label %exit, label %cont37 | |
| cont37: | |
| %len38 = extractvalue [100 x i64] %len, 38 | |
| %early38 = icmp eq i64 %iv, %len38 | |
| call void @side_effect() | |
| br i1 %early38, label %exit, label %cont38 | |
| cont38: | |
| %len39 = extractvalue [100 x i64] %len, 39 | |
| %early39 = icmp eq i64 %iv, %len39 | |
| call void @side_effect() | |
| br i1 %early39, label %exit, label %cont39 | |
| cont39: | |
| br label %backedge | |
| backedge: | |
| call void @side_effect() | |
| %cmp2 = icmp ult i64 %iv, 999 | |
| %iv.next = add i64 %iv, 1 | |
| br i1 %cmp2, label %loop, label %exit | |
| exit: | |
| ret void | |
| } | |
| declare void @side_effect() | |
| ; The exit condition %outer.cond.1 depends on a phi in %inner. Make sure we do | |
| ; not incorrectly determine %x.lcssa <= -1. | |
| define i32 @exit_cond_depends_on_inner_loop() { | |
| ; CHECK-LABEL: @exit_cond_depends_on_inner_loop( | |
| ; CHECK-NEXT: entry: | |
| ; CHECK-NEXT: br label [[OUTER_HEADER:%.*]] | |
| ; CHECK: outer.header: | |
| ; CHECK-NEXT: [[IV_OUTER:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_OUTER_NEXT:%.*]], [[OUTER_LATCH:%.*]] ] | |
| ; CHECK-NEXT: br label [[INNER:%.*]] | |
| ; CHECK: inner: | |
| ; CHECK-NEXT: [[X:%.*]] = phi i32 [ -1, [[OUTER_HEADER]] ], [ [[CALL:%.*]], [[INNER]] ] | |
| ; CHECK-NEXT: [[CALL]] = call i32 @match() | |
| ; CHECK-NEXT: [[INNER_COND:%.*]] = icmp sgt i32 [[CALL]], -1 | |
| ; CHECK-NEXT: br i1 [[INNER_COND]], label [[INNER]], label [[OUTER_EXITING_1:%.*]] | |
| ; CHECK: outer.exiting.1: | |
| ; CHECK-NEXT: [[X_LCSSA:%.*]] = phi i32 [ [[X]], [[INNER]] ] | |
| ; CHECK-NEXT: [[OUTER_COND_1:%.*]] = icmp sgt i32 [[X_LCSSA]], -1 | |
| ; CHECK-NEXT: br i1 [[OUTER_COND_1]], label [[EXIT:%.*]], label [[OUTER_LATCH]] | |
| ; CHECK: outer.latch: | |
| ; CHECK-NEXT: [[IV_OUTER_NEXT]] = add nuw nsw i32 [[IV_OUTER]], 1 | |
| ; CHECK-NEXT: [[OUTER_COND_2:%.*]] = icmp samesign ult i32 [[IV_OUTER]], 100 | |
| ; CHECK-NEXT: br i1 [[OUTER_COND_2]], label [[OUTER_HEADER]], label [[EXIT]] | |
| ; CHECK: exit: | |
| ; CHECK-NEXT: [[X_RES:%.*]] = phi i32 [ [[X_LCSSA]], [[OUTER_EXITING_1]] ], [ -1, [[OUTER_LATCH]] ] | |
| ; CHECK-NEXT: ret i32 [[X_RES]] | |
| ; | |
| entry: | |
| br label %outer.header | |
| outer.header: | |
| %iv.outer = phi i32 [ 0, %entry ], [ %iv.outer.next , %outer.latch ] | |
| br label %inner | |
| inner: | |
| %x = phi i32 [ -1, %outer.header ], [ %call, %inner ] | |
| %call = call i32 @match() | |
| %inner.cond = icmp sgt i32 %call, -1 | |
| br i1 %inner.cond, label %inner, label %outer.exiting.1 | |
| outer.exiting.1: | |
| %x.lcssa = phi i32 [ %x, %inner ] | |
| %outer.cond.1 = icmp sgt i32 %x.lcssa, -1 | |
| br i1 %outer.cond.1, label %exit, label %outer.latch | |
| outer.latch: | |
| %iv.outer.next = add nuw nsw i32 %iv.outer, 1 | |
| %outer.cond.2 = icmp ult i32 %iv.outer, 100 | |
| br i1 %outer.cond.2, label %outer.header, label %exit | |
| exit: | |
| %x.res = phi i32 [ %x.lcssa, %outer.exiting.1 ], [ -1, %outer.latch ] | |
| ret i32 %x.res | |
| } | |
| declare i32 @match() |