[flang-commits] [flang] b9c78b2 - [flang] Add hlfir.assign definition
Jean Perier via flang-commits
flang-commits at lists.llvm.org
Tue Nov 15 03:00:46 PST 2022
Author: Jean Perier
Date: 2022-11-15T12:00:16+01:00
New Revision: b9c78b2c59e2408640bf8350cdeb2b72b5d5db21
URL: https://github.com/llvm/llvm-project/commit/b9c78b2c59e2408640bf8350cdeb2b72b5d5db21
DIFF: https://github.com/llvm/llvm-project/commit/b9c78b2c59e2408640bf8350cdeb2b72b5d5db21.diff
LOG: [flang] Add hlfir.assign definition
Add hlfir.assign that represent Fortran assignment.
See https://github.com/llvm/llvm-project/blob/main/flang/docs/HighLevelFIR.md.
Operation attributes will be added later when they can be used.
Differential Revision: https://reviews.llvm.org/D138012
Added:
flang/test/HLFIR/assign.fir
Modified:
flang/include/flang/Optimizer/HLFIR/CMakeLists.txt
flang/include/flang/Optimizer/HLFIR/HLFIROpBase.td
flang/include/flang/Optimizer/HLFIR/HLFIROps.td
flang/test/HLFIR/invalid.fir
Removed:
################################################################################
diff --git a/flang/include/flang/Optimizer/HLFIR/CMakeLists.txt b/flang/include/flang/Optimizer/HLFIR/CMakeLists.txt
index 18f2cef35509c..bf90996edf3c3 100644
--- a/flang/include/flang/Optimizer/HLFIR/CMakeLists.txt
+++ b/flang/include/flang/Optimizer/HLFIR/CMakeLists.txt
@@ -1,6 +1,6 @@
set(LLVM_TARGET_DEFINITIONS HLFIROpBase.td)
-mlir_tablegen(HLFIRTypes.h.inc -gen-typedef-decls)
-mlir_tablegen(HLFIRTypes.cpp.inc -gen-typedef-defs)
+mlir_tablegen(HLFIRTypes.h.inc -gen-typedef-decls -typedefs-dialect=hlfir)
+mlir_tablegen(HLFIRTypes.cpp.inc -gen-typedef-defs -typedefs-dialect=hlfir)
mlir_tablegen(HLFIRDialect.h.inc -gen-dialect-decls -dialect=hlfir)
mlir_tablegen(HLFIRDialect.cpp.inc -gen-dialect-defs -dialect=hlfir)
mlir_tablegen(HLFIRAttributes.h.inc -gen-attrdef-decls -attrdefs-dialect=hlfir)
diff --git a/flang/include/flang/Optimizer/HLFIR/HLFIROpBase.td b/flang/include/flang/Optimizer/HLFIR/HLFIROpBase.td
index ffb33c0870607..244cf79cd0ce2 100644
--- a/flang/include/flang/Optimizer/HLFIR/HLFIROpBase.td
+++ b/flang/include/flang/Optimizer/HLFIR/HLFIROpBase.td
@@ -16,6 +16,7 @@
include "mlir/IR/AttrTypeBase.td"
include "mlir/IR/OpBase.td"
+include "flang/Optimizer/Dialect/FIRTypes.td"
def hlfir_Dialect : Dialect {
let name = "hlfir";
@@ -72,7 +73,17 @@ def hlfir_ExprType : TypeDef<hlfir_Dialect, "Expr"> {
def IsFortranVariablePred
: CPred<"::hlfir::isFortranVariableType($_self)">;
+def AnyFortranVariable : Type<IsFortranVariablePred, "any HLFIR variable type">;
+
+
+def AnyFortranValue : TypeConstraint<Or<[AnyLogicalLike.predicate,
+ AnyIntegerLike.predicate, AnyRealLike.predicate,
+ fir_ComplexType.predicate, AnyComplex.predicate,
+ hlfir_ExprType.predicate]>, "any Fortran value type">;
+
+
+def AnyFortranEntity : TypeConstraint<Or<[AnyFortranVariable.predicate,
+ AnyFortranValue.predicate]>, "any Fortran value or variable type">;
-def AnyFortranVariableLike : Type<IsFortranVariablePred, "any HLFIR variable type">;
#endif // FORTRAN_DIALECT_HLFIR_OP_BASE
diff --git a/flang/include/flang/Optimizer/HLFIR/HLFIROps.td b/flang/include/flang/Optimizer/HLFIR/HLFIROps.td
index 60430ded39736..3a8094721197a 100644
--- a/flang/include/flang/Optimizer/HLFIR/HLFIROps.td
+++ b/flang/include/flang/Optimizer/HLFIR/HLFIROps.td
@@ -83,7 +83,7 @@ def hlfir_DeclareOp : hlfir_Op<"declare", [AttrSizedOperandSegments,
OptionalAttr<fir_FortranVariableFlagsAttr>:$fortran_attrs
);
- let results = (outs AnyFortranVariableLike, AnyRefOrBoxLike);
+ let results = (outs AnyFortranVariable, AnyRefOrBoxLike);
let assemblyFormat = [{
$memref (`(` $shape^ `)`)? (`typeparams` $typeparams^)?
@@ -116,4 +116,21 @@ def hlfir_DeclareOp : hlfir_Op<"declare", [AttrSizedOperandSegments,
let hasVerifier = 1;
}
+def fir_AssignOp : hlfir_Op<"assign", [MemoryEffects<[MemWrite]>]> {
+ let summary = "Assign an expression or variable value to a Fortran variable";
+
+ let description = [{
+ Assign rhs to lhs following Fortran intrinsic assignments rules.
+ The operation deals with inserting a temporary if the lhs and rhs
+ may overlap.
+ }];
+
+ let arguments = (ins AnyFortranEntity:$rhs,
+ Arg<AnyFortranVariable, "", [MemWrite]>:$lhs);
+
+ let assemblyFormat = [{
+ $rhs `to` $lhs attr-dict `:` type(operands)
+ }];
+}
+
#endif // FORTRAN_DIALECT_HLFIR_OPS
diff --git a/flang/test/HLFIR/assign.fir b/flang/test/HLFIR/assign.fir
new file mode 100644
index 0000000000000..fed2621da33ac
--- /dev/null
+++ b/flang/test/HLFIR/assign.fir
@@ -0,0 +1,130 @@
+// Test hlfir.assign operation parse, verify (no errors), and unparse.
+
+// RUN: fir-opt %s | fir-opt | FileCheck %s
+
+func.func @scalar_logical(%arg0: !fir.ref<!fir.logical<1>>, %arg1: !fir.ref<!fir.logical<1>>) {
+ hlfir.assign %arg1 to %arg0 : !fir.ref<!fir.logical<1>>, !fir.ref<!fir.logical<1>>
+ return
+}
+// CHECK-LABEL: func.func @scalar_logical(
+// CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.logical<1>>,
+// CHECK-SAME: %[[VAL_1:.*]]: !fir.ref<!fir.logical<1>>) {
+// CHECK: hlfir.assign %[[VAL_1]] to %[[VAL_0]] : !fir.ref<!fir.logical<1>>, !fir.ref<!fir.logical<1>>
+
+func.func @scalar_logical_2(%arg0: !fir.ref<!fir.logical<1>>, %arg1: i1) {
+ hlfir.assign %arg1 to %arg0 : i1, !fir.ref<!fir.logical<1>>
+ return
+}
+// CHECK-LABEL: func.func @scalar_logical_2(
+// CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.logical<1>>,
+// CHECK-SAME: %[[VAL_1:.*]]: i1) {
+// CHECK: hlfir.assign %[[VAL_1]] to %[[VAL_0]] : i1, !fir.ref<!fir.logical<1>>
+
+func.func @scalar_integer(%arg0: !fir.ref<i32>, %arg1: !fir.ref<i32>) {
+ hlfir.assign %arg1 to %arg0 : !fir.ref<i32>, !fir.ref<i32>
+ return
+}
+// CHECK-LABEL: func.func @scalar_integer(
+// CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<i32>,
+// CHECK-SAME: %[[VAL_1:.*]]: !fir.ref<i32>) {
+// CHECK: hlfir.assign %[[VAL_1]] to %[[VAL_0]] : !fir.ref<i32>, !fir.ref<i32>
+
+func.func @scalar_integer_2(%arg0: !fir.ref<i32>, %arg1: i32) {
+ hlfir.assign %arg1 to %arg0 : i32, !fir.ref<i32>
+ return
+}
+// CHECK-LABEL: func.func @scalar_integer_2(
+// CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<i32>,
+// CHECK-SAME: %[[VAL_1:.*]]: i32) {
+// CHECK: hlfir.assign %[[VAL_1]] to %[[VAL_0]] : i32, !fir.ref<i32>
+
+func.func @scalar_real(%arg0: !fir.ref<f16>, %arg1: !fir.ref<f16>) {
+ hlfir.assign %arg1 to %arg0 : !fir.ref<f16>, !fir.ref<f16>
+ return
+}
+// CHECK-LABEL: func.func @scalar_real(
+// CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<f16>,
+// CHECK-SAME: %[[VAL_1:.*]]: !fir.ref<f16>) {
+// CHECK: hlfir.assign %[[VAL_1]] to %[[VAL_0]] : !fir.ref<f16>, !fir.ref<f16>
+
+func.func @scalar_complex(%arg0: !fir.ref<!fir.complex<8>>, %arg1: !fir.ref<!fir.complex<8>>) {
+ hlfir.assign %arg1 to %arg0 : !fir.ref<!fir.complex<8>>, !fir.ref<!fir.complex<8>>
+ return
+}
+// CHECK-LABEL: func.func @scalar_complex(
+// CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.complex<8>>,
+// CHECK-SAME: %[[VAL_1:.*]]: !fir.ref<!fir.complex<8>>) {
+// CHECK: hlfir.assign %[[VAL_1]] to %[[VAL_0]] : !fir.ref<!fir.complex<8>>, !fir.ref<!fir.complex<8>>
+
+func.func @scalar_complex_2(%arg0: !fir.ref<!fir.complex<8>>, %arg1: !fir.complex<8>) {
+ hlfir.assign %arg1 to %arg0 : !fir.complex<8>, !fir.ref<!fir.complex<8>>
+ return
+}
+// CHECK-LABEL: func.func @scalar_complex_2(
+// CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.complex<8>>,
+// CHECK-SAME: %[[VAL_1:.*]]: !fir.complex<8>) {
+// CHECK: hlfir.assign %[[VAL_1]] to %[[VAL_0]] : !fir.complex<8>, !fir.ref<!fir.complex<8>>
+
+
+func.func @scalar_character(%arg0: !fir.boxchar<1>, %arg1: !fir.boxchar<1>) {
+ hlfir.assign %arg1 to %arg0 : !fir.boxchar<1>, !fir.boxchar<1>
+ return
+}
+// CHECK-LABEL: func.func @scalar_character(
+// CHECK-SAME: %[[VAL_0:.*]]: !fir.boxchar<1>,
+// CHECK-SAME: %[[VAL_1:.*]]: !fir.boxchar<1>) {
+// CHECK: hlfir.assign %[[VAL_1]] to %[[VAL_0]] : !fir.boxchar<1>, !fir.boxchar<1>
+
+func.func @scalar_character_2(%arg0: !fir.ref<!fir.char<1,32>>, %arg1: !fir.ref<!fir.char<1,64>>) {
+ hlfir.assign %arg1 to %arg0 : !fir.ref<!fir.char<1,64>>, !fir.ref<!fir.char<1,32>>
+ return
+}
+// CHECK-LABEL: func.func @scalar_character_2(
+// CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.char<1,32>>,
+// CHECK-SAME: %[[VAL_1:.*]]: !fir.ref<!fir.char<1,64>>) {
+// CHECK: hlfir.assign %[[VAL_1]] to %[[VAL_0]] : !fir.ref<!fir.char<1,64>>, !fir.ref<!fir.char<1,32>>
+
+func.func @scalar_character_3(%arg0: !fir.boxchar<1>, %arg1: !hlfir.expr<!fir.char<1,?>>) {
+ hlfir.assign %arg1 to %arg0 : !hlfir.expr<!fir.char<1,?>>, !fir.boxchar<1>
+ return
+}
+// CHECK-LABEL: func.func @scalar_character_3(
+// CHECK-SAME: %[[VAL_0:.*]]: !fir.boxchar<1>,
+// CHECK-SAME: %[[VAL_1:.*]]: !hlfir.expr<!fir.char<1,?>>) {
+// CHECK: hlfir.assign %[[VAL_1]] to %[[VAL_0]] : !hlfir.expr<!fir.char<1,?>>, !fir.boxchar<1>
+
+func.func @array(%arg0: !fir.ref<!fir.array<10xi32>>, %arg1: i32) {
+ hlfir.assign %arg1 to %arg0 : i32, !fir.ref<!fir.array<10xi32>>
+ return
+}
+// CHECK-LABEL: func.func @array(
+// CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.array<10xi32>>,
+// CHECK-SAME: %[[VAL_1:.*]]: i32) {
+// CHECK: hlfir.assign %[[VAL_1]] to %[[VAL_0]] : i32, !fir.ref<!fir.array<10xi32>>
+
+func.func @array_2(%arg0: !fir.ref<!fir.array<10xi32>>, %arg1: !hlfir.expr<?xi32>) {
+ hlfir.assign %arg1 to %arg0 : !hlfir.expr<?xi32>, !fir.ref<!fir.array<10xi32>>
+ return
+}
+// CHECK-LABEL: func.func @array_2(
+// CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.array<10xi32>>,
+// CHECK-SAME: %[[VAL_1:.*]]: !hlfir.expr<?xi32>) {
+// CHECK: hlfir.assign %[[VAL_1]] to %[[VAL_0]] : !hlfir.expr<?xi32>, !fir.ref<!fir.array<10xi32>>
+
+func.func @array_3(%arg0: !fir.box<!fir.array<?xi32>>, %arg1: !hlfir.expr<?xi32>) {
+ hlfir.assign %arg1 to %arg0 : !hlfir.expr<?xi32>, !fir.box<!fir.array<?xi32>>
+ return
+}
+// CHECK-LABEL: func.func @array_3(
+// CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?xi32>>,
+// CHECK-SAME: %[[VAL_1:.*]]: !hlfir.expr<?xi32>) {
+// CHECK: hlfir.assign %[[VAL_1]] to %[[VAL_0]] : !hlfir.expr<?xi32>, !fir.box<!fir.array<?xi32>>
+
+func.func @array_4(%arg0: !fir.box<!fir.array<?xi32>>, %arg1: !fir.box<!fir.array<?xi32>>) {
+ hlfir.assign %arg1 to %arg0 : !fir.box<!fir.array<?xi32>>, !fir.box<!fir.array<?xi32>>
+ return
+}
+// CHECK-LABEL: func.func @array_4(
+// CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?xi32>>,
+// CHECK-SAME: %[[VAL_1:.*]]: !fir.box<!fir.array<?xi32>>) {
+// CHECK: hlfir.assign %[[VAL_1]] to %[[VAL_0]] : !fir.box<!fir.array<?xi32>>, !fir.box<!fir.array<?xi32>>
diff --git a/flang/test/HLFIR/invalid.fir b/flang/test/HLFIR/invalid.fir
index 1ed753fed7f26..cf99e6bd75993 100644
--- a/flang/test/HLFIR/invalid.fir
+++ b/flang/test/HLFIR/invalid.fir
@@ -35,3 +35,38 @@ func.func @bad_array_declare(%arg0: !fir.ref<!fir.array<?x?xf32>>) {
%0:2 = hlfir.declare %arg0 {uniq_name = "x"} : (!fir.ref<!fir.array<?x?xf32>>) -> (!fir.box<!fir.array<?x?xf32>>, !fir.ref<!fir.array<?x?xf32>>)
return
}
+
+// -----
+func.func @bad_assign_scalar_character(%arg0: !fir.boxchar<1>, %arg1: !fir.char<1,?>) {
+ // expected-error at +1 {{'hlfir.assign' op operand #0 must be any Fortran value or variable type, but got '!fir.char<1,?>'}}
+ hlfir.assign %arg1 to %arg0 : !fir.char<1,?>, !fir.boxchar<1>
+ return
+}
+
+// -----
+func.func @bad_assign_scalar_character_1(%arg0: !fir.boxchar<1>, %arg1: !hlfir.expr<!fir.char<1,?>>) {
+ // expected-error at +1 {{'hlfir.assign' op operand #1 must be any HLFIR variable type, but got '!hlfir.expr<!fir.char<1,?>>'}}
+ hlfir.assign %arg0 to %arg1 : !fir.boxchar<1>, !hlfir.expr<!fir.char<1,?>>
+ return
+}
+
+// -----
+func.func @bad_assign_scalar_integer(%arg0: !fir.ref<i32>, %arg1: i32) {
+ // expected-error at +1 {{'hlfir.assign' op operand #1 must be any HLFIR variable type, but got 'i32'}}
+ hlfir.assign %arg0 to %arg1 : !fir.ref<i32>, i32
+ return
+}
+
+// -----
+func.func @bad_assign_array(%arg0: !fir.ref<!fir.array<?xi32>>, %arg1: !hlfir.expr<?xi32>) {
+ // expected-error at +1 {{'hlfir.assign' op operand #1 must be any HLFIR variable type, but got '!fir.ref<!fir.array<?xi32>>'}}
+ hlfir.assign %arg1 to %arg0 : !hlfir.expr<?xi32>, !fir.ref<!fir.array<?xi32>>
+ return
+}
+
+// -----
+func.func @bad_assign_array_2(%arg0: !fir.ref<!fir.array<10xi32>>, %arg1: !hlfir.expr<?xi32>) {
+ // expected-error at +1 {{'hlfir.assign' op operand #1 must be any HLFIR variable type, but got '!hlfir.expr<?xi32>'}}
+ hlfir.assign %arg0 to %arg1 : !fir.ref<!fir.array<10xi32>>, !hlfir.expr<?xi32>
+ return
+}
More information about the flang-commits
mailing list