| ; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 2 |
| ; RUN: opt -passes='print<scalar-evolution>' -disable-output %s 2>&1 | FileCheck %s |
| |
| define void @loop_guard_improves_exact_backedge_taken_count_1(i32 %conv) { |
| ; CHECK-LABEL: 'loop_guard_improves_exact_backedge_taken_count_1' |
| ; CHECK-NEXT: Classifying expressions for: @loop_guard_improves_exact_backedge_taken_count_1 |
| ; CHECK-NEXT: %and = and i32 %conv, 1 |
| ; CHECK-NEXT: --> (zext i1 (trunc i32 %conv to i1) to i32) U: [0,2) S: [0,2) |
| ; CHECK-NEXT: %conv8 = zext i32 %and to i64 |
| ; CHECK-NEXT: --> (zext i1 (trunc i32 %conv to i1) to i64) U: [0,2) S: [0,2) |
| ; CHECK-NEXT: %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] |
| ; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,1) S: [0,1) Exits: 0 LoopDispositions: { %loop: Computable } |
| ; CHECK-NEXT: %iv.next = add i64 %iv, 1 |
| ; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,2) S: [1,2) Exits: 1 LoopDispositions: { %loop: Computable } |
| ; CHECK-NEXT: Determining loop execution counts for: @loop_guard_improves_exact_backedge_taken_count_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: |
| %and = and i32 %conv, 1 |
| %conv8 = zext i32 %and to i64 |
| %c = icmp ugt i32 %and, 0 |
| br i1 %c, label %exit, label %loop |
| |
| loop: |
| %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] |
| call void @clobber() |
| %iv.next = add i64 %iv, 1 |
| %exitcond = icmp eq i64 %iv, %conv8 |
| br i1 %exitcond, label %exit, label %loop |
| |
| exit: |
| ret void |
| } |
| |
| define void @loop_guard_improves_exact_backedge_taken_count_2(i32 %conv) { |
| ; CHECK-LABEL: 'loop_guard_improves_exact_backedge_taken_count_2' |
| ; CHECK-NEXT: Classifying expressions for: @loop_guard_improves_exact_backedge_taken_count_2 |
| ; CHECK-NEXT: %and = and i32 %conv, 1 |
| ; CHECK-NEXT: --> (zext i1 (trunc i32 %conv to i1) to i32) U: [0,2) S: [0,2) |
| ; CHECK-NEXT: %conv8 = zext i32 %and to i64 |
| ; CHECK-NEXT: --> (zext i1 (trunc i32 %conv to i1) to i64) U: [0,2) S: [0,2) |
| ; CHECK-NEXT: %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] |
| ; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,2) S: [0,2) Exits: (zext i1 (trunc i32 %conv to i1) to i64) LoopDispositions: { %loop: Computable } |
| ; CHECK-NEXT: %iv.next = add i64 %iv, 1 |
| ; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,3) S: [1,3) Exits: (1 + (zext i1 (trunc i32 %conv to i1) to i64))<nuw><nsw> LoopDispositions: { %loop: Computable } |
| ; CHECK-NEXT: Determining loop execution counts for: @loop_guard_improves_exact_backedge_taken_count_2 |
| ; CHECK-NEXT: Loop %loop: backedge-taken count is (zext i1 (trunc i32 %conv to i1) to i64) |
| ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 1 |
| ; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (zext i1 (trunc i32 %conv to i1) to i64) |
| ; CHECK-NEXT: Loop %loop: Trip multiple is 2 |
| ; |
| entry: |
| %and = and i32 %conv, 1 |
| %conv8 = zext i32 %and to i64 |
| %c = icmp eq i32 %and, 1 |
| br i1 %c, label %loop, label %exit |
| |
| loop: |
| %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] |
| call void @clobber() |
| %iv.next = add i64 %iv, 1 |
| %exitcond = icmp eq i64 %iv, %conv8 |
| br i1 %exitcond, label %exit, label %loop |
| |
| exit: |
| ret void |
| } |
| |
| declare void @use(i32) |
| |
| define void @rewrite_preserve_add_nsw(i32 %a) { |
| ; CHECK-LABEL: 'rewrite_preserve_add_nsw' |
| ; CHECK-NEXT: Classifying expressions for: @rewrite_preserve_add_nsw |
| ; CHECK-NEXT: %add = add nsw i32 %a, 4 |
| ; CHECK-NEXT: --> (4 + %a)<nsw> U: [-2147483644,-2147483648) S: [-2147483644,-2147483648) |
| ; CHECK-NEXT: %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ] |
| ; CHECK-NEXT: --> {0,+,1}<nuw><%loop> U: [0,-2147483648) S: [0,-2147483648) Exits: (4 + %a)<nsw> LoopDispositions: { %loop: Computable } |
| ; CHECK-NEXT: %iv.next = add i32 %iv, 1 |
| ; CHECK-NEXT: --> {1,+,1}<nuw><%loop> U: [1,-2147483647) S: [1,-2147483647) Exits: (5 + %a) LoopDispositions: { %loop: Computable } |
| ; CHECK-NEXT: Determining loop execution counts for: @rewrite_preserve_add_nsw |
| ; CHECK-NEXT: Loop %loop: backedge-taken count is (4 + %a)<nsw> |
| ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 2147483647 |
| ; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (4 + %a)<nsw> |
| ; CHECK-NEXT: Loop %loop: Trip multiple is 1 |
| ; |
| entry: |
| %add = add nsw i32 %a, 4 |
| call void @use(i32 noundef %add) |
| %pre = icmp sgt i32 %a, -4 |
| br i1 %pre, label %loop, label %exit |
| |
| loop: |
| %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ] |
| call void @clobber() |
| %iv.next = add i32 %iv, 1 |
| %ec = icmp slt i32 %iv, %add |
| br i1 %ec, label %loop, label %exit |
| |
| exit: |
| ret void |
| } |
| |
| declare void @clobber() |
| |
| |
| declare void @clobber.i32(i32) |
| |
| define void @test_guards_across_loops(i32 %N) { |
| ; CHECK-LABEL: 'test_guards_across_loops' |
| ; CHECK-NEXT: Classifying expressions for: @test_guards_across_loops |
| ; CHECK-NEXT: %iv.1 = phi i32 [ 0, %entry ], [ %iv.1.next, %loop.1 ] |
| ; CHECK-NEXT: --> {0,+,1}<%loop.1> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop.1: Computable } |
| ; CHECK-NEXT: %iv.1.next = add i32 %iv.1, 1 |
| ; CHECK-NEXT: --> {1,+,1}<%loop.1> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop.1: Computable } |
| ; CHECK-NEXT: %iv.2 = phi i32 [ 0, %loop.1 ], [ %iv.2.next, %loop.2 ] |
| ; CHECK-NEXT: --> {0,+,1}<nuw><%loop.2> U: full-set S: full-set Exits: (1 + %N) LoopDispositions: { %loop.2: Computable } |
| ; CHECK-NEXT: %iv.2.next = add i32 %iv.2, 1 |
| ; CHECK-NEXT: --> {1,+,1}<nw><%loop.2> U: full-set S: full-set Exits: (2 + %N) LoopDispositions: { %loop.2: Computable } |
| ; CHECK-NEXT: Determining loop execution counts for: @test_guards_across_loops |
| ; CHECK-NEXT: Loop %loop.2: backedge-taken count is (1 + (zext i32 %N to i64))<nuw><nsw> |
| ; CHECK-NEXT: Loop %loop.2: constant max backedge-taken count is i64 4294967296 |
| ; CHECK-NEXT: Loop %loop.2: symbolic max backedge-taken count is (1 + (zext i32 %N to i64))<nuw><nsw> |
| ; CHECK-NEXT: Loop %loop.2: Trip multiple is 1 |
| ; CHECK-NEXT: Loop %loop.1: Unpredictable backedge-taken count. |
| ; CHECK-NEXT: Loop %loop.1: Unpredictable constant max backedge-taken count. |
| ; CHECK-NEXT: Loop %loop.1: Unpredictable symbolic max backedge-taken count. |
| ; CHECK-NEXT: Loop %loop.1: Predicated backedge-taken count is (1 + (zext i32 %N to i64))<nuw><nsw> |
| ; CHECK-NEXT: Predicates: |
| ; CHECK-NEXT: {0,+,1}<%loop.1> Added Flags: <nusw> |
| ; CHECK-NEXT: Loop %loop.1: Predicated constant max backedge-taken count is i64 4294967296 |
| ; CHECK-NEXT: Predicates: |
| ; CHECK-NEXT: {0,+,1}<%loop.1> Added Flags: <nusw> |
| ; CHECK-NEXT: Loop %loop.1: Predicated symbolic max backedge-taken count is (1 + (zext i32 %N to i64))<nuw><nsw> |
| ; CHECK-NEXT: Predicates: |
| ; CHECK-NEXT: {0,+,1}<%loop.1> Added Flags: <nusw> |
| ; |
| entry: |
| br label %loop.1 |
| |
| loop.1: |
| %iv.1 = phi i32 [ 0, %entry ], [ %iv.1.next, %loop.1 ] |
| call void @clobber.i32(i32 %iv.1) |
| %ec.1 = icmp ugt i32 %iv.1, %N |
| %iv.1.next = add i32 %iv.1, 1 |
| br i1 %ec.1, label %loop.2, label %loop.1 |
| |
| loop.2: |
| %iv.2 = phi i32 [ 0, %loop.1 ], [ %iv.2.next, %loop.2 ] |
| call void @clobber.i32(i32 %iv.2) |
| %ec.2 = icmp ugt i32 %iv.2, %N |
| %iv.2.next = add i32 %iv.2, 1 |
| br i1 %ec.2, label %exit, label %loop.2 |
| |
| exit: |
| ret void |
| } |