[flang-commits] [flang] bd2623b - [fir] Update fir.insert_on_range op

Valentin Clement via flang-commits flang-commits at lists.llvm.org
Tue Sep 28 02:03:42 PDT 2021


Author: V Donaldson
Date: 2021-09-28T11:03:28+02:00
New Revision: bd2623b9c22d02a87ebed7b770e0312799ea0a04

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

LOG: [fir] Update fir.insert_on_range op

Update the fir.insert_on_range operation. Add a better description,
builder and verifier.

This patch is part of the upstreaming effort from fir-dev branch.

Reviewed By: jeanPerier

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

Co-authored-by: Jean Perier <jperier at nvidia.com>
Co-authored-by: Eric Schweitz <eschweitz at nvidia.com>
Co-authored-by: Valentin Clement <clementval at gmail.com>

Added: 
    

Modified: 
    flang/include/flang/Optimizer/Dialect/FIROps.td
    flang/lib/Optimizer/Dialect/FIROps.cpp
    flang/test/Fir/fir-ops.fir
    flang/test/Fir/invalid.fir

Removed: 
    


################################################################################
diff  --git a/flang/include/flang/Optimizer/Dialect/FIROps.td b/flang/include/flang/Optimizer/Dialect/FIROps.td
index fc9fd05a310a3..5aedc017740f0 100644
--- a/flang/include/flang/Optimizer/Dialect/FIROps.td
+++ b/flang/include/flang/Optimizer/Dialect/FIROps.td
@@ -2214,18 +2214,35 @@ def fir_InsertOnRangeOp : fir_OneResultOp<"insert_on_range", [NoSideEffect]> {
   let summary = "insert sub-value into a range on an existing sequence";
 
   let description = [{
-    Insert a constant value into an entity with an array type. Returns a
-    new ssa value where the range of offsets from the original array have been
-    replaced with the constant. The result is an array type entity.
+    Insert copies of a value into an entity with an array type.
+    Returns a new ssa value with the same type as the original entity.
+    The values are inserted at a contiguous range of indices in Fortran
+    row-to-column element order as specified by lower and upper bound
+    coordinates.
+
+    ```mlir
+      %a = fir.undefined !fir.array<10x10xf32>
+      %c = constant 3.0 : f32
+      %1 = fir.insert_on_range %a, %c, [0 : index, 7 : index, 0 : index, 2 : index] : (!fir.array<10x10xf32>, f32) -> !fir.array<10x10xf32>
+    ```
+
+    The first 28 elements of %1, with coordinates from (0,0) to (7,2), have
+    the value 3.0.
   }];
 
-  let arguments = (ins fir_SequenceType:$seq, AnyType:$val,
-                       Variadic<Index>:$coor);
+  let arguments = (ins fir_SequenceType:$seq, AnyType:$val, ArrayAttr:$coor);
   let results = (outs fir_SequenceType);
 
   let assemblyFormat = [{
-    operands attr-dict `:` functional-type(operands, results)
+    $seq `,` $val `,` $coor attr-dict `:` functional-type(operands, results)
   }];
+
+  let builders = [
+    OpBuilder<(ins "mlir::Type":$rty, "mlir::Value":$adt, "mlir::Value":$val,
+      "llvm::ArrayRef<mlir::Value>":$vcoor)>
+  ];
+
+  let verifier = [{ return ::verify(*this); }];
 }
 
 def fir_LenParamIndexOp : fir_OneResultOp<"len_param_index", [NoSideEffect]> {

diff  --git a/flang/lib/Optimizer/Dialect/FIROps.cpp b/flang/lib/Optimizer/Dialect/FIROps.cpp
index fdec783d3a112..05d222a2ff4c9 100644
--- a/flang/lib/Optimizer/Dialect/FIROps.cpp
+++ b/flang/lib/Optimizer/Dialect/FIROps.cpp
@@ -658,6 +658,70 @@ mlir::ParseResult fir::GlobalOp::verifyValidLinkage(StringRef linkage) {
   return mlir::success(llvm::is_contained(validNames, linkage));
 }
 
+template <bool AllowFields>
+static void appendAsAttribute(llvm::SmallVectorImpl<mlir::Attribute> &attrs,
+                              mlir::Value val) {
+  if (auto *op = val.getDefiningOp()) {
+    if (auto cop = mlir::dyn_cast<mlir::ConstantOp>(op)) {
+      // append the integer constant value
+      if (auto iattr = cop.getValue().dyn_cast<mlir::IntegerAttr>()) {
+        attrs.push_back(iattr);
+        return;
+      }
+    } else if (auto fld = mlir::dyn_cast<fir::FieldIndexOp>(op)) {
+      if constexpr (AllowFields) {
+        // append the field name and the record type
+        attrs.push_back(fld.field_idAttr());
+        attrs.push_back(fld.on_typeAttr());
+        return;
+      }
+    }
+  }
+  llvm::report_fatal_error("cannot build Op with these arguments");
+}
+
+template <bool AllowFields = true>
+static mlir::ArrayAttr collectAsAttributes(mlir::MLIRContext *ctxt,
+                                           OperationState &result,
+                                           llvm::ArrayRef<mlir::Value> inds) {
+  llvm::SmallVector<mlir::Attribute> attrs;
+  for (auto v : inds)
+    appendAsAttribute<AllowFields>(attrs, v);
+  assert(!attrs.empty());
+  return mlir::ArrayAttr::get(ctxt, attrs);
+}
+
+//===----------------------------------------------------------------------===//
+// InsertOnRangeOp
+//===----------------------------------------------------------------------===//
+
+void fir::InsertOnRangeOp::build(mlir::OpBuilder &builder,
+                                 OperationState &result, mlir::Type resTy,
+                                 mlir::Value aggVal, mlir::Value eleVal,
+                                 llvm::ArrayRef<mlir::Value> inds) {
+  auto aa = collectAsAttributes<false>(builder.getContext(), result, inds);
+  build(builder, result, resTy, aggVal, eleVal, aa);
+}
+
+/// Range bounds must be nonnegative, and the range must not be empty.
+static mlir::LogicalResult verify(fir::InsertOnRangeOp op) {
+  if (op.coor().size() < 2 || op.coor().size() % 2 != 0)
+    return op.emitOpError("has uneven number of values in ranges");
+  bool rangeIsKnownToBeNonempty = false;
+  for (auto i = op.coor().end(), b = op.coor().begin(); i != b;) {
+    int64_t ub = (*--i).cast<IntegerAttr>().getInt();
+    int64_t lb = (*--i).cast<IntegerAttr>().getInt();
+    if (lb < 0 || ub < 0)
+      return op.emitOpError("negative range bound");
+    if (rangeIsKnownToBeNonempty)
+      continue;
+    if (lb > ub)
+      return op.emitOpError("empty range");
+    rangeIsKnownToBeNonempty = lb < ub;
+  }
+  return mlir::success();
+}
+
 //===----------------------------------------------------------------------===//
 // InsertValueOp
 //===----------------------------------------------------------------------===//

diff  --git a/flang/test/Fir/fir-ops.fir b/flang/test/Fir/fir-ops.fir
index 445bf781ccfa2..dfd97a8b171a9 100644
--- a/flang/test/Fir/fir-ops.fir
+++ b/flang/test/Fir/fir-ops.fir
@@ -621,10 +621,10 @@ func @test_misc_ops(%arr1 : !fir.ref<!fir.array<?x?xf32>>, %m : index, %n : inde
   %c1_i32 = constant 9 : i32
 
   // CHECK: [[ARR2:%.*]] = fir.zero_bits !fir.array<10xi32>
-  // CHECK: [[ARR3:%.*]] = fir.insert_on_range [[ARR2]], [[C1_I32]], [[C2]], [[C9]] : (!fir.array<10xi32>, i32, index, index) -> !fir.array<10xi32>
+  // CHECK: [[ARR3:%.*]] = fir.insert_on_range [[ARR2]], [[C1_I32]], [2 : index, 9 : index] : (!fir.array<10xi32>, i32) -> !fir.array<10xi32>
   // CHECK: fir.call @noret1([[ARR3]]) : (!fir.array<10xi32>) -> ()
   %arr2 = fir.zero_bits !fir.array<10xi32>
-  %arr3 = fir.insert_on_range %arr2, %c1_i32, %c2, %c9 : (!fir.array<10xi32>, i32, index, index) -> !fir.array<10xi32>
+    %arr3 = fir.insert_on_range %arr2, %c1_i32, [2 : index, 9 : index] : (!fir.array<10xi32>, i32) -> !fir.array<10xi32>
   fir.call @noret1(%arr3) : (!fir.array<10xi32>) -> ()
 
   // CHECK: [[SHAPE:%.*]] = fir.shape_shift [[INDXM:%.*]], [[INDXN:%.*]], [[INDXO:%.*]], [[INDXP:%.*]] : (index, index, index, index) -> !fir.shapeshift<2>

diff  --git a/flang/test/Fir/invalid.fir b/flang/test/Fir/invalid.fir
index 8348c7583b745..f1e482568674d 100644
--- a/flang/test/Fir/invalid.fir
+++ b/flang/test/Fir/invalid.fir
@@ -377,3 +377,43 @@ fir.do_loop %i = %c1 to %c10 step %c1 -> 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 {
 }
+
+// -----
+
+fir.global internal @_QEmultiarray : !fir.array<32x32xi32> {
+  %c0_i32 = constant 1 : i32
+  %0 = fir.undefined !fir.array<32x32xi32>
+  // expected-error at +1 {{'fir.insert_on_range' op has uneven number of values in ranges}}
+  %2 = fir.insert_on_range %0, %c0_i32, [0 : index, 31 : index, 0 : index] : (!fir.array<32x32xi32>, i32) -> !fir.array<32x32xi32>
+  fir.has_value %2 : !fir.array<32x32xi32>
+}
+
+// -----
+
+fir.global internal @_QEmultiarray : !fir.array<32x32xi32> {
+  %c0_i32 = constant 1 : i32
+  %0 = fir.undefined !fir.array<32x32xi32>
+  // expected-error at +1 {{'fir.insert_on_range' op has uneven number of values in ranges}}
+  %2 = fir.insert_on_range %0, %c0_i32, [0 : index] : (!fir.array<32x32xi32>, i32) -> !fir.array<32x32xi32>
+  fir.has_value %2 : !fir.array<32x32xi32>
+}
+
+// -----
+
+fir.global internal @_QEmultiarray : !fir.array<32x32xi32> {
+  %c0_i32 = constant 1 : i32
+  %0 = fir.undefined !fir.array<32x32xi32>
+  // expected-error at +1 {{'fir.insert_on_range' op negative range bound}}
+  %2 = fir.insert_on_range %0, %c0_i32, [-1 : index, 0 : index] : (!fir.array<32x32xi32>, i32) -> !fir.array<32x32xi32>
+  fir.has_value %2 : !fir.array<32x32xi32>
+}
+
+// -----
+
+fir.global internal @_QEmultiarray : !fir.array<32x32xi32> {
+  %c0_i32 = constant 1 : i32
+  %0 = fir.undefined !fir.array<32x32xi32>
+  // expected-error at +1 {{'fir.insert_on_range' op empty range}}
+  %2 = fir.insert_on_range %0, %c0_i32, [10 : index, 9 : index] : (!fir.array<32x32xi32>, i32) -> !fir.array<32x32xi32>
+  fir.has_value %2 : !fir.array<32x32xi32>
+}


        


More information about the flang-commits mailing list