[fir] Add substring to fir.slice operation

This patch adds the substriing information to the fir.slice
operation. This will be used by character operations in later
upstreaming patches.

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

Reviewed By: jeanPerier

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

Co-authored-by: Eric Schweitz <eschweitz@nvidia.com>
This commit is contained in:
Valentin Clement 2021-10-26 10:32:48 +02:00
parent a458ef4f73
commit 7812f510d2
No known key found for this signature in database
GPG Key ID: 086D54783C928776
4 changed files with 50 additions and 5 deletions

View File

@ -1907,21 +1907,38 @@ def fir_SliceOp : fir_Op<"slice", [NoSideEffect, AttrSizedOperandSegments]> {
```mlir
%fld = fir.field_index component, !fir.type<t{...component:ct...}>
%d = fir.slice %lo, %hi, %step path %fld : (index, index, index, !fir.field) -> !fir.slice<1>
%d = fir.slice %lo, %hi, %step path %fld :
(index, index, index, !fir.field) -> !fir.slice<1>
```
Projections of `!fir.char` type can be further narrowed to invariant
substrings.
```mlir
%d = fir.slice %lo, %hi, %step substr %offset, %width :
(index, index, index, index, index) -> !fir.slice<1>
```
}];
let arguments = (ins
Variadic<AnyCoordinateType>:$triples,
Variadic<AnyComponentType>:$fields
Variadic<AnyIntegerType>:$triples,
Variadic<AnyComponentType>:$fields,
Variadic<AnyIntegerType>:$substr
);
let results = (outs fir_SliceType);
let assemblyFormat = [{
$triples (`path` $fields^)? attr-dict `:` functional-type(operands, results)
$triples (`path` $fields^)? (`substr` $substr^)? attr-dict `:`
functional-type(operands, results)
}];
let builders = [
OpBuilder<(ins "mlir::ValueRange":$triples,
CArg<"mlir::ValueRange", "llvm::None">:$fields,
CArg<"mlir::ValueRange", "llvm::None">:$substr)>
];
let verifier = "return ::verify(*this);";
let extraClassDeclaration = [{

View File

@ -2811,13 +2811,21 @@ static mlir::LogicalResult verify(fir::ShiftOp &op) {
// SliceOp
//===----------------------------------------------------------------------===//
void fir::SliceOp::build(mlir::OpBuilder &builder, mlir::OperationState &result,
mlir::ValueRange trips, mlir::ValueRange path,
mlir::ValueRange substr) {
const auto rank = trips.size() / 3;
auto sliceTy = fir::SliceType::get(builder.getContext(), rank);
build(builder, result, sliceTy, trips, path, substr);
}
/// Return the output rank of a slice op. The output rank must be between 1 and
/// the rank of the array being sliced (inclusive).
unsigned fir::SliceOp::getOutputRank(mlir::ValueRange triples) {
unsigned rank = 0;
if (!triples.empty()) {
for (unsigned i = 1, end = triples.size(); i < end; i += 3) {
auto op = triples[i].getDefiningOp();
auto *op = triples[i].getDefiningOp();
if (!mlir::isa_and_nonnull<fir::UndefOp>(op))
++rank;
}

View File

@ -699,3 +699,13 @@ func @char_convert() {
fir.char_convert %2 for %1 to %3 : !fir.ref<!fir.char<1>>, i32, !fir.ref<!fir.array<?x!fir.char<2,?>>>
return
}
func @slice_substr() {
%lb = arith.constant 0 : index
%ub = arith.constant 42 : index
%c1 = arith.constant 1 : index
%offset = arith.constant 10 : index
%0 = fir.slice %lb, %ub, %c1 substr %offset, %c1 : (index, index, index, index, index) -> !fir.slice<1>
// CHECK: fir.slice %{{.*}}, %{{.*}}, %{{.*}} substr %{{.*}}, %{{.*}} : (index, index, index, index, index) -> !fir.slice<1>
return
}

View File

@ -606,3 +606,13 @@ func @bad_array_modify(%arr1 : !fir.ref<!fir.array<?x?xf32>>, %m : index, %n : i
fir.array_merge_store %av1, %av2 to %arr1 : !fir.array<?x?xf32>, !fir.array<?x?xf32>, !fir.ref<!fir.array<?x?xf32>>
return
}
// -----
func @slice_must_be_integral() {
%0 = arith.constant 42 : i32
%1 = fir.field_index field, !fir.type<t(param:i32){field:i32}> (%0 : i32)
// expected-error@+1 {{'fir.slice' op operand #0 must be any integer, but got '!fir.field'}}
%2 = fir.slice %1, %1, %1 : (!fir.field, !fir.field, !fir.field) -> !fir.slice<1>
return
}