[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