[flang-commits] [flang] 15ea26d - [fir] Add fir.char_convert op
Valentin Clement via flang-commits
flang-commits at lists.llvm.org
Fri Oct 1 05:40:20 PDT 2021
Author: Eric Schweitz
Date: 2021-10-01T14:40:11+02:00
New Revision: 15ea26de243ab56dd0cfe8cafee1366b59d2bb84
URL: https://github.com/llvm/llvm-project/commit/15ea26de243ab56dd0cfe8cafee1366b59d2bb84
DIFF: https://github.com/llvm/llvm-project/commit/15ea26de243ab56dd0cfe8cafee1366b59d2bb84.diff
LOG: [fir] Add fir.char_convert op
Add the fir-char_convert op.
This patch is part of the upstreaming effort from fir-dev branch.
Reviewed By: kiranchandramohan
Differential Revision: https://reviews.llvm.org/D110818
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 c118d0d47562c..2e37db7317f0e 100644
--- a/flang/include/flang/Optimizer/Dialect/FIROps.td
+++ b/flang/include/flang/Optimizer/Dialect/FIROps.td
@@ -294,6 +294,46 @@ def fir_LoadOp : fir_OneResultOp<"load"> {
}];
}
+def fir_CharConvertOp : fir_Op<"char_convert", []> {
+ let summary = [{
+ Primitive to convert an entity of type CHARACTER from one KIND to a
+
diff erent KIND.
+ }];
+
+ let description = [{
+ Copy a CHARACTER (must be in memory) of KIND _k1_ to a CHARACTER (also must
+ be in memory) of KIND _k2_ where _k1_ != _k2_ and the buffers do not
+ overlap. This latter restriction is unchecked, as the Fortran language
+ definition eliminates the overlapping in memory case.
+
+ The number of code points copied is specified explicitly as the second
+ argument. The length of the !fir.char type is ignored.
+
+ ```mlir
+ fir.char_convert %1 for %2 to %3 : !fir.ref<!fir.char<1,?>>, i32,
+ !fir.ref<!fir.char<2,20>>
+ ```
+
+ Should future support for encodings other than ASCII be supported, codegen
+ can generate a call to a runtime helper routine which will map the code
+ points from UTF-8 to UCS-2, for example. Such remappings may not always
+ be possible as they may involve the creation of more code points than the
+ `count` limit. These details are left as future to-dos.
+ }];
+
+ let arguments = (ins
+ Arg<AnyReferenceLike, "", [MemRead]>:$from,
+ AnyIntegerType:$count,
+ Arg<AnyReferenceLike, "", [MemWrite]>:$to
+ );
+
+ let assemblyFormat = [{
+ $from `for` $count `to` $to attr-dict `:` type(operands)
+ }];
+
+ let verifier = "return ::verify(*this);";
+}
+
def fir_StoreOp : fir_Op<"store", []> {
let summary = "store an SSA-value to a memory location";
diff --git a/flang/lib/Optimizer/Dialect/FIROps.cpp b/flang/lib/Optimizer/Dialect/FIROps.cpp
index 69f7e854b6450..bc4d685a525de 100644
--- a/flang/lib/Optimizer/Dialect/FIROps.cpp
+++ b/flang/lib/Optimizer/Dialect/FIROps.cpp
@@ -667,6 +667,24 @@ static mlir::ParseResult parseCmpOp(mlir::OpAsmParser &parser,
return success();
}
+//===----------------------------------------------------------------------===//
+// CharConvertOp
+//===----------------------------------------------------------------------===//
+
+static mlir::LogicalResult verify(fir::CharConvertOp op) {
+ auto unwrap = [&](mlir::Type t) {
+ t = fir::unwrapSequenceType(fir::dyn_cast_ptrEleTy(t));
+ return t.dyn_cast<fir::CharacterType>();
+ };
+ auto inTy = unwrap(op.from().getType());
+ auto outTy = unwrap(op.to().getType());
+ if (!(inTy && outTy))
+ return op.emitOpError("not a reference to a character");
+ if (inTy.getFKind() == outTy.getFKind())
+ return op.emitOpError("buffers must have
diff erent KIND values");
+ return mlir::success();
+}
+
//===----------------------------------------------------------------------===//
// CmpcOp
//===----------------------------------------------------------------------===//
diff --git a/flang/test/Fir/fir-ops.fir b/flang/test/Fir/fir-ops.fir
index 2abbcd3f032d8..21f3755c4e35e 100644
--- a/flang/test/Fir/fir-ops.fir
+++ b/flang/test/Fir/fir-ops.fir
@@ -682,3 +682,12 @@ func @test_save_result(%buffer: !fir.ref<!fir.array<?x!fir.char<1,?>>>) {
fir.save_result %res to %buffer(%shape) typeparams %c50 : !fir.array<?x!fir.char<1,?>>, !fir.ref<!fir.array<?x!fir.char<1,?>>>, !fir.shape<1>, index
return
}
+
+func @char_convert() {
+ %1 = fir.undefined i32
+ %2 = fir.undefined !fir.ref<!fir.char<1>>
+ %3 = fir.undefined !fir.ref<!fir.array<?x!fir.char<2,?>>>
+ // CHECK: fir.char_convert %{{.*}} for %{{.*}} to %{{.*}} : !fir.ref<!fir.char<1>>, i32, !fir.ref<!fir.array<?x!fir.char<2,?>>>
+ fir.char_convert %2 for %1 to %3 : !fir.ref<!fir.char<1>>, i32, !fir.ref<!fir.array<?x!fir.char<2,?>>>
+ return
+}
diff --git a/flang/test/Fir/invalid.fir b/flang/test/Fir/invalid.fir
index 4e74de90ed0e0..a2b367cef3252 100644
--- a/flang/test/Fir/invalid.fir
+++ b/flang/test/Fir/invalid.fir
@@ -380,6 +380,50 @@ fir.do_loop %i = %c1 to %c10 step %c1 -> index {
// -----
+func @ugly_char_convert() {
+ %1 = fir.undefined i32
+ %2 = fir.undefined !fir.ref<!fir.char<1>>
+ %3 = fir.undefined !fir.ref<!fir.array<?x!fir.char<1>>>
+ // expected-error at +1 {{'fir.char_convert' op buffers must have
diff erent KIND values}}
+ fir.char_convert %2 for %1 to %3 : !fir.ref<!fir.char<1>>, i32, !fir.ref<!fir.array<?x!fir.char<1>>>
+ return
+}
+
+// -----
+
+func @ugly_char_convert() {
+ %1 = fir.undefined i32
+ %2 = fir.undefined !fir.ref<!fir.char<1>>
+ %3 = fir.undefined !fir.ref<!fir.array<?xf32>>
+ // expected-error at +1 {{'fir.char_convert' op not a reference to a character}}
+ fir.char_convert %2 for %1 to %3 : !fir.ref<!fir.char<1>>, i32, !fir.ref<!fir.array<?xf32>>
+ return
+}
+
+// -----
+
+func @ugly_char_convert() {
+ %1 = fir.undefined i32
+ %2 = fir.undefined !fir.ref<!fir.char<1>>
+ %3 = fir.undefined !fir.ref<!fir.array<?x!fir.char<2,?>>>
+ // expected-error at +1 {{'fir.char_convert' op operand #0 must be any reference, but got 'i32'}}
+ fir.char_convert %1 for %1 to %3 : i32, i32, !fir.ref<!fir.array<?x!fir.char<2,?>>>
+ return
+}
+
+// -----
+
+func @ugly_char_convert() {
+ %1 = fir.undefined i32
+ %2 = fir.undefined !fir.ref<!fir.char<1>>
+ %3 = fir.undefined !fir.ref<!fir.array<?x!fir.char<2,?>>>
+ // expected-error at +1 {{'fir.char_convert' op operand #1 must be any integer, but got '!fir.ref<!fir.char<1>>'}}
+ fir.char_convert %2 for %2 to %3 : !fir.ref<!fir.char<1>>, !fir.ref<!fir.char<1>>, !fir.ref<!fir.array<?x!fir.char<2,?>>>
+ return
+}
+
+// -----
+
fir.global internal @_QEmultiarray : !fir.array<32x32xi32> {
%c0_i32 = constant 1 : i32
%0 = fir.undefined !fir.array<32x32xi32>
More information about the flang-commits
mailing list