[flang-commits] [flang] d090f42 - [flang][fir] Add diagnostic tests for FIR ops verifier

via flang-commits flang-commits at lists.llvm.org
Fri Mar 5 07:21:23 PST 2021


Author: Valentin Clement
Date: 2021-03-05T10:21:17-05:00
New Revision: d090f427780f7c6c556dd79a80673405850a09c8

URL: https://github.com/llvm/llvm-project/commit/d090f427780f7c6c556dd79a80673405850a09c8
DIFF: https://github.com/llvm/llvm-project/commit/d090f427780f7c6c556dd79a80673405850a09c8.diff

LOG: [flang][fir] Add diagnostic tests for FIR ops verifier

Add diagnostic tests with fir-opt for the diagnostics emitted by the ops verifier

Reviewed By: jeanPerier

Differential Revision: https://reviews.llvm.org/D97996

Added: 
    flang/test/Fir/invalid.fir

Modified: 
    flang/lib/Optimizer/Dialect/FIROps.cpp

Removed: 
    


################################################################################
diff  --git a/flang/lib/Optimizer/Dialect/FIROps.cpp b/flang/lib/Optimizer/Dialect/FIROps.cpp
index cb8ec75d2cf2..f6ec7bb2cd99 100644
--- a/flang/lib/Optimizer/Dialect/FIROps.cpp
+++ b/flang/lib/Optimizer/Dialect/FIROps.cpp
@@ -531,8 +531,6 @@ void fir::DispatchTableOp::appendTableEntry(mlir::Operation *op) {
 
 static mlir::LogicalResult verify(fir::EmboxOp op) {
   auto eleTy = fir::dyn_cast_ptrEleTy(op.memref().getType());
-  if (!eleTy)
-    return op.emitOpError("must embox a memory reference type");
   bool isArray = false;
   if (auto seqTy = eleTy.dyn_cast<fir::SequenceType>()) {
     eleTy = seqTy.getEleTy();
@@ -554,20 +552,10 @@ static mlir::LogicalResult verify(fir::EmboxOp op) {
       if (!fir::isa_integer(lp.getType()))
         return op.emitOpError("LEN parameters must be integral type");
   }
-  if (op.getShape()) {
-    auto shapeTy = op.getShape().getType();
-    if (!(shapeTy.isa<fir::ShapeType>() || shapeTy.isa<ShapeShiftType>()))
-      return op.emitOpError("must be shape or shapeshift type");
-    if (!isArray)
-      return op.emitOpError("shape must not be provided for a scalar");
-  }
-  if (op.getSlice()) {
-    auto sliceTy = op.getSlice().getType();
-    if (!sliceTy.isa<fir::SliceType>())
-      return op.emitOpError("must be a slice type");
-    if (!isArray)
-      return op.emitOpError("slice must not be provided for a scalar");
-  }
+  if (op.getShape() && !isArray)
+    return op.emitOpError("shape must not be provided for a scalar");
+  if (op.getSlice() && !isArray)
+    return op.emitOpError("slice must not be provided for a scalar");
   return mlir::success();
 }
 
@@ -841,9 +829,6 @@ static mlir::ParseResult parseIterWhileOp(mlir::OpAsmParser &parser,
                                 std::get<1>(operand_type), result.operands))
         return failure();
     if (prependCount) {
-      // This is an assert here, because these types are verified.
-      assert(regionTypes[0].isa<mlir::IndexType>() &&
-             regionTypes[1].isSignlessInteger(1));
       result.addTypes(regionTypes);
     } else {
       result.addTypes(i1Type);

diff  --git a/flang/test/Fir/invalid.fir b/flang/test/Fir/invalid.fir
new file mode 100644
index 000000000000..8348c7583b74
--- /dev/null
+++ b/flang/test/Fir/invalid.fir
@@ -0,0 +1,379 @@
+// FIR ops diagnotic tests
+
+// RUN: fir-opt -split-input-file -verify-diagnostics %s
+
+// expected-error at +1{{custom op 'fir.string_lit' must have character type}}
+%0 = fir.string_lit "Hello, World!"(13) : !fir.int<32>
+
+// -----
+
+// expected-error at +1{{custom op 'fir.string_lit' found an invalid constant}}
+%0 = fir.string_lit 20(13) : !fir.int<32>
+
+// -----
+
+// expected-error at +1{{'fir.string_lit' op values in list must be integers}}
+%2 = fir.string_lit [158, 2.0](2) : !fir.char<2>
+
+// -----
+
+func @bad_rebox_1(%arg0: !fir.ref<!fir.array<?x?xf32>>) {
+  %c10 = constant 10 : index
+  %0 = fir.shape %c10 : (index) -> !fir.shape<1>
+  // expected-error at +1{{op operand #0 must be The type of a Fortran descriptor, but got '!fir.ref<!fir.array<?x?xf32>>'}}
+  %1 = fir.rebox %arg0(%0) : (!fir.ref<!fir.array<?x?xf32>>, !fir.shape<1>) -> !fir.box<!fir.array<?xf32>>
+  return
+}
+
+// -----
+
+func @bad_rebox_2(%arg0: !fir.box<!fir.array<?x?xf32>>) {
+  %c10 = constant 10 : index
+  %0 = fir.shape %c10 : (index) -> !fir.shape<1>
+  // expected-error at +1{{op result #0 must be The type of a Fortran descriptor, but got '!fir.ref<!fir.array<?xf32>>'}}
+  %1 = fir.rebox %arg0(%0) : (!fir.box<!fir.array<?x?xf32>>, !fir.shape<1>) -> !fir.ref<!fir.array<?xf32>>
+  return
+}
+
+// -----
+
+func @bad_rebox_3(%arg0: !fir.box<!fir.array<*:f32>>) {
+  %c10 = constant 10 : index
+  %0 = fir.shape %c10 : (index) -> !fir.shape<1>
+  // expected-error at +1{{op box operand must not have unknown rank or type}}
+  %1 = fir.rebox %arg0(%0) : (!fir.box<!fir.array<*:f32>>, !fir.shape<1>) -> !fir.box<!fir.array<?xf32>>
+  return
+}
+
+// -----
+
+func @bad_rebox_4(%arg0: !fir.box<!fir.array<?xf32>>) {
+  // expected-error at +1{{op result type must not have unknown rank or type}}
+  %0 = fir.rebox %arg0 : (!fir.box<!fir.array<?xf32>>) -> !fir.box<!fir.array<*:f32>>
+  return
+}
+
+// -----
+
+func @bad_rebox_5(%arg0: !fir.box<!fir.array<?x?xf32>>) {
+  %c1 = constant 1 : index
+  %c10 = constant 10 : index
+  %0 = fir.slice %c1, %c10, %c1 : (index, index, index) -> !fir.slice<1>
+  // expected-error at +1{{op slice operand rank must match box operand rank}}
+  %1 = fir.rebox %arg0 [%0] : (!fir.box<!fir.array<?x?xf32>>, !fir.slice<1>) -> !fir.box<!fir.array<?xf32>>
+  return
+}
+
+// -----
+
+func @bad_rebox_6(%arg0: !fir.box<!fir.array<?xf32>>) {
+  %c1 = constant 1 : index
+  %c10 = constant 10 : index
+  %0 = fir.slice %c1, %c10, %c1 : (index, index, index) -> !fir.slice<1>
+  %1 = fir.shift %c1, %c1 : (index, index) -> !fir.shift<2>
+  // expected-error at +1{{shape operand and input box ranks must match when there is a slice}}
+  %2 = fir.rebox %arg0(%1) [%0] : (!fir.box<!fir.array<?xf32>>, !fir.shift<2>, !fir.slice<1>) -> !fir.box<!fir.array<?xf32>>
+  return
+}
+
+// -----
+
+func @bad_rebox_7(%arg0: !fir.box<!fir.array<?xf32>>) {
+  %c1 = constant 1 : index
+  %c10 = constant 10 : index
+  %0 = fir.slice %c1, %c10, %c1 : (index, index, index) -> !fir.slice<1>
+  %1 = fir.shape %c10 : (index) -> !fir.shape<1>
+  // expected-error at +1{{shape operand must absent or be a fir.shift when there is a slice}}
+  %2 = fir.rebox %arg0(%1) [%0] : (!fir.box<!fir.array<?xf32>>, !fir.shape<1>, !fir.slice<1>) -> !fir.box<!fir.array<?xf32>>
+  return
+}
+
+// -----
+
+func @bad_rebox_8(%arg0: !fir.box<!fir.array<?x?xf32>>) {
+  %c1 = constant 1 : index
+  %c10 = constant 10 : index
+  %undef = fir.undefined index
+  %0 = fir.slice %c1, %undef, %undef, %c1, %c10, %c1 : (index, index, index, index, index, index) -> !fir.slice<2>
+  // expected-error at +1{{result type rank and rank after applying slice operand must match}}
+  %1 = fir.rebox %arg0 [%0] : (!fir.box<!fir.array<?x?xf32>>, !fir.slice<2>) -> !fir.box<!fir.array<?x?xf32>>
+  return
+}
+
+// -----
+
+func @bad_rebox_9(%arg0: !fir.box<!fir.array<?xf32>>) {
+  %c10 = constant 10 : index
+  %0 = fir.shift %c10, %c10 : (index, index) -> !fir.shift<2>
+  // expected-error at +1{{shape operand and input box ranks must match when the shape is a fir.shift}}
+  %1 = fir.rebox %arg0(%0) : (!fir.box<!fir.array<?xf32>>, !fir.shift<2>) -> !fir.box<!fir.array<?x?xf32>>
+  return
+}
+
+// -----
+
+func @bad_rebox_10(%arg0: !fir.box<!fir.array<?xf32>>) {
+  %c10 = constant 10 : index
+  %0 = fir.shape %c10, %c10 : (index, index) -> !fir.shape<2>
+  // expected-error at +1{{result type and shape operand ranks must match}}
+  %1 = fir.rebox %arg0(%0) : (!fir.box<!fir.array<?xf32>>, !fir.shape<2>) -> !fir.box<!fir.array<?xf32>>
+  return
+}
+
+// -----
+
+func @bad_rebox_11(%arg0: !fir.box<!fir.array<?x?xf32>>) {
+  %c42 = constant 42 : index
+  %0 = fir.shape %c42 : (index) -> !fir.shape<1>
+  // expected-error at +1{{op input and output element types must match for intrinsic types}}
+  %1 = fir.rebox %arg0(%0) : (!fir.box<!fir.array<?x?xf32>>, !fir.shape<1>) -> !fir.box<!fir.array<?xf64>>
+  return
+}
+
+// -----
+
+func @array_access(%arr : !fir.ref<!fir.array<?x?xf32>>) {
+  %c1 = constant 1 : index
+  %c100 = constant 100 : index
+  %c50 = constant 50 : index
+  %shape = fir.shape %c100, %c50 : (index, index) -> !fir.shape<2>
+  // expected-error at +1 {{'fir.array_coor' op operand #0 must be any reference or box, but got 'index'}}
+  %p = fir.array_coor %c100(%shape) %c1, %c1 : (index, !fir.shape<2>, index, index) -> !fir.ref<f32>
+  return
+}
+
+// -----
+
+func @array_access(%arr : !fir.ref<f32>) {
+  %c1 = constant 1 : index
+  %c100 = constant 100 : index
+  %c50 = constant 50 : index
+  %shape = fir.shape %c100, %c50 : (index, index) -> !fir.shape<2>
+  // expected-error at +1 {{'fir.array_coor' op must be a reference to an array}}
+  %p = fir.array_coor %arr(%shape) %c1, %c1 : (!fir.ref<f32>, !fir.shape<2>, index, index) -> !fir.ref<f32>
+  return
+}
+
+// -----
+
+func @array_access(%arr : !fir.ref<!fir.array<?x?xf32>>) {
+  %c1 = constant 1 : index
+  %c100 = constant 100 : index
+  %c50 = constant 50 : index
+  %shape = fir.shape %c100, %c50 : (index, index) -> !fir.shape<2>
+  %c47 = constant 47 : index
+  %c78 = constant 78 : index
+  %c3 = constant 3 : index
+  %slice = fir.slice %c47, %c78, %c3 : (index,index,index) -> !fir.slice<1>
+  // expected-error at +1 {{'fir.array_coor' op rank of dimension in slice mismatched}}
+  %p = fir.array_coor %arr(%shape)[%slice] %c1, %c1 : (!fir.ref<!fir.array<?x?xf32>>, !fir.shape<2>, !fir.slice<1>, index, index) -> !fir.ref<f32>
+  return
+}
+
+// -----
+
+func @array_access(%arr : !fir.ref<!fir.array<?x?xf32>>) {
+  %c1 = constant 1 : index
+  %c100 = constant 100 : index
+  %shape = fir.shape %c100 : (index) -> !fir.shape<1>
+  // expected-error at +1 {{'fir.array_coor' op rank of dimension mismatched}}
+  %p = fir.array_coor %arr(%shape) %c1, %c1 : (!fir.ref<!fir.array<?x?xf32>>, !fir.shape<1>, index, index) -> !fir.ref<f32>
+  return
+}
+
+// -----
+
+func @array_access(%arr : !fir.ref<!fir.array<?x?xf32>>) {
+  %c1 = constant 1 : index
+  %c100 = constant 100 : index
+  %shift = fir.shift %c1 : (index) -> !fir.shift<1>
+  // expected-error at +1 {{'fir.array_coor' op shift can only be provided with fir.box memref}}
+  %p = fir.array_coor %arr(%shift) %c1, %c1 : (!fir.ref<!fir.array<?x?xf32>>, !fir.shift<1>, index, index) -> !fir.ref<f32>
+  return
+}
+
+// -----
+
+func @array_access(%arr : !fir.ref<!fir.array<?x?xf32>>) {
+  %c1 = constant 1 : index
+  %c100 = constant 100 : index
+  %c50 = constant 50 : index
+  %shape = fir.shape %c100, %c50 : (index, index) -> !fir.shape<2>
+  // expected-error at +1 {{'fir.array_coor' op number of indices do not match dim rank}}
+  %p = fir.array_coor %arr(%shape) %c1 : (!fir.ref<!fir.array<?x?xf32>>, !fir.shape<2>, index) -> !fir.ref<f32>
+  return
+}
+
+// -----
+
+func @test_misc_ops(%arr1 : !fir.ref<!fir.array<?x?xf32>>, %m : index, %n : index, %o : index, %p : index) {
+  %c2 = constant 2 : index
+  %s = fir.shape_shift %m, %n, %o, %p : (index, index, index, index) -> !fir.shapeshift<2>
+  // expected-error at +1 {{'fir.array_load' op operand #0 must be any reference or box, but got 'index'}}
+  %av1 = fir.array_load %c2(%s) : (index, !fir.shapeshift<2>) -> !fir.array<?x?xf32>
+  return
+}
+
+// -----
+
+func @test_misc_ops(%arr1 : !fir.ref<f32>, %m : index, %n : index, %o : index, %p : index) {
+  %s = fir.shape_shift %m, %n, %o, %p : (index, index, index, index) -> !fir.shapeshift<2>
+  // expected-error at +1 {{'fir.array_load' op must be a reference to an array}}
+  %av1 = fir.array_load %arr1(%s) : (!fir.ref<f32>, !fir.shapeshift<2>) -> !fir.array<?x?xf32>
+  return
+}
+
+// -----
+
+func @test_misc_ops(%arr1 : !fir.ref<!fir.array<?x?xf32>>, %m : index, %n : index, %o : index, %p : index) {
+  %s = fir.shape_shift %m, %n: (index, index) -> !fir.shapeshift<1>
+  // expected-error at +1 {{'fir.array_load' op rank of dimension mismatched}}
+  %av1 = fir.array_load %arr1(%s) : (!fir.ref<!fir.array<?x?xf32>>, !fir.shapeshift<1>) -> !fir.array<?x?xf32>
+  return
+}
+
+// -----
+
+func @test_misc_ops(%arr1 : !fir.ref<!fir.array<?x?xf32>>, %m : index, %n : index, %o : index, %p : index) {
+  %c2 = constant 2 : index
+  %shift = fir.shift %c2 : (index) -> !fir.shift<1>
+  // expected-error at +1 {{'fir.array_load' op shift can only be provided with fir.box memref}}
+  %av1 = fir.array_load %arr1(%shift) : (!fir.ref<!fir.array<?x?xf32>>, !fir.shift<1>) -> !fir.array<?x?xf32>
+  return
+}
+
+// -----
+
+func @test_misc_ops(%arr1 : !fir.ref<!fir.array<?x?xf32>>, %m : index, %n : index, %o : index, %p : index) {
+  %c47 = constant 47 : index
+  %c78 = constant 78 : index
+  %c3 = constant 3 : index
+  %slice = fir.slice %c47, %c78, %c3 : (index,index,index) -> !fir.slice<1>
+  %s = fir.shape_shift %m, %n, %o, %p: (index, index, index, index) -> !fir.shapeshift<2>
+  // expected-error at +1 {{'fir.array_load' op rank of dimension in slice mismatched}}
+  %av1 = fir.array_load %arr1(%s)[%slice] : (!fir.ref<!fir.array<?x?xf32>>, !fir.shapeshift<2>, !fir.slice<1>) -> !fir.array<?x?xf32>
+  return
+}
+
+// -----
+
+func @test_coordinate_of(%arr : !fir.ref<!fir.array<?x?xf32>>) {
+  %1 = constant 10 : i32
+  // expected-error at +1 {{'fir.coordinate_of' op cannot find coordinate with unknown extents}}
+  %2 = fir.coordinate_of %arr, %1 : (!fir.ref<!fir.array<?x?xf32>>, i32) -> !fir.ref<f32>
+  return
+}
+
+// -----
+
+func @test_coordinate_of(%arr : !fir.ref<!fir.array<*:f32>>) {
+  %1 = constant 10 : i32
+  // expected-error at +1 {{'fir.coordinate_of' op cannot find coordinate in unknown shape}}
+  %2 = fir.coordinate_of %arr, %1 : (!fir.ref<!fir.array<*:f32>>, i32) -> !fir.ref<f32>
+  return
+}
+
+// -----
+
+func @test_coordinate_of(%arr : !fir.ref<!fir.char<10>>) {
+  %1 = constant 10 : i32
+  // expected-error at +1 {{'fir.coordinate_of' op cannot apply coordinate_of to this type}}
+  %2 = fir.coordinate_of %arr, %1 : (!fir.ref<!fir.char<10>>, i32) -> !fir.ref<f32>
+  return
+}
+
+// -----
+
+%0 = constant 22 : i32
+// expected-error at +1 {{'fir.embox' op operand #0 must be any reference, but got 'i32'}}
+%1 = fir.embox %0 : (i32) -> !fir.box<i32>
+
+// -----
+
+func @fun(%0 : !fir.ref<i32>) {
+  %c_100 = constant 100 : index
+  %1 = fir.shape %c_100 : (index) -> !fir.shape<1>
+  // expected-error at +1 {{'fir.embox' op shape must not be provided for a scalar}}
+  %2 = fir.embox %0(%1) : (!fir.ref<i32>, !fir.shape<1>) -> !fir.box<i32>
+}
+
+// -----
+
+func @fun(%0 : !fir.ref<i32>) {
+  %c_100 = constant 100 : index
+  %1 = fir.slice %c_100, %c_100, %c_100 : (index, index, index) -> !fir.slice<1>
+  // expected-error at +1 {{'fir.embox' op operand #1 must be any legal shape type, but got '!fir.slice<1>'}}
+  %2 = fir.embox %0(%1) : (!fir.ref<i32>, !fir.slice<1>) -> !fir.box<i32>
+}
+
+// -----
+
+func @fun(%0 : !fir.ref<i32>) {
+  %c_100 = constant 100 : index
+  %1 = fir.shape %c_100 : (index) -> !fir.shape<1>
+  // expected-error at +1 {{'fir.embox' op operand #1 must be FIR slice, but got '!fir.shape<1>'}}
+  %2 = fir.embox %0[%1] : (!fir.ref<i32>, !fir.shape<1>) -> !fir.box<i32>
+}
+
+// -----
+
+func @fun(%0 : !fir.ref<i32>) {
+  %c_100 = constant 100 : index
+  %1 = fir.slice %c_100, %c_100, %c_100 : (index, index, index) -> !fir.slice<1>
+  // expected-error at +1 {{'fir.embox' op slice must not be provided for a scalar}}
+  %2 = fir.embox %0[%1] : (!fir.ref<i32>, !fir.slice<1>) -> !fir.box<i32>
+}
+
+// -----
+
+%lo = constant 1 : index
+%c1 = constant 1 : index
+%up = constant 10 : index
+%okIn = constant 1 : i1
+%shIn = constant 1 : i16
+// expected-error at +1 {{'fir.iterate_while' op expected body first argument to be an index argument for the induction variable}}
+%v:3 = fir.iterate_while (%i = %lo to %up step %c1) and (%ok = %okIn) iter_args(%sh = %shIn) -> (i16, i1, i16) {
+  %shNew = fir.call @bar(%sh) : (i16) -> i16
+  %okNew = fir.call @foo(%sh) : (i16) -> i1
+  fir.result %shNew, %okNew, %shNew : i16, i1, i16
+}
+
+// -----
+
+%lo = constant 1 : index
+%c1 = constant 1 : index
+%up = constant 10 : index
+%okIn = constant 1 : i1
+%shIn = constant 1 : i16
+// expected-error at +1 {{'fir.iterate_while' op expected body second argument to be an index argument for the induction variable}}
+%v:3 = fir.iterate_while (%i = %lo to %up step %c1) and (%ok = %okIn) iter_args(%sh = %shIn) -> (index, f32, i16) {
+  %shNew = fir.call @bar(%sh) : (i16) -> i16
+  %dummy = fir.call @foo(%sh) : (i16) -> f32
+  fir.result %i, %dummy, %shNew : index, f32, i16
+}
+
+// -----
+
+%c1 = constant 1 : index
+%c10 = constant 10 : index
+// expected-error at +1 {{'fir.do_loop' op unordered loop has no final value}}
+fir.do_loop %i = %c1 to %c10 step %c1 unordered -> index {
+}
+
+// -----
+
+%c1 = constant 1 : index
+%c10 = constant 10 : index
+fir.do_loop %i = %c1 to %c10 step %c1 -> index {
+  %f1 = constant 1.0 : f32
+  // expected-error at +1 {{'fir.result' op types mismatch between result op and its parent}}
+  fir.result %f1 : f32
+}
+
+// -----
+
+%c1 = constant 1 : index
+%c10 = constant 10 : index
+// expected-error at +1 {{'fir.result' op parent of result must have same arity}}
+fir.do_loop %i = %c1 to %c10 step %c1 -> index {
+}


        


More information about the flang-commits mailing list