| ; 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 |
| |
| 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 |
| } |
| |
| 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 void @const_max_btc_32_or_order_1(i64 %n) { |
| ; CHECK-LABEL: 'const_max_btc_32_or_order_1' |
| ; CHECK-NEXT: Classifying expressions for: @const_max_btc_32_or_order_1 |
| ; CHECK-NEXT: %and.pre = and i1 %pre.1, %pre.0 |
| ; CHECK-NEXT: --> (%pre.1 umin %pre.0) U: full-set S: full-set |
| ; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ 0, %ph ] |
| ; CHECK-NEXT: --> {0,+,1}<nuw><%loop> U: [0,-9223372036854775808) S: [0,-9223372036854775808) Exits: %n LoopDispositions: { %loop: Computable } |
| ; CHECK-NEXT: %iv.next = add i64 %iv, 1 |
| ; CHECK-NEXT: --> {1,+,1}<nuw><%loop> U: [1,-9223372036854775807) S: [1,-9223372036854775807) Exits: (1 + %n) LoopDispositions: { %loop: Computable } |
| ; CHECK-NEXT: Determining loop execution counts for: @const_max_btc_32_or_order_1 |
| ; CHECK-NEXT: Loop %loop: backedge-taken count is %n |
| ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 9223372036854775807 |
| ; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is %n |
| ; CHECK-NEXT: Loop %loop: Trip multiple is 1 |
| ; |
| entry: |
| %pre.0 = icmp slt i64 %n, 33 |
| %pre.1 = icmp ne i64 %n, 0 |
| %and.pre = and i1 %pre.1, %pre.0 |
| br i1 %and.pre, label %ph, label %exit |
| |
| ph: |
| %pre.2 = icmp sgt i64 %n, 0 |
| br i1 %pre.2, label %loop, label %exit |
| |
| loop: |
| %iv = phi i64 [ %iv.next, %loop ], [ 0, %ph ] |
| call void @foo() |
| %iv.next = add i64 %iv, 1 |
| %ec = icmp eq i64 %iv, %n |
| br i1 %ec, label %exit, label %loop |
| |
| exit: |
| ret void |
| } |
| |
| ; Same as @const_max_btc_32_or_order_1, but with operands in the OR swapped. |
| define void @const_max_btc_32_or_order_2(i64 %n) { |
| ; CHECK-LABEL: 'const_max_btc_32_or_order_2' |
| ; CHECK-NEXT: Classifying expressions for: @const_max_btc_32_or_order_2 |
| ; CHECK-NEXT: %and.pre = and i1 %pre.0, %pre.1 |
| ; CHECK-NEXT: --> (%pre.0 umin %pre.1) U: full-set S: full-set |
| ; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ 0, %ph ] |
| ; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,33) S: [0,33) Exits: %n LoopDispositions: { %loop: Computable } |
| ; CHECK-NEXT: %iv.next = add i64 %iv, 1 |
| ; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,34) S: [1,34) Exits: (1 + %n) LoopDispositions: { %loop: Computable } |
| ; CHECK-NEXT: Determining loop execution counts for: @const_max_btc_32_or_order_2 |
| ; CHECK-NEXT: Loop %loop: backedge-taken count is %n |
| ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 32 |
| ; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is %n |
| ; CHECK-NEXT: Loop %loop: Trip multiple is 1 |
| ; |
| entry: |
| %pre.0 = icmp slt i64 %n, 33 |
| %pre.1 = icmp ne i64 %n, 0 |
| %and.pre = and i1 %pre.0, %pre.1 |
| br i1 %and.pre, label %ph, label %exit |
| |
| ph: |
| %pre.2 = icmp sgt i64 %n, 0 |
| br i1 %pre.2, label %loop, label %exit |
| |
| loop: |
| %iv = phi i64 [ %iv.next, %loop ], [ 0, %ph ] |
| call void @foo() |
| %iv.next = add i64 %iv, 1 |
| %ec = icmp eq i64 %iv, %n |
| br i1 %ec, label %exit, label %loop |
| |
| exit: |
| ret void |
| } |
| |
| declare void @foo() |