; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py
; RUN: opt -passes='print<scalar-evolution>' -disable-output %s 2>&1 | FileCheck %s
; Test case for PR40961. The loop guard limit the constant max backedge-taken count.
define void @test_guard_less_than_16(ptr nocapture %a, i64 %i) {
; CHECK-LABEL: 'test_guard_less_than_16'
; CHECK-NEXT: Classifying expressions for: @test_guard_less_than_16
; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ %i, %entry ]
; CHECK-NEXT: --> {%i,+,1}<nuw><nsw><%loop> U: full-set S: full-set Exits: 15 LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %idx = getelementptr inbounds i32, ptr %a, i64 %iv
; CHECK-NEXT: --> {((4 * %i) + %a),+,4}<%loop> U: full-set S: full-set Exits: (60 + %a) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %iv.next = add nuw nsw i64 %iv, 1
; CHECK-NEXT: --> {(1 + %i),+,1}<nuw><nsw><%loop> U: full-set S: full-set Exits: 16 LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @test_guard_less_than_16
; CHECK-NEXT: Loop %loop: backedge-taken count is (15 + (-1 * %i))
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 15
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (15 + (-1 * %i))
; CHECK-NEXT: Loop %loop: Trip multiple is 1
;
entry:
%cmp3 = icmp ult i64 %i, 16
br i1 %cmp3, label %loop, label %exit
loop:
%iv = phi i64 [ %iv.next, %loop ], [ %i, %entry ]
%idx = getelementptr inbounds i32, ptr %a, i64 %iv
store i32 1, ptr %idx, align 4
%iv.next = add nuw nsw i64 %iv, 1
%exitcond = icmp eq i64 %iv.next, 16
br i1 %exitcond, label %exit, label %loop
exit:
ret void
}
define void @test_guard_less_than_16_operands_swapped(ptr nocapture %a, i64 %i) {
; CHECK-LABEL: 'test_guard_less_than_16_operands_swapped'
; CHECK-NEXT: Classifying expressions for: @test_guard_less_than_16_operands_swapped
; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ %i, %entry ]
; CHECK-NEXT: --> {%i,+,1}<nuw><nsw><%loop> U: full-set S: full-set Exits: 15 LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %idx = getelementptr inbounds i32, ptr %a, i64 %iv
; CHECK-NEXT: --> {((4 * %i) + %a),+,4}<%loop> U: full-set S: full-set Exits: (60 + %a) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %iv.next = add nuw nsw i64 %iv, 1
; CHECK-NEXT: --> {(1 + %i),+,1}<nuw><nsw><%loop> U: full-set S: full-set Exits: 16 LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @test_guard_less_than_16_operands_swapped
; CHECK-NEXT: Loop %loop: backedge-taken count is (15 + (-1 * %i))
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 15
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (15 + (-1 * %i))
; CHECK-NEXT: Loop %loop: Trip multiple is 1
;
entry:
%cmp3 = icmp ugt i64 16, %i
br i1 %cmp3, label %loop, label %exit
loop:
%iv = phi i64 [ %iv.next, %loop ], [ %i, %entry ]
%idx = getelementptr inbounds i32, ptr %a, i64 %iv
store i32 1, ptr %idx, align 4
%iv.next = add nuw nsw i64 %iv, 1
%exitcond = icmp eq i64 %iv.next, 16
br i1 %exitcond, label %exit, label %loop
exit:
ret void
}
define void @test_guard_less_than_16_branches_flipped(ptr nocapture %a, i64 %i) {
; CHECK-LABEL: 'test_guard_less_than_16_branches_flipped'
; CHECK-NEXT: Classifying expressions for: @test_guard_less_than_16_branches_flipped
; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ %i, %entry ]
; CHECK-NEXT: --> {%i,+,1}<nuw><nsw><%loop> U: full-set S: full-set Exits: 15 LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %idx = getelementptr inbounds i32, ptr %a, i64 %iv
; CHECK-NEXT: --> {((4 * %i) + %a),+,4}<%loop> U: full-set S: full-set Exits: (60 + %a) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %iv.next = add nuw nsw i64 %iv, 1
; CHECK-NEXT: --> {(1 + %i),+,1}<nuw><nsw><%loop> U: full-set S: full-set Exits: 16 LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @test_guard_less_than_16_branches_flipped
; CHECK-NEXT: Loop %loop: backedge-taken count is (15 + (-1 * %i))
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 -1
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (15 + (-1 * %i))
; CHECK-NEXT: Loop %loop: Trip multiple is 1
;
entry:
%cmp3 = icmp ult i64 %i, 16
br i1 %cmp3, label %exit, label %loop
loop:
%iv = phi i64 [ %iv.next, %loop ], [ %i, %entry ]
%idx = getelementptr inbounds i32, ptr %a, i64 %iv
store i32 1, ptr %idx, align 4
%iv.next = add nuw nsw i64 %iv, 1
%exitcond = icmp eq i64 %iv.next, 16
br i1 %exitcond, label %exit, label %loop
exit:
ret void
}
define void @test_guard_uge_16_branches_flipped(ptr nocapture %a, i64 %i) {
; CHECK-LABEL: 'test_guard_uge_16_branches_flipped'
; CHECK-NEXT: Classifying expressions for: @test_guard_uge_16_branches_flipped
; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ %i, %entry ]
; CHECK-NEXT: --> {%i,+,1}<nuw><nsw><%loop> U: full-set S: full-set Exits: 15 LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %idx = getelementptr inbounds i32, ptr %a, i64 %iv
; CHECK-NEXT: --> {((4 * %i) + %a),+,4}<%loop> U: full-set S: full-set Exits: (60 + %a) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %iv.next = add nuw nsw i64 %iv, 1
; CHECK-NEXT: --> {(1 + %i),+,1}<nuw><nsw><%loop> U: full-set S: full-set Exits: 16 LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @test_guard_uge_16_branches_flipped
; CHECK-NEXT: Loop %loop: backedge-taken count is (15 + (-1 * %i))
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 15
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (15 + (-1 * %i))
; CHECK-NEXT: Loop %loop: Trip multiple is 1
;
entry:
%cmp3 = icmp uge i64 %i, 16
br i1 %cmp3, label %exit, label %loop
loop:
%iv = phi i64 [ %iv.next, %loop ], [ %i, %entry ]
%idx = getelementptr inbounds i32, ptr %a, i64 %iv
store i32 1, ptr %idx, align 4
%iv.next = add nuw nsw i64 %iv, 1
%exitcond = icmp eq i64 %iv.next, 16
br i1 %exitcond, label %exit, label %loop
exit:
ret void
}
define void @test_guard_eq_12(ptr nocapture %a, i64 %N) {
; CHECK-LABEL: 'test_guard_eq_12'
; CHECK-NEXT: Classifying expressions for: @test_guard_eq_12
; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,13) S: [0,13) Exits: %N LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %idx = getelementptr inbounds i32, ptr %a, i64 %iv
; CHECK-NEXT: --> {%a,+,4}<nuw><%loop> U: full-set S: full-set Exits: ((4 * %N) + %a) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %iv.next = add nuw nsw i64 %iv, 1
; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,14) S: [1,14) Exits: (1 + %N) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @test_guard_eq_12
; CHECK-NEXT: Loop %loop: backedge-taken count is %N
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 12
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is %N
; CHECK-NEXT: Loop %loop: Trip multiple is 13
;
entry:
%c.1 = icmp eq i64 %N, 12
br i1 %c.1, label %loop, label %exit
loop:
%iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
%idx = getelementptr inbounds i32, ptr %a, i64 %iv
store i32 1, ptr %idx, align 4
%iv.next = add nuw nsw i64 %iv, 1
%exitcond = icmp eq i64 %iv, %N
br i1 %exitcond, label %exit, label %loop
exit:
ret void
}
define void @test_guard_ule_12(ptr nocapture %a, i64 %N) {
; CHECK-LABEL: 'test_guard_ule_12'
; CHECK-NEXT: Classifying expressions for: @test_guard_ule_12
; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,13) S: [0,13) Exits: %N LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %idx = getelementptr inbounds i32, ptr %a, i64 %iv
; CHECK-NEXT: --> {%a,+,4}<nuw><%loop> U: full-set S: full-set Exits: ((4 * %N) + %a) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %iv.next = add nuw nsw i64 %iv, 1
; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,14) S: [1,14) Exits: (1 + %N) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @test_guard_ule_12
; CHECK-NEXT: Loop %loop: backedge-taken count is %N
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 12
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is %N
; CHECK-NEXT: Loop %loop: Trip multiple is 1
;
entry:
%c.1 = icmp ule i64 %N, 12
br i1 %c.1, label %loop, label %exit
loop:
%iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
%idx = getelementptr inbounds i32, ptr %a, i64 %iv
store i32 1, ptr %idx, align 4
%iv.next = add nuw nsw i64 %iv, 1
%exitcond = icmp eq i64 %iv, %N
br i1 %exitcond, label %exit, label %loop
exit:
ret void
}
define void @test_guard_ule_12_step2(ptr nocapture %a, i64 %N) {
; CHECK-LABEL: 'test_guard_ule_12_step2'
; CHECK-NEXT: Classifying expressions for: @test_guard_ule_12_step2
; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
; CHECK-NEXT: --> {0,+,2}<nuw><nsw><%loop> U: [0,13) S: [0,13) Exits: (2 * (%N /u 2))<nuw> LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %idx = getelementptr inbounds i32, ptr %a, i64 %iv
; CHECK-NEXT: --> {%a,+,8}<nuw><%loop> U: full-set S: full-set Exits: ((8 * (%N /u 2)) + %a) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %iv.next = add nuw nsw i64 %iv, 2
; CHECK-NEXT: --> {2,+,2}<nuw><nsw><%loop> U: [2,15) S: [2,15) Exits: (2 + (2 * (%N /u 2))<nuw>) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @test_guard_ule_12_step2
; CHECK-NEXT: Loop %loop: backedge-taken count is (%N /u 2)
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 6
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (%N /u 2)
; CHECK-NEXT: Loop %loop: Trip multiple is 1
;
entry:
%c.1 = icmp ule i64 %N, 12
br i1 %c.1, label %loop, label %exit
loop:
%iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
%idx = getelementptr inbounds i32, ptr %a, i64 %iv
store i32 1, ptr %idx, align 4
%iv.next = add nuw nsw i64 %iv, 2
%exitcond = icmp eq i64 %iv, %N
br i1 %exitcond, label %exit, label %loop
exit:
ret void
}
define void @test_multiple_const_guards_order1(ptr nocapture %a, i64 %i) {
; CHECK-LABEL: 'test_multiple_const_guards_order1'
; CHECK-NEXT: Classifying expressions for: @test_multiple_const_guards_order1
; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,10) S: [0,10) Exits: %i LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %idx = getelementptr inbounds i32, ptr %a, i64 %iv
; CHECK-NEXT: --> {%a,+,4}<nuw><%loop> U: full-set S: full-set Exits: ((4 * %i) + %a) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %iv.next = add nuw nsw i64 %iv, 1
; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,11) S: [1,11) Exits: (1 + %i) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @test_multiple_const_guards_order1
; CHECK-NEXT: Loop %loop: backedge-taken count is %i
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 9
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is %i
; CHECK-NEXT: Loop %loop: Trip multiple is 1
;
entry:
%c.1 = icmp ult i64 %i, 16
br i1 %c.1, label %guardbb, label %exit
guardbb:
%c.2 = icmp ult i64 %i, 10
br i1 %c.2, label %loop, label %exit
loop:
%iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
%idx = getelementptr inbounds i32, ptr %a, i64 %iv
store i32 1, ptr %idx, align 4
%iv.next = add nuw nsw i64 %iv, 1
%exitcond = icmp eq i64 %iv, %i
br i1 %exitcond, label %exit, label %loop
exit:
ret void
}
define void @test_multiple_const_guards_order2(ptr nocapture %a, i64 %i) {
; CHECK-LABEL: 'test_multiple_const_guards_order2'
; CHECK-NEXT: Classifying expressions for: @test_multiple_const_guards_order2
; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,10) S: [0,10) Exits: %i LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %idx = getelementptr inbounds i32, ptr %a, i64 %iv
; CHECK-NEXT: --> {%a,+,4}<nuw><%loop> U: full-set S: full-set Exits: ((4 * %i) + %a) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %iv.next = add nuw nsw i64 %iv, 1
; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,11) S: [1,11) Exits: (1 + %i) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @test_multiple_const_guards_order2
; CHECK-NEXT: Loop %loop: backedge-taken count is %i
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 9
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is %i
; CHECK-NEXT: Loop %loop: Trip multiple is 1
;
entry:
%c.1 = icmp ult i64 %i, 10
br i1 %c.1, label %guardbb, label %exit
guardbb:
%c.2 = icmp ult i64 %i, 16
br i1 %c.2, label %loop, label %exit
loop:
%iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
%idx = getelementptr inbounds i32, ptr %a, i64 %iv
store i32 1, ptr %idx, align 4
%iv.next = add nuw nsw i64 %iv, 1
%exitcond = icmp eq i64 %iv, %i
br i1 %exitcond, label %exit, label %loop
exit:
ret void
}
define void @test_multiple_var_guards_order1(ptr nocapture %a, i64 %i, i64 %N) {
; CHECK-LABEL: 'test_multiple_var_guards_order1'
; CHECK-NEXT: Classifying expressions for: @test_multiple_var_guards_order1
; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,11) S: [0,11) Exits: %i LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %idx = getelementptr inbounds i32, ptr %a, i64 %iv
; CHECK-NEXT: --> {%a,+,4}<nuw><%loop> U: full-set S: full-set Exits: ((4 * %i) + %a) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %iv.next = add nuw nsw i64 %iv, 1
; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,12) S: [1,12) Exits: (1 + %i) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @test_multiple_var_guards_order1
; CHECK-NEXT: Loop %loop: backedge-taken count is %i
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 10
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is %i
; CHECK-NEXT: Loop %loop: Trip multiple is 1
;
entry:
%c.1 = icmp ult i64 %N, 12
br i1 %c.1, label %guardbb, label %exit
guardbb:
%c.2 = icmp ult i64 %i, %N
br i1 %c.2, label %loop, label %exit
loop:
%iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
%idx = getelementptr inbounds i32, ptr %a, i64 %iv
store i32 1, ptr %idx, align 4
%iv.next = add nuw nsw i64 %iv, 1
%exitcond = icmp eq i64 %iv, %i
br i1 %exitcond, label %exit, label %loop
exit:
ret void
}
define void @test_multiple_var_guards_order2(ptr nocapture %a, i64 %i, i64 %N) {
; CHECK-LABEL: 'test_multiple_var_guards_order2'
; CHECK-NEXT: Classifying expressions for: @test_multiple_var_guards_order2
; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,11) S: [0,11) Exits: %i LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %idx = getelementptr inbounds i32, ptr %a, i64 %iv
; CHECK-NEXT: --> {%a,+,4}<nuw><%loop> U: full-set S: full-set Exits: ((4 * %i) + %a) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %iv.next = add nuw nsw i64 %iv, 1
; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,12) S: [1,12) Exits: (1 + %i) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @test_multiple_var_guards_order2
; CHECK-NEXT: Loop %loop: backedge-taken count is %i
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 10
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is %i
; CHECK-NEXT: Loop %loop: Trip multiple is 1
;
entry:
%c.1 = icmp ult i64 %i, %N
br i1 %c.1, label %guardbb, label %exit
guardbb:
%c.2 = icmp ult i64 %N, 12
br i1 %c.2, label %loop, label %exit
loop:
%iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
%idx = getelementptr inbounds i32, ptr %a, i64 %iv
store i32 1, ptr %idx, align 4
%iv.next = add nuw nsw i64 %iv, 1
%exitcond = icmp eq i64 %iv, %i
br i1 %exitcond, label %exit, label %loop
exit:
ret void
}
; The guards here reference each other in a cycle.
define void @test_multiple_var_guards_cycle(ptr nocapture %a, i64 %i, i64 %N) {
; CHECK-LABEL: 'test_multiple_var_guards_cycle'
; CHECK-NEXT: Classifying expressions for: @test_multiple_var_guards_cycle
; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,-9223372036854775808) S: [0,-9223372036854775808) Exits: %N LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %idx = getelementptr inbounds i32, ptr %a, i64 %iv
; CHECK-NEXT: --> {%a,+,4}<nuw><%loop> U: full-set S: full-set Exits: ((4 * %N) + %a) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %iv.next = add nuw nsw i64 %iv, 1
; CHECK-NEXT: --> {1,+,1}<nuw><%loop> U: [1,-1) S: [1,-1) Exits: (1 + %N) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @test_multiple_var_guards_cycle
; CHECK-NEXT: Loop %loop: backedge-taken count is %N
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 -3
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is %N
; CHECK-NEXT: Loop %loop: Trip multiple is 1
;
entry:
%c.1 = icmp ult i64 %N, %i
br i1 %c.1, label %guardbb, label %exit
guardbb:
%c.2 = icmp ult i64 %i, %N
br i1 %c.2, label %loop, label %exit
loop:
%iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
%idx = getelementptr inbounds i32, ptr %a, i64 %iv
store i32 1, ptr %idx, align 4
%iv.next = add nuw nsw i64 %iv, 1
%exitcond = icmp eq i64 %iv, %N
br i1 %exitcond, label %exit, label %loop
exit:
ret void
}
define void @test_guard_ult_ne(ptr nocapture readonly %data, i64 %count) {
; CHECK-LABEL: 'test_guard_ult_ne'
; CHECK-NEXT: Classifying expressions for: @test_guard_ult_ne
; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,4) S: [0,4) Exits: (-1 + %count) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %idx = getelementptr inbounds i32, ptr %data, i64 %iv
; CHECK-NEXT: --> {%data,+,4}<nuw><%loop> U: full-set S: full-set Exits: (-4 + (4 * %count) + %data) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %iv.next = add nuw i64 %iv, 1
; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,5) S: [1,5) Exits: %count LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @test_guard_ult_ne
; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %count)
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 3
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %count)
; CHECK-NEXT: Loop %loop: Trip multiple is 1
;
entry:
%cmp.ult = icmp ult i64 %count, 5
br i1 %cmp.ult, label %guardbb, label %exit
guardbb:
%cmp.ne = icmp ne i64 %count, 0
br i1 %cmp.ne, label %loop, label %exit
loop:
%iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
%idx = getelementptr inbounds i32, ptr %data, i64 %iv
store i32 1, ptr %idx, align 4
%iv.next = add nuw i64 %iv, 1
%exitcond.not = icmp eq i64 %iv.next, %count
br i1 %exitcond.not, label %exit, label %loop
exit:
ret void
}
define void @test_guard_ne_ult(ptr nocapture readonly %data, i64 %count) {
; CHECK-LABEL: 'test_guard_ne_ult'
; CHECK-NEXT: Classifying expressions for: @test_guard_ne_ult
; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,4) S: [0,4) Exits: (-1 + %count) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %idx = getelementptr inbounds i32, ptr %data, i64 %iv
; CHECK-NEXT: --> {%data,+,4}<nuw><%loop> U: full-set S: full-set Exits: (-4 + (4 * %count) + %data) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %iv.next = add nuw i64 %iv, 1
; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,5) S: [1,5) Exits: %count LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @test_guard_ne_ult
; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %count)
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 3
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %count)
; CHECK-NEXT: Loop %loop: Trip multiple is 1
;
entry:
%cmp.ne = icmp ne i64 %count, 0
br i1 %cmp.ne, label %guardbb, label %exit
guardbb:
%cmp.ult = icmp ult i64 %count, 5
br i1 %cmp.ult, label %loop, label %exit
loop:
%iv = phi i64 [ %iv.next, %loop ], [ 0, %guardbb ]
%idx = getelementptr inbounds i32, ptr %data, i64 %iv
store i32 1, ptr %idx, align 4
%iv.next = add nuw i64 %iv, 1
%exitcond.not = icmp eq i64 %iv.next, %count
br i1 %exitcond.not, label %exit, label %loop
exit:
ret void
}
define void @test_guard_if_and_enter(ptr nocapture readonly %data, i64 %count) {
; CHECK-LABEL: 'test_guard_if_and_enter'
; CHECK-NEXT: Classifying expressions for: @test_guard_if_and_enter
; CHECK-NEXT: %cmp.and = and i1 %cmp.ult, %cmp.ne
; CHECK-NEXT: --> (%cmp.ult umin %cmp.ne) U: full-set S: full-set
; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,4) S: [0,4) Exits: (-1 + %count) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %idx = getelementptr inbounds i32, ptr %data, i64 %iv
; CHECK-NEXT: --> {%data,+,4}<nuw><%loop> U: full-set S: full-set Exits: (-4 + (4 * %count) + %data) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %iv.next = add nuw i64 %iv, 1
; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,5) S: [1,5) Exits: %count LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @test_guard_if_and_enter
; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %count)
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 3
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %count)
; CHECK-NEXT: Loop %loop: Trip multiple is 1
;
entry:
%cmp.ult = icmp ult i64 %count, 5
%cmp.ne = icmp ne i64 %count, 0
%cmp.and = and i1 %cmp.ult, %cmp.ne
br i1 %cmp.and, label %loop, label %exit
loop:
%iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
%idx = getelementptr inbounds i32, ptr %data, i64 %iv
store i32 1, ptr %idx, align 4
%iv.next = add nuw i64 %iv, 1
%exitcond.not = icmp eq i64 %iv.next, %count
br i1 %exitcond.not, label %exit, label %loop
exit:
ret void
}
define void @test_guard_if_and_skip(ptr nocapture readonly %data, i64 %count) {
; CHECK-LABEL: 'test_guard_if_and_skip'
; CHECK-NEXT: Classifying expressions for: @test_guard_if_and_skip
; CHECK-NEXT: %cmp.and = and i1 %cmp.ult, %cmp.ne
; CHECK-NEXT: --> (%cmp.ult umin %cmp.ne) U: full-set S: full-set
; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
; CHECK-NEXT: --> {0,+,1}<nuw><%loop> U: full-set S: full-set Exits: (-1 + %count) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %idx = getelementptr inbounds i32, ptr %data, i64 %iv
; CHECK-NEXT: --> {%data,+,4}<%loop> U: full-set S: full-set Exits: (-4 + (4 * %count) + %data) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %iv.next = add nuw i64 %iv, 1
; CHECK-NEXT: --> {1,+,1}<nuw><%loop> U: [1,0) S: [1,0) Exits: %count LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @test_guard_if_and_skip
; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %count)
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 -1
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %count)
; CHECK-NEXT: Loop %loop: Trip multiple is 1
;
entry:
%cmp.ult = icmp ult i64 %count, 5
%cmp.ne = icmp ne i64 %count, 0
%cmp.and = and i1 %cmp.ult, %cmp.ne
br i1 %cmp.and, label %exit, label %loop
loop:
%iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
%idx = getelementptr inbounds i32, ptr %data, i64 %iv
store i32 1, ptr %idx, align 4
%iv.next = add nuw i64 %iv, 1
%exitcond.not = icmp eq i64 %iv.next, %count
br i1 %exitcond.not, label %exit, label %loop
exit:
ret void
}
define void @test_guard_if_and_and(ptr nocapture readonly %data, i64 %count, i1 %c) {
; CHECK-LABEL: 'test_guard_if_and_and'
; CHECK-NEXT: Classifying expressions for: @test_guard_if_and_and
; CHECK-NEXT: %cmp.and1 = and i1 %c, %cmp.ne
; CHECK-NEXT: --> (%c umin %cmp.ne) U: full-set S: full-set
; CHECK-NEXT: %cmp.and = and i1 %cmp.ult, %cmp.and1
; CHECK-NEXT: --> (%c umin %cmp.ult umin %cmp.ne) U: full-set S: full-set
; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,4) S: [0,4) Exits: (-1 + %count) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %idx = getelementptr inbounds i32, ptr %data, i64 %iv
; CHECK-NEXT: --> {%data,+,4}<nuw><%loop> U: full-set S: full-set Exits: (-4 + (4 * %count) + %data) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %iv.next = add nuw i64 %iv, 1
; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,5) S: [1,5) Exits: %count LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @test_guard_if_and_and
; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %count)
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 3
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %count)
; CHECK-NEXT: Loop %loop: Trip multiple is 1
;
entry:
%cmp.ult = icmp ult i64 %count, 5
%cmp.ne = icmp ne i64 %count, 0
%cmp.and1 = and i1 %c, %cmp.ne
%cmp.and = and i1 %cmp.ult, %cmp.and1
br i1 %cmp.and, label %loop, label %exit
loop:
%iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
%idx = getelementptr inbounds i32, ptr %data, i64 %iv
store i32 1, ptr %idx, align 4
%iv.next = add nuw i64 %iv, 1
%exitcond.not = icmp eq i64 %iv.next, %count
br i1 %exitcond.not, label %exit, label %loop
exit:
ret void
}
define void @test_guard_if_and_or(ptr nocapture readonly %data, i64 %count, i1 %c) {
; CHECK-LABEL: 'test_guard_if_and_or'
; CHECK-NEXT: Classifying expressions for: @test_guard_if_and_or
; CHECK-NEXT: %cmp.or = or i1 %c, %cmp.ne
; CHECK-NEXT: --> (%c umax %cmp.ne) U: full-set S: full-set
; CHECK-NEXT: %cmp.and = and i1 %cmp.ult, %cmp.or
; CHECK-NEXT: --> ((%c umax %cmp.ne) umin %cmp.ult) U: full-set S: full-set
; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
; CHECK-NEXT: --> {0,+,1}<nuw><%loop> U: full-set S: full-set Exits: (-1 + %count) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %idx = getelementptr inbounds i32, ptr %data, i64 %iv
; CHECK-NEXT: --> {%data,+,4}<%loop> U: full-set S: full-set Exits: (-4 + (4 * %count) + %data) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %iv.next = add nuw i64 %iv, 1
; CHECK-NEXT: --> {1,+,1}<nuw><%loop> U: [1,0) S: [1,0) Exits: %count LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @test_guard_if_and_or
; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %count)
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 -1
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %count)
; CHECK-NEXT: Loop %loop: Trip multiple is 1
;
entry:
%cmp.ult = icmp ult i64 %count, 5
%cmp.ne = icmp ne i64 %count, 0
%cmp.or = or i1 %c, %cmp.ne
%cmp.and = and i1 %cmp.ult, %cmp.or
br i1 %cmp.and, label %loop, label %exit
loop:
%iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
%idx = getelementptr inbounds i32, ptr %data, i64 %iv
store i32 1, ptr %idx, align 4
%iv.next = add nuw i64 %iv, 1
%exitcond.not = icmp eq i64 %iv.next, %count
br i1 %exitcond.not, label %exit, label %loop
exit:
ret void
}
define void @test_guard_if_or_skip(ptr nocapture readonly %data, i64 %count) {
; CHECK-LABEL: 'test_guard_if_or_skip'
; CHECK-NEXT: Classifying expressions for: @test_guard_if_or_skip
; CHECK-NEXT: %cmp.or = or i1 %cmp.uge, %cmp.eq
; CHECK-NEXT: --> (%cmp.uge umax %cmp.eq) U: full-set S: full-set
; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,4) S: [0,4) Exits: (-1 + %count) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %idx = getelementptr inbounds i32, ptr %data, i64 %iv
; CHECK-NEXT: --> {%data,+,4}<nuw><%loop> U: full-set S: full-set Exits: (-4 + (4 * %count) + %data) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %iv.next = add nuw i64 %iv, 1
; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,5) S: [1,5) Exits: %count LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @test_guard_if_or_skip
; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %count)
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 3
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %count)
; CHECK-NEXT: Loop %loop: Trip multiple is 1
;
entry:
%cmp.uge = icmp uge i64 %count, 5
%cmp.eq = icmp eq i64 %count, 0
%cmp.or = or i1 %cmp.uge, %cmp.eq
br i1 %cmp.or, label %exit, label %loop
loop:
%iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
%idx = getelementptr inbounds i32, ptr %data, i64 %iv
store i32 1, ptr %idx, align 4
%iv.next = add nuw i64 %iv, 1
%exitcond.not = icmp eq i64 %iv.next, %count
br i1 %exitcond.not, label %exit, label %loop
exit:
ret void
}
define void @test_guard_if_or_enter(ptr nocapture readonly %data, i64 %count) {
; CHECK-LABEL: 'test_guard_if_or_enter'
; CHECK-NEXT: Classifying expressions for: @test_guard_if_or_enter
; CHECK-NEXT: %cmp.or = or i1 %cmp.uge, %cmp.eq
; CHECK-NEXT: --> (%cmp.uge umax %cmp.eq) U: full-set S: full-set
; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
; CHECK-NEXT: --> {0,+,1}<nuw><%loop> U: full-set S: full-set Exits: (-1 + %count) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %idx = getelementptr inbounds i32, ptr %data, i64 %iv
; CHECK-NEXT: --> {%data,+,4}<%loop> U: full-set S: full-set Exits: (-4 + (4 * %count) + %data) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %iv.next = add nuw i64 %iv, 1
; CHECK-NEXT: --> {1,+,1}<nuw><%loop> U: [1,0) S: [1,0) Exits: %count LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @test_guard_if_or_enter
; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %count)
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 -1
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %count)
; CHECK-NEXT: Loop %loop: Trip multiple is 1
;
entry:
%cmp.uge = icmp uge i64 %count, 5
%cmp.eq = icmp eq i64 %count, 0
%cmp.or = or i1 %cmp.uge, %cmp.eq
br i1 %cmp.or, label %loop, label %exit
loop:
%iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
%idx = getelementptr inbounds i32, ptr %data, i64 %iv
store i32 1, ptr %idx, align 4
%iv.next = add nuw i64 %iv, 1
%exitcond.not = icmp eq i64 %iv.next, %count
br i1 %exitcond.not, label %exit, label %loop
exit:
ret void
}
define void @test_guard_if_or_or(ptr nocapture readonly %data, i64 %count, i1 %c) {
; CHECK-LABEL: 'test_guard_if_or_or'
; CHECK-NEXT: Classifying expressions for: @test_guard_if_or_or
; CHECK-NEXT: %cmp.or1 = or i1 %c, %cmp.eq
; CHECK-NEXT: --> (%c umax %cmp.eq) U: full-set S: full-set
; CHECK-NEXT: %cmp.or = or i1 %cmp.uge, %cmp.or1
; CHECK-NEXT: --> (%c umax %cmp.uge umax %cmp.eq) U: full-set S: full-set
; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,4) S: [0,4) Exits: (-1 + %count) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %idx = getelementptr inbounds i32, ptr %data, i64 %iv
; CHECK-NEXT: --> {%data,+,4}<nuw><%loop> U: full-set S: full-set Exits: (-4 + (4 * %count) + %data) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %iv.next = add nuw i64 %iv, 1
; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,5) S: [1,5) Exits: %count LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @test_guard_if_or_or
; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %count)
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 3
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %count)
; CHECK-NEXT: Loop %loop: Trip multiple is 1
;
entry:
%cmp.uge = icmp uge i64 %count, 5
%cmp.eq = icmp eq i64 %count, 0
%cmp.or1 = or i1 %c, %cmp.eq
%cmp.or = or i1 %cmp.uge, %cmp.or1
br i1 %cmp.or, label %exit, label %loop
loop:
%iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
%idx = getelementptr inbounds i32, ptr %data, i64 %iv
store i32 1, ptr %idx, align 4
%iv.next = add nuw i64 %iv, 1
%exitcond.not = icmp eq i64 %iv.next, %count
br i1 %exitcond.not, label %exit, label %loop
exit:
ret void
}
define void @test_guard_if_or_and(ptr nocapture readonly %data, i64 %count, i1 %c) {
; CHECK-LABEL: 'test_guard_if_or_and'
; CHECK-NEXT: Classifying expressions for: @test_guard_if_or_and
; CHECK-NEXT: %cmp.and = and i1 %c, %cmp.eq
; CHECK-NEXT: --> (%c umin %cmp.eq) U: full-set S: full-set
; CHECK-NEXT: %cmp.or = or i1 %cmp.uge, %cmp.and
; CHECK-NEXT: --> ((%c umin %cmp.eq) umax %cmp.uge) U: full-set S: full-set
; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
; CHECK-NEXT: --> {0,+,1}<nuw><%loop> U: full-set S: full-set Exits: (-1 + %count) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %idx = getelementptr inbounds i32, ptr %data, i64 %iv
; CHECK-NEXT: --> {%data,+,4}<%loop> U: full-set S: full-set Exits: (-4 + (4 * %count) + %data) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %iv.next = add nuw i64 %iv, 1
; CHECK-NEXT: --> {1,+,1}<nuw><%loop> U: [1,0) S: [1,0) Exits: %count LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @test_guard_if_or_and
; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %count)
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 -1
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %count)
; CHECK-NEXT: Loop %loop: Trip multiple is 1
;
entry:
%cmp.uge = icmp uge i64 %count, 5
%cmp.eq = icmp eq i64 %count, 0
%cmp.and = and i1 %c, %cmp.eq
%cmp.or = or i1 %cmp.uge, %cmp.and
br i1 %cmp.or, label %exit, label %loop
loop:
%iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
%idx = getelementptr inbounds i32, ptr %data, i64 %iv
store i32 1, ptr %idx, align 4
%iv.next = add nuw i64 %iv, 1
%exitcond.not = icmp eq i64 %iv.next, %count
br i1 %exitcond.not, label %exit, label %loop
exit:
ret void
}
; Test case for PR47247. Both the guard condition and the assume limit the
; constant max backedge-taken count.
define void @test_guard_and_assume(ptr nocapture readonly %data, i64 %count) {
; CHECK-LABEL: 'test_guard_and_assume'
; CHECK-NEXT: Classifying expressions for: @test_guard_and_assume
; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,4) S: [0,4) Exits: (-1 + %count) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %idx = getelementptr inbounds i32, ptr %data, i64 %iv
; CHECK-NEXT: --> {%data,+,4}<nuw><%loop> U: full-set S: full-set Exits: (-4 + (4 * %count) + %data) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %iv.next = add nuw i64 %iv, 1
; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,5) S: [1,5) Exits: %count LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @test_guard_and_assume
; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %count)
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 3
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %count)
; CHECK-NEXT: Loop %loop: Trip multiple is 1
;
entry:
%cmp = icmp ult i64 %count, 5
tail call void @llvm.assume(i1 %cmp)
%cmp18.not = icmp eq i64 %count, 0
br i1 %cmp18.not, label %exit, label %loop
loop:
%iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
%idx = getelementptr inbounds i32, ptr %data, i64 %iv
store i32 1, ptr %idx, align 4
%iv.next = add nuw i64 %iv, 1
%exitcond.not = icmp eq i64 %iv.next, %count
br i1 %exitcond.not, label %exit, label %loop
exit:
ret void
}
define void @test_guard_assume_and(ptr nocapture readonly %data, i64 %count) {
; CHECK-LABEL: 'test_guard_assume_and'
; CHECK-NEXT: Classifying expressions for: @test_guard_assume_and
; CHECK-NEXT: %cmp.and = and i1 %cmp.ult, %cmp.ne
; CHECK-NEXT: --> (%cmp.ult umin %cmp.ne) U: full-set S: full-set
; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,4) S: [0,4) Exits: (-1 + %count) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %idx = getelementptr inbounds i32, ptr %data, i64 %iv
; CHECK-NEXT: --> {%data,+,4}<nuw><%loop> U: full-set S: full-set Exits: (-4 + (4 * %count) + %data) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %iv.next = add nuw i64 %iv, 1
; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,5) S: [1,5) Exits: %count LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @test_guard_assume_and
; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %count)
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 3
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %count)
; CHECK-NEXT: Loop %loop: Trip multiple is 1
;
entry:
%cmp.ult = icmp ult i64 %count, 5
%cmp.ne = icmp ne i64 %count, 0
%cmp.and = and i1 %cmp.ult, %cmp.ne
call void @llvm.assume(i1 %cmp.and)
br label %loop
loop:
%iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
%idx = getelementptr inbounds i32, ptr %data, i64 %iv
store i32 1, ptr %idx, align 4
%iv.next = add nuw i64 %iv, 1
%exitcond.not = icmp eq i64 %iv.next, %count
br i1 %exitcond.not, label %exit, label %loop
exit:
ret void
}
; Function Attrs: nounwind willreturn
declare void @llvm.assume(i1 noundef)
define void @guard_pessimizes_analysis_step1(i1 %c, i32 %N) {
; CHECK-LABEL: 'guard_pessimizes_analysis_step1'
; CHECK-NEXT: Classifying expressions for: @guard_pessimizes_analysis_step1
; CHECK-NEXT: %init = phi i32 [ 2, %entry ], [ 3, %bb1 ]
; CHECK-NEXT: --> %init U: [2,4) S: [2,4)
; CHECK-NEXT: %iv = phi i32 [ %iv.next, %loop ], [ %init, %loop.ph ]
; CHECK-NEXT: --> {%init,+,1}<nuw><nsw><%loop> U: [2,11) S: [2,11) Exits: 9 LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %iv.next = add i32 %iv, 1
; CHECK-NEXT: --> {(1 + %init)<nuw><nsw>,+,1}<nuw><nsw><%loop> U: [3,12) S: [3,12) Exits: 10 LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @guard_pessimizes_analysis_step1
; CHECK-NEXT: Loop %loop: backedge-taken count is (9 + (-1 * %init)<nsw>)<nsw>
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 7
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (9 + (-1 * %init)<nsw>)<nsw>
; CHECK-NEXT: Loop %loop: Trip multiple is 1
;
entry:
br i1 %c, label %bb1, label %guard
bb1:
br label %guard
guard:
%init = phi i32 [ 2, %entry ], [ 3, %bb1 ]
%c.1 = icmp ult i32 %init, %N
br i1 %c.1, label %loop.ph, label %exit
loop.ph:
br label %loop
loop:
%iv = phi i32 [ %iv.next, %loop ], [ %init, %loop.ph ]
%iv.next = add i32 %iv, 1
%exitcond = icmp eq i32 %iv.next, 10
br i1 %exitcond, label %exit, label %loop
exit:
ret void
}
define void @guard_pessimizes_analysis_step2(i1 %c, i32 %N) {
; CHECK-LABEL: 'guard_pessimizes_analysis_step2'
; CHECK-NEXT: Classifying expressions for: @guard_pessimizes_analysis_step2
; CHECK-NEXT: %init = phi i32 [ 2, %entry ], [ 3, %bb1 ]
; CHECK-NEXT: --> %init U: [2,4) S: [2,4)
; CHECK-NEXT: %iv = phi i32 [ %iv.next, %loop ], [ %init, %loop.ph ]
; CHECK-NEXT: --> {%init,+,2}<nuw><nsw><%loop> U: [2,10) S: [2,10) Exits: ((2 * ((8 + (-1 * %init)<nsw>)<nsw> /u 2))<nuw><nsw> + %init) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %iv.next = add nuw nsw i32 %iv, 2
; CHECK-NEXT: --> {(2 + %init)<nuw><nsw>,+,2}<nuw><nsw><%loop> U: [4,12) S: [4,12) Exits: (2 + (2 * ((8 + (-1 * %init)<nsw>)<nsw> /u 2))<nuw><nsw> + %init) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @guard_pessimizes_analysis_step2
; CHECK-NEXT: Loop %loop: backedge-taken count is ((8 + (-1 * %init)<nsw>)<nsw> /u 2)
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 3
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((8 + (-1 * %init)<nsw>)<nsw> /u 2)
; CHECK-NEXT: Loop %loop: Trip multiple is 1
;
entry:
br i1 %c, label %bb1, label %guard
bb1:
br label %guard
guard:
%init = phi i32 [ 2, %entry ], [ 3, %bb1 ]
%c.1 = icmp ult i32 %init, %N
br i1 %c.1, label %loop.ph, label %exit
loop.ph:
br label %loop
loop:
%iv = phi i32 [ %iv.next, %loop ], [ %init, %loop.ph ]
%iv.next = add nuw nsw i32 %iv, 2
%exitcond = icmp eq i32 %iv.next, 10
br i1 %exitcond, label %exit, label %loop
exit:
ret void
}
define void @crash(ptr %ptr) {
; CHECK-LABEL: 'crash'
; CHECK-NEXT: Classifying expressions for: @crash
; CHECK-NEXT: %text.addr.5 = phi ptr [ %incdec.ptr112, %while.cond111 ], [ null, %while.body ]
; CHECK-NEXT: --> {null,+,-1}<nw><%while.cond111> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %while.cond111: Computable, %while.body: Variant }
; CHECK-NEXT: %incdec.ptr112 = getelementptr inbounds i8, ptr %text.addr.5, i64 -1
; CHECK-NEXT: --> {(-1 + null)<nuw><nsw>,+,-1}<nw><%while.cond111> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %while.cond111: Computable, %while.body: Variant }
; CHECK-NEXT: %lastout.2271 = phi ptr [ %incdec.ptr126, %while.body125 ], [ %ptr, %while.end117 ]
; CHECK-NEXT: --> {%ptr,+,1}<nuw><%while.body125> U: full-set S: full-set Exits: {(-2 + (-1 * (ptrtoint ptr %ptr to i64)) + %ptr),+,-1}<nw><%while.cond111> LoopDispositions: { %while.body125: Computable }
; CHECK-NEXT: %incdec.ptr126 = getelementptr inbounds i8, ptr %lastout.2271, i64 1
; CHECK-NEXT: --> {(1 + %ptr),+,1}<nuw><%while.body125> U: full-set S: full-set Exits: {(-1 + (-1 * (ptrtoint ptr %ptr to i64)) + %ptr),+,-1}<nw><%while.cond111> LoopDispositions: { %while.body125: Computable }
; CHECK-NEXT: Determining loop execution counts for: @crash
; CHECK-NEXT: Loop %while.body125: backedge-taken count is {(-2 + (-1 * (ptrtoint ptr %ptr to i64))),+,-1}<nw><%while.cond111>
; CHECK-NEXT: Loop %while.body125: constant max backedge-taken count is i64 -2
; CHECK-NEXT: Loop %while.body125: symbolic max backedge-taken count is {(-2 + (-1 * (ptrtoint ptr %ptr to i64))),+,-1}<nw><%while.cond111>
; CHECK-NEXT: Loop %while.body125: Trip multiple is 1
; CHECK-NEXT: Loop %while.cond111: Unpredictable backedge-taken count.
; CHECK-NEXT: Loop %while.cond111: Unpredictable constant max backedge-taken count.
; CHECK-NEXT: Loop %while.cond111: Unpredictable symbolic max backedge-taken count.
; CHECK-NEXT: Loop %while.body: Unpredictable backedge-taken count.
; CHECK-NEXT: Loop %while.body: Unpredictable constant max backedge-taken count.
; CHECK-NEXT: Loop %while.body: Unpredictable symbolic max backedge-taken count.
;
entry:
br label %while.body
while.body:
br label %while.cond111
while.cond111:
%text.addr.5 = phi ptr [ %incdec.ptr112, %while.cond111 ], [ null, %while.body ]
%incdec.ptr112 = getelementptr inbounds i8, ptr %text.addr.5, i64 -1
br i1 false, label %while.end117, label %while.cond111
while.end117:
%cmp118 = icmp ult ptr %ptr, %incdec.ptr112
br i1 %cmp118, label %while.body125, label %while.cond134.preheader
while.cond134.preheader:
br label %while.body
while.body125:
%lastout.2271 = phi ptr [ %incdec.ptr126, %while.body125 ], [ %ptr, %while.end117 ]
%incdec.ptr126 = getelementptr inbounds i8, ptr %lastout.2271, i64 1
%exitcond.not = icmp eq ptr %incdec.ptr126, %incdec.ptr112
br i1 %exitcond.not, label %while.end129, label %while.body125
while.end129: ; preds = %while.body125
ret void
}
define void @test_guard_uge(i32 %blockSize) {
; CHECK-LABEL: 'test_guard_uge'
; CHECK-NEXT: Classifying expressions for: @test_guard_uge
; CHECK-NEXT: %shr = lshr i32 %blockSize, 2
; CHECK-NEXT: --> (%blockSize /u 4) U: [0,1073741824) S: [0,1073741824)
; CHECK-NEXT: %iv = phi i32 [ %dec, %while.body ], [ %shr, %while.body.preheader ]
; CHECK-NEXT: --> {(%blockSize /u 4),+,-1}<nsw><%while.body> U: [-1073741822,1073741824) S: [-1073741822,1073741824) Exits: 1 LoopDispositions: { %while.body: Computable }
; CHECK-NEXT: %dec = add i32 %iv, -1
; CHECK-NEXT: --> {(-1 + (%blockSize /u 4))<nsw>,+,-1}<nsw><%while.body> U: [-1073741823,1073741823) S: [-1073741823,1073741823) Exits: 0 LoopDispositions: { %while.body: Computable }
; CHECK-NEXT: Determining loop execution counts for: @test_guard_uge
; CHECK-NEXT: Loop %while.body: backedge-taken count is (-1 + (%blockSize /u 4))<nsw>
; CHECK-NEXT: Loop %while.body: constant max backedge-taken count is i32 1073741822
; CHECK-NEXT: Loop %while.body: symbolic max backedge-taken count is (-1 + (%blockSize /u 4))<nsw>
; CHECK-NEXT: Loop %while.body: Trip multiple is 1
;
%shr = lshr i32 %blockSize, 2
%guard = icmp uge i32 %blockSize, 4
br i1 %guard, label %while.body.preheader, label %while.end
while.body.preheader:
br label %while.body
while.body:
%iv = phi i32 [ %dec, %while.body ], [ %shr, %while.body.preheader ]
%dec = add i32 %iv, -1
%cmp.not = icmp eq i32 %dec, 0
br i1 %cmp.not, label %while.end.loopexit, label %while.body
while.end.loopexit:
br label %while.end
while.end:
ret void
}
define void @test_guard_ugt(i32 %blockSize) {
; CHECK-LABEL: 'test_guard_ugt'
; CHECK-NEXT: Classifying expressions for: @test_guard_ugt
; CHECK-NEXT: %shr = lshr i32 %blockSize, 2
; CHECK-NEXT: --> (%blockSize /u 4) U: [0,1073741824) S: [0,1073741824)
; CHECK-NEXT: %iv = phi i32 [ %dec, %while.body ], [ %shr, %while.body.preheader ]
; CHECK-NEXT: --> {(%blockSize /u 4),+,-1}<nsw><%while.body> U: [-1073741822,1073741824) S: [-1073741822,1073741824) Exits: 1 LoopDispositions: { %while.body: Computable }
; CHECK-NEXT: %dec = add i32 %iv, -1
; CHECK-NEXT: --> {(-1 + (%blockSize /u 4))<nsw>,+,-1}<nsw><%while.body> U: [-1073741823,1073741823) S: [-1073741823,1073741823) Exits: 0 LoopDispositions: { %while.body: Computable }
; CHECK-NEXT: Determining loop execution counts for: @test_guard_ugt
; CHECK-NEXT: Loop %while.body: backedge-taken count is (-1 + (%blockSize /u 4))<nsw>
; CHECK-NEXT: Loop %while.body: constant max backedge-taken count is i32 1073741822
; CHECK-NEXT: Loop %while.body: symbolic max backedge-taken count is (-1 + (%blockSize /u 4))<nsw>
; CHECK-NEXT: Loop %while.body: Trip multiple is 1
;
%shr = lshr i32 %blockSize, 2
%guard = icmp ugt i32 %blockSize, 3
br i1 %guard, label %while.body.preheader, label %while.end
while.body.preheader:
br label %while.body
while.body:
%iv = phi i32 [ %dec, %while.body ], [ %shr, %while.body.preheader ]
%dec = add i32 %iv, -1
%cmp.not = icmp eq i32 %dec, 0
br i1 %cmp.not, label %while.end.loopexit, label %while.body
while.end.loopexit:
br label %while.end
while.end:
ret void
}
define void @test_guard_uge_and_ule(i32 %blockSize) {
; CHECK-LABEL: 'test_guard_uge_and_ule'
; CHECK-NEXT: Classifying expressions for: @test_guard_uge_and_ule
; CHECK-NEXT: %shr = lshr i32 %blockSize, 2
; CHECK-NEXT: --> (%blockSize /u 4) U: [0,1073741824) S: [0,1073741824)
; CHECK-NEXT: %iv = phi i32 [ %dec, %while.body ], [ %shr, %while.body.preheader ]
; CHECK-NEXT: --> {(%blockSize /u 4),+,-1}<nsw><%while.body> U: [-255,1073741824) S: [-255,1073741824) Exits: 1 LoopDispositions: { %while.body: Computable }
; CHECK-NEXT: %dec = add i32 %iv, -1
; CHECK-NEXT: --> {(-1 + (%blockSize /u 4))<nsw>,+,-1}<nsw><%while.body> U: [-256,1073741823) S: [-256,1073741823) Exits: 0 LoopDispositions: { %while.body: Computable }
; CHECK-NEXT: Determining loop execution counts for: @test_guard_uge_and_ule
; CHECK-NEXT: Loop %while.body: backedge-taken count is (-1 + (%blockSize /u 4))<nsw>
; CHECK-NEXT: Loop %while.body: constant max backedge-taken count is i32 255
; CHECK-NEXT: Loop %while.body: symbolic max backedge-taken count is (-1 + (%blockSize /u 4))<nsw>
; CHECK-NEXT: Loop %while.body: Trip multiple is 1
;
%shr = lshr i32 %blockSize, 2
%guard1 = icmp uge i32 %blockSize, 4
br i1 %guard1, label %while.guard, label %while.end
while.guard:
%guard2 = icmp ule i32 %blockSize, 1024
br i1 %guard2, label %while.body.preheader, label %while.end
while.body.preheader:
br label %while.body
while.body:
%iv = phi i32 [ %dec, %while.body ], [ %shr, %while.body.preheader ]
%dec = add i32 %iv, -1
%cmp.not = icmp eq i32 %dec, 0
br i1 %cmp.not, label %while.end.loopexit, label %while.body
while.end.loopexit:
br label %while.end
while.end:
ret void
}
define void @test_guard_ugt_and_ult(i32 %blockSize) {
; CHECK-LABEL: 'test_guard_ugt_and_ult'
; CHECK-NEXT: Classifying expressions for: @test_guard_ugt_and_ult
; CHECK-NEXT: %shr = lshr i32 %blockSize, 2
; CHECK-NEXT: --> (%blockSize /u 4) U: [0,1073741824) S: [0,1073741824)
; CHECK-NEXT: %iv = phi i32 [ %dec, %while.body ], [ %shr, %while.body.preheader ]
; CHECK-NEXT: --> {(%blockSize /u 4),+,-1}<nsw><%while.body> U: [-255,1073741824) S: [-255,1073741824) Exits: 1 LoopDispositions: { %while.body: Computable }
; CHECK-NEXT: %dec = add i32 %iv, -1
; CHECK-NEXT: --> {(-1 + (%blockSize /u 4))<nsw>,+,-1}<nsw><%while.body> U: [-256,1073741823) S: [-256,1073741823) Exits: 0 LoopDispositions: { %while.body: Computable }
; CHECK-NEXT: Determining loop execution counts for: @test_guard_ugt_and_ult
; CHECK-NEXT: Loop %while.body: backedge-taken count is (-1 + (%blockSize /u 4))<nsw>
; CHECK-NEXT: Loop %while.body: constant max backedge-taken count is i32 255
; CHECK-NEXT: Loop %while.body: symbolic max backedge-taken count is (-1 + (%blockSize /u 4))<nsw>
; CHECK-NEXT: Loop %while.body: Trip multiple is 1
;
%shr = lshr i32 %blockSize, 2
%guard1 = icmp ugt i32 %blockSize, 3
br i1 %guard1, label %while.guard, label %while.end
while.guard:
%guard2 = icmp ult i32 %blockSize, 1025
br i1 %guard2, label %while.body.preheader, label %while.end
while.body.preheader:
br label %while.body
while.body:
%iv = phi i32 [ %dec, %while.body ], [ %shr, %while.body.preheader ]
%dec = add i32 %iv, -1
%cmp.not = icmp eq i32 %dec, 0
br i1 %cmp.not, label %while.end.loopexit, label %while.body
while.end.loopexit:
br label %while.end
while.end:
ret void
}
define void @test_guard_slt_sgt_1(ptr nocapture %a, i64 %N) {
; CHECK-LABEL: 'test_guard_slt_sgt_1'
; CHECK-NEXT: Classifying expressions for: @test_guard_slt_sgt_1
; CHECK-NEXT: %and = and i1 %c.0, %c.1
; CHECK-NEXT: --> (%c.0 umin %c.1) U: full-set S: full-set
; CHECK-NEXT: %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,11) S: [0,11) Exits: (-1 + %N) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %idx = getelementptr inbounds i32, ptr %a, i64 %iv
; CHECK-NEXT: --> {%a,+,4}<nuw><%loop> U: full-set S: full-set Exits: (-4 + (4 * %N) + %a) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %iv.next = add nuw nsw i64 %iv, 1
; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,12) S: [1,12) Exits: %N LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @test_guard_slt_sgt_1
; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %N)
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 10
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %N)
; CHECK-NEXT: Loop %loop: Trip multiple is 1
;
entry:
%c.0 = icmp slt i64 %N, 12
%c.1 = icmp sgt i64 %N, 0
%and = and i1 %c.0, %c.1
br i1 %and, label %loop, label %exit
loop:
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
%idx = getelementptr inbounds i32, ptr %a, i64 %iv
store i32 1, ptr %idx, align 4
%iv.next = add nuw nsw i64 %iv, 1
%exitcond = icmp eq i64 %iv.next, %N
br i1 %exitcond, label %exit, label %loop
exit:
ret void
}
define void @test_guard_slt_sgt_2(ptr nocapture %a, i64 %i) {
; CHECK-LABEL: 'test_guard_slt_sgt_2'
; CHECK-NEXT: Classifying expressions for: @test_guard_slt_sgt_2
; CHECK-NEXT: %and = and i1 %c.0, %c.1
; CHECK-NEXT: --> (%c.0 umin %c.1) U: full-set S: full-set
; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ %i, %entry ]
; CHECK-NEXT: --> {%i,+,1}<nuw><nsw><%loop> U: full-set S: full-set Exits: 17 LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %idx = getelementptr inbounds i32, ptr %a, i64 %iv
; CHECK-NEXT: --> {((4 * %i) + %a),+,4}<%loop> U: full-set S: full-set Exits: (68 + %a) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %iv.next = add nuw nsw i64 %iv, 1
; CHECK-NEXT: --> {(1 + %i),+,1}<nuw><nsw><%loop> U: full-set S: full-set Exits: 18 LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @test_guard_slt_sgt_2
; CHECK-NEXT: Loop %loop: backedge-taken count is (17 + (-1 * %i))
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 12
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (17 + (-1 * %i))
; CHECK-NEXT: Loop %loop: Trip multiple is 1
;
entry:
%c.0 = icmp slt i64 %i, 16
%c.1 = icmp sgt i64 %i, 4
%and = and i1 %c.0, %c.1
br i1 %and, label %loop, label %exit
loop:
%iv = phi i64 [ %iv.next, %loop ], [ %i, %entry ]
%idx = getelementptr inbounds i32, ptr %a, i64 %iv
store i32 1, ptr %idx, align 4
%iv.next = add nuw nsw i64 %iv, 1
%exitcond = icmp eq i64 %iv.next, 18
br i1 %exitcond, label %exit, label %loop
exit:
ret void
}
define void @test_guard_sle_sge_1(ptr nocapture %a, i64 %N) {
; CHECK-LABEL: 'test_guard_sle_sge_1'
; CHECK-NEXT: Classifying expressions for: @test_guard_sle_sge_1
; CHECK-NEXT: %and = and i1 %c.0, %c.1
; CHECK-NEXT: --> (%c.0 umin %c.1) U: full-set S: full-set
; CHECK-NEXT: %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,12) S: [0,12) Exits: (-1 + %N) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %idx = getelementptr inbounds i32, ptr %a, i64 %iv
; CHECK-NEXT: --> {%a,+,4}<nuw><%loop> U: full-set S: full-set Exits: (-4 + (4 * %N) + %a) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %iv.next = add nuw nsw i64 %iv, 1
; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,13) S: [1,13) Exits: %N LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @test_guard_sle_sge_1
; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %N)
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 11
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %N)
; CHECK-NEXT: Loop %loop: Trip multiple is 1
;
entry:
%c.0 = icmp sle i64 %N, 12
%c.1 = icmp sge i64 %N, 1
%and = and i1 %c.0, %c.1
br i1 %and, label %loop, label %exit
loop:
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
%idx = getelementptr inbounds i32, ptr %a, i64 %iv
store i32 1, ptr %idx, align 4
%iv.next = add nuw nsw i64 %iv, 1
%exitcond = icmp eq i64 %iv.next, %N
br i1 %exitcond, label %exit, label %loop
exit:
ret void
}
define void @test_guard_sle_sge_2(ptr nocapture %a, i64 %i) {
; CHECK-LABEL: 'test_guard_sle_sge_2'
; CHECK-NEXT: Classifying expressions for: @test_guard_sle_sge_2
; CHECK-NEXT: %and = and i1 %c.0, %c.1
; CHECK-NEXT: --> (%c.0 umin %c.1) U: full-set S: full-set
; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ %i, %entry ]
; CHECK-NEXT: --> {%i,+,1}<nuw><nsw><%loop> U: full-set S: full-set Exits: 17 LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %idx = getelementptr inbounds i32, ptr %a, i64 %iv
; CHECK-NEXT: --> {((4 * %i) + %a),+,4}<%loop> U: full-set S: full-set Exits: (68 + %a) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %iv.next = add nuw nsw i64 %iv, 1
; CHECK-NEXT: --> {(1 + %i),+,1}<nuw><nsw><%loop> U: full-set S: full-set Exits: 18 LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @test_guard_sle_sge_2
; CHECK-NEXT: Loop %loop: backedge-taken count is (17 + (-1 * %i))
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 13
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (17 + (-1 * %i))
; CHECK-NEXT: Loop %loop: Trip multiple is 1
;
entry:
%c.0 = icmp sle i64 %i, 16
%c.1 = icmp sge i64 %i, 4
%and = and i1 %c.0, %c.1
br i1 %and, label %loop, label %exit
loop:
%iv = phi i64 [ %iv.next, %loop ], [ %i, %entry ]
%idx = getelementptr inbounds i32, ptr %a, i64 %iv
store i32 1, ptr %idx, align 4
%iv.next = add nuw nsw i64 %iv, 1
%exitcond = icmp eq i64 %iv.next, 18
br i1 %exitcond, label %exit, label %loop
exit:
ret void
}
; The function below uses a single condition to ensure %N > 0 && %N < 8.
; InstCombine transforms such checks with 2 conditions to a single check as in
; the test function.
define void @optimized_range_check_unsigned(ptr %pred, i32 %N) {
; CHECK-LABEL: 'optimized_range_check_unsigned'
; CHECK-NEXT: Classifying expressions for: @optimized_range_check_unsigned
; CHECK-NEXT: %N.off = add i32 %N, -1
; CHECK-NEXT: --> (-1 + %N) U: full-set S: full-set
; CHECK-NEXT: %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,7) S: [0,7) Exits: (-1 + %N) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %gep = getelementptr inbounds i16, ptr %pred, i32 %iv
; CHECK-NEXT: --> {%pred,+,2}<nuw><%loop> U: full-set S: full-set Exits: ((2 * (zext i32 (-1 + %N) to i64))<nuw><nsw> + %pred) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %iv.next = add nuw nsw i32 %iv, 1
; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,8) S: [1,8) Exits: %N LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @optimized_range_check_unsigned
; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %N)
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 6
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %N)
; CHECK-NEXT: Loop %loop: Trip multiple is 1
;
entry:
%N.off = add i32 %N, -1
%cmp = icmp ult i32 %N.off, 7
br i1 %cmp, label %loop, label %exit
loop:
%iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
%gep = getelementptr inbounds i16, ptr %pred, i32 %iv
store i16 0, ptr %gep, align 2
%iv.next = add nuw nsw i32 %iv, 1
%ec = icmp eq i32 %iv.next, %N
br i1 %ec, label %exit, label %loop
exit:
ret void
}
; Same as @optimized_range_check_unsigned, but with the icmp operands swapped.
define void @optimized_range_check_unsigned_icmp_ops_swapped(ptr %pred, i32 %N) {
; CHECK-LABEL: 'optimized_range_check_unsigned_icmp_ops_swapped'
; CHECK-NEXT: Classifying expressions for: @optimized_range_check_unsigned_icmp_ops_swapped
; CHECK-NEXT: %N.off = add i32 %N, -1
; CHECK-NEXT: --> (-1 + %N) U: full-set S: full-set
; CHECK-NEXT: %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,7) S: [0,7) Exits: (-1 + %N) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %gep = getelementptr inbounds i16, ptr %pred, i32 %iv
; CHECK-NEXT: --> {%pred,+,2}<nuw><%loop> U: full-set S: full-set Exits: ((2 * (zext i32 (-1 + %N) to i64))<nuw><nsw> + %pred) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %iv.next = add nuw nsw i32 %iv, 1
; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,8) S: [1,8) Exits: %N LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @optimized_range_check_unsigned_icmp_ops_swapped
; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %N)
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 6
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %N)
; CHECK-NEXT: Loop %loop: Trip multiple is 1
;
entry:
%N.off = add i32 %N, -1
%cmp = icmp ugt i32 7, %N.off
br i1 %cmp, label %loop, label %exit
loop:
%iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
%gep = getelementptr inbounds i16, ptr %pred, i32 %iv
store i16 0, ptr %gep, align 2
%iv.next = add nuw nsw i32 %iv, 1
%ec = icmp eq i32 %iv.next, %N
br i1 %ec, label %exit, label %loop
exit:
ret void
}
; The function below uses a single condition to ensure %N > 2 && %N < 22.
; InstCombine transforms such checks with 2 conditions to a single check as in
; the test function.
define void @optimized_range_check_unsigned2(ptr %pred, i32 %N) {
; CHECK-LABEL: 'optimized_range_check_unsigned2'
; CHECK-NEXT: Classifying expressions for: @optimized_range_check_unsigned2
; CHECK-NEXT: %N.off = add i32 %N, -2
; CHECK-NEXT: --> (-2 + %N) U: full-set S: full-set
; CHECK-NEXT: %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,21) S: [0,21) Exits: (-1 + %N) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %gep = getelementptr inbounds i16, ptr %pred, i32 %iv
; CHECK-NEXT: --> {%pred,+,2}<nuw><%loop> U: full-set S: full-set Exits: ((2 * (zext i32 (-1 + %N) to i64))<nuw><nsw> + %pred) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %iv.next = add nuw nsw i32 %iv, 1
; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,22) S: [1,22) Exits: %N LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @optimized_range_check_unsigned2
; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %N)
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 20
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %N)
; CHECK-NEXT: Loop %loop: Trip multiple is 1
;
entry:
%N.off = add i32 %N, -2
%cmp = icmp ult i32 %N.off, 20
br i1 %cmp, label %loop, label %exit
loop:
%iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
%gep = getelementptr inbounds i16, ptr %pred, i32 %iv
store i16 0, ptr %gep, align 2
%iv.next = add nuw nsw i32 %iv, 1
%ec = icmp eq i32 %iv.next, %N
br i1 %ec, label %exit, label %loop
exit:
ret void
}
; Same as @optimized_range_check_unsigned, but %N already has a range limited
; to [2,4) beforehand.
define void @optimized_range_check_unsigned3(ptr %pred, i1 %c) {
; CHECK-LABEL: 'optimized_range_check_unsigned3'
; CHECK-NEXT: Classifying expressions for: @optimized_range_check_unsigned3
; CHECK-NEXT: %N = select i1 %c, i32 2, i32 3
; CHECK-NEXT: --> %N U: [2,4) S: [2,4)
; CHECK-NEXT: %N.off = add i32 %N, -1
; CHECK-NEXT: --> (-1 + %N)<nsw> U: [1,3) S: [1,3)
; CHECK-NEXT: %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,3) S: [0,3) Exits: (-1 + %N)<nsw> LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %gep = getelementptr inbounds i16, ptr %pred, i32 %iv
; CHECK-NEXT: --> {%pred,+,2}<nuw><%loop> U: full-set S: full-set Exits: ((2 * (zext i32 (-1 + %N)<nsw> to i64))<nuw><nsw> + %pred) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %iv.next = add nuw nsw i32 %iv, 1
; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,4) S: [1,4) Exits: %N LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @optimized_range_check_unsigned3
; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %N)<nsw>
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 2
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %N)<nsw>
; CHECK-NEXT: Loop %loop: Trip multiple is 1
;
entry:
%N = select i1 %c, i32 2, i32 3
%N.off = add i32 %N, -1
%cmp = icmp ult i32 %N.off, 7
br i1 %cmp, label %loop, label %exit
loop:
%iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
%gep = getelementptr inbounds i16, ptr %pred, i32 %iv
store i16 0, ptr %gep, align 2
%iv.next = add nuw nsw i32 %iv, 1
%ec = icmp eq i32 %iv.next, %N
br i1 %ec, label %exit, label %loop
exit:
ret void
}
; Similar to @optimized_range_check_unsigned, but the initial compare checks
; against unsigned max (-1), which breaks the range check idiom.
define void @not_optimized_range_check_unsigned1(ptr %pred, i32 %N) {
; CHECK-LABEL: 'not_optimized_range_check_unsigned1'
; CHECK-NEXT: Classifying expressions for: @not_optimized_range_check_unsigned1
; CHECK-NEXT: %N.off = add i32 %N, -1
; CHECK-NEXT: --> (-1 + %N) U: full-set S: full-set
; CHECK-NEXT: %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,-2147483648) S: [0,-2147483648) Exits: (-1 + %N) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %gep = getelementptr inbounds i16, ptr %pred, i32 %iv
; CHECK-NEXT: --> {%pred,+,2}<nuw><%loop> U: full-set S: full-set Exits: ((2 * (zext i32 (-1 + %N) to i64))<nuw><nsw> + %pred) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %iv.next = add nuw nsw i32 %iv, 1
; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,-2147483648) S: [1,-2147483648) Exits: %N LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @not_optimized_range_check_unsigned1
; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %N)
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 -2
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %N)
; CHECK-NEXT: Loop %loop: Trip multiple is 1
;
entry:
%N.off = add i32 %N, -1
%cmp = icmp ult i32 %N.off, -1
br i1 %cmp, label %loop, label %exit
loop:
%iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
%gep = getelementptr inbounds i16, ptr %pred, i32 %iv
store i16 0, ptr %gep, align 2
%iv.next = add nuw nsw i32 %iv, 1
%ec = icmp eq i32 %iv.next, %N
br i1 %ec, label %exit, label %loop
exit:
ret void
}
; Similar to @optimized_range_check_unsigned, but the initial compare checks
; against 0, which breaks the range check idiom.
define void @not_optimized_range_check_unsigned2(ptr %pred, i32 %N) {
; CHECK-LABEL: 'not_optimized_range_check_unsigned2'
; CHECK-NEXT: Classifying expressions for: @not_optimized_range_check_unsigned2
; CHECK-NEXT: %N.off = add i32 %N, -1
; CHECK-NEXT: --> (-1 + %N) U: full-set S: full-set
; CHECK-NEXT: %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,-2147483648) S: [0,-2147483648) Exits: (-1 + %N) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %gep = getelementptr inbounds i16, ptr %pred, i32 %iv
; CHECK-NEXT: --> {%pred,+,2}<nuw><%loop> U: full-set S: full-set Exits: ((2 * (zext i32 (-1 + %N) to i64))<nuw><nsw> + %pred) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %iv.next = add nuw nsw i32 %iv, 1
; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,-2147483648) S: [1,-2147483648) Exits: %N LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @not_optimized_range_check_unsigned2
; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %N)
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 -2
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %N)
; CHECK-NEXT: Loop %loop: Trip multiple is 1
;
entry:
%N.off = add i32 %N, -1
%cmp = icmp ult i32 %N.off, 0
br i1 %cmp, label %loop, label %exit
loop:
%iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
%gep = getelementptr inbounds i16, ptr %pred, i32 %iv
store i16 0, ptr %gep, align 2
%iv.next = add nuw nsw i32 %iv, 1
%ec = icmp eq i32 %iv.next, %N
br i1 %ec, label %exit, label %loop
exit:
ret void
}
define i32 @sle_sgt_ult_umax_to_smax(i32 %num) {
; CHECK-LABEL: 'sle_sgt_ult_umax_to_smax'
; CHECK-NEXT: Classifying expressions for: @sle_sgt_ult_umax_to_smax
; CHECK-NEXT: %iv = phi i32 [ 0, %guard.3 ], [ %iv.next, %loop ]
; CHECK-NEXT: --> {0,+,4}<nuw><nsw><%loop> U: [0,25) S: [0,25) Exits: (4 * ((-4 + %num) /u 4))<nuw> LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %iv.next = add nuw i32 %iv, 4
; CHECK-NEXT: --> {4,+,4}<nuw><nsw><%loop> U: [4,29) S: [4,29) Exits: (4 + (4 * ((-4 + %num) /u 4))<nuw>) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @sle_sgt_ult_umax_to_smax
; CHECK-NEXT: Loop %loop: backedge-taken count is ((-4 + %num) /u 4)
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 6
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-4 + %num) /u 4)
; CHECK-NEXT: Loop %loop: Trip multiple is 1
;
guard.1:
%cmp.1 = icmp sle i32 %num, 0
br i1 %cmp.1, label %exit, label %guard.2
guard.2:
%cmp.2 = icmp sgt i32 %num, 28
br i1 %cmp.2, label %exit, label %guard.3
guard.3:
%cmp.3 = icmp ult i32 %num, 4
br i1 %cmp.3, label %exit, label %loop
loop:
%iv = phi i32 [ 0, %guard.3 ], [ %iv.next, %loop ]
%iv.next = add nuw i32 %iv, 4
%ec = icmp eq i32 %iv.next, %num
br i1 %ec, label %exit, label %loop
exit:
ret i32 0
}
; Similar to @sle_sgt_ult_umax_to_smax but with different predicate order.
define i32 @ult_sle_sgt_umax_to_smax(i32 %num) {
; CHECK-LABEL: 'ult_sle_sgt_umax_to_smax'
; CHECK-NEXT: Classifying expressions for: @ult_sle_sgt_umax_to_smax
; CHECK-NEXT: %iv = phi i32 [ 0, %guard.3 ], [ %iv.next, %loop ]
; CHECK-NEXT: --> {0,+,4}<nuw><%loop> U: [0,-3) S: [-2147483648,2147483645) Exits: (4 * ((-4 + %num) /u 4))<nuw> LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %iv.next = add nuw i32 %iv, 4
; CHECK-NEXT: --> {4,+,4}<nuw><%loop> U: [4,-3) S: [-2147483648,2147483645) Exits: (4 + (4 * ((-4 + %num) /u 4))<nuw>) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @ult_sle_sgt_umax_to_smax
; CHECK-NEXT: Loop %loop: backedge-taken count is ((-4 + %num) /u 4)
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 1073741823
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-4 + %num) /u 4)
; CHECK-NEXT: Loop %loop: Trip multiple is 1
;
guard.1:
%cmp.1 = icmp ult i32 %num, 4
br i1 %cmp.1, label %exit, label %guard.2
guard.2:
%cmp.2 = icmp sgt i32 %num, 28
br i1 %cmp.2, label %exit, label %guard.3
guard.3:
%cmp.3 = icmp sle i32 %num, 0
br i1 %cmp.3, label %exit, label %loop
loop:
%iv = phi i32 [ 0, %guard.3 ], [ %iv.next, %loop ]
%iv.next = add nuw i32 %iv, 4
%ec = icmp eq i32 %iv.next, %num
br i1 %ec, label %exit, label %loop
exit:
ret i32 0
}
define i32 @ptr_induction_ult_1(ptr %a, ptr %b) {
; CHECK-LABEL: 'ptr_induction_ult_1'
; CHECK-NEXT: Classifying expressions for: @ptr_induction_ult_1
; CHECK-NEXT: %ptr.iv = phi ptr [ %ptr.iv.next, %loop ], [ %a, %entry ]
; CHECK-NEXT: --> {%a,+,4}<nw><%loop> U: full-set S: full-set Exits: %a LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %ptr.iv.next = getelementptr i32, ptr %ptr.iv, i64 1
; CHECK-NEXT: --> {(4 + %a),+,4}<nw><%loop> U: full-set S: full-set Exits: (4 + %a) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @ptr_induction_ult_1
; CHECK-NEXT: Loop %loop: backedge-taken count is i64 0
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 0
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is i64 0
; CHECK-NEXT: Loop %loop: Trip multiple is 1
;
entry:
%cmp.6 = icmp ult ptr %a, %b
br i1 %cmp.6, label %loop, label %exit
loop:
%ptr.iv = phi ptr [ %ptr.iv.next, %loop ], [ %a, %entry ]
%ptr.iv.next = getelementptr i32, ptr %ptr.iv, i64 1
%exitcond = icmp eq ptr %ptr.iv, %a
br i1 %exitcond, label %exit, label %loop
exit:
ret i32 0
}
define void @ptr_induction_eq_1(ptr %a, ptr %b) {
; CHECK-LABEL: 'ptr_induction_eq_1'
; CHECK-NEXT: Classifying expressions for: @ptr_induction_eq_1
; CHECK-NEXT: %ptr.iv = phi ptr [ %ptr.iv.next, %loop ], [ %a, %entry ]
; CHECK-NEXT: --> {%a,+,8}<nuw><%loop> U: full-set S: full-set Exits: ((8 * ((-8 + (-1 * (ptrtoint ptr %a to i64)) + (ptrtoint ptr %b to i64)) /u 8))<nuw> + %a) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %ptr.iv.next = getelementptr inbounds i8, ptr %ptr.iv, i64 8
; CHECK-NEXT: --> {(8 + %a),+,8}<nuw><%loop> U: full-set S: full-set Exits: (8 + (8 * ((-8 + (-1 * (ptrtoint ptr %a to i64)) + (ptrtoint ptr %b to i64)) /u 8))<nuw> + %a) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @ptr_induction_eq_1
; CHECK-NEXT: Loop %loop: backedge-taken count is ((-8 + (-1 * (ptrtoint ptr %a to i64)) + (ptrtoint ptr %b to i64)) /u 8)
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 2305843009213693951
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-8 + (-1 * (ptrtoint ptr %a to i64)) + (ptrtoint ptr %b to i64)) /u 8)
; CHECK-NEXT: Loop %loop: Trip multiple is 1
;
entry:
%cmp = icmp eq ptr %a, %b
br i1 %cmp, label %exit, label %loop
loop:
%ptr.iv = phi ptr [ %ptr.iv.next, %loop ], [ %a, %entry ]
%ptr.iv.next = getelementptr inbounds i8, ptr %ptr.iv, i64 8
%exitcond = icmp eq ptr %ptr.iv.next, %b
br i1 %exitcond, label %exit, label %loop
exit:
ret void
}
define void @ptr_induction_eq_2(ptr %a, i64 %n) {
; CHECK-LABEL: 'ptr_induction_eq_2'
; CHECK-NEXT: Classifying expressions for: @ptr_induction_eq_2
; CHECK-NEXT: %b = getelementptr inbounds ptr, ptr %a, i64 %n
; CHECK-NEXT: --> ((8 * %n)<nsw> + %a) U: full-set S: full-set
; CHECK-NEXT: %ptr.iv = phi ptr [ %ptr.iv.next, %loop ], [ %a, %entry ]
; CHECK-NEXT: --> {%a,+,8}<nuw><%loop> U: full-set S: full-set Exits: ((8 * ((-8 + (8 * %n)<nsw>) /u 8))<nuw> + %a) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %ptr.iv.next = getelementptr inbounds i8, ptr %ptr.iv, i64 8
; CHECK-NEXT: --> {(8 + %a),+,8}<nuw><%loop> U: full-set S: full-set Exits: (8 + (8 * ((-8 + (8 * %n)<nsw>) /u 8))<nuw> + %a) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @ptr_induction_eq_2
; CHECK-NEXT: Loop %loop: backedge-taken count is ((-8 + (8 * %n)<nsw>) /u 8)
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 2305843009213693951
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-8 + (8 * %n)<nsw>) /u 8)
; CHECK-NEXT: Loop %loop: Trip multiple is 1
;
entry:
%b = getelementptr inbounds ptr, ptr %a, i64 %n
%cmp = icmp eq ptr %a, %b
br i1 %cmp, label %exit, label %loop
loop:
%ptr.iv = phi ptr [ %ptr.iv.next, %loop ], [ %a, %entry ]
%ptr.iv.next = getelementptr inbounds i8, ptr %ptr.iv, i64 8
%exitcond = icmp eq ptr %ptr.iv.next, %b
br i1 %exitcond, label %exit, label %loop
exit:
ret void
}
define void @ptr_induction_early_exit_eq_1_with_align_on_load(ptr %a, ptr %b, ptr %c) {
; CHECK-LABEL: 'ptr_induction_early_exit_eq_1_with_align_on_load'
; CHECK-NEXT: Classifying expressions for: @ptr_induction_early_exit_eq_1_with_align_on_load
; CHECK-NEXT: %a_ = load ptr, ptr %a, align 8, !align !0
; CHECK-NEXT: --> %a_ U: [0,-7) S: [-9223372036854775808,9223372036854775801)
; CHECK-NEXT: %b_ = load ptr, ptr %b, align 8, !align !0
; CHECK-NEXT: --> %b_ U: [0,-7) S: [-9223372036854775808,9223372036854775801)
; CHECK-NEXT: %ptr.iv = phi ptr [ %ptr.iv.next, %loop.inc ], [ %a_, %entry ]
; CHECK-NEXT: --> {%a_,+,8}<nuw><%loop> U: [0,-7) S: [-9223372036854775808,9223372036854775801) Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %ld1 = load ptr, ptr %ptr.iv, align 8
; CHECK-NEXT: --> %ld1 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
; CHECK-NEXT: %ptr.iv.next = getelementptr inbounds i8, ptr %ptr.iv, i64 8
; CHECK-NEXT: --> {(8 + %a_),+,8}<nw><%loop> U: [0,-7) S: [-9223372036854775808,9223372036854775801) Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @ptr_induction_early_exit_eq_1_with_align_on_load
; CHECK-NEXT: Loop %loop: <multiple exits> Unpredictable backedge-taken count.
; CHECK-NEXT: exit count for loop: ***COULDNOTCOMPUTE***
; CHECK-NEXT: exit count for loop.inc: ((-8 + (-1 * (ptrtoint ptr %a_ to i64)) + (ptrtoint ptr %b_ to i64)) /u 8)
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 2305843009213693951
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-8 + (-1 * (ptrtoint ptr %a_ to i64)) + (ptrtoint ptr %b_ to i64)) /u 8)
; CHECK-NEXT: symbolic max exit count for loop: ***COULDNOTCOMPUTE***
; CHECK-NEXT: symbolic max exit count for loop.inc: ((-8 + (-1 * (ptrtoint ptr %a_ to i64)) + (ptrtoint ptr %b_ to i64)) /u 8)
;
entry:
%a_ = load ptr, ptr %a, !align !{i64 8}
%b_ = load ptr, ptr %b, !align !{i64 8}
%cmp = icmp eq ptr %a_, %b_
br i1 %cmp, label %exit, label %loop
loop:
%ptr.iv = phi ptr [ %ptr.iv.next, %loop.inc ], [ %a_, %entry ]
%ld1 = load ptr, ptr %ptr.iv, align 8
%earlyexitcond = icmp eq ptr %ld1, %c
br i1 %earlyexitcond, label %exit, label %loop.inc
loop.inc:
%ptr.iv.next = getelementptr inbounds i8, ptr %ptr.iv, i64 8
%exitcond = icmp eq ptr %ptr.iv.next, %b_
br i1 %exitcond, label %exit, label %loop
exit:
ret void
}
define void @ptr_induction_early_exit_eq_1_with_align_on_arguments(ptr align 8 %a, ptr align 8 %b, ptr %c) {
; CHECK-LABEL: 'ptr_induction_early_exit_eq_1_with_align_on_arguments'
; CHECK-NEXT: Classifying expressions for: @ptr_induction_early_exit_eq_1_with_align_on_arguments
; CHECK-NEXT: %ptr.iv = phi ptr [ %ptr.iv.next, %loop.inc ], [ %a, %entry ]
; CHECK-NEXT: --> {%a,+,8}<nuw><%loop> U: [0,-7) S: [-9223372036854775808,9223372036854775801) Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %ld1 = load ptr, ptr %ptr.iv, align 8
; CHECK-NEXT: --> %ld1 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
; CHECK-NEXT: %ptr.iv.next = getelementptr inbounds i8, ptr %ptr.iv, i64 8
; CHECK-NEXT: --> {(8 + %a),+,8}<nw><%loop> U: [0,-7) S: [-9223372036854775808,9223372036854775801) Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @ptr_induction_early_exit_eq_1_with_align_on_arguments
; CHECK-NEXT: Loop %loop: <multiple exits> Unpredictable backedge-taken count.
; CHECK-NEXT: exit count for loop: ***COULDNOTCOMPUTE***
; CHECK-NEXT: exit count for loop.inc: ((-8 + (-1 * (ptrtoint ptr %a to i64)) + (ptrtoint ptr %b to i64)) /u 8)
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 2305843009213693951
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-8 + (-1 * (ptrtoint ptr %a to i64)) + (ptrtoint ptr %b to i64)) /u 8)
; CHECK-NEXT: symbolic max exit count for loop: ***COULDNOTCOMPUTE***
; CHECK-NEXT: symbolic max exit count for loop.inc: ((-8 + (-1 * (ptrtoint ptr %a to i64)) + (ptrtoint ptr %b to i64)) /u 8)
;
entry:
%cmp = icmp eq ptr %a, %b
br i1 %cmp, label %exit, label %loop
loop:
%ptr.iv = phi ptr [ %ptr.iv.next, %loop.inc ], [ %a, %entry ]
%ld1 = load ptr, ptr %ptr.iv, align 8
%earlyexitcond = icmp eq ptr %ld1, %c
br i1 %earlyexitcond, label %exit, label %loop.inc
loop.inc:
%ptr.iv.next = getelementptr inbounds i8, ptr %ptr.iv, i64 8
%exitcond = icmp eq ptr %ptr.iv.next, %b
br i1 %exitcond, label %exit, label %loop
exit:
ret void
}
define void @ptr_induction_early_exit_eq_1_align_assumption_1(ptr %a, ptr %b, ptr %c) {
; CHECK-LABEL: 'ptr_induction_early_exit_eq_1_align_assumption_1'
; CHECK-NEXT: Classifying expressions for: @ptr_induction_early_exit_eq_1_align_assumption_1
; CHECK-NEXT: %a_ = load ptr, ptr %a, align 8
; CHECK-NEXT: --> %a_ U: [0,-7) S: [-9223372036854775808,9223372036854775801)
; CHECK-NEXT: %b_ = load ptr, ptr %b, align 8
; CHECK-NEXT: --> %b_ U: [0,-7) S: [-9223372036854775808,9223372036854775801)
; CHECK-NEXT: %ptr.iv = phi ptr [ %ptr.iv.next, %loop.inc ], [ %a_, %entry ]
; CHECK-NEXT: --> {%a_,+,8}<nuw><%loop> U: [0,-7) S: [-9223372036854775808,9223372036854775801) Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %ld1 = load ptr, ptr %ptr.iv, align 8
; CHECK-NEXT: --> %ld1 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
; CHECK-NEXT: %ptr.iv.next = getelementptr inbounds i8, ptr %ptr.iv, i64 8
; CHECK-NEXT: --> {(8 + %a_),+,8}<nw><%loop> U: [0,-7) S: [-9223372036854775808,9223372036854775801) Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @ptr_induction_early_exit_eq_1_align_assumption_1
; CHECK-NEXT: Loop %loop: <multiple exits> Unpredictable backedge-taken count.
; CHECK-NEXT: exit count for loop: ***COULDNOTCOMPUTE***
; CHECK-NEXT: exit count for loop.inc: ((-8 + (-1 * (ptrtoint ptr %a_ to i64)) + (ptrtoint ptr %b_ to i64)) /u 8)
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 2305843009213693951
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-8 + (-1 * (ptrtoint ptr %a_ to i64)) + (ptrtoint ptr %b_ to i64)) /u 8)
; CHECK-NEXT: symbolic max exit count for loop: ***COULDNOTCOMPUTE***
; CHECK-NEXT: symbolic max exit count for loop.inc: ((-8 + (-1 * (ptrtoint ptr %a_ to i64)) + (ptrtoint ptr %b_ to i64)) /u 8)
;
entry:
%a_ = load ptr, ptr %a
call void @llvm.assume(i1 true) [ "align"(ptr %a_, i64 8) ]
%b_ = load ptr, ptr %b
call void @llvm.assume(i1 true) [ "align"(ptr %b_, i64 8) ]
%cmp = icmp eq ptr %a_, %b_
br i1 %cmp, label %exit, label %loop
loop:
%ptr.iv = phi ptr [ %ptr.iv.next, %loop.inc ], [ %a_, %entry ]
%ld1 = load ptr, ptr %ptr.iv, align 8
%earlyexitcond = icmp eq ptr %ld1, %c
br i1 %earlyexitcond, label %exit, label %loop.inc
loop.inc:
%ptr.iv.next = getelementptr inbounds i8, ptr %ptr.iv, i64 8
%exitcond = icmp eq ptr %ptr.iv.next, %b_
br i1 %exitcond, label %exit, label %loop
exit:
ret void
}
define void @ptr_induction_early_exit_eq_1_align_assumption_2(ptr %a, ptr %b, ptr %c) {
; CHECK-LABEL: 'ptr_induction_early_exit_eq_1_align_assumption_2'
; CHECK-NEXT: Classifying expressions for: @ptr_induction_early_exit_eq_1_align_assumption_2
; CHECK-NEXT: %a_ = load ptr, ptr %a, align 8
; CHECK-NEXT: --> %a_ U: [0,-7) S: [-9223372036854775808,9223372036854775801)
; CHECK-NEXT: %b_ = load ptr, ptr %b, align 8
; CHECK-NEXT: --> %b_ U: [0,-7) S: [-9223372036854775808,9223372036854775801)
; CHECK-NEXT: %ptr.iv = phi ptr [ %ptr.iv.next, %loop.inc ], [ %a_, %entry ]
; CHECK-NEXT: --> {%a_,+,8}<nuw><%loop> U: [0,-7) S: [-9223372036854775808,9223372036854775801) Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %ld1 = load ptr, ptr %ptr.iv, align 8
; CHECK-NEXT: --> %ld1 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
; CHECK-NEXT: %ptr.iv.next = getelementptr inbounds i8, ptr %ptr.iv, i64 8
; CHECK-NEXT: --> {(8 + %a_),+,8}<nw><%loop> U: [0,-7) S: [-9223372036854775808,9223372036854775801) Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @ptr_induction_early_exit_eq_1_align_assumption_2
; CHECK-NEXT: Loop %loop: <multiple exits> Unpredictable backedge-taken count.
; CHECK-NEXT: exit count for loop: ***COULDNOTCOMPUTE***
; CHECK-NEXT: exit count for loop.inc: ((-8 + (-1 * (ptrtoint ptr %a_ to i64)) + (ptrtoint ptr %b_ to i64)) /u 8)
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 2305843009213693951
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-8 + (-1 * (ptrtoint ptr %a_ to i64)) + (ptrtoint ptr %b_ to i64)) /u 8)
; CHECK-NEXT: symbolic max exit count for loop: ***COULDNOTCOMPUTE***
; CHECK-NEXT: symbolic max exit count for loop.inc: ((-8 + (-1 * (ptrtoint ptr %a_ to i64)) + (ptrtoint ptr %b_ to i64)) /u 8)
;
entry:
%a_ = load ptr, ptr %a
%b_ = load ptr, ptr %b
call void @llvm.assume(i1 true) [ "align"(ptr %a_, i64 8) ]
call void @llvm.assume(i1 true) [ "align"(ptr %b_, i64 8) ]
%cmp = icmp eq ptr %a_, %b_
br i1 %cmp, label %exit, label %loop
loop:
%ptr.iv = phi ptr [ %ptr.iv.next, %loop.inc ], [ %a_, %entry ]
%ld1 = load ptr, ptr %ptr.iv, align 8
%earlyexitcond = icmp eq ptr %ld1, %c
br i1 %earlyexitcond, label %exit, label %loop.inc
loop.inc:
%ptr.iv.next = getelementptr inbounds i8, ptr %ptr.iv, i64 8
%exitcond = icmp eq ptr %ptr.iv.next, %b_
br i1 %exitcond, label %exit, label %loop
exit:
ret void
}
define void @ptr_induction_early_exit_eq_2(ptr %a, i64 %n, ptr %c) {
; CHECK-LABEL: 'ptr_induction_early_exit_eq_2'
; CHECK-NEXT: Classifying expressions for: @ptr_induction_early_exit_eq_2
; CHECK-NEXT: %b = getelementptr inbounds ptr, ptr %a, i64 %n
; CHECK-NEXT: --> ((8 * %n)<nsw> + %a) U: full-set S: full-set
; CHECK-NEXT: %ptr.iv = phi ptr [ %ptr.iv.next, %loop.inc ], [ %a, %entry ]
; CHECK-NEXT: --> {%a,+,8}<nuw><%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %ld1 = load ptr, ptr %ptr.iv, align 8
; CHECK-NEXT: --> %ld1 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
; CHECK-NEXT: %ptr.iv.next = getelementptr inbounds i8, ptr %ptr.iv, i64 8
; CHECK-NEXT: --> {(8 + %a),+,8}<nw><%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @ptr_induction_early_exit_eq_2
; CHECK-NEXT: Loop %loop: <multiple exits> Unpredictable backedge-taken count.
; CHECK-NEXT: exit count for loop: ***COULDNOTCOMPUTE***
; CHECK-NEXT: exit count for loop.inc: ((-8 + (8 * %n)<nsw>) /u 8)
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 2305843009213693951
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-8 + (8 * %n)<nsw>) /u 8)
; CHECK-NEXT: symbolic max exit count for loop: ***COULDNOTCOMPUTE***
; CHECK-NEXT: symbolic max exit count for loop.inc: ((-8 + (8 * %n)<nsw>) /u 8)
;
entry:
%b = getelementptr inbounds ptr, ptr %a, i64 %n
%cmp = icmp eq ptr %a, %b
br i1 %cmp, label %exit, label %loop
loop:
%ptr.iv = phi ptr [ %ptr.iv.next, %loop.inc ], [ %a, %entry ]
%ld1 = load ptr, ptr %ptr.iv, align 8
%earlyexitcond = icmp eq ptr %ld1, %c
br i1 %earlyexitcond, label %exit, label %loop.inc
loop.inc:
%ptr.iv.next = getelementptr inbounds i8, ptr %ptr.iv, i64 8
%exitcond = icmp eq ptr %ptr.iv.next, %b
br i1 %exitcond, label %exit, label %loop
exit:
ret void
}
define void @gep_addrec_nw(ptr %a) {
; CHECK-LABEL: 'gep_addrec_nw'
; CHECK-NEXT: Classifying expressions for: @gep_addrec_nw
; CHECK-NEXT: %lsr.iv1 = phi ptr [ %uglygep2, %for.body ], [ %a, %entry ]
; CHECK-NEXT: --> {%a,+,4}<nw><%for.body> U: full-set S: full-set Exits: (1512 + %a) LoopDispositions: { %for.body: Computable }
; CHECK-NEXT: %lsr.iv = phi i64 [ %lsr.iv.next, %for.body ], [ 379, %entry ]
; CHECK-NEXT: --> {379,+,-1}<nsw><%for.body> U: [1,380) S: [1,380) Exits: 1 LoopDispositions: { %for.body: Computable }
; CHECK-NEXT: %lsr.iv.next = add nsw i64 %lsr.iv, -1
; CHECK-NEXT: --> {378,+,-1}<nsw><%for.body> U: [0,379) S: [0,379) Exits: 0 LoopDispositions: { %for.body: Computable }
; CHECK-NEXT: %uglygep2 = getelementptr i8, ptr %lsr.iv1, i64 4
; CHECK-NEXT: --> {(4 + %a),+,4}<nw><%for.body> U: full-set S: full-set Exits: (1516 + %a) LoopDispositions: { %for.body: Computable }
; CHECK-NEXT: Determining loop execution counts for: @gep_addrec_nw
; CHECK-NEXT: Loop %for.body: backedge-taken count is i64 378
; CHECK-NEXT: Loop %for.body: constant max backedge-taken count is i64 378
; CHECK-NEXT: Loop %for.body: symbolic max backedge-taken count is i64 378
; CHECK-NEXT: Loop %for.body: Trip multiple is 379
;
entry:
br label %for.body
for.body: ; preds = %for.body, %entry
%lsr.iv1 = phi ptr [ %uglygep2, %for.body ], [ %a, %entry ]
%lsr.iv = phi i64 [ %lsr.iv.next, %for.body ], [ 379, %entry ]
store i32 1, ptr %lsr.iv1, align 4
%lsr.iv.next = add nsw i64 %lsr.iv, -1
%uglygep2 = getelementptr i8, ptr %lsr.iv1, i64 4
%exitcond.not = icmp eq i64 %lsr.iv.next, 0
br i1 %exitcond.not, label %for.end, label %for.body
for.end: ; preds = %for.body
ret void
}