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 @@ -300,4 +300,23 @@ let builders = [OpBuilder<(ins "hlfir::AssociateOp":$associate)>]; } +def hlfir_AsExprOp : hlfir_Op<"as_expr", []> { + let summary = "Take the value of an array, character or derived expression"; + + let description = [{ + Take the value of an array, character or derived expression. + }]; + + let arguments = (ins AnyFortranVariable:$var); + let results = (outs hlfir_ExprType); + + let assemblyFormat = [{ + $var attr-dict `:` functional-type(operands, results) + }]; + + + let builders = [OpBuilder<(ins "mlir::Value":$var)>]; +} + + #endif // FORTRAN_DIALECT_HLFIR_OPS 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 @@ -415,5 +415,23 @@ associate.getMustFreeStrorageFlag()); } +//===----------------------------------------------------------------------===// +// AsExprOp +//===----------------------------------------------------------------------===// + +void hlfir::AsExprOp::build(mlir::OpBuilder &builder, + mlir::OperationState &result, mlir::Value var) { + hlfir::ExprType::Shape typeShape; + mlir::Type type = getFortranElementOrSequenceType(var.getType()); + if (auto seqType = type.dyn_cast()) { + typeShape.append(seqType.getShape().begin(), seqType.getShape().end()); + type = seqType.getEleTy(); + } + + auto resultType = hlfir::ExprType::get(builder.getContext(), typeShape, type, + /*isPolymorphic: TODO*/ false); + return build(builder, result, resultType, var); +} + #define GET_OP_CLASSES #include "flang/Optimizer/HLFIR/HLFIROps.cpp.inc" diff --git a/flang/test/HLFIR/as_expr.fir b/flang/test/HLFIR/as_expr.fir new file mode 100644 --- /dev/null +++ b/flang/test/HLFIR/as_expr.fir @@ -0,0 +1,35 @@ +// Test hlfir.as_expr operation parse, verify (no errors), and unparse. + +// RUN: fir-opt %s | fir-opt | FileCheck %s + +func.func @char_expr(%arg0: !fir.boxchar<1>) { + %0 = hlfir.as_expr %arg0 : (!fir.boxchar<1>) -> !hlfir.expr> + return +} +// CHECK-LABEL: func.func @char_expr( +// CHECK-SAME: %[[VAL_0:.*]]: !fir.boxchar<1>) { +// CHECK: hlfir.as_expr %[[VAL_0]] : (!fir.boxchar<1>) -> !hlfir.expr> + +func.func @char_expr_2(%arg0: !fir.ref>) { + %0 = hlfir.as_expr %arg0 : (!fir.ref>) -> !hlfir.expr> + return +} +// CHECK-LABEL: func.func @char_expr_2( +// CHECK-SAME: %[[VAL_0:.*]]: !fir.ref>) { +// CHECK: hlfir.as_expr %[[VAL_0]] : (!fir.ref>) -> !hlfir.expr> + +func.func @array_expr(%arg0: !fir.box>) { + %0 = hlfir.as_expr %arg0 : (!fir.box>) -> !hlfir.expr + return +} +// CHECK-LABEL: func.func @array_expr( +// CHECK-SAME: %[[VAL_0:.*]]: !fir.box>) { +// CHECK: hlfir.as_expr %[[VAL_0]] : (!fir.box>) -> !hlfir.expr + +func.func @array_expr_2(%arg0: !fir.ref>) { + %0 = hlfir.as_expr %arg0 : (!fir.ref>) -> !hlfir.expr<10xi32> + return +} +// CHECK-LABEL: func.func @array_expr_2( +// CHECK-SAME: %[[VAL_0:.*]]: !fir.ref>) { +// CHECK: hlfir.as_expr %[[VAL_0]] : (!fir.ref>) -> !hlfir.expr<10xi32>