[Mlir-commits] [mlir] [mlir][arith] Add more canonicalization and integration tests coverage (PR #92272)

Jacob Yu llvmlistbot at llvm.org
Thu May 16 08:00:42 PDT 2024


https://github.com/pingshiyu updated https://github.com/llvm/llvm-project/pull/92272

>From bda65c65482ed65dc5a2030301e4256256e2311f Mon Sep 17 00:00:00 2001
From: pingshiyu <pingshiyu at gmail.com>
Date: Wed, 15 May 2024 15:31:40 +0100
Subject: [PATCH 1/6] [mlir][arith] new regression tests from independent
 interpreter development

---
 mlir/test/Dialect/Arith/canonicalize.mlir     | 30 +++++++++++
 .../Dialect/Arith/CPU/test-semantics.mlir     | 52 +++++++++++++++++++
 2 files changed, 82 insertions(+)
 create mode 100644 mlir/test/Integration/Dialect/Arith/CPU/test-semantics.mlir

diff --git a/mlir/test/Dialect/Arith/canonicalize.mlir b/mlir/test/Dialect/Arith/canonicalize.mlir
index e4f95bb0545a2..aa79ad1bead56 100644
--- a/mlir/test/Dialect/Arith/canonicalize.mlir
+++ b/mlir/test/Dialect/Arith/canonicalize.mlir
@@ -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
diff --git a/mlir/test/Integration/Dialect/Arith/CPU/test-semantics.mlir b/mlir/test/Integration/Dialect/Arith/CPU/test-semantics.mlir
new file mode 100644
index 0000000000000..cd1cad4d56da9
--- /dev/null
+++ b/mlir/test/Integration/Dialect/Arith/CPU/test-semantics.mlir
@@ -0,0 +1,52 @@
+// Regression test suite from an independent development of Arith's
+// semantics and a fuzzer
+
+// 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
+
+module {
+  func.func @extsiOnI1() {
+    %true = arith.constant -1 : i1
+    %0 = arith.extsi %true : i1 to i16
+    vector.print %true : i1
+    vector.print %0 : i16
+    return
+  }
+
+  func.func @extuiOn1I1() {
+    %true = arith.constant true
+    %0 = arith.extui %true : i1 to i64
+    vector.print %true : i1
+    vector.print %0 : i64
+    return
+  }
+
+  func.func @trunciI16ToI8() {
+    %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() {
+
+    // CHECK:      1
+    // CHECK:      -1
+    func.call @extsiOnI1() : () -> ()
+    
+    // CHECK:      1
+    // CHECK:      1
+    func.call @extuiOn1I1() : () -> ()
+
+    // CHECK:      20194
+    // CHECK:      -30
+    func.call @trunciI16ToI8() : () -> ()
+
+
+    return
+  }
+}
\ No newline at end of file

>From 060398397aac1cede7a8d2101277e349ab4f0416 Mon Sep 17 00:00:00 2001
From: Jacob Yu <pingshiyu at gmail.com>
Date: Wed, 15 May 2024 21:49:20 +0100
Subject: [PATCH 2/6] Update
 mlir/test/Integration/Dialect/Arith/CPU/test-semantics.mlir

Co-authored-by: Fehr Mathieu <mathieu.fehr at gmail.com>
---
 mlir/test/Integration/Dialect/Arith/CPU/test-semantics.mlir | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/mlir/test/Integration/Dialect/Arith/CPU/test-semantics.mlir b/mlir/test/Integration/Dialect/Arith/CPU/test-semantics.mlir
index cd1cad4d56da9..bc909f0bfbccf 100644
--- a/mlir/test/Integration/Dialect/Arith/CPU/test-semantics.mlir
+++ b/mlir/test/Integration/Dialect/Arith/CPU/test-semantics.mlir
@@ -49,4 +49,4 @@ module {
 
     return
   }
-}
\ No newline at end of file
+}

>From d67d02af849c54904a3047a9bf484cf9f874baec Mon Sep 17 00:00:00 2001
From: pingshiyu <pingshiyu at gmail.com>
Date: Wed, 15 May 2024 22:05:04 +0100
Subject: [PATCH 3/6] fix up! adding check-nexts

---
 .../Dialect/Arith/CPU/test-int-trunc-ext.mlir | 49 +++++++++++++++++++
 1 file changed, 49 insertions(+)
 create mode 100644 mlir/test/Integration/Dialect/Arith/CPU/test-int-trunc-ext.mlir

diff --git a/mlir/test/Integration/Dialect/Arith/CPU/test-int-trunc-ext.mlir b/mlir/test/Integration/Dialect/Arith/CPU/test-int-trunc-ext.mlir
new file mode 100644
index 0000000000000..bb494d889ea8f
--- /dev/null
+++ b/mlir/test/Integration/Dialect/Arith/CPU/test-int-trunc-ext.mlir
@@ -0,0 +1,49 @@
+// tests arith truncation and extension operations.
+
+// 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
+
+module {
+  func.func @extsiOnI1() {
+    %true = arith.constant -1 : i1
+    %0 = arith.extsi %true : i1 to i16
+    vector.print %true : i1
+    vector.print %0 : i16
+    return
+  }
+
+  func.func @extuiOn1I1() {
+    %true = arith.constant true
+    %0 = arith.extui %true : i1 to i64
+    vector.print %true : i1
+    vector.print %0 : i64
+    return
+  }
+
+  func.func @trunciI16ToI8() {
+    %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() {
+    // CHECK:      1
+    // CHECK-NEXT: -1
+    func.call @extsiOnI1() : () -> ()
+    
+    // CHECK-NEXT: 1
+    // CHECK-NEXT: 1
+    func.call @extuiOn1I1() : () -> ()
+
+    // CHECK-NEXT: 20194
+    // CHECK-NEXT: -30
+    func.call @trunciI16ToI8() : () -> ()
+
+    return
+  }
+}
\ No newline at end of file

>From 21c34310b294044ac98dc809740ebcdfae6a8bbd Mon Sep 17 00:00:00 2001
From: pingshiyu <pingshiyu at gmail.com>
Date: Wed, 15 May 2024 22:24:02 +0100
Subject: [PATCH 4/6] formatting

---
 .../test/Dialect/Arith/canonicalize-mini.mlir | 31 ++++++++
 .../Dialect/Arith/CPU/test-int-trunc-ext.mlir | 70 +++++++++----------
 2 files changed, 65 insertions(+), 36 deletions(-)
 create mode 100644 mlir/test/Dialect/Arith/canonicalize-mini.mlir

diff --git a/mlir/test/Dialect/Arith/canonicalize-mini.mlir b/mlir/test/Dialect/Arith/canonicalize-mini.mlir
new file mode 100644
index 0000000000000..57a4453e041a9
--- /dev/null
+++ b/mlir/test/Dialect/Arith/canonicalize-mini.mlir
@@ -0,0 +1,31 @@
+// RUN: mlir-opt %s -canonicalize="test-convergence" --split-input-file | FileCheck %s
+
+// 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
+}
\ No newline at end of file
diff --git a/mlir/test/Integration/Dialect/Arith/CPU/test-int-trunc-ext.mlir b/mlir/test/Integration/Dialect/Arith/CPU/test-int-trunc-ext.mlir
index bb494d889ea8f..c8d773d948d27 100644
--- a/mlir/test/Integration/Dialect/Arith/CPU/test-int-trunc-ext.mlir
+++ b/mlir/test/Integration/Dialect/Arith/CPU/test-int-trunc-ext.mlir
@@ -6,44 +6,42 @@
 // RUN:                   --shared-libs=%mlir_c_runner_utils | \
 // RUN:   FileCheck %s --match-full-lines
 
-module {
-  func.func @extsiOnI1() {
-    %true = arith.constant -1 : i1
-    %0 = arith.extsi %true : i1 to i16
-    vector.print %true : i1
-    vector.print %0 : i16
-    return
-  }
+func.func @extsiOnI1() {
+  %true = arith.constant -1 : i1
+  %0 = arith.extsi %true : i1 to i16
+  vector.print %true : i1
+  vector.print %0 : i16
+  return
+}
 
-  func.func @extuiOn1I1() {
-    %true = arith.constant true
-    %0 = arith.extui %true : i1 to i64
-    vector.print %true : i1
-    vector.print %0 : i64
-    return
-  }
+func.func @extuiOn1I1() {
+  %true = arith.constant true
+  %0 = arith.extui %true : i1 to i64
+  vector.print %true : i1
+  vector.print %0 : i64
+  return
+}
 
-  func.func @trunciI16ToI8() {
-    %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 @trunciI16ToI8() {
+  %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() {
-    // CHECK:      1
-    // CHECK-NEXT: -1
-    func.call @extsiOnI1() : () -> ()
-    
-    // CHECK-NEXT: 1
-    // CHECK-NEXT: 1
-    func.call @extuiOn1I1() : () -> ()
+func.func @entry() {
+  // CHECK:      1
+  // CHECK-NEXT: -1
+  func.call @extsiOnI1() : () -> ()
+  
+  // CHECK-NEXT: 1
+  // CHECK-NEXT: 1
+  func.call @extuiOn1I1() : () -> ()
 
-    // CHECK-NEXT: 20194
-    // CHECK-NEXT: -30
-    func.call @trunciI16ToI8() : () -> ()
+  // CHECK-NEXT: 20194
+  // CHECK-NEXT: -30
+  func.call @trunciI16ToI8() : () -> ()
 
-    return
-  }
-}
\ No newline at end of file
+  return
+}

>From 5a2b65cac1b86a9a5cd86572ea5cbb2eca51cb11 Mon Sep 17 00:00:00 2001
From: pingshiyu <pingshiyu at gmail.com>
Date: Wed, 15 May 2024 22:27:01 +0100
Subject: [PATCH 5/6] removed unneeded files

---
 .../test/Dialect/Arith/canonicalize-mini.mlir | 31 -----------
 .../Dialect/Arith/CPU/test-semantics.mlir     | 52 -------------------
 2 files changed, 83 deletions(-)
 delete mode 100644 mlir/test/Dialect/Arith/canonicalize-mini.mlir
 delete mode 100644 mlir/test/Integration/Dialect/Arith/CPU/test-semantics.mlir

diff --git a/mlir/test/Dialect/Arith/canonicalize-mini.mlir b/mlir/test/Dialect/Arith/canonicalize-mini.mlir
deleted file mode 100644
index 57a4453e041a9..0000000000000
--- a/mlir/test/Dialect/Arith/canonicalize-mini.mlir
+++ /dev/null
@@ -1,31 +0,0 @@
-// RUN: mlir-opt %s -canonicalize="test-convergence" --split-input-file | FileCheck %s
-
-// 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
-}
\ No newline at end of file
diff --git a/mlir/test/Integration/Dialect/Arith/CPU/test-semantics.mlir b/mlir/test/Integration/Dialect/Arith/CPU/test-semantics.mlir
deleted file mode 100644
index bc909f0bfbccf..0000000000000
--- a/mlir/test/Integration/Dialect/Arith/CPU/test-semantics.mlir
+++ /dev/null
@@ -1,52 +0,0 @@
-// Regression test suite from an independent development of Arith's
-// semantics and a fuzzer
-
-// 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
-
-module {
-  func.func @extsiOnI1() {
-    %true = arith.constant -1 : i1
-    %0 = arith.extsi %true : i1 to i16
-    vector.print %true : i1
-    vector.print %0 : i16
-    return
-  }
-
-  func.func @extuiOn1I1() {
-    %true = arith.constant true
-    %0 = arith.extui %true : i1 to i64
-    vector.print %true : i1
-    vector.print %0 : i64
-    return
-  }
-
-  func.func @trunciI16ToI8() {
-    %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() {
-
-    // CHECK:      1
-    // CHECK:      -1
-    func.call @extsiOnI1() : () -> ()
-    
-    // CHECK:      1
-    // CHECK:      1
-    func.call @extuiOn1I1() : () -> ()
-
-    // CHECK:      20194
-    // CHECK:      -30
-    func.call @trunciI16ToI8() : () -> ()
-
-
-    return
-  }
-}

>From ac20f66ca1dabc0047c4d073a3debe51a2c240bd Mon Sep 17 00:00:00 2001
From: pingshiyu <pingshiyu at gmail.com>
Date: Thu, 16 May 2024 16:00:26 +0100
Subject: [PATCH 6/6] adding rest of integration tests

---
 .../Dialect/Arith/CPU/test-arithmetic.mlir    |  73 +++++++++
 .../Dialect/Arith/CPU/test-i1-operations.mlir | 146 ++++++++++++++++++
 .../Dialect/Arith/CPU/test-indices.mlir       | 132 ++++++++++++++++
 .../Dialect/Arith/CPU/test-int-trunc-ext.mlir |  58 +++----
 .../Dialect/Arith/CPU/test-shifts.mlir        | 103 ++++++++++++
 5 files changed, 486 insertions(+), 26 deletions(-)
 create mode 100644 mlir/test/Integration/Dialect/Arith/CPU/test-arithmetic.mlir
 create mode 100644 mlir/test/Integration/Dialect/Arith/CPU/test-i1-operations.mlir
 create mode 100644 mlir/test/Integration/Dialect/Arith/CPU/test-indices.mlir
 create mode 100644 mlir/test/Integration/Dialect/Arith/CPU/test-shifts.mlir

diff --git a/mlir/test/Integration/Dialect/Arith/CPU/test-arithmetic.mlir b/mlir/test/Integration/Dialect/Arith/CPU/test-arithmetic.mlir
new file mode 100644
index 0000000000000..b6ff34c2d8960
--- /dev/null
+++ b/mlir/test/Integration/Dialect/Arith/CPU/test-arithmetic.mlir
@@ -0,0 +1,73 @@
+// tests simple arithmetic operations (i.e. add/sub/mul/div) and their variants (e.g. signed/unsigned, floor/ceildiv)
+
+// 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 @divsiRoundTowardsZero() {
+    // divsi should round towards zero (rather than -infinity)
+    // divsi -97 68 = -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 @mulsimuluiExtendedOverflows() {
+    // mulsi and mului extended versions, with overflow
+    // mulsi_extended -100, -100 : i8 = (16, 39); mului_extended -100, -100 : i8 = (16, 95)
+    %c-100_i8 = arith.constant -100 : i8
+    %low, %high = arith.mulsi_extended %c-100_i8, %c-100_i8 : i8
+    vector.print %low : i8
+    vector.print %high : i8
+    %low_0, %high_1 = arith.mului_extended %c-100_i8, %c-100_i8 : i8
+    vector.print %low_0 : i8
+    vector.print %high_1 : i8
+    return
+}
+
+func.func @remsiPrintZero() {
+    // remsi minInt -1 = 0
+    // remsi -2^(w-1) -1 = 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 @ceildivsiKeepSigns() {
+    // ceildivsi should keep signs
+    // forall w, y. (w > 0, y > 0) => -2^w `ceildiv` y : i_w < 0
+    %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 @entry() {
+
+    // CHECK:       -1
+    func.call @divsiRoundTowardsZero() : () -> ()
+
+    // CHECK-NEXT:  16
+    // CHECK-NEXT:  39
+    // CHECK-NEXT:  16
+    // CHECK-NEXT:  95
+    func.call @mulsimuluiExtendedOverflows() : () -> ()
+
+    // CHECK-NEXT:  -1
+    // CHECK-NEXT:  -128
+    // CHECK-NEXT:  0
+    func.call @remsiPrintZero() : () -> ()
+
+    // CHECK-NEXT:  -18
+    func.call @ceildivsiKeepSigns() : () -> ()
+    
+    return
+}
diff --git a/mlir/test/Integration/Dialect/Arith/CPU/test-i1-operations.mlir b/mlir/test/Integration/Dialect/Arith/CPU/test-i1-operations.mlir
new file mode 100644
index 0000000000000..c8674d661fb66
--- /dev/null
+++ b/mlir/test/Integration/Dialect/Arith/CPU/test-i1-operations.mlir
@@ -0,0 +1,146 @@
+// tests arith operations on i1 type.
+
+// 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 @zeroPlusOneOnI1() {
+    // addi on i1
+    // addi(0, 1) : i1 = 1 : i1; addi(0, -1) : i1 = 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 @i1Printing() {
+    // printing i1 values
+    // print(0 : i1) = '0'; print(1 : i1) = '1'; print(-1 : i1) = '1'
+    %false = arith.constant false
+    %true = arith.constant 1 : i1
+    %true_0 = arith.constant -1 : i1
+    vector.print %false : i1
+    vector.print %true : i1
+    vector.print %true_0 : i1
+    return
+}
+
+func.func @signedComparisonOnI1s() {
+    // signed comparisons on i1s
+    // slt 0 1 = false, sle 0 1 = false, sgt 0 1 = true, sge 0 1 = true
+    %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 @sge0And1IsTrue() {
+    // sge 0 -1, sge 0 1, should be true
+    // sge 0 -1 == sge 0 1 == true (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 @divsiI1SignedRepr() {
+    // divsi should output unsigned representation, e.g. in the case of i1
+    // repr (divsi (x : i1) (x : i1)) = 1 (not represented as -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 @adduiExtendedI1() {
+    // addui_extended on i1
+    // addui_extended 1 1 : i1 = 0, 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 @adduiExtendedOverflowBitIsN1() {
+    // addui_extended overflow bit is treated as -1
+    // addui_extended -1633386 -1643386 = ... 1 (overflow because negative numbers are large positive numbers)
+    %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 @mulsiExtendedOnI1() {
+    // mulsi_extended on i1, tests for overflow bit
+    // mulsi_extended 1, 1 : i1 = (1, 0)
+    %true = arith.constant true
+    %low, %high = arith.mulsi_extended %true, %true : i1
+    vector.print %low : i1
+    vector.print %high : i1
+    return
+}
+
+func.func @entry() {
+    // CHECK:      1
+    // CHECK-NEXT: 1
+    // CHECK-NEXT: 1
+    func.call @zeroPlusOneOnI1() : () -> ()
+
+    // CHECK-NEXT: 0
+    // CHECK-NEXT: 1
+    // CHECK-NEXT: 1
+    func.call @i1Printing() : () -> ()
+
+    // CHECK-NEXT: 0
+    // CHECK-NEXT: 0
+    // CHECK-NEXT: 1
+    // CHECK-NEXT: 1
+    func.call @signedComparisonOnI1s() : () -> ()
+
+    // CHECK-NEXT: 1
+    // CHECK-NEXT: 1
+    func.call @sge0And1IsTrue() : () -> ()
+
+    // CHECK-NEXT: %2=1
+    // CHECK-NEXT: %3=1
+    func.call @divsiI1SignedRepr() : () -> ()
+
+    // CHECK-NEXT: 0
+    // CHECK-NEXT: 1
+    func.call @adduiExtendedI1() : () -> ()
+
+    // CHECK-NEXT: 0
+    func.call @adduiExtendedOverflowBitIsN1() : () -> ()
+
+    // CHECK-NEXT: 1
+    // CHECK-NEXT: 0
+    func.call @mulsiExtendedOnI1() : () -> ()
+
+    return
+}
diff --git a/mlir/test/Integration/Dialect/Arith/CPU/test-indices.mlir b/mlir/test/Integration/Dialect/Arith/CPU/test-indices.mlir
new file mode 100644
index 0000000000000..99bb5167fee16
--- /dev/null
+++ b/mlir/test/Integration/Dialect/Arith/CPU/test-indices.mlir
@@ -0,0 +1,132 @@
+// tests arith operations on indices.
+
+// 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 @largestIndexPrinting() {
+    // printing index values
+    // print(0 : index) = '0'; print(1 : index) = '1'; print(-1 : index) = '2^w - 1'
+    %c0 = arith.constant 0 : index
+    %c1 = arith.constant 1 : index
+    %c-1 = arith.constant -1 : index
+    vector.print %c0 : index
+    vector.print %c1 : index
+    vector.print %c-1 : index
+    return
+}
+
+func.func @i32Neg1IndexCast() {
+    // index casting of -1 : i32 -> 2^64 - 1
+    // index_cast(-1 : i32) = 2^64 - 1;
+    %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 @indexCastuiAndSi() {
+    // casting to index, ui and si
+    // -1 : i32; index_cast(-1 : i32) = 2^64 - 1; index_castui(-1 : i32) = 2^32 - 1
+    %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 @indexCastAfterConversion() {
+    // index should be represented as unsigned ints, and reflected through comparison:
+    // index_cast(x) `slt` index_cast(y) == x `slt` y
+    %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 @indexConstantsRepresentation() {
+    // index constants are printed as unsigned
+    // vector.print(arith.constant(x)) ~= toUnsignedRepr x
+    %c-1 = arith.constant -1 : index
+    %c63 = arith.constant 63 : index
+    %c0 = arith.constant 0 : index
+    vector.print %c-1 : index
+    vector.print %c63 : index
+    vector.print %c0 : index
+    return
+}
+
+func.func @zeroUltMinIndex() {
+    // 0 `ult` -2^63 = true
+    %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 @indexCastuiDowncast() {
+    // index_castui casting down truncates bits
+    // index_castui 11277513 = 1 : i3
+    %c11277513 = arith.constant 11277513 : index
+    %0 = arith.index_castui %c11277513 : index to i3
+    vector.print %0 : i3
+    return
+}
+
+func.func @indexCastDowncast() {
+    // index_cast casting down truncates bits
+    // index_cast -3762 = 334 : i12
+    %c3762 = arith.constant -3762 : index
+    %0 = arith.index_cast %c3762 : index to i12
+    vector.print %0 : i12
+    return
+}
+
+func.func @c0() -> i64 {
+    // heper function for below test
+    %c100_i64 = arith.constant 100 : i64
+    return %c100_i64 : i64
+}
+
+func.func @entry() {
+    // CHECK:      0
+    // CHECK-NEXT: 1
+    // CHECK-NEXT: 18446744073709551615
+    func.call @largestIndexPrinting() : () -> ()
+
+    // CHECK-NEXT: -1
+    // CHECK-NEXT: 18446744073709551615
+    func.call @i32Neg1IndexCast() : () -> ()
+
+    // CHECK-NEXT: -1
+    // CHECK-NEXT: 18446744073709551615
+    // CHECK-NEXT: 4294967295
+    func.call @indexCastuiAndSi() : () -> ()
+
+    // CHECK-NEXT: 1
+    func.call @indexCastAfterConversion() : () -> ()
+
+    // CHECK-NEXT: 18446744073709551615
+    // CHECK-NEXT: 63
+    // CHECK-NEXT: 0
+    func.call @indexConstantsRepresentation() : () -> ()
+
+    // CHECK-NEXT: 1
+    func.call @zeroUltMinIndex() : () -> ()
+
+    // CHECK-NEXT: 1
+    func.call @indexCastuiDowncast() : () -> ()
+
+    // CHECK-NEXT: 334
+    func.call @indexCastDowncast() : () -> ()
+
+    return
+}
diff --git a/mlir/test/Integration/Dialect/Arith/CPU/test-int-trunc-ext.mlir b/mlir/test/Integration/Dialect/Arith/CPU/test-int-trunc-ext.mlir
index c8d773d948d27..c91fd0593e6bd 100644
--- a/mlir/test/Integration/Dialect/Arith/CPU/test-int-trunc-ext.mlir
+++ b/mlir/test/Integration/Dialect/Arith/CPU/test-int-trunc-ext.mlir
@@ -7,41 +7,47 @@
 // RUN:   FileCheck %s --match-full-lines
 
 func.func @extsiOnI1() {
-  %true = arith.constant -1 : i1
-  %0 = arith.extsi %true : i1 to i16
-  vector.print %true : i1
-  vector.print %0 : i16
-  return
+    // extsi on 1 : i1
+    // extsi(1: i1) = -1 : i16
+    %true = arith.constant -1 : i1
+    %0 = arith.extsi %true : i1 to i16
+    vector.print %true : i1
+    vector.print %0 : i16
+    return
 }
 
 func.func @extuiOn1I1() {
-  %true = arith.constant true
-  %0 = arith.extui %true : i1 to i64
-  vector.print %true : i1
-  vector.print %0 : i64
-  return
+    // extui should extend i1 with 0 bits not 1s
+    // extui(1 : i1) = 1 : i64
+    %true = arith.constant true
+    %0 = arith.extui %true : i1 to i64
+    vector.print %true : i1
+    vector.print %0 : i64
+    return
 }
 
 func.func @trunciI16ToI8() {
-  %c20194_i16 = arith.constant 20194 : i16
-  %0 = arith.trunci %c20194_i16 : i16 to i8
-  vector.print %c20194_i16 : i16
-  vector.print %0 : i8
-  return
+    // trunci on 20194 : i16
+    // trunci(20194 : i16) = -30 : i8
+    %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() {
-  // CHECK:      1
-  // CHECK-NEXT: -1
-  func.call @extsiOnI1() : () -> ()
-  
-  // CHECK-NEXT: 1
-  // CHECK-NEXT: 1
-  func.call @extuiOn1I1() : () -> ()
+    // CHECK:      1
+    // CHECK-NEXT: -1
+    func.call @extsiOnI1() : () -> ()
+    
+    // CHECK-NEXT: 1
+    // CHECK-NEXT: 1
+    func.call @extuiOn1I1() : () -> ()
 
-  // CHECK-NEXT: 20194
-  // CHECK-NEXT: -30
-  func.call @trunciI16ToI8() : () -> ()
+    // CHECK-NEXT: 20194
+    // CHECK-NEXT: -30
+    func.call @trunciI16ToI8() : () -> ()
 
-  return
+    return
 }
diff --git a/mlir/test/Integration/Dialect/Arith/CPU/test-shifts.mlir b/mlir/test/Integration/Dialect/Arith/CPU/test-shifts.mlir
new file mode 100644
index 0000000000000..21891c96af3ab
--- /dev/null
+++ b/mlir/test/Integration/Dialect/Arith/CPU/test-shifts.mlir
@@ -0,0 +1,103 @@
+// tests arith shifting operations.
+
+// 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 @shrsiPreserveSigns() {
+    // shrsi preserves signs
+    // shrsi -10 7 : i8 = -1
+    %c7_i8 = arith.constant 7 : i8
+    %c-10_i8 = arith.constant -10 : i8
+    %0 = arith.shrsi %c-10_i8, %c7_i8 : i8
+    vector.print %c7_i8 : i8
+    vector.print %c-10_i8 : i8
+    vector.print %0 : i8
+    return
+}
+
+func.func @shiftOnZero() {
+    // shifts on zero is identity
+    // shrsi 7 0 : i8 = 7; shrui -10 0 : i8 = -10; shli 7 0 : i8 = 7
+    %c7_i8 = arith.constant 7 : i8
+    %c-10_i8 = arith.constant -10 : i8
+    %c0_i8 = arith.constant 0 : i8
+    %0 = arith.shrsi %c7_i8, %c0_i8 : i8
+    %1 = arith.shrui %c-10_i8, %c0_i8 : i8
+    %2 = arith.shli %c7_i8, %c0_i8 : i8
+    vector.print %0 : i8
+    vector.print %1 : i8
+    vector.print %2 : i8
+    return
+}
+
+func.func @shiftOnZeroI1NonPoison() {
+    // shift by zero : i1 should be non poison
+    // sh{rsi, rui, li} 0 0 : i1 = 0
+    %false = arith.constant 0 : i1
+    %0 = arith.shrsi %false, %false : i1
+    %1 = arith.shrui %false, %false : i1
+    %2 = arith.shli %false, %false : i1
+    vector.print %0 : i1
+    vector.print %1 : i1
+    vector.print %2 : i1
+    return
+}
+
+func.func @cmpiUnsigned() {
+    // cmpi on i8, unsigned flags tests
+    // 1 `ult` 1 = false (0); 1 `ule` 1 = true (1); 1 `ugt` 1 = false (0); 1 `uge` 1 = true (1)
+    %c1_i8 = arith.constant 1 : i8
+    %0 = arith.cmpi ult, %c1_i8, %c1_i8 : i8
+    %1 = arith.cmpi ule, %c1_i8, %c1_i8 : i8
+    %2 = arith.cmpi ugt, %c1_i8, %c1_i8 : i8
+    %3 = arith.cmpi uge, %c1_i8, %c1_i8 : i8
+    vector.print %0 : i1
+    vector.print %1 : i1
+    vector.print %2 : i1
+    vector.print %3 : i1
+    return
+}
+
+func.func @shiftLeftValueGoesIntoTheVoid() {
+    // shli on i8, value goes off into the void (overflow/modulus needed)
+    // shli (-100), 7
+    %c-100_i8 = arith.constant -100 : i8
+    %c7_i8 = arith.constant 7 : i8
+    %0 = arith.shli %c-100_i8, %c7_i8 : i8
+    vector.print %c-100_i8 : i8
+    vector.print %c7_i8 : i8
+    vector.print %0 : i8
+    return
+}
+
+func.func @entry() {
+    // CHECK:       7
+    // CHECK-NEXT:  -10
+    // CHECK-NEXT:  -1
+    func.call @shrsiPreserveSigns() : () -> ()
+
+    // CHECK-NEXT:  7
+    // CHECK-NEXT:  -10
+    // CHECK-NEXT:  7
+    func.call @shiftOnZero() : () -> ()
+
+    // CHECK-NEXT:  0
+    // CHECK-NEXT:  0
+    // CHECK-NEXT:  0
+    func.call @shiftOnZeroI1NonPoison() : () -> ()
+
+    // CHECK-NEXT:  0
+    // CHECK-NEXT:  1
+    // CHECK-NEXT:  0
+    // CHECK-NEXT:  1
+    func.call @cmpiUnsigned() : () -> ()
+
+    // CHECK-NEXT:  -100
+    // CHECK-NEXT:  7
+    // CHECK-NEXT:  0
+    func.call @shiftLeftValueGoesIntoTheVoid() : () -> ()
+    
+    return
+}



More information about the Mlir-commits mailing list