Files
TheRock/compiler/amd-llvm/mlir/test/Dialect/SCF/trip_count.mlir
T
derek.holloway 7502bf64a4
CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

821 lines
26 KiB
MLIR

// RUN: mlir-opt %s -test-scf-for-utils --split-input-file | FileCheck %s
// CHECK-LABEL: func.func @trip_count_index_zero_to_zero(
func.func @trip_count_index_zero_to_zero(%a : i32, %b : i32) -> i32 {
%c0 = arith.constant 0 : index
%c1 = arith.constant 1 : index
// CHECK: "test.trip-count" = 0
%r = scf.for %i = %c0 to %c0 step %c1 iter_args(%0 = %a) -> i32 {
scf.yield %b : i32
}
return %r : i32
}
// -----
// CHECK-LABEL: func.func @trip_count_index_zero_to_zero_step_dyn(
func.func @trip_count_index_zero_to_zero_step_dyn(%a : i32, %b : i32, %step : index) -> i32 {
%c0 = arith.constant 0 : index
// CHECK: "test.trip-count" = 0
%r = scf.for %i = %c0 to %c0 step %step iter_args(%0 = %a) -> i32 {
scf.yield %b : i32
}
return %r : i32
}
// -----
// CHECK-LABEL: func.func @trip_count_i32_zero_to_zero(
func.func @trip_count_i32_zero_to_zero(%a : i32, %b : i32) -> i32 {
%c0 = arith.constant 0 : i32
%c1 = arith.constant 1 : i32
// CHECK: "test.trip-count" = 0
%r = scf.for %i = %c0 to %c0 step %c1 iter_args(%0 = %a) -> i32 : i32 {
scf.yield %b : i32
}
return %r : i32
}
// -----
// CHECK-LABEL: func.func @trip_count_i32_zero_to_zero_step_dyn(
func.func @trip_count_i32_zero_to_zero_step_dyn(%a : i32, %b : i32, %step : i32) -> i32 {
%c0 = arith.constant 0 : i32
// CHECK: "test.trip-count" = 0
%r = scf.for %i = %c0 to %c0 step %step iter_args(%0 = %a) -> i32 : i32 {
scf.yield %b : i32
}
return %r : i32
}
// -----
// CHECK-LABEL: func.func @trip_count_index_one_to_zero(
func.func @trip_count_index_one_to_zero(%a : i32, %b : i32) -> i32 {
%c0 = arith.constant 0 : index
%c1 = arith.constant 1 : index
// Index type has a unknown bitwidth, we can't compute a loop tripcount
// in theory because of overflow concerns.
// CHECK: "test.trip-count" = 0
%r2 = scf.for %i = %c1 to %c0 step %c1 iter_args(%0 = %a) -> i32 {
scf.yield %b : i32
}
return %r2 : i32
}
// -----
// CHECK-LABEL: func.func @trip_count_i32_one_to_zero(
func.func @trip_count_i32_one_to_zero(%a : i32, %b : i32) -> i32 {
%c0 = arith.constant 0 : i32
%c1 = arith.constant 1 : i32
// CHECK: "test.trip-count" = 0
%r2 = scf.for %i = %c1 to %c0 step %c1 iter_args(%0 = %a) -> i32 : i32 {
scf.yield %b : i32
}
return %r2 : i32
}
// -----
// CHECK-LABEL: func.func @trip_count_i32_one_to_zero_dyn_step(
func.func @trip_count_i32_one_to_zero_dyn_step(%a : i32, %b : i32, %step : i32) -> i32 {
%c0 = arith.constant 0 : i32
%c1 = arith.constant 1 : i32
// CHECK: "test.trip-count" = 0
%r2 = scf.for %i = %c1 to %c0 step %step iter_args(%0 = %a) -> i32 : i32 {
scf.yield %b : i32
}
return %r2 : i32
}
// -----
// CHECK-LABEL: func.func @trip_count_index_negative_step(
func.func @trip_count_index_negative_step(%a : i32, %b : i32) -> i32 {
%c0 = arith.constant 0 : index
%c1 = arith.constant 1 : index
%c-1 = arith.constant -1 : index
// Negative step is invalid, loop won't execute.
// CHECK: "test.trip-count" = 0
%r3 = scf.for %i = %c1 to %c0 step %c-1 iter_args(%0 = %a) -> i32 {
scf.yield %b : i32
}
return %r3 : i32
}
// -----
// CHECK-LABEL: func.func @trip_count_i32_negative_step(
func.func @trip_count_i32_negative_step(%a : i32, %b : i32) -> i32 {
%c0 = arith.constant 0 : i32
%c1 = arith.constant 1 : i32
%c-1 = arith.constant -1 : i32
// Negative step is invalid, loop won't execute.
// CHECK: "test.trip-count" = 0
%r3 = scf.for %i = %c1 to %c0 step %c-1 iter_args(%0 = %a) -> i32 : i32 {
scf.yield %b : i32
}
return %r3 : i32
}
// -----
// CHECK-LABEL: func.func @trip_count_index_negative_step_unsigned_loop(
func.func @trip_count_index_negative_step_unsigned_loop(%a : i32, %b : i32) -> i32 {
%c0 = arith.constant 0 : index
%c1 = arith.constant 1 : index
%c-1 = arith.constant -1 : index
// Negative step is invalid, loop won't execute.
// CHECK: "test.trip-count" = 0
%r3 = scf.for unsigned %i = %c1 to %c0 step %c-1 iter_args(%0 = %a) -> i32 {
scf.yield %b : i32
}
return %r3 : i32
}
// -----
// CHECK-LABEL: func.func @trip_count_i32_negative_step_unsigned_loop(
func.func @trip_count_i32_negative_step_unsigned_loop(%a : i32, %b : i32) -> i32 {
%c0 = arith.constant 0 : i32
%c1 = arith.constant 1 : i32
%c-1 = arith.constant -1 : i32
// Negative step is invalid, loop won't execute.
// CHECK: "test.trip-count" = 0
%r3 = scf.for unsigned %i = %c1 to %c0 step %c-1 iter_args(%0 = %a) -> i32 : i32 {
scf.yield %b : i32
}
return %r3 : i32
}
// -----
// CHECK-LABEL: func.func @trip_count_index_normal_loop(
func.func @trip_count_index_normal_loop(%a : i32, %b : i32) -> i32 {
%c0 = arith.constant 0 : index
%c2 = arith.constant 2 : index
%c10 = arith.constant 10 : index
// Index type has a unknown bitwidth, we can't compute a loop tripcount
// in theory because of overflow concerns.
// CHECK: "test.trip-count" = 5
%r4 = scf.for %i = %c0 to %c10 step %c2 iter_args(%0 = %a) -> i32 {
scf.yield %b : i32
}
return %r4 : i32
}
// -----
// CHECK-LABEL: func.func @trip_count_i32_normal_loop(
func.func @trip_count_i32_normal_loop(%a : i32, %b : i32) -> i32 {
%c0 = arith.constant 0 : i32
%c2 = arith.constant 2 : i32
%c10 = arith.constant 10 : i32
// Normal loop
// CHECK: "test.trip-count" = 5
%r4 = scf.for %i = %c0 to %c10 step %c2 iter_args(%0 = %a) -> i32 : i32 {
scf.yield %b : i32
}
return %r4 : i32
}
// -----
// CHECK-LABEL: func.func @trip_count_index_signed_crossing_zero(
func.func @trip_count_index_signed_crossing_zero(%a : i32, %b : i32) -> i32 {
%c-1 = arith.constant -1 : index
%c1 = arith.constant 1 : index
// Index type has a unknown bitwidth, we can't compute a loop tripcount
// in theory because of overflow concerns.
// CHECK: "test.trip-count" = 2
%r5 = scf.for %i = %c-1 to %c1 step %c1 iter_args(%0 = %a) -> i32 {
scf.yield %b : i32
}
return %r5 : i32
}
// -----
// CHECK-LABEL: func.func @trip_count_i32_signed_crossing_zero(
func.func @trip_count_i32_signed_crossing_zero(%a : i32, %b : i32) -> i32 {
%c-1 = arith.constant -1 : i32
%c1 = arith.constant 1 : i32
// This loop execute with signed comparison, but not unsigned, because it is crossing 0.
// CHECK: "test.trip-count" = 2
%r5 = scf.for %i = %c-1 to %c1 step %c1 iter_args(%0 = %a) -> i32 : i32 {
scf.yield %b : i32
}
return %r5 : i32
}
// -----
// CHECK-LABEL: func.func @trip_count_index_unsigned_crossing_zero(
func.func @trip_count_index_unsigned_crossing_zero(%a : i32, %b : i32) -> i32 {
%c-1 = arith.constant -1 : index
%c1 = arith.constant 1 : index
// Index type has a unknown bitwidth, we can't compute a loop tripcount
// in theory because of overflow concerns.
// CHECK: "test.trip-count" = 0
%r6 = scf.for unsigned %i = %c-1 to %c1 step %c1 iter_args(%0 = %a) -> i32 {
scf.yield %b : i32
}
return %r6 : i32
}
// -----
// CHECK-LABEL: func.func @trip_count_i32_unsigned_crossing_zero(
func.func @trip_count_i32_unsigned_crossing_zero(%a : i32, %b : i32) -> i32 {
%c-1 = arith.constant -1 : i32
%c1 = arith.constant 1 : i32
// This loop execute with signed comparison, but not unsigned, because it is crossing 0.
// CHECK: "test.trip-count" = 0
%r6 = scf.for unsigned %i = %c-1 to %c1 step %c1 iter_args(%0 = %a) -> i32 : i32 {
scf.yield %b : i32
}
return %r6 : i32
}
// -----
// CHECK-LABEL: func.func @trip_count_i32_unsigned_crossing_zero_dyn_step(
func.func @trip_count_i32_unsigned_crossing_zero_dyn_step(%a : i32, %b : i32, %step : i32) -> i32 {
%c-1 = arith.constant -1 : i32
%c1 = arith.constant 1 : i32
// This loop execute with signed comparison, but not unsigned, because it is crossing 0.
// CHECK: "test.trip-count" = 0
%r6 = scf.for unsigned %i = %c-1 to %c1 step %step iter_args(%0 = %a) -> i32 : i32 {
scf.yield %b : i32
}
return %r6 : i32
}
// -----
// CHECK-LABEL: func.func @trip_count_index_negative_bounds_signed(
func.func @trip_count_index_negative_bounds_signed(%a : i32, %b : i32) -> i32 {
%c-10 = arith.constant -10 : index
%c-1 = arith.constant -1 : index
%c2 = arith.constant 2 : index
// Index type has a unknown bitwidth, we can't compute a loop tripcount
// in theory because of overflow concerns.
// CHECK: "test.trip-count" = 5
%r7 = scf.for %i = %c-10 to %c-1 step %c2 iter_args(%0 = %a) -> i32 {
scf.yield %b : i32
}
return %r7 : i32
}
// -----
// CHECK-LABEL: func.func @trip_count_i32_negative_bounds_signed(
func.func @trip_count_i32_negative_bounds_signed(%a : i32, %b : i32) -> i32 {
%c-10 = arith.constant -10 : i32
%c-1 = arith.constant -1 : i32
%c2 = arith.constant 2 : i32
// This loop execute with signed comparison, because both bounds are
// negative and there is no crossing of 0 here.
// CHECK: "test.trip-count" = 5
%r7 = scf.for %i = %c-10 to %c-1 step %c2 iter_args(%0 = %a) -> i32 : i32 {
scf.yield %b : i32
}
return %r7 : i32
}
// -----
// CHECK-LABEL: func.func @trip_count_index_negative_bounds_unsigned(
func.func @trip_count_index_negative_bounds_unsigned(%a : i32, %b : i32) -> i32 {
%c-10 = arith.constant -10 : index
%c-1 = arith.constant -1 : index
%c2 = arith.constant 2 : index
// Index type has a unknown bitwidth, we can't compute a loop tripcount
// in theory because of overflow concerns.
// CHECK: "test.trip-count" = 5
%r8 = scf.for %i = %c-10 to %c-1 step %c2 iter_args(%0 = %a) -> i32 {
scf.yield %b : i32
}
return %r8 : i32
}
// -----
// CHECK-LABEL: func.func @trip_count_i32_negative_bounds_unsigned(
func.func @trip_count_i32_negative_bounds_unsigned(%a : i32, %b : i32) -> i32 {
%c-10 = arith.constant -10 : i32
%c-1 = arith.constant -1 : i32
%c2 = arith.constant 2 : i32
// CHECK: "test.trip-count" = 5
%r8 = scf.for %i = %c-10 to %c-1 step %c2 iter_args(%0 = %a) -> i32 : i32 {
scf.yield %b : i32
}
return %r8 : i32
}
// -----
// CHECK-LABEL: func.func @trip_count_index_overflow_signed(
func.func @trip_count_index_overflow_signed(%a : i32, %b : i32) -> i32 {
%c1 = arith.constant 1 : index
%c_max = arith.constant 2147483647 : index // 2^31 - 1
%c_min = arith.constant 2147483648 : index // -2^31
// Index type has a unknown bitwidth, we can't compute a loop tripcount
// in theory because of overflow concerns.
// CHECK: "test.trip-count" = 1
%r9 = scf.for %i = %c_max to %c_min step %c1 iter_args(%0 = %a) -> i32 {
scf.yield %b : i32
}
return %r9 : i32
}
// -----
// CHECK-LABEL: func.func @trip_count_i32_overflow_signed(
func.func @trip_count_i32_overflow_signed(%a : i32, %b : i32) -> i32 {
%c1 = arith.constant 1 : i32
%c_max = arith.constant 2147483647 : i32 // 2^31 - 1
%c_min = arith.constant 2147483648 : i32 // -2^31
// This loop crosses the 2^31 threshold, which would overflow a signed 32-bit integer.
// CHECK: "test.trip-count" = 0
%r9 = scf.for %i = %c_max to %c_min step %c1 iter_args(%0 = %a) -> i32 : i32 {
scf.yield %b : i32
}
return %r9 : i32
}
// -----
// CHECK-LABEL: func.func @trip_count_i32_overflow_signed_dyn_step(
func.func @trip_count_i32_overflow_signed_dyn_step(%a : i32, %b : i32, %step : i32) -> i32 {
%c_max = arith.constant 2147483647 : i32 // 2^31 - 1
%c_min = arith.constant 2147483648 : i32 // -2^31
// This loop crosses the 2^31 threshold, which would overflow a signed 32-bit integer.
// CHECK: "test.trip-count" = 0
%r9 = scf.for %i = %c_max to %c_min step %step iter_args(%0 = %a) -> i32 : i32 {
scf.yield %b : i32
}
return %r9 : i32
}
// -----
// CHECK-LABEL: func.func @trip_count_index_overflow_unsigned(
func.func @trip_count_index_overflow_unsigned(%a : i32, %b : i32) -> i32 {
%c1 = arith.constant 1 : index
%c_max = arith.constant 2147483647 : index // 2^31 - 1
%c_min = arith.constant 2147483648 : index // -2^31
// Index type has a unknown bitwidth, we can't compute a loop tripcount
// in theory because of overflow concerns.
// CHECK: "test.trip-count" = 1
%r10 = scf.for unsigned %i = %c_max to %c_min step %c1 iter_args(%0 = %a) -> i32 {
scf.yield %b : i32
}
return %r10 : i32
}
// -----
// CHECK-LABEL: func.func @trip_count_i32_overflow_unsigned(
func.func @trip_count_i32_overflow_unsigned(%a : i32, %b : i32) -> i32 {
%c1 = arith.constant 1 : i32
%c_max = arith.constant 2147483647 : i32 // 2^31 - 1
%c_min = arith.constant 2147483648 : i32 // -2^31
// The same loop with unsigned comparison executes normally
// CHECK: "test.trip-count" = 1
%r10 = scf.for unsigned %i = %c_max to %c_min step %c1 iter_args(%0 = %a) -> i32 : i32 {
scf.yield %b : i32
}
return %r10 : i32
}
// -----
// CHECK-LABEL: func.func @trip_count_index_overflow_64bit_signed(
func.func @trip_count_index_overflow_64bit_signed(%a : i32, %b : i32) -> i32 {
%c1 = arith.constant 1 : index
%c_max = arith.constant 9223372036854775807 : index // 2^63 - 1
%c_min = arith.constant -9223372036854775808 : index // -2^63
// This loop crosses the 2^63 threshold, which would overflow a signed 64-bit integer.
// Index type has a unknown bitwidth, we can't compute a loop tripcount.
// CHECK: "test.trip-count" = 0
%r11 = scf.for %i = %c_max to %c_min step %c1 iter_args(%0 = %a) -> i32 {
scf.yield %b : i32
}
return %r11 : i32
}
// -----
// CHECK-LABEL: func.func @trip_count_i64_overflow_64bit_signed(
func.func @trip_count_i64_overflow_64bit_signed(%a : i32, %b : i32) -> i32 {
%c1 = arith.constant 1 : i64
%c_max = arith.constant 9223372036854775807 : i64 // 2^63 - 1
%c_min = arith.constant -9223372036854775808 : i64 // -2^63
// This loop crosses the 2^63 threshold, which would overflow a signed 64-bit integer.
// CHECK: "test.trip-count" = 0
%r11 = scf.for %i = %c_max to %c_min step %c1 iter_args(%0 = %a) -> i32 : i64 {
scf.yield %b : i32
}
return %r11 : i32
}
// -----
// CHECK-LABEL: func.func @trip_count_index_overflow_64bit_unsigned(
func.func @trip_count_index_overflow_64bit_unsigned(%a : i32, %b : i32) -> i32 {
%c1 = arith.constant 1 : index
%c_max = arith.constant 9223372036854775807 : index // 2^63 - 1
%c_min = arith.constant -9223372036854775808 : index // -2^63
// Index type has a unknown bitwidth, we can't compute a loop tripcount
// in theory because of overflow concerns.
// CHECK: "test.trip-count" = 1
%r12 = scf.for unsigned %i = %c_max to %c_min step %c1 iter_args(%0 = %a) -> i32 {
scf.yield %b : i32
}
return %r12 : i32
}
// -----
// CHECK-LABEL: func.func @trip_count_i32_overflow_64bit_unsigned(
func.func @trip_count_i32_overflow_64bit_unsigned(%a : i32, %b : i32) -> i32 {
%c1 = arith.constant 1 : i64
%c_max = arith.constant 9223372036854775807 : i64 // 2^63 - 1
%c_min = arith.constant -9223372036854775808 : i64 // -2^63
// The same loop with unsigned comparison executes normally
// CHECK: "test.trip-count" = 1
%r12 = scf.for unsigned %i = %c_max to %c_min step %c1 iter_args(%0 = %a) -> i32 : i64 {
scf.yield %b : i32
}
return %r12 : i32
}
// -----
// CHECK-LABEL:func.func @trip_count_step_greater_than_iteration(
func.func @trip_count_step_greater_than_iteration() -> i32 {
%c0_i32 = arith.constant 0 : i32
%c4_i32 = arith.constant 4 : i32
%c17_i32 = arith.constant 17 : i32
%c16_i32 = arith.constant 16 : i32
// CHECK: "test.trip-count" = 1
%1 = scf.for %arg0 = %c16_i32 to %c17_i32 step %c4_i32 iter_args(%arg1 = %c0_i32) -> (i32) : i32 {
scf.yield %arg0 : i32
}
return %1 : i32
}
// -----
// CHECK-LABEL:func.func @trip_count_arith_add(
func.func @trip_count_arith_add(%lb : i32) -> i32 {
%c0_i32 = arith.constant 0 : i32
%c4_i32 = arith.constant 4 : i32
%c17_i32 = arith.constant 17 : i32
%c16_i32 = arith.constant 16 : i32
// Can't compute a trip-count in the absence of overflow flag.
// CHECK: "test.trip-count" = "none"
%ub = arith.addi %lb, %c16_i32 : i32
%1 = scf.for %arg0 = %lb to %ub step %c4_i32 iter_args(%arg1 = %c0_i32) -> (i32) : i32 {
scf.yield %arg0 : i32
}
return %1 : i32
}
// -----
// CHECK-LABEL:func.func @trip_count_arith_add_negative(
func.func @trip_count_arith_add_negative(%lb : i32) -> i32 {
%c0_i32 = arith.constant 0 : i32
%c4_i32 = arith.constant 4 : i32
%c-16_i32 = arith.constant -16 : i32
// Can't compute a trip-count in the absence of overflow flag.
// CHECK: "test.trip-count" = "none"
%ub = arith.addi %lb, %c-16_i32 : i32
%1 = scf.for %arg0 = %lb to %ub step %c4_i32 iter_args(%arg1 = %c0_i32) -> (i32) : i32 {
scf.yield %arg0 : i32
}
return %1 : i32
}
// -----
// CHECK-LABEL:func.func @trip_count_arith_add_nsw_loop_signed(
func.func @trip_count_arith_add_nsw_loop_signed(%lb : i32) -> i32 {
%c0_i32 = arith.constant 0 : i32
%c4_i32 = arith.constant 4 : i32
%c16_i32 = arith.constant 16 : i32
%ub = arith.addi %lb, %c16_i32 overflow<nsw> : i32
// CHECK: "test.trip-count" = 4
%1 = scf.for %arg0 = %lb to %ub step %c4_i32 iter_args(%arg1 = %c0_i32) -> (i32) : i32 {
scf.yield %arg0 : i32
}
return %1 : i32
}
// -----
// CHECK-LABEL:func.func @trip_count_arith_add_negative_nsw_loop_signed(
func.func @trip_count_arith_add_negative_nsw_loop_signed(%lb : i32) -> i32 {
%c0_i32 = arith.constant 0 : i32
%c4_i32 = arith.constant 4 : i32
%c-16_i32 = arith.constant -16 : i32
%ub = arith.addi %lb, %c-16_i32 overflow<nsw> : i32
// CHECK: "test.trip-count" = 0
%1 = scf.for %arg0 = %lb to %ub step %c4_i32 iter_args(%arg1 = %c0_i32) -> (i32) : i32 {
scf.yield %arg0 : i32
}
return %1 : i32
}
// -----
// CHECK-LABEL:func.func @trip_count_arith_add_negative_nsw_loop_signed_step_dyn(
func.func @trip_count_arith_add_negative_nsw_loop_signed_step_dyn(%lb : i32, %step : i32) -> i32 {
%c0_i32 = arith.constant 0 : i32
%c-16_i32 = arith.constant -16 : i32
%ub = arith.addi %lb, %c-16_i32 overflow<nsw> : i32
// CHECK: "test.trip-count" = 0
%1 = scf.for %arg0 = %lb to %ub step %step iter_args(%arg1 = %c0_i32) -> (i32) : i32 {
scf.yield %arg0 : i32
}
return %1 : i32
}
// -----
// CHECK-LABEL:func.func @trip_count_arith_add_nsw_loop_unsigned(
func.func @trip_count_arith_add_nsw_loop_unsigned(%lb : i32) -> i32 {
%c0_i32 = arith.constant 0 : i32
%c4_i32 = arith.constant 4 : i32
%c16_i32 = arith.constant 16 : i32
// Can't compute a trip-count when the overflow flag mismatches the loop comparison signess
// CHECK: "test.trip-count" = "none"
%ub = arith.addi %lb, %c16_i32 overflow<nsw> : i32
%1 = scf.for unsigned %arg0 = %lb to %ub step %c4_i32 iter_args(%arg1 = %c0_i32) -> (i32) : i32 {
scf.yield %arg0 : i32
}
return %1 : i32
}
// -----
// CHECK-LABEL:func.func @trip_count_arith_add_negative_nsw_loop_unsigned(
func.func @trip_count_arith_add_negative_nsw_loop_unsigned(%lb : i32) -> i32 {
%c0_i32 = arith.constant 0 : i32
%c4_i32 = arith.constant 4 : i32
%c-16_i32 = arith.constant -16 : i32
// Can't compute a trip-count when the overflow flag mismatches the loop comparison signess
// CHECK: "test.trip-count" = "none"
%ub = arith.addi %lb, %c-16_i32 overflow<nsw> : i32
%1 = scf.for unsigned %arg0 = %lb to %ub step %c4_i32 iter_args(%arg1 = %c0_i32) -> (i32) : i32 {
scf.yield %arg0 : i32
}
return %1 : i32
}
// -----
// CHECK-LABEL:func.func @trip_count_arith_add_nuw_loop_signed(
func.func @trip_count_arith_add_nuw_loop_signed(%lb : i32) -> i32 {
%c0_i32 = arith.constant 0 : i32
%c4_i32 = arith.constant 4 : i32
%c16_i32 = arith.constant 16 : i32
// Can't compute a trip-count when the overflow flag mismatches the loop comparison signess
// CHECK: "test.trip-count" = "none"
%ub = arith.addi %lb, %c16_i32 overflow<nuw> : i32
%1 = scf.for %arg0 = %lb to %ub step %c4_i32 iter_args(%arg1 = %c0_i32) -> (i32) : i32 {
scf.yield %arg0 : i32
}
return %1 : i32
}
// -----
// CHECK-LABEL:func.func @trip_count_arith_add_negative_nuw_loop_signed(
func.func @trip_count_arith_add_negative_nuw_loop_signed(%lb : i32) -> i32 {
%c0_i32 = arith.constant 0 : i32
%c4_i32 = arith.constant 4 : i32
%c-16_i32 = arith.constant -16 : i32
// Can't compute a trip-count when the overflow flag mismatches the loop comparison signess
// CHECK: "test.trip-count" = "none"
%ub = arith.addi %lb, %c-16_i32 overflow<nuw> : i32
%1 = scf.for %arg0 = %lb to %ub step %c4_i32 iter_args(%arg1 = %c0_i32) -> (i32) : i32 {
scf.yield %arg0 : i32
}
return %1 : i32
}
// -----
// CHECK-LABEL:func.func @trip_count_arith_add_nuw_loop_unsigned(
func.func @trip_count_arith_add_nuw_loop_unsigned(%lb : i32) -> i32 {
%c0_i32 = arith.constant 0 : i32
%c4_i32 = arith.constant 4 : i32
%c16_i32 = arith.constant 16 : i32
// CHECK: "test.trip-count" = 4
%ub = arith.addi %lb, %c16_i32 overflow<nuw> : i32
%1 = scf.for unsigned %arg0 = %lb to %ub step %c4_i32 iter_args(%arg1 = %c0_i32) -> (i32) : i32 {
scf.yield %arg0 : i32
}
return %1 : i32
}
// -----
// CHECK-LABEL:func.func @trip_count_arith_add_negative_nuw_loop_unsigned(
func.func @trip_count_arith_add_negative_nuw_loop_unsigned(%lb : i32) -> i32 {
%c0_i32 = arith.constant 0 : i32
%c4_i32 = arith.constant 4 : i32
%c-16_i32 = arith.constant -16 : i32
// CHECK: "test.trip-count" = 0
%ub = arith.addi %lb, %c-16_i32 overflow<nuw> : i32
%1 = scf.for unsigned %arg0 = %lb to %ub step %c4_i32 iter_args(%arg1 = %c0_i32) -> (i32) : i32 {
scf.yield %arg0 : i32
}
return %1 : i32
}
// -----
// CHECK-LABEL:func.func @trip_count_arith_add_negative_nuw_loop_unsigned_step_dyn(
func.func @trip_count_arith_add_negative_nuw_loop_unsigned_step_dyn(%lb : i32, %step : i32) -> i32 {
%c0_i32 = arith.constant 0 : i32
%c-16_i32 = arith.constant -16 : i32
// CHECK: "test.trip-count" = 0
%ub = arith.addi %lb, %c-16_i32 overflow<nuw> : i32
%1 = scf.for unsigned %arg0 = %lb to %ub step %step iter_args(%arg1 = %c0_i32) -> (i32) : i32 {
scf.yield %arg0 : i32
}
return %1 : i32
}
// -----
// CHECK-LABEL:func.func @trip_count_arith_add_nuw_loop_unsigned_invalid(
func.func @trip_count_arith_add_nuw_loop_unsigned_invalid(%lb : i32, %other : i32) -> i32 {
%c0_i32 = arith.constant 0 : i32
%c4_i32 = arith.constant 4 : i32
%c16_i32 = arith.constant 16 : i32
// The addition here is not adding from %lb
// CHECK: "test.trip-count" = "none"
%ub = arith.addi %other, %c16_i32 overflow<nuw> : i32
%1 = scf.for unsigned %arg0 = %lb to %ub step %c4_i32 iter_args(%arg1 = %c0_i32) -> (i32) : i32 {
scf.yield %arg0 : i32
}
return %1 : i32
}
// -----
// CHECK-LABEL:func.func @trip_count_i8_unsigned_full_range(
func.func @trip_count_i8_unsigned_full_range(%a : i32, %b : i32) -> i32 {
%c0 = arith.constant 0 : i8
%c255 = arith.constant 255 : i8
%c1 = arith.constant 1 : i8
// Unsigned i8 from 0 to 255: trip count is 255
// Trip counts are returned in their natural bitwidth and printed as signed.
// 255 in i8 is represented as -1 when printed in signed format.
// CHECK: "test.trip-count" = -1 : i8
%r = scf.for unsigned %i = %c0 to %c255 step %c1 iter_args(%0 = %a) -> i32 : i8 {
scf.yield %b : i32
}
return %r : i32
}
// -----
// CHECK-LABEL:func.func @trip_count_i8_unsigned_partial_range(
func.func @trip_count_i8_unsigned_partial_range(%a : i32, %b : i32) -> i32 {
%c0 = arith.constant 0 : i8
%c200 = arith.constant 200 : i8
%c1 = arith.constant 1 : i8
// Unsigned i8 from 0 to 200: trip count is 200
// 200 in i8 is represented as -56 when printed in signed format.
// CHECK: "test.trip-count" = -56 : i8
%r = scf.for unsigned %i = %c0 to %c200 step %c1 iter_args(%0 = %a) -> i32 : i8 {
scf.yield %b : i32
}
return %r : i32
}
// -----
// CHECK-LABEL:func.func @trip_count_i8_unsigned_high_range(
func.func @trip_count_i8_unsigned_high_range(%a : i32, %b : i32) -> i32 {
%c200 = arith.constant 200 : i8
%c255 = arith.constant 255 : i8
%c1 = arith.constant 1 : i8
// Unsigned i8 from 200 to 255: trip count is 55
// CHECK: "test.trip-count" = 55 : i8
%r = scf.for unsigned %i = %c200 to %c255 step %c1 iter_args(%0 = %a) -> i32 : i8 {
scf.yield %b : i32
}
return %r : i32
}
// -----
// CHECK-LABEL:func.func @trip_count_i8_signed_crossing_zero(
func.func @trip_count_i8_signed_crossing_zero(%a : i32, %b : i32) -> i32 {
%c-128 = arith.constant -128 : i32
%c127 = arith.constant 127 : i32
%c1 = arith.constant 1 : i32
// Signed i32 from -128 to 127, crossing zero
// CHECK: "test.trip-count" = 255
%r = scf.for %i = %c-128 to %c127 step %c1 iter_args(%0 = %a) -> i32 : i32 {
scf.yield %b : i32
}
return %r : i32
}
// -----
// CHECK-LABEL:func.func @trip_count_i8_signed_overflow_fix(
func.func @trip_count_i8_signed_overflow_fix(%a : i32, %b : i32) -> i32 {
%c-128 = arith.constant -128 : i8
%c127 = arith.constant 127 : i8
%c1 = arith.constant 1 : i8
// Signed i8 from -128 to 127: tests overflow fix
// Without the fix, computing (127 - (-128)) would overflow in i8.
// The trip count should be 255, but will be printed as -1 in i8 signed format.
// CHECK: "test.trip-count" = -1 : i8
%r = scf.for %i = %c-128 to %c127 step %c1 iter_args(%0 = %a) -> i32 : i8 {
scf.yield %b : i32
}
return %r : i32
}
// -----
// CHECK-LABEL:func.func @trip_count_i16_unsigned_full_range(
func.func @trip_count_i16_unsigned_full_range(%a : i32, %b : i32) -> i32 {
%c0 = arith.constant 0 : i16
%c65535 = arith.constant 65535 : i16
%c1 = arith.constant 1 : i16
// Unsigned i16 from 0 to 65535: trip count is 65535
// 65535 in i16 is represented as -1 when printed in signed format.
// CHECK: "test.trip-count" = -1 : i16
%r = scf.for unsigned %i = %c0 to %c65535 step %c1 iter_args(%0 = %a) -> i32 : i16 {
scf.yield %b : i32
}
return %r : i32
}
// -----
// CHECK-LABEL:func.func @trip_count_i8_unsigned_step_2(
func.func @trip_count_i8_unsigned_step_2(%a : i32, %b : i32) -> i32 {
%c0 = arith.constant 0 : i8
%c255 = arith.constant 255 : i8
%c2 = arith.constant 2 : i8
// Unsigned i8 from 0 to 255 step 2: trip count is 128 (255/2 rounded up)
// 128 in i8 is represented as -128 when printed in signed format.
// CHECK: "test.trip-count" = -128 : i8
%r = scf.for unsigned %i = %c0 to %c255 step %c2 iter_args(%0 = %a) -> i32 : i8 {
scf.yield %b : i32
}
return %r : i32
}