From 8bcc1ea75e0ced110698e9f6a7cf003d30315bed Mon Sep 17 00:00:00 2001 From: David Sherwood Date: Wed, 11 Sep 2024 12:29:58 +0000 Subject: [PATCH 1/2] [NFC][Analysis] Add more SCEV tests for ptr inductions I've added more tests to Analysis/ScalarEvolution/max-backedge-taken-count-guard-info.ll to cover more cases of ptr inductions, in particular highlighting what seems to be a disparity between single exit and multiple exit loops. --- .../max-backedge-taken-count-guard-info.ll | 139 ++++++++++++++++++ 1 file changed, 139 insertions(+) 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 413bd21554c98d..af75bb71c1013e 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 @@ -1595,6 +1595,145 @@ exit: ret i32 0 } +define i32 @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}<%loop> U: full-set S: full-set Exits: ((8 * ((-8 + (-1 * (ptrtoint ptr %a to i64)) + (ptrtoint ptr %b to i64)) /u 8)) + %a) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %ptr.iv.next = getelementptr inbounds i8, ptr %ptr.iv, i64 8 +; CHECK-NEXT: --> {(8 + %a),+,8}<%loop> U: full-set S: full-set Exits: (8 + (8 * ((-8 + (-1 * (ptrtoint ptr %a to i64)) + (ptrtoint ptr %b to i64)) /u 8)) + %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 i32 0 +} + +define i32 @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) + %a) U: full-set S: full-set +; CHECK-NEXT: %ptr.iv = phi ptr [ %ptr.iv.next, %loop ], [ %a, %entry ] +; CHECK-NEXT: --> {%a,+,8}<%loop> U: full-set S: full-set Exits: ((8 * ((-8 + (8 * %n)) /u 8)) + %a) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %ptr.iv.next = getelementptr inbounds i8, ptr %ptr.iv, i64 8 +; CHECK-NEXT: --> {(8 + %a),+,8}<%loop> U: full-set S: full-set Exits: (8 + (8 * ((-8 + (8 * %n)) /u 8)) + %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)) /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)) /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 i32 0 +} + +; TODO: It feels like we should be able to calculate the symbolic max +; exit count for the loop.inc block here, in the same way as +; ptr_induction_eq_1. The problem seems to be in howFarToZero when the +; ControlsOnlyExit is set to false. +define i32 @ptr_induction_early_exit_eq_1(ptr %a, ptr %b, ptr %c) { +; CHECK-LABEL: 'ptr_induction_early_exit_eq_1' +; CHECK-NEXT: Classifying expressions for: @ptr_induction_early_exit_eq_1 +; CHECK-NEXT: %ptr.iv = phi ptr [ %ptr.iv.next, %loop.inc ], [ %a, %entry ] +; CHECK-NEXT: --> {%a,+,8}<%loop> U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %ld1 = load ptr, ptr %ptr.iv, align 8 +; CHECK-NEXT: --> %ld1 U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: %ptr.iv.next = getelementptr inbounds i8, ptr %ptr.iv, i64 8 +; CHECK-NEXT: --> {(8 + %a),+,8}<%loop> U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Computable } +; CHECK-NEXT: Determining loop execution counts for: @ptr_induction_early_exit_eq_1 +; CHECK-NEXT: Loop %loop: Unpredictable backedge-taken count. +; CHECK-NEXT: exit count for loop: ***COULDNOTCOMPUTE*** +; CHECK-NEXT: exit count for loop.inc: ***COULDNOTCOMPUTE*** +; CHECK-NEXT: Loop %loop: Unpredictable constant max backedge-taken count. +; CHECK-NEXT: Loop %loop: Unpredictable symbolic max backedge-taken count. +; CHECK-NEXT: symbolic max exit count for loop: ***COULDNOTCOMPUTE*** +; CHECK-NEXT: symbolic max exit count for loop.inc: ***COULDNOTCOMPUTE*** +; +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 i32 0 +} + +define i32 @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) + %a) U: full-set S: full-set +; CHECK-NEXT: %ptr.iv = phi ptr [ %ptr.iv.next, %loop.inc ], [ %a, %entry ] +; CHECK-NEXT: --> {%a,+,8}<%loop> U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %ld1 = load ptr, ptr %ptr.iv, align 8 +; CHECK-NEXT: --> %ld1 U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: %ptr.iv.next = getelementptr inbounds i8, ptr %ptr.iv, i64 8 +; CHECK-NEXT: --> {(8 + %a),+,8}<%loop> U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Computable } +; CHECK-NEXT: Determining loop execution counts for: @ptr_induction_early_exit_eq_2 +; CHECK-NEXT: Loop %loop: Unpredictable backedge-taken count. +; CHECK-NEXT: exit count for loop: ***COULDNOTCOMPUTE*** +; CHECK-NEXT: exit count for loop.inc: ((-8 + (8 * %n)) /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)) /u 8) +; CHECK-NEXT: symbolic max exit count for loop: ***COULDNOTCOMPUTE*** +; CHECK-NEXT: symbolic max exit count for loop.inc: ((-8 + (8 * %n)) /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 i32 0 +} + + define void @gep_addrec_nw(ptr %a) { ; CHECK-LABEL: 'gep_addrec_nw' ; CHECK-NEXT: Classifying expressions for: @gep_addrec_nw From faad556c635d6793b389d7ae71519434e57b0018 Mon Sep 17 00:00:00 2001 From: David Sherwood Date: Thu, 12 Sep 2024 12:27:26 +0000 Subject: [PATCH 2/2] Make new tests return void --- .../max-backedge-taken-count-guard-info.ll | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) 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 af75bb71c1013e..37d6584b1e85f1 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 @@ -1595,7 +1595,7 @@ exit: ret i32 0 } -define i32 @ptr_induction_eq_1(ptr %a, ptr %b) { +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 ] @@ -1619,10 +1619,10 @@ loop: br i1 %exitcond, label %exit, label %loop exit: - ret i32 0 + ret void } -define i32 @ptr_induction_eq_2(ptr %a, i64 %n) { +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 @@ -1649,14 +1649,14 @@ loop: br i1 %exitcond, label %exit, label %loop exit: - ret i32 0 + ret void } ; TODO: It feels like we should be able to calculate the symbolic max ; exit count for the loop.inc block here, in the same way as ; ptr_induction_eq_1. The problem seems to be in howFarToZero when the ; ControlsOnlyExit is set to false. -define i32 @ptr_induction_early_exit_eq_1(ptr %a, ptr %b, ptr %c) { +define void @ptr_induction_early_exit_eq_1(ptr %a, ptr %b, ptr %c) { ; CHECK-LABEL: 'ptr_induction_early_exit_eq_1' ; CHECK-NEXT: Classifying expressions for: @ptr_induction_early_exit_eq_1 ; CHECK-NEXT: %ptr.iv = phi ptr [ %ptr.iv.next, %loop.inc ], [ %a, %entry ] @@ -1690,10 +1690,10 @@ loop.inc: br i1 %exitcond, label %exit, label %loop exit: - ret i32 0 + ret void } -define i32 @ptr_induction_early_exit_eq_2(ptr %a, i64 %n, ptr %c) { +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 @@ -1730,7 +1730,7 @@ loop.inc: br i1 %exitcond, label %exit, label %loop exit: - ret i32 0 + ret void }