blob: b20891d2f9ed8983b46c277ba4b6ae3670a2b355 [file] [log] [blame]
; 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()