diff --git a/llvm/test/Analysis/ScalarEvolution/max-backedge-taken-count-guard-info.ll b/llvm/test/Analysis/ScalarEvolution/max-backedge-taken-count-guard-info.ll index 9adb8ad9cd6735..67dab25c18979b 100644 --- a/llvm/test/Analysis/ScalarEvolution/max-backedge-taken-count-guard-info.ll +++ b/llvm/test/Analysis/ScalarEvolution/max-backedge-taken-count-guard-info.ll @@ -555,6 +555,84 @@ exit: ret void } +define void @test_guard_if_and_and(i32* 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: --> %cmp.and1 U: full-set S: full-set +; CHECK-NEXT: %cmp.and = and i1 %cmp.ult, %cmp.and1 +; CHECK-NEXT: --> %cmp.and U: full-set S: full-set +; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ] +; CHECK-NEXT: --> {0,+,1}<%loop> U: [0,-1) S: [0,-1) Exits: (-1 + %count) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %idx = getelementptr inbounds i32, i32* %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}<%loop> U: [1,0) S: [1,0) 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: max backedge-taken count is -2 +; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (-1 + %count) +; CHECK-NEXT: Predicates: +; CHECK: 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, i32* %data, i64 %iv + store i32 1, i32* %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(i32* 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: --> %cmp.or U: full-set S: full-set +; CHECK-NEXT: %cmp.and = and i1 %cmp.ult, %cmp.or +; CHECK-NEXT: --> %cmp.and U: full-set S: full-set +; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ] +; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (-1 + %count) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %idx = getelementptr inbounds i32, i32* %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}<%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: max backedge-taken count is -1 +; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (-1 + %count) +; CHECK-NEXT: Predicates: +; CHECK: 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, i32* %data, i64 %iv + store i32 1, i32* %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(i32* nocapture readonly %data, i64 %count) { ; CHECK-LABEL: 'test_guard_if_or_skip' ; CHECK-NEXT: Classifying expressions for: @test_guard_if_or_skip @@ -627,6 +705,84 @@ exit: ret void } +define void @test_guard_if_or_or(i32* 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: --> %cmp.or1 U: full-set S: full-set +; CHECK-NEXT: %cmp.or = or i1 %cmp.uge, %cmp.or1 +; CHECK-NEXT: --> %cmp.or U: full-set S: full-set +; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ] +; CHECK-NEXT: --> {0,+,1}<%loop> U: [0,-1) S: [0,-1) Exits: (-1 + %count) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %idx = getelementptr inbounds i32, i32* %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}<%loop> U: [1,0) S: [1,0) 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: max backedge-taken count is -2 +; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (-1 + %count) +; CHECK-NEXT: Predicates: +; CHECK: 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, i32* %data, i64 %iv + store i32 1, i32* %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(i32* 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: --> %cmp.and U: full-set S: full-set +; CHECK-NEXT: %cmp.or = or i1 %cmp.uge, %cmp.and +; CHECK-NEXT: --> %cmp.or U: full-set S: full-set +; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ] +; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (-1 + %count) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %idx = getelementptr inbounds i32, i32* %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}<%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: max backedge-taken count is -1 +; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (-1 + %count) +; CHECK-NEXT: Predicates: +; CHECK: 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, i32* %data, i64 %iv + store i32 1, i32* %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 ; max backedge-taken count.