From ec940be4e2ca39112ed447278ed0e1a9887c22bf Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Wed, 2 Oct 2024 11:03:14 +0100 Subject: [PATCH] [SCEV] Add tests for umin_seq change in #92177 SCEV-only tests for https://github.com/llvm/llvm-project/pull/92177 --- .../umin-seq-operand-may-trigger-ub.ll | 111 ++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 llvm/test/Analysis/ScalarEvolution/umin-seq-operand-may-trigger-ub.ll diff --git a/llvm/test/Analysis/ScalarEvolution/umin-seq-operand-may-trigger-ub.ll b/llvm/test/Analysis/ScalarEvolution/umin-seq-operand-may-trigger-ub.ll new file mode 100644 index 00000000000000..8085592111ff5a --- /dev/null +++ b/llvm/test/Analysis/ScalarEvolution/umin-seq-operand-may-trigger-ub.ll @@ -0,0 +1,111 @@ +; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 5 +; RUN: opt -passes='print' -scalar-evolution-classify-expressions=0 -disable-output %s 2>&1 | FileCheck %s + +; The UDiv in the latch may never be executed. The backedge-taken-count +; expressions must account for the fact that evaluating the UDiv +; unconditionally may trigger UB. +; FIXME: umin_seq should be used instead of umin for BTCs. +define i64 @multi_exit_exit_count_with_udiv_by_value_in_latch(ptr %dst, i64 %N) { +; CHECK-LABEL: 'multi_exit_exit_count_with_udiv_by_value_in_latch' +; CHECK-NEXT: Determining loop execution counts for: @multi_exit_exit_count_with_udiv_by_value_in_latch +; CHECK-NEXT: Loop %loop.header: backedge-taken count is ((42 /u %N) umin (0 smax %N)) +; CHECK-NEXT: exit count for loop.header: (0 smax %N) +; CHECK-NEXT: exit count for loop.latch: (42 /u %N) +; CHECK-NEXT: Loop %loop.header: constant max backedge-taken count is i64 42 +; CHECK-NEXT: Loop %loop.header: symbolic max backedge-taken count is ((42 /u %N) umin (0 smax %N)) +; CHECK-NEXT: symbolic max exit count for loop.header: (0 smax %N) +; CHECK-NEXT: symbolic max exit count for loop.latch: (42 /u %N) +; CHECK-NEXT: Loop %loop.header: Trip multiple is 1 +; +entry: + br label %loop.header + +loop.header: + %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ] + %gep = getelementptr inbounds i32, ptr %dst, i64 %iv + store i32 1, ptr %gep + %c.0 = icmp slt i64 %iv, %N + br i1 %c.0, label %loop.latch, label %exit + +loop.latch: + %iv.next = add i64 %iv, 1 + %d = udiv i64 42, %N + %c.1 = icmp slt i64 %iv, %d + br i1 %c.1, label %loop.header, label %exit + +exit: + %p = phi i64 [ 1, %loop.header ], [ 0, %loop.latch] + ret i64 %p +} + +; The UDiv in the latch may never be executed. The backedge-taken-count +; expressions must account for the fact that evaluating the UDiv +; unconditionally may trigger UB. +; FIXME: umin_seq should be used instead of umin for BTCs. +define i64 @multi_exit_exit_count_with_udiv_by_value_in_latch_different_bounds(ptr %dst, i64 %N, i64 %M) { +; CHECK-LABEL: 'multi_exit_exit_count_with_udiv_by_value_in_latch_different_bounds' +; CHECK-NEXT: Determining loop execution counts for: @multi_exit_exit_count_with_udiv_by_value_in_latch_different_bounds +; CHECK-NEXT: Loop %loop.header: backedge-taken count is ((0 smax %N) umin_seq (42 /u %M)) +; CHECK-NEXT: exit count for loop.header: (0 smax %N) +; CHECK-NEXT: exit count for loop.latch: (42 /u %M) +; CHECK-NEXT: Loop %loop.header: constant max backedge-taken count is i64 42 +; CHECK-NEXT: Loop %loop.header: symbolic max backedge-taken count is ((0 smax %N) umin_seq (42 /u %M)) +; CHECK-NEXT: symbolic max exit count for loop.header: (0 smax %N) +; CHECK-NEXT: symbolic max exit count for loop.latch: (42 /u %M) +; CHECK-NEXT: Loop %loop.header: Trip multiple is 1 +; +entry: + br label %loop.header + +loop.header: + %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ] + %gep = getelementptr inbounds i32, ptr %dst, i64 %iv + store i32 1, ptr %gep + %c.0 = icmp slt i64 %iv, %N + br i1 %c.0, label %loop.latch, label %exit + +loop.latch: + %iv.next = add i64 %iv, 1 + %d = udiv i64 42, %M + %c.1 = icmp slt i64 %iv, %d + br i1 %c.1, label %loop.header, label %exit + +exit: + %p = phi i64 [ 1, %loop.header ], [ 0, %loop.latch] + ret i64 %p +} + +; The UDiv in the latch cannot trigger UB, evaluating it unconditionally in the +; trip count expression is fine. +define i64 @multi_exit_exit_count_with_udiv_by_constant_in_latch(ptr %dst, i64 %N) { +; CHECK-LABEL: 'multi_exit_exit_count_with_udiv_by_constant_in_latch' +; CHECK-NEXT: Determining loop execution counts for: @multi_exit_exit_count_with_udiv_by_constant_in_latch +; CHECK-NEXT: Loop %loop.header: backedge-taken count is ((%N /u 42) umin (0 smax %N)) +; CHECK-NEXT: exit count for loop.header: (0 smax %N) +; CHECK-NEXT: exit count for loop.latch: (%N /u 42) +; CHECK-NEXT: Loop %loop.header: constant max backedge-taken count is i64 439208192231179800 +; CHECK-NEXT: Loop %loop.header: symbolic max backedge-taken count is ((%N /u 42) umin (0 smax %N)) +; CHECK-NEXT: symbolic max exit count for loop.header: (0 smax %N) +; CHECK-NEXT: symbolic max exit count for loop.latch: (%N /u 42) +; CHECK-NEXT: Loop %loop.header: Trip multiple is 1 +; +entry: + br label %loop.header + +loop.header: + %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ] + %gep = getelementptr inbounds i32, ptr %dst, i64 %iv + store i32 1, ptr %gep + %c.0 = icmp slt i64 %iv, %N + br i1 %c.0, label %loop.latch, label %exit + +loop.latch: + %iv.next = add i64 %iv, 1 + %d = udiv i64 %N, 42 + %c.1 = icmp slt i64 %iv, %d + br i1 %c.1, label %loop.header, label %exit + +exit: + %p = phi i64 [ 1, %loop.header ], [ 0, %loop.latch] + ret i64 %p +}