diff --git a/flang/include/flang/Optimizer/HLFIR/CMakeLists.txt b/flang/include/flang/Optimizer/HLFIR/CMakeLists.txt --- a/flang/include/flang/Optimizer/HLFIR/CMakeLists.txt +++ b/flang/include/flang/Optimizer/HLFIR/CMakeLists.txt @@ -5,6 +5,8 @@ mlir_tablegen(HLFIRDialect.cpp.inc -gen-dialect-defs -dialect=hlfir) mlir_tablegen(HLFIRAttributes.h.inc -gen-attrdef-decls -attrdefs-dialect=hlfir) mlir_tablegen(HLFIRAttributes.cpp.inc -gen-attrdef-defs -attrdefs-dialect=hlfir) +mlir_tablegen(HLFIREnums.h.inc -gen-enum-decls) +mlir_tablegen(HLFIREnums.cpp.inc -gen-enum-defs) set(LLVM_TARGET_DEFINITIONS HLFIROps.td) mlir_tablegen(HLFIROps.h.inc -gen-op-decls) diff --git a/flang/include/flang/Optimizer/HLFIR/HLFIRDialect.h b/flang/include/flang/Optimizer/HLFIR/HLFIRDialect.h --- a/flang/include/flang/Optimizer/HLFIR/HLFIRDialect.h +++ b/flang/include/flang/Optimizer/HLFIR/HLFIRDialect.h @@ -26,6 +26,8 @@ #include "flang/Optimizer/HLFIR/HLFIRDialect.h.inc" +#include "flang/Optimizer/HLFIR/HLFIREnums.h.inc" + #define GET_TYPEDEF_CLASSES #include "flang/Optimizer/HLFIR/HLFIRTypes.h.inc" diff --git a/flang/include/flang/Optimizer/HLFIR/HLFIROpBase.td b/flang/include/flang/Optimizer/HLFIR/HLFIROpBase.td --- a/flang/include/flang/Optimizer/HLFIR/HLFIROpBase.td +++ b/flang/include/flang/Optimizer/HLFIR/HLFIROpBase.td @@ -15,6 +15,7 @@ #define FORTRAN_DIALECT_HLFIR_OP_BASE include "mlir/IR/AttrTypeBase.td" +include "mlir/IR/EnumAttr.td" include "mlir/IR/OpBase.td" include "flang/Optimizer/Dialect/FIRTypes.td" @@ -108,4 +109,12 @@ def AnyScalarCharacterExpr : Type; +def hlfir_CharExtremumPredicateAttr : I32EnumAttr< + "CharExtremumPredicate", "", + [ + I32EnumAttrCase<"min", 0>, + I32EnumAttrCase<"max", 1> + ]> { + let cppNamespace = "hlfir"; +} #endif // FORTRAN_DIALECT_HLFIR_OP_BASE diff --git a/flang/include/flang/Optimizer/HLFIR/HLFIROps.td b/flang/include/flang/Optimizer/HLFIR/HLFIROps.td --- a/flang/include/flang/Optimizer/HLFIR/HLFIROps.td +++ b/flang/include/flang/Optimizer/HLFIR/HLFIROps.td @@ -236,6 +236,27 @@ let hasVerifier = 1; } +def hlfir_CharExtremumOp : hlfir_Op<"char_extremum", []> { + let summary = "Find max/min from given character strings"; + let description = [{ + Find the minimum or maximum of two or more character strings of a same character kind and return the string with the minimum or maximum number of characters. Example: + + %0 = hlfir.char_extremum(min, %arg0, %arg1) : (!fir.ref>, !fir.ref>) -> index + }]; + + let arguments = (ins hlfir_CharExtremumPredicateAttr:$predicate, + Variadic:$strings + ); + + let results = (outs AnyScalarCharacterExpr); + + let assemblyFormat = [{ + $predicate `,` $strings attr-dict `:` functional-type(operands, results) + }]; + + let hasVerifier = 1; +} + def hlfir_SetLengthOp : hlfir_Op<"set_length", []> { let summary = "change the length of a character entity"; let description = [{ diff --git a/flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp b/flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp --- a/flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp +++ b/flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp @@ -402,6 +402,22 @@ build(builder, result, resultType, strings, len); } +//===----------------------------------------------------------------------===// +// CharExtremumOp +//===----------------------------------------------------------------------===// + +mlir::LogicalResult hlfir::CharExtremumOp::verify() { + // there could probably be some refactoring between this verify() and ConcatOp's verify since they're the same... + if (getStrings().size() < 2) + return emitOpError("must be provided at least two string operands"); + unsigned kind = getCharacterKind(getResult().getType()); + for (auto string : getStrings()) + if (kind != getCharacterKind(string.getType())) + return emitOpError("strings must have the same KIND as the result type"); + return mlir::success(); +} + + //===----------------------------------------------------------------------===// // SetLengthOp //===----------------------------------------------------------------------===// @@ -527,4 +543,5 @@ } #define GET_OP_CLASSES +#include "flang/Optimizer/HLFIR/HLFIREnums.cpp.inc" #include "flang/Optimizer/HLFIR/HLFIROps.cpp.inc"