Skip to content

[mlir][arith] Add more canonicalization and integration tests coverage #92272

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 13 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions mlir/test/Dialect/Arith/canonicalize.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -3022,6 +3022,36 @@ func.func @minsi_i0() -> i0 {
return %minsi : i0
}

// CHECK-LABEL: @extsiOnI1
// CHECK: %[[TRUE:.*]] = arith.constant true
// CHECK: %[[CST:.*]] = arith.constant -1 : i16
// CHECK: return %[[TRUE]], %[[CST]]
func.func @extsiOnI1() -> (i1, i16) {
%true = arith.constant -1 : i1
%0 = arith.extsi %true : i1 to i16
return %true, %0 : i1, i16
}

// CHECK-LABEL: @extuiOn1I1
// CHECK: %[[TRUE:.*]] = arith.constant true
// CHECK: %[[CST:.*]] = arith.constant 1 : i64
// CHECK: return %[[TRUE]], %[[CST]]
func.func @extuiOn1I1() -> (i1, i64) {
%true = arith.constant true
%0 = arith.extui %true : i1 to i64
return %true, %0 : i1, i64
}

// CHECK-LABEL: @trunciI16ToI8
// CHECK: %[[CST:.*]] = arith.constant 20194 : i16
// CHECK: %[[CST2:.*]] = arith.constant -30 : i8
// CHECK: return %[[CST]], %[[CST2]]
func.func @trunciI16ToI8() -> (i16, i8) {
%c20194_i16 = arith.constant 20194 : i16
%0 = arith.trunci %c20194_i16 : i16 to i8
return %c20194_i16, %0 : i16, i8
}

// CHECK-LABEL: @mulsi_extended_i0
// CHECK: %[[ZERO:.*]] = arith.constant 0 : i0
// CHECK: return %[[ZERO]], %[[ZERO]] : i0
Expand Down
57 changes: 57 additions & 0 deletions mlir/test/Integration/Dialect/Arith/CPU/addition.mlir
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// Tests arith operations on i1 type.
// These tests are intended to be target agnostic: they should yield the same results
// regardless of the target platform.

// RUN: mlir-opt %s --convert-scf-to-cf --convert-cf-to-llvm --convert-vector-to-llvm \
// RUN: --convert-func-to-llvm --convert-arith-to-llvm | \
// RUN: mlir-cpu-runner -e entry -entry-point-result=void \
// RUN: --shared-libs=%mlir_c_runner_utils | \
// RUN: FileCheck %s --match-full-lines

func.func @zero_plus_one_on_i1() {
// addi on i1
// addi(0, 1) : i1 = 1 : i1; addi(0, -1) : i1 = 1
// CHECK: 1
// CHECK-NEXT: 1
// CHECK-NEXT: 1
%false = arith.constant 0 : i1
%true = arith.constant 1 : i1
%true_0 = arith.constant -1 : i1
vector.print %true_0 : i1
%0 = arith.addi %false, %true : i1
vector.print %0 : i1
%1 = arith.addi %false, %true_0 : i1
vector.print %1 : i1
return
}

func.func @addui_extended_i1() {
// addui_extended on i1
// addui_extended 1 1 : i1 = 0, 1
// CHECK-NEXT: 0
// CHECK-NEXT: 1
%true = arith.constant 1 : i1
%sum, %overflow = arith.addui_extended %true, %true : i1, i1
vector.print %sum : i1
vector.print %overflow : i1
return
}

func.func @addui_extended_overflow_bit_is_n1() {
// addui_extended overflow bit is treated as -1
// addui_extended -1633386 -1643386 = ... 1 (overflow because negative numbers are large positive numbers)
// CHECK-NEXT: 0
%c-16433886_i64 = arith.constant -16433886 : i64
%sum, %overflow = arith.addui_extended %c-16433886_i64, %c-16433886_i64 : i64, i1
%false = arith.constant false
%0 = arith.cmpi sge, %overflow, %false : i1
vector.print %0 : i1 // but prints as "1"
return
}

func.func @entry() {
func.call @zero_plus_one_on_i1() : () -> ()
func.call @addui_extended_i1() : () -> ()
func.call @addui_extended_overflow_bit_is_n1() : () -> ()
return
}
61 changes: 61 additions & 0 deletions mlir/test/Integration/Dialect/Arith/CPU/comparison.mlir
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// Tests comparison operations.
// These tests are intended to be target agnostic: they should yield the same results
// regardless of the target platform.

// RUN: mlir-opt %s --convert-scf-to-cf --convert-cf-to-llvm --convert-vector-to-llvm \
// RUN: --convert-func-to-llvm --convert-arith-to-llvm | \
// RUN: mlir-cpu-runner -e entry -entry-point-result=void \
// RUN: --shared-libs=%mlir_c_runner_utils | \
// RUN: FileCheck %s --match-full-lines

func.func @signed_comparison_on_i1s() {
// signed comparisons on i1s
// slt 0 1 = false, sle 0 1 = false, sgt 0 1 = true, sge 0 1 = true
// CHECK: 0
// CHECK-NEXT: 0
// CHECK-NEXT: 1
// CHECK-NEXT: 1
%false = arith.constant false
%true = arith.constant true
%0 = arith.cmpi slt, %false, %true : i1
%1 = arith.cmpi sle, %false, %true : i1
%2 = arith.cmpi sgt, %false, %true : i1
%3 = arith.cmpi sge, %false, %true : i1
vector.print %0 : i1
vector.print %1 : i1
vector.print %2 : i1
vector.print %3 : i1
return
}

func.func @sge_0_1_is_true() {
// sge 0 -1, sge 0 1, should be true
// sge 0 -1 == sge 0 1 == true (1)
// CHECK-NEXT: 1
// CHECK-NEXT: 1
%false = arith.constant 0 : i1
%true = arith.constant 1 : i1
%true_0 = arith.constant -1 : i1
%0 = arith.cmpi sge, %false, %true : i1
%1 = arith.cmpi sge, %false, %true_0 : i1
vector.print %0 : i1
vector.print %1 : i1
return
}

func.func @zero_ult_min_index() {
// 0 `ult` -2^63 = true
// CHECK-NEXT: 1
%c0 = arith.constant 0 : index
%c-9223372036854775808 = arith.constant -9223372036854775808 : index
%0 = arith.cmpi ult, %c0, %c-9223372036854775808 : index
vector.print %0 : i1
return
}

func.func @entry() {
func.call @signed_comparison_on_i1s() : () -> ()
func.call @sge_0_1_is_true() : () -> ()
func.call @zero_ult_min_index() : () -> ()
return
}
69 changes: 69 additions & 0 deletions mlir/test/Integration/Dialect/Arith/CPU/division.mlir
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// Tests division operations and their variants (e.g. ceil/floordiv, rem etc)
// These tests are intended to be target agnostic: they should yield the same results
// regardless of the target platform.

// RUN: mlir-opt %s --test-lower-to-llvm | \
// RUN: mlir-cpu-runner -e entry -entry-point-result=void \
// RUN: --shared-libs=%mlir_c_runner_utils | \
// RUN: FileCheck %s --match-full-lines

func.func @divsi_round_towards_zero() {
// divsi should round towards zero (rather than -infinity)
// divsi -97 68 = -1
// CHECK: -1
%c68_i8 = arith.constant 68 : i8
%c-97_i8 = arith.constant -97 : i8
%0 = arith.divsi %c-97_i8, %c68_i8 : i8
vector.print %0 : i8
return
}

func.func @remsi_print_zero() {
// remsi minInt -1 = 0
// remsi -2^(w-1) -1 = 0
// CHECK-NEXT: -1
// CHECK-NEXT: -128
// CHECK-NEXT: 0
%c-1_i8 = arith.constant -1 : i8
%c-128_i8 = arith.constant -128 : i8
%0 = arith.remsi %c-128_i8, %c-1_i8 : i8
vector.print %c-1_i8 : i8
vector.print %c-128_i8 : i8
vector.print %0 : i8
return
}

func.func @ceildivsi_keep_signs() {
// ceildivsi should keep signs
// forall w, y. (w > 0, y > 0) => -2^w `ceildiv` y : i_w < 0
// CHECK-NEXT: -18
%c7_i8 = arith.constant 7 : i8
%c-128_i8 = arith.constant -128 : i8
%0 = arith.ceildivsi %c-128_i8, %c7_i8 : i8
vector.print %0 : i8
return
}

func.func @divsi_i1_signed_repr() {
// divsi should output unsigned representation, e.g. in the case of i1
// repr (divsi (x : i1) (x : i1)) = 1 (not represented as -1)
// CHECK-NEXT: %2=1
// CHECK-NEXT: %3=1
%false = arith.constant false
%true = arith.constant true
%0 = arith.divsi %true, %true : i1
vector.print str "%2="
vector.print %0 : i1
%1 = arith.cmpi sge, %false, %0 : i1
vector.print str "%3="
vector.print %1 : i1
return
}

func.func @entry() {
func.call @divsi_round_towards_zero() : () -> ()
func.call @remsi_print_zero() : () -> ()
func.call @ceildivsi_keep_signs() : () -> ()
func.call @divsi_i1_signed_repr() : () -> ()
return
}
77 changes: 77 additions & 0 deletions mlir/test/Integration/Dialect/Arith/CPU/index-casts.mlir
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// Tests casting on index types.
// These tests are intended to be target agnostic: they should yield the same results
// regardless of the target platform.

// RUN: mlir-opt %s --test-lower-to-llvm | \
// RUN: mlir-cpu-runner -e entry -entry-point-result=void \
// RUN: --shared-libs=%mlir_c_runner_utils | \
// RUN: FileCheck %s --match-full-lines

func.func @i32_neg_1_index_cast() {
// index casting of -1 : i32 -> 2^64 - 1
// index_cast(-1 : i32) = 2^64 - 1;
// CHECK: -1
// CHECK-NEXT: 18446744073709551615
%c-1_i32 = arith.constant -1 : i32
%0 = arith.index_cast %c-1_i32 : i32 to index
vector.print %c-1_i32 : i32
vector.print %0 : index
return
}

func.func @index_castui_and_index_cast() {
// casting to index, ui and si
// -1 : i32; index_cast(-1 : i32) = 2^64 - 1; index_castui(-1 : i32) = 2^32 - 1
// CHECK-NEXT: -1
// CHECK-NEXT: 18446744073709551615
// CHECK-NEXT: 4294967295
%c-1_i32 = arith.constant -1 : i32
%0 = arith.index_cast %c-1_i32 : i32 to index
%1 = arith.index_castui %c-1_i32 : i32 to index
vector.print %c-1_i32 : i32
vector.print %0 : index
vector.print %1 : index
return
}

func.func @index_cast_after_conversion() {
// index should be represented as unsigned ints, and reflected through comparison:
// index_cast(x) `slt` index_cast(y) == x `slt` y
// CHECK-NEXT: 1
%c15608_i32 = arith.constant 15608 : i32
%c-9705694_i64 = arith.constant -9705694 : i64
%0 = arith.index_cast %c15608_i32 : i32 to index // small positive num
%1 = arith.index_cast %c-9705694_i64 : i64 to index // large positive num
%2 = arith.cmpi slt, %1, %0 : index // %1 `slt` %0 => true
vector.print %2 : i1
return
}

func.func @index_castui_downcast() {
// index_castui casting down truncates bits
// index_castui 11277513 = 1 : i3
// CHECK-NEXT: 1
%c11277513 = arith.constant 11277513 : index
%0 = arith.index_castui %c11277513 : index to i3
vector.print %0 : i3
return
}

func.func @index_cast_downcast() {
// index_cast casting down truncates bits
// index_cast -3762 = 334 : i12
// CHECK-NEXT: 334
%c3762 = arith.constant -3762 : index
%0 = arith.index_cast %c3762 : index to i12
vector.print %0 : i12
return
}

func.func @entry() {
func.call @i32_neg_1_index_cast() : () -> ()
func.call @index_castui_and_index_cast() : () -> ()
func.call @index_cast_after_conversion() : () -> ()
func.call @index_castui_downcast() : () -> ()
func.call @index_cast_downcast() : () -> ()
return
}
52 changes: 52 additions & 0 deletions mlir/test/Integration/Dialect/Arith/CPU/int-trunc-ext.mlir
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Tests arith truncation and extension operations.
// These tests are intended to be target agnostic: they should yield the same results
// regardless of the target platform.

// RUN: mlir-opt %s --convert-scf-to-cf --convert-cf-to-llvm --convert-vector-to-llvm \
// RUN: --convert-func-to-llvm --convert-arith-to-llvm | \
// RUN: mlir-cpu-runner -e entry -entry-point-result=void \
// RUN: --shared-libs=%mlir_c_runner_utils | \
// RUN: FileCheck %s --match-full-lines

func.func @extsi_on_i1() {
// extsi on 1 : i1
// extsi(1: i1) = -1 : i16
// CHECK: 1
// CHECK-NEXT: -1
%true = arith.constant -1 : i1
%0 = arith.extsi %true : i1 to i16
vector.print %true : i1
vector.print %0 : i16
return
}

func.func @extui_on_1_i1() {
// extui should extend i1 with 0 bits not 1s
// extui(1 : i1) = 1 : i64
// CHECK-NEXT: 1
// CHECK-NEXT: 1
%true = arith.constant true
%0 = arith.extui %true : i1 to i64
vector.print %true : i1
vector.print %0 : i64
return
}

func.func @trunci_i16_to_i8() {
// trunci on 20194 : i16
// trunci(20194 : i16) = -30 : i8
// CHECK-NEXT: 20194
// CHECK-NEXT: -30
%c20194_i16 = arith.constant 20194 : i16
%0 = arith.trunci %c20194_i16 : i16 to i8
vector.print %c20194_i16 : i16
vector.print %0 : i8
return
}

func.func @entry() {
func.call @extsi_on_i1() : () -> ()
func.call @extui_on_1_i1() : () -> ()
func.call @trunci_i16_to_i8() : () -> ()
return
}
Loading