[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