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
821 lines
26 KiB
MLIR
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
|
|
} |