Skip to content

Commit bd2623b

Browse files
vdonaldsonjeanPerierschweitzpgiclementval
committed
[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 <[email protected]> Co-authored-by: Eric Schweitz <[email protected]> Co-authored-by: Valentin Clement <[email protected]>
1 parent 0446f12 commit bd2623b

File tree

4 files changed

+129
-8
lines changed

4 files changed

+129
-8
lines changed

flang/include/flang/Optimizer/Dialect/FIROps.td

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2214,18 +2214,35 @@ def fir_InsertOnRangeOp : fir_OneResultOp<"insert_on_range", [NoSideEffect]> {
22142214
let summary = "insert sub-value into a range on an existing sequence";
22152215

22162216
let description = [{
2217-
Insert a constant value into an entity with an array type. Returns a
2218-
new ssa value where the range of offsets from the original array have been
2219-
replaced with the constant. The result is an array type entity.
2217+
Insert copies of a value into an entity with an array type.
2218+
Returns a new ssa value with the same type as the original entity.
2219+
The values are inserted at a contiguous range of indices in Fortran
2220+
row-to-column element order as specified by lower and upper bound
2221+
coordinates.
2222+
2223+
```mlir
2224+
%a = fir.undefined !fir.array<10x10xf32>
2225+
%c = constant 3.0 : f32
2226+
%1 = fir.insert_on_range %a, %c, [0 : index, 7 : index, 0 : index, 2 : index] : (!fir.array<10x10xf32>, f32) -> !fir.array<10x10xf32>
2227+
```
2228+
2229+
The first 28 elements of %1, with coordinates from (0,0) to (7,2), have
2230+
the value 3.0.
22202231
}];
22212232

2222-
let arguments = (ins fir_SequenceType:$seq, AnyType:$val,
2223-
Variadic<Index>:$coor);
2233+
let arguments = (ins fir_SequenceType:$seq, AnyType:$val, ArrayAttr:$coor);
22242234
let results = (outs fir_SequenceType);
22252235

22262236
let assemblyFormat = [{
2227-
operands attr-dict `:` functional-type(operands, results)
2237+
$seq `,` $val `,` $coor attr-dict `:` functional-type(operands, results)
22282238
}];
2239+
2240+
let builders = [
2241+
OpBuilder<(ins "mlir::Type":$rty, "mlir::Value":$adt, "mlir::Value":$val,
2242+
"llvm::ArrayRef<mlir::Value>":$vcoor)>
2243+
];
2244+
2245+
let verifier = [{ return ::verify(*this); }];
22292246
}
22302247

22312248
def fir_LenParamIndexOp : fir_OneResultOp<"len_param_index", [NoSideEffect]> {

flang/lib/Optimizer/Dialect/FIROps.cpp

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -658,6 +658,70 @@ mlir::ParseResult fir::GlobalOp::verifyValidLinkage(StringRef linkage) {
658658
return mlir::success(llvm::is_contained(validNames, linkage));
659659
}
660660

661+
template <bool AllowFields>
662+
static void appendAsAttribute(llvm::SmallVectorImpl<mlir::Attribute> &attrs,
663+
mlir::Value val) {
664+
if (auto *op = val.getDefiningOp()) {
665+
if (auto cop = mlir::dyn_cast<mlir::ConstantOp>(op)) {
666+
// append the integer constant value
667+
if (auto iattr = cop.getValue().dyn_cast<mlir::IntegerAttr>()) {
668+
attrs.push_back(iattr);
669+
return;
670+
}
671+
} else if (auto fld = mlir::dyn_cast<fir::FieldIndexOp>(op)) {
672+
if constexpr (AllowFields) {
673+
// append the field name and the record type
674+
attrs.push_back(fld.field_idAttr());
675+
attrs.push_back(fld.on_typeAttr());
676+
return;
677+
}
678+
}
679+
}
680+
llvm::report_fatal_error("cannot build Op with these arguments");
681+
}
682+
683+
template <bool AllowFields = true>
684+
static mlir::ArrayAttr collectAsAttributes(mlir::MLIRContext *ctxt,
685+
OperationState &result,
686+
llvm::ArrayRef<mlir::Value> inds) {
687+
llvm::SmallVector<mlir::Attribute> attrs;
688+
for (auto v : inds)
689+
appendAsAttribute<AllowFields>(attrs, v);
690+
assert(!attrs.empty());
691+
return mlir::ArrayAttr::get(ctxt, attrs);
692+
}
693+
694+
//===----------------------------------------------------------------------===//
695+
// InsertOnRangeOp
696+
//===----------------------------------------------------------------------===//
697+
698+
void fir::InsertOnRangeOp::build(mlir::OpBuilder &builder,
699+
OperationState &result, mlir::Type resTy,
700+
mlir::Value aggVal, mlir::Value eleVal,
701+
llvm::ArrayRef<mlir::Value> inds) {
702+
auto aa = collectAsAttributes<false>(builder.getContext(), result, inds);
703+
build(builder, result, resTy, aggVal, eleVal, aa);
704+
}
705+
706+
/// Range bounds must be nonnegative, and the range must not be empty.
707+
static mlir::LogicalResult verify(fir::InsertOnRangeOp op) {
708+
if (op.coor().size() < 2 || op.coor().size() % 2 != 0)
709+
return op.emitOpError("has uneven number of values in ranges");
710+
bool rangeIsKnownToBeNonempty = false;
711+
for (auto i = op.coor().end(), b = op.coor().begin(); i != b;) {
712+
int64_t ub = (*--i).cast<IntegerAttr>().getInt();
713+
int64_t lb = (*--i).cast<IntegerAttr>().getInt();
714+
if (lb < 0 || ub < 0)
715+
return op.emitOpError("negative range bound");
716+
if (rangeIsKnownToBeNonempty)
717+
continue;
718+
if (lb > ub)
719+
return op.emitOpError("empty range");
720+
rangeIsKnownToBeNonempty = lb < ub;
721+
}
722+
return mlir::success();
723+
}
724+
661725
//===----------------------------------------------------------------------===//
662726
// InsertValueOp
663727
//===----------------------------------------------------------------------===//

flang/test/Fir/fir-ops.fir

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -621,10 +621,10 @@ func @test_misc_ops(%arr1 : !fir.ref<!fir.array<?x?xf32>>, %m : index, %n : inde
621621
%c1_i32 = constant 9 : i32
622622

623623
// CHECK: [[ARR2:%.*]] = fir.zero_bits !fir.array<10xi32>
624-
// CHECK: [[ARR3:%.*]] = fir.insert_on_range [[ARR2]], [[C1_I32]], [[C2]], [[C9]] : (!fir.array<10xi32>, i32, index, index) -> !fir.array<10xi32>
624+
// CHECK: [[ARR3:%.*]] = fir.insert_on_range [[ARR2]], [[C1_I32]], [2 : index, 9 : index] : (!fir.array<10xi32>, i32) -> !fir.array<10xi32>
625625
// CHECK: fir.call @noret1([[ARR3]]) : (!fir.array<10xi32>) -> ()
626626
%arr2 = fir.zero_bits !fir.array<10xi32>
627-
%arr3 = fir.insert_on_range %arr2, %c1_i32, %c2, %c9 : (!fir.array<10xi32>, i32, index, index) -> !fir.array<10xi32>
627+
%arr3 = fir.insert_on_range %arr2, %c1_i32, [2 : index, 9 : index] : (!fir.array<10xi32>, i32) -> !fir.array<10xi32>
628628
fir.call @noret1(%arr3) : (!fir.array<10xi32>) -> ()
629629

630630
// CHECK: [[SHAPE:%.*]] = fir.shape_shift [[INDXM:%.*]], [[INDXN:%.*]], [[INDXO:%.*]], [[INDXP:%.*]] : (index, index, index, index) -> !fir.shapeshift<2>

flang/test/Fir/invalid.fir

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,3 +377,43 @@ fir.do_loop %i = %c1 to %c10 step %c1 -> index {
377377
// expected-error@+1 {{'fir.result' op parent of result must have same arity}}
378378
fir.do_loop %i = %c1 to %c10 step %c1 -> index {
379379
}
380+
381+
// -----
382+
383+
fir.global internal @_QEmultiarray : !fir.array<32x32xi32> {
384+
%c0_i32 = constant 1 : i32
385+
%0 = fir.undefined !fir.array<32x32xi32>
386+
// expected-error@+1 {{'fir.insert_on_range' op has uneven number of values in ranges}}
387+
%2 = fir.insert_on_range %0, %c0_i32, [0 : index, 31 : index, 0 : index] : (!fir.array<32x32xi32>, i32) -> !fir.array<32x32xi32>
388+
fir.has_value %2 : !fir.array<32x32xi32>
389+
}
390+
391+
// -----
392+
393+
fir.global internal @_QEmultiarray : !fir.array<32x32xi32> {
394+
%c0_i32 = constant 1 : i32
395+
%0 = fir.undefined !fir.array<32x32xi32>
396+
// expected-error@+1 {{'fir.insert_on_range' op has uneven number of values in ranges}}
397+
%2 = fir.insert_on_range %0, %c0_i32, [0 : index] : (!fir.array<32x32xi32>, i32) -> !fir.array<32x32xi32>
398+
fir.has_value %2 : !fir.array<32x32xi32>
399+
}
400+
401+
// -----
402+
403+
fir.global internal @_QEmultiarray : !fir.array<32x32xi32> {
404+
%c0_i32 = constant 1 : i32
405+
%0 = fir.undefined !fir.array<32x32xi32>
406+
// expected-error@+1 {{'fir.insert_on_range' op negative range bound}}
407+
%2 = fir.insert_on_range %0, %c0_i32, [-1 : index, 0 : index] : (!fir.array<32x32xi32>, i32) -> !fir.array<32x32xi32>
408+
fir.has_value %2 : !fir.array<32x32xi32>
409+
}
410+
411+
// -----
412+
413+
fir.global internal @_QEmultiarray : !fir.array<32x32xi32> {
414+
%c0_i32 = constant 1 : i32
415+
%0 = fir.undefined !fir.array<32x32xi32>
416+
// expected-error@+1 {{'fir.insert_on_range' op empty range}}
417+
%2 = fir.insert_on_range %0, %c0_i32, [10 : index, 9 : index] : (!fir.array<32x32xi32>, i32) -> !fir.array<32x32xi32>
418+
fir.has_value %2 : !fir.array<32x32xi32>
419+
}

0 commit comments

Comments
 (0)