[flang-commits] [flang] [flang] translate pure and elemental attribute in FIR (PR #109954)
via flang-commits
flang-commits at lists.llvm.org
Wed Sep 25 06:33:27 PDT 2024
https://github.com/jeanPerier updated https://github.com/llvm/llvm-project/pull/109954
>From 8b259ae1029fb0fb8e254a4db3c0d63113f6d05f Mon Sep 17 00:00:00 2001
From: Jean Perier <jperier at nvidia.com>
Date: Wed, 25 Sep 2024 03:16:59 -0700
Subject: [PATCH 1/2] [flang] translate pure and elemental attribute in FIR
---
flang/include/flang/Lower/CallInterface.h | 9 ++++++++
.../flang/Optimizer/Dialect/FIRAttr.td | 2 ++
flang/lib/Lower/CallInterface.cpp | 23 +++++++++++++++++++
flang/lib/Lower/ConvertCall.cpp | 8 ++-----
.../HLFIR/array-ctor-as-elemental-nested.f90 | 2 +-
.../Lower/HLFIR/array-ctor-as-elemental.f90 | 2 +-
.../test/Lower/HLFIR/elemental-array-ops.f90 | 2 +-
.../HLFIR/elemental-user-procedure-ref.f90 | 14 +++++------
flang/test/Lower/HLFIR/forall.f90 | 12 +++++-----
flang/test/Lower/HLFIR/where-nonelemental.f90 | 6 ++---
.../test/Lower/array-elemental-calls-char.f90 | 2 +-
.../test/Lower/array-user-def-assignments.f90 | 2 +-
12 files changed, 57 insertions(+), 27 deletions(-)
diff --git a/flang/include/flang/Lower/CallInterface.h b/flang/include/flang/Lower/CallInterface.h
index 9a688330e8bd2d..1fb390455733f3 100644
--- a/flang/include/flang/Lower/CallInterface.h
+++ b/flang/include/flang/Lower/CallInterface.h
@@ -42,6 +42,10 @@ namespace mlir {
class Location;
}
+namespace fir {
+class FortranProcedureFlagsEnumAttr;
+}
+
namespace Fortran::lower {
class AbstractConverter;
class SymMap;
@@ -235,6 +239,11 @@ class CallInterface {
return characteristic && characteristic->CanBeCalledViaImplicitInterface();
}
+ /// Translate Fortran procedure attributes into FIR attribute.
+ /// Return attribute is nullptr if the procedure has no attributes.
+ fir::FortranProcedureFlagsEnumAttr
+ getProcedureAttrs(mlir::MLIRContext *) const;
+
protected:
CallInterface(Fortran::lower::AbstractConverter &c) : converter{c} {}
/// CRTP handle.
diff --git a/flang/include/flang/Optimizer/Dialect/FIRAttr.td b/flang/include/flang/Optimizer/Dialect/FIRAttr.td
index 6400756b384482..e96e0f5837e157 100644
--- a/flang/include/flang/Optimizer/Dialect/FIRAttr.td
+++ b/flang/include/flang/Optimizer/Dialect/FIRAttr.td
@@ -62,6 +62,8 @@ def fir_FortranVariableFlagsAttr : fir_Attr<"FortranVariableFlags"> {
/// Fortran procedure attributes (F2023 15.6.2.1). BIND attribute (18.3.7)
/// is also tracked in the same enum. Recursive (resp. Impure) attribute
/// is implied by the absence of opposite NonRecursive (resp. Pure) attribute.
+/// Beware that "elemental" does not implicitly imply "pure" as is does in
+/// Fortran, "pure" must be made explicit when generating the FIR attribute.
def FIRfuncNoAttributes : I32BitEnumAttrCaseNone<"none">;
def FIRfuncElemental : I32BitEnumAttrCaseBit<"elemental", 0>;
def FIRfuncPure : I32BitEnumAttrCaseBit<"pure", 1>;
diff --git a/flang/lib/Lower/CallInterface.cpp b/flang/lib/Lower/CallInterface.cpp
index c0ef96adc20c3e..f541f847382917 100644
--- a/flang/lib/Lower/CallInterface.cpp
+++ b/flang/lib/Lower/CallInterface.cpp
@@ -1546,6 +1546,29 @@ Fortran::lower::CallInterface<T>::getResultType() const {
return types;
}
+template <typename T>
+fir::FortranProcedureFlagsEnumAttr
+Fortran::lower::CallInterface<T>::getProcedureAttrs(
+ mlir::MLIRContext *mlirContext) const {
+ if (characteristic) {
+ fir::FortranProcedureFlagsEnum flags = fir::FortranProcedureFlagsEnum::none;
+ if (characteristic->IsBindC())
+ flags = flags | fir::FortranProcedureFlagsEnum::bind_c;
+ if (characteristic->IsPure())
+ flags = flags | fir::FortranProcedureFlagsEnum::pure;
+ if (characteristic->IsElemental())
+ flags = flags | fir::FortranProcedureFlagsEnum::elemental;
+ // TODO:
+ // - SIMPLE: F2023, not yet handled by semantics.
+ // - NON_RECURSIVE: not part of the characteristics. Maybe this should
+ // simply not be part of FortranProcedureFlagsEnum since cannot accurately
+ // be known on the caller side.
+ if (flags != fir::FortranProcedureFlagsEnum::none)
+ return fir::FortranProcedureFlagsEnumAttr::get(mlirContext, flags);
+ }
+ return nullptr;
+}
+
template class Fortran::lower::CallInterface<Fortran::lower::CalleeInterface>;
template class Fortran::lower::CallInterface<Fortran::lower::CallerInterface>;
diff --git a/flang/lib/Lower/ConvertCall.cpp b/flang/lib/Lower/ConvertCall.cpp
index 017bfd049d3dc5..ee5eb225f0d7e3 100644
--- a/flang/lib/Lower/ConvertCall.cpp
+++ b/flang/lib/Lower/ConvertCall.cpp
@@ -631,13 +631,9 @@ std::pair<fir::ExtendedValue, bool> Fortran::lower::genCallOpAndResult(
if (callNumResults != 0)
callResult = dispatch.getResult(0);
} else {
- // TODO: gather other procedure attributes.
- fir::FortranProcedureFlagsEnumAttr procAttrs;
- if (caller.characterize().IsBindC())
- procAttrs = fir::FortranProcedureFlagsEnumAttr::get(
- builder.getContext(), fir::FortranProcedureFlagsEnum::bind_c);
-
// Standard procedure call with fir.call.
+ fir::FortranProcedureFlagsEnumAttr procAttrs =
+ caller.getProcedureAttrs(builder.getContext());
auto call = builder.create<fir::CallOp>(
loc, funcType.getResults(), funcSymbolAttr, operands, procAttrs);
diff --git a/flang/test/Lower/HLFIR/array-ctor-as-elemental-nested.f90 b/flang/test/Lower/HLFIR/array-ctor-as-elemental-nested.f90
index a30c6c6e4a2273..1dc033d0ba033e 100644
--- a/flang/test/Lower/HLFIR/array-ctor-as-elemental-nested.f90
+++ b/flang/test/Lower/HLFIR/array-ctor-as-elemental-nested.f90
@@ -31,7 +31,7 @@
! CHECK: %[[VAL_21:.*]]:3 = hlfir.associate %[[VAL_22:.*]](%[[VAL_17]]) {adapt.valuebyref} : (!hlfir.expr<2xf32>, !fir.shape<1>) -> (!fir.ref<!fir.array<2xf32>>, !fir.ref<!fir.array<2xf32>>, i1)
! CHECK: %[[VAL_23:.*]] = fir.embox %[[VAL_21]]#0(%[[VAL_17]]) : (!fir.ref<!fir.array<2xf32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xf32>>
! CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_23]] : (!fir.box<!fir.array<2xf32>>) -> !fir.box<!fir.array<?xf32>>
-! CHECK: %[[VAL_25:.*]] = fir.call @_QPfoo(%[[VAL_24]]) fastmath<contract> : (!fir.box<!fir.array<?xf32>>) -> f32
+! CHECK: %[[VAL_25:.*]] = fir.call @_QPfoo(%[[VAL_24]]) proc_attrs<pure> fastmath<contract> : (!fir.box<!fir.array<?xf32>>) -> f32
! CHECK: hlfir.end_associate %[[VAL_21]]#1, %[[VAL_21]]#2 : !fir.ref<!fir.array<2xf32>>, i1
! CHECK: hlfir.destroy %[[VAL_22]] : !hlfir.expr<2xf32>
! CHECK: hlfir.yield_element %[[VAL_25]] : f32
diff --git a/flang/test/Lower/HLFIR/array-ctor-as-elemental.f90 b/flang/test/Lower/HLFIR/array-ctor-as-elemental.f90
index 277e2683c64f86..4d3f93c7d48cec 100644
--- a/flang/test/Lower/HLFIR/array-ctor-as-elemental.f90
+++ b/flang/test/Lower/HLFIR/array-ctor-as-elemental.f90
@@ -107,7 +107,7 @@ integer pure function foo(i)
! CHECK: %[[VAL_13:.*]] = arith.addi %[[VAL_5]], %[[VAL_12]] : index
! CHECK: %[[VAL_14:.*]] = fir.convert %[[VAL_13]] : (index) -> i64
! CHECK: %[[VAL_15:.*]] = fir.convert %[[VAL_14]] : (i64) -> i32
-! CHECK: %[[VAL_16:.*]] = fir.call @_QPfoo(%[[VAL_15]]) fastmath<contract> : (i32) -> i32
+! CHECK: %[[VAL_16:.*]] = fir.call @_QPfoo(%[[VAL_15]]) proc_attrs<pure> fastmath<contract> : (i32) -> i32
! CHECK: hlfir.yield_element %[[VAL_16]] : i32
! CHECK: }
! CHECK: %[[VAL_17:.*]]:3 = hlfir.associate %[[VAL_18:.*]](%[[VAL_3]]) {adapt.valuebyref} : (!hlfir.expr<4xi32>, !fir.shape<1>) -> (!fir.ref<!fir.array<4xi32>>, !fir.ref<!fir.array<4xi32>>, i1)
diff --git a/flang/test/Lower/HLFIR/elemental-array-ops.f90 b/flang/test/Lower/HLFIR/elemental-array-ops.f90
index 18e1fb0a787e73..aefc4d978a27dc 100644
--- a/flang/test/Lower/HLFIR/elemental-array-ops.f90
+++ b/flang/test/Lower/HLFIR/elemental-array-ops.f90
@@ -182,7 +182,7 @@ end subroutine char_return
! CHECK: %[[VAL_23:.*]] = arith.constant 0 : index
! CHECK: %[[VAL_24:.*]] = arith.cmpi sgt, %[[VAL_22]], %[[VAL_23]] : index
! CHECK: %[[VAL_25:.*]] = arith.select %[[VAL_24]], %[[VAL_22]], %[[VAL_23]] : index
-! CHECK: %[[VAL_27:.*]] = fir.call @_QPcallee(%[[VAL_2]], %[[VAL_25]], %[[VAL_20]]) fastmath<contract> : (!fir.ref<!fir.char<1,3>>, index, !fir.boxchar<1>) -> !fir.boxchar<1>
+! CHECK: %[[VAL_27:.*]] = fir.call @_QPcallee(%[[VAL_2]], %[[VAL_25]], %[[VAL_20]]) proc_attrs<elemental, pure> fastmath<contract> : (!fir.ref<!fir.char<1,3>>, index, !fir.boxchar<1>) -> !fir.boxchar<1>
! CHECK: %[[VAL_28:.*]]:2 = hlfir.declare %[[VAL_2]] typeparams %[[VAL_25]] {uniq_name = ".tmp.func_result"} : (!fir.ref<!fir.char<1,3>>, index) -> (!fir.ref<!fir.char<1,3>>, !fir.ref<!fir.char<1,3>>)
! CHECK: %[[MustFree:.*]] = arith.constant false
! CHECK: %[[ResultTemp:.*]] = hlfir.as_expr %[[VAL_28]]#0 move %[[MustFree]] : (!fir.ref<!fir.char<1,3>>, i1) -> !hlfir.expr<!fir.char<1,3>>
diff --git a/flang/test/Lower/HLFIR/elemental-user-procedure-ref.f90 b/flang/test/Lower/HLFIR/elemental-user-procedure-ref.f90
index aea23d8d94672c..d4d8b858aaeea6 100644
--- a/flang/test/Lower/HLFIR/elemental-user-procedure-ref.f90
+++ b/flang/test/Lower/HLFIR/elemental-user-procedure-ref.f90
@@ -18,7 +18,7 @@ real elemental function elem(a, b)
! CHECK: %[[VAL_6:.*]] = hlfir.elemental %[[VAL_4]] unordered : (!fir.shape<1>) -> !hlfir.expr<100xf32> {
! CHECK: ^bb0(%[[VAL_7:.*]]: index):
! CHECK: %[[VAL_8:.*]] = hlfir.designate %[[VAL_5]]#0 (%[[VAL_7]]) : (!fir.ref<!fir.array<100xf32>>, index) -> !fir.ref<f32>
-! CHECK: %[[VAL_9:.*]] = fir.call @_QPelem(%[[VAL_2]]#1, %[[VAL_8]]) fastmath<contract> : (!fir.ref<i32>, !fir.ref<f32>) -> f32
+! CHECK: %[[VAL_9:.*]] = fir.call @_QPelem(%[[VAL_2]]#1, %[[VAL_8]]) proc_attrs<elemental, pure> fastmath<contract> : (!fir.ref<i32>, !fir.ref<f32>) -> f32
! CHECK: hlfir.yield_element %[[VAL_9]] : f32
! CHECK: }
! CHECK: fir.call
@@ -43,7 +43,7 @@ real elemental function elem_val(a, b)
! CHECK: ^bb0(%[[VAL_9:.*]]: index, %[[VAL_10:.*]]: index):
! CHECK: %[[VAL_11:.*]] = hlfir.designate %[[VAL_6]]#0 (%[[VAL_9]], %[[VAL_10]]) : (!fir.ref<!fir.array<10x20xf32>>, index, index) -> !fir.ref<f32>
! CHECK: %[[VAL_12:.*]] = fir.load %[[VAL_11]] : !fir.ref<f32>
-! CHECK: %[[VAL_13:.*]] = fir.call @_QPelem_val(%[[VAL_7]], %[[VAL_12]]) fastmath<contract> : (i32, f32) -> f32
+! CHECK: %[[VAL_13:.*]] = fir.call @_QPelem_val(%[[VAL_7]], %[[VAL_12]]) proc_attrs<elemental, pure> fastmath<contract> : (i32, f32) -> f32
! CHECK: hlfir.yield_element %[[VAL_13]] : f32
! CHECK: }
! CHECK: fir.call
@@ -67,7 +67,7 @@ real elemental function char_elem(a, b)
! CHECK: %[[VAL_9:.*]] = hlfir.elemental %[[VAL_7]] unordered : (!fir.shape<1>) -> !hlfir.expr<100xf32> {
! CHECK: ^bb0(%[[VAL_10:.*]]: index):
! CHECK: %[[VAL_11:.*]] = hlfir.designate %[[VAL_8]]#0 (%[[VAL_10]]) typeparams %[[VAL_4]]#1 : (!fir.box<!fir.array<100x!fir.char<1,?>>>, index, index) -> !fir.boxchar<1>
-! CHECK: %[[VAL_12:.*]] = fir.call @_QPchar_elem(%[[VAL_3]]#0, %[[VAL_11]]) fastmath<contract> : (!fir.boxchar<1>, !fir.boxchar<1>) -> f32
+! CHECK: %[[VAL_12:.*]] = fir.call @_QPchar_elem(%[[VAL_3]]#0, %[[VAL_11]]) proc_attrs<elemental, pure> fastmath<contract> : (!fir.boxchar<1>, !fir.boxchar<1>) -> f32
! CHECK: hlfir.yield_element %[[VAL_12]] : f32
! CHECK: }
! CHECK: fir.call
@@ -93,7 +93,7 @@ elemental subroutine elem_sub(a, b)
! CHECK: fir.do_loop %[[VAL_8:.*]] = %[[VAL_7]] to %[[VAL_4]] step %[[VAL_7]] unordered {
! CHECK: fir.do_loop %[[VAL_9:.*]] = %[[VAL_7]] to %[[VAL_3]] step %[[VAL_7]] unordered {
! CHECK: %[[VAL_10:.*]] = hlfir.designate %[[VAL_6]]#0 (%[[VAL_9]], %[[VAL_8]]) : (!fir.ref<!fir.array<10x20xf32>>, index, index) -> !fir.ref<f32>
-! CHECK: fir.call @_QPelem_sub(%[[VAL_2]]#1, %[[VAL_10]]) fastmath<contract> : (!fir.ref<i32>, !fir.ref<f32>) -> ()
+! CHECK: fir.call @_QPelem_sub(%[[VAL_2]]#1, %[[VAL_10]]) proc_attrs<elemental, pure> fastmath<contract> : (!fir.ref<i32>, !fir.ref<f32>) -> ()
! CHECK: }
! CHECK: }
@@ -116,7 +116,7 @@ impure elemental subroutine impure_elem(a)
! CHECK: fir.do_loop %[[VAL_6:.*]] = %[[VAL_5]] to %[[VAL_2]] step %[[VAL_5]] {
! CHECK: fir.do_loop %[[VAL_7:.*]] = %[[VAL_5]] to %[[VAL_1]] step %[[VAL_5]] {
! CHECK: %[[VAL_8:.*]] = hlfir.designate %[[VAL_4]]#0 (%[[VAL_7]], %[[VAL_6]]) : (!fir.ref<!fir.array<10x20xf32>>, index, index) -> !fir.ref<f32>
-! CHECK: fir.call @_QPimpure_elem(%[[VAL_8]]) fastmath<contract> : (!fir.ref<f32>) -> ()
+! CHECK: fir.call @_QPimpure_elem(%[[VAL_8]]) proc_attrs<elemental> fastmath<contract> : (!fir.ref<f32>) -> ()
! CHECK: }
! CHECK: }
! CHECK: return
@@ -141,7 +141,7 @@ elemental subroutine ordered_elem(a)
! CHECK: fir.do_loop %[[VAL_6:.*]] = %[[VAL_5]] to %[[VAL_2]] step %[[VAL_5]] {
! CHECK: fir.do_loop %[[VAL_7:.*]] = %[[VAL_5]] to %[[VAL_1]] step %[[VAL_5]] {
! CHECK: %[[VAL_8:.*]] = hlfir.designate %[[VAL_4]]#0 (%[[VAL_7]], %[[VAL_6]]) : (!fir.ref<!fir.array<10x20xf32>>, index, index) -> !fir.ref<f32>
-! CHECK: fir.call @_QPordered_elem(%[[VAL_8]]) fastmath<contract> : (!fir.ref<f32>) -> ()
+! CHECK: fir.call @_QPordered_elem(%[[VAL_8]]) proc_attrs<elemental, pure> fastmath<contract> : (!fir.ref<f32>) -> ()
! CHECK: }
! CHECK: }
! CHECK: return
@@ -174,7 +174,7 @@ impure elemental subroutine impure_elem(a)
! CHECK: fir.do_loop %[[VAL_14:.*]] = %[[VAL_13]] to %[[VAL_2]] step %[[VAL_13]] {
! CHECK: fir.do_loop %[[VAL_15:.*]] = %[[VAL_13]] to %[[VAL_1]] step %[[VAL_13]] {
! CHECK: %[[VAL_16:.*]] = hlfir.designate %[[VAL_11]]#0 (%[[VAL_15]], %[[VAL_14]]) : (!fir.ref<!fir.array<10x20xf32>>, index, index) -> !fir.ref<f32>
-! CHECK: fir.call @_QPimpure_elem(%[[VAL_16]]) fastmath<contract> : (!fir.ref<f32>) -> ()
+! CHECK: fir.call @_QPimpure_elem(%[[VAL_16]]) proc_attrs<elemental> fastmath<contract> : (!fir.ref<f32>) -> ()
! CHECK: }
! CHECK: }
! CHECK: hlfir.end_associate %[[VAL_11]]#1, %[[VAL_11]]#2 : !fir.ref<!fir.array<10x20xf32>>, i1
diff --git a/flang/test/Lower/HLFIR/forall.f90 b/flang/test/Lower/HLFIR/forall.f90
index c12f0c6a826b50..709e233746a91f 100644
--- a/flang/test/Lower/HLFIR/forall.f90
+++ b/flang/test/Lower/HLFIR/forall.f90
@@ -86,7 +86,7 @@ subroutine test_forall_mask()
! CHECK: } (%[[VAL_9:.*]]: i64) {
! CHECK: %[[VAL_10:.*]] = hlfir.forall_index "i" %[[VAL_9]] : (i64) -> !fir.ref<i64>
! CHECK: hlfir.forall_mask {
-! CHECK: %[[VAL_11:.*]] = fir.call @_QPpredicate(%[[VAL_10]]) fastmath<contract> : (!fir.ref<i64>) -> !fir.logical<4>
+! CHECK: %[[VAL_11:.*]] = fir.call @_QPpredicate(%[[VAL_10]]) proc_attrs<pure> fastmath<contract> : (!fir.ref<i64>) -> !fir.logical<4>
! CHECK: %[[VAL_12:.*]] = fir.convert %[[VAL_11]] : (!fir.logical<4>) -> i1
! CHECK: hlfir.yield %[[VAL_12]] : i1
! CHECK: } do {
@@ -113,8 +113,8 @@ subroutine test_forall_several_indices()
! CHECK: %[[VAL_6:.*]]:2 = hlfir.declare {{.*}}Ey
! CHECK: %[[VAL_7:.*]] = fir.call @_QPibar() fastmath<contract> : () -> i32
! CHECK: %[[VAL_8:.*]] = fir.call @_QPifoo() fastmath<contract> : () -> i32
-! CHECK: %[[VAL_9:.*]] = fir.call @_QPjfoo() fastmath<contract> : () -> i64
-! CHECK: %[[VAL_10:.*]] = fir.call @_QPjbar() fastmath<contract> : () -> i64
+! CHECK: %[[VAL_9:.*]] = fir.call @_QPjfoo() proc_attrs<pure> fastmath<contract> : () -> i64
+! CHECK: %[[VAL_10:.*]] = fir.call @_QPjbar() proc_attrs<pure> fastmath<contract> : () -> i64
! CHECK: hlfir.forall lb {
! CHECK: hlfir.yield %[[VAL_7]] : i32
! CHECK: } ub {
@@ -126,7 +126,7 @@ subroutine test_forall_several_indices()
! CHECK: hlfir.yield %[[VAL_10]] : i64
! CHECK: } (%[[VAL_12:.*]]: i64) {
! CHECK: hlfir.region_assign {
-! CHECK: %[[VAL_13:.*]] = fir.call @_QPifoo2(%[[VAL_11]], %[[VAL_12]]) fastmath<contract> : (i64, i64) -> i64
+! CHECK: %[[VAL_13:.*]] = fir.call @_QPifoo2(%[[VAL_11]], %[[VAL_12]]) proc_attrs<pure> fastmath<contract> : (i64, i64) -> i64
! CHECK: %[[VAL_14:.*]] = hlfir.designate %[[VAL_6]]#0 (%[[VAL_13]]) : (!fir.ref<!fir.array<10xi32>>, i64) -> !fir.ref<i32>
! CHECK: %[[VAL_15:.*]] = fir.load %[[VAL_14]] : !fir.ref<i32>
! CHECK: hlfir.yield %[[VAL_15]] : i32
@@ -169,10 +169,10 @@ subroutine test_nested_foralls()
! CHECK: hlfir.yield %[[VAL_12]] : !fir.ref<i32>
! CHECK: }
! CHECK: hlfir.forall lb {
-! CHECK: %[[VAL_13:.*]] = fir.call @_QPjfoo() fastmath<contract> : () -> i64
+! CHECK: %[[VAL_13:.*]] = fir.call @_QPjfoo() proc_attrs<pure> fastmath<contract> : () -> i64
! CHECK: hlfir.yield %[[VAL_13]] : i64
! CHECK: } ub {
-! CHECK: %[[VAL_14:.*]] = fir.call @_QPjbar() fastmath<contract> : () -> i64
+! CHECK: %[[VAL_14:.*]] = fir.call @_QPjbar() proc_attrs<pure> fastmath<contract> : () -> i64
! CHECK: hlfir.yield %[[VAL_14]] : i64
! CHECK: } (%[[VAL_15:.*]]: i64) {
! CHECK: hlfir.region_assign {
diff --git a/flang/test/Lower/HLFIR/where-nonelemental.f90 b/flang/test/Lower/HLFIR/where-nonelemental.f90
index 15a281b0ba6813..643f417c476748 100644
--- a/flang/test/Lower/HLFIR/where-nonelemental.f90
+++ b/flang/test/Lower/HLFIR/where-nonelemental.f90
@@ -125,7 +125,7 @@ integer pure function pure_ifoo()
! CHECK: hlfir.where {
! CHECK: %[[VAL_21:.*]] = llvm.intr.stacksave : !llvm.ptr
! CHECK-NOT: hlfir.exactly_once
-! CHECK: %[[VAL_23:.*]] = fir.call @_QPpure_logical_func1() fastmath<contract> : () -> !fir.array<100x!fir.logical<4>>
+! CHECK: %[[VAL_23:.*]] = fir.call @_QPpure_logical_func1() proc_attrs<pure> fastmath<contract> : () -> !fir.array<100x!fir.logical<4>>
! CHECK: hlfir.yield %{{.*}} : !hlfir.expr<100x!fir.logical<4>> cleanup {
! CHECK: llvm.intr.stackrestore %[[VAL_21]] : !llvm.ptr
! CHECK: }
@@ -173,7 +173,7 @@ integer pure function pure_ifoo()
! CHECK: hlfir.elsewhere mask {
! CHECK: %[[VAL_129:.*]] = hlfir.exactly_once : !hlfir.expr<100x!fir.logical<4>> {
! CHECK: %[[VAL_139:.*]] = llvm.intr.stacksave : !llvm.ptr
-! CHECK: %[[VAL_141:.*]] = fir.call @_QPpure_logical_func2() fastmath<contract> : () -> !fir.array<100x!fir.logical<4>>
+! CHECK: %[[VAL_141:.*]] = fir.call @_QPpure_logical_func2() proc_attrs<pure> fastmath<contract> : () -> !fir.array<100x!fir.logical<4>>
! CHECK: hlfir.yield %{{.*}} : !hlfir.expr<100x!fir.logical<4>> cleanup {
! CHECK: llvm.intr.stackrestore %[[VAL_139]] : !llvm.ptr
! CHECK: }
@@ -185,7 +185,7 @@ integer pure function pure_ifoo()
! CHECK: hlfir.yield %{{.*}} : !fir.box<!fir.array<?xf32>>
! CHECK: } to {
! CHECK: %[[VAL_165:.*]] = hlfir.exactly_once : i32 {
-! CHECK: %[[VAL_166:.*]] = fir.call @_QPpure_ifoo() fastmath<contract> : () -> i32
+! CHECK: %[[VAL_166:.*]] = fir.call @_QPpure_ifoo() proc_attrs<pure> fastmath<contract> : () -> i32
! CHECK: hlfir.yield %[[VAL_166]] : i32
! CHECK: }
! CHECK: hlfir.designate
diff --git a/flang/test/Lower/array-elemental-calls-char.f90 b/flang/test/Lower/array-elemental-calls-char.f90
index 652e79232c1b5e..603cc677805fc9 100644
--- a/flang/test/Lower/array-elemental-calls-char.f90
+++ b/flang/test/Lower/array-elemental-calls-char.f90
@@ -123,7 +123,7 @@ subroutine foo2b(i, j, c)
! CHECK: %[[VAL_13:.*]] = fir.emboxchar %[[VAL_7]], %[[VAL_3]] : (!fir.ref<!fir.char<1,10>>, index) -> !fir.boxchar<1>
! CHECK: %[[VAL_14:.*]] = arith.addi %[[VAL_9]], %[[VAL_5]] : index
! CHECK: %[[VAL_15:.*]] = fir.array_coor %[[VAL_1]](%[[VAL_8]]) %[[VAL_14]] : (!fir.ref<!fir.array<10xi32>>, !fir.shape<1>, index) -> !fir.ref<i32>
-! CHECK: %[[VAL_16:.*]] = fir.call @_QPelem2(%[[VAL_13]], %[[VAL_15]]) fastmath<contract> : (!fir.boxchar<1>, !fir.ref<i32>) -> i32
+! CHECK: %[[VAL_16:.*]] = fir.call @_QPelem2(%[[VAL_13]], %[[VAL_15]]) proc_attrs<elemental, pure> fastmath<contract> : (!fir.boxchar<1>, !fir.ref<i32>) -> i32
! CHECK: %[[VAL_17:.*]] = fir.array_coor %[[VAL_0]](%[[VAL_8]]) %[[VAL_14]] : (!fir.ref<!fir.array<10xi32>>, !fir.shape<1>, index) -> !fir.ref<i32>
! CHECK: fir.store %[[VAL_16]] to %[[VAL_17]] : !fir.ref<i32>
! CHECK: %[[VAL_18:.*]] = arith.subi %[[VAL_10]], %[[VAL_5]] : index
diff --git a/flang/test/Lower/array-user-def-assignments.f90 b/flang/test/Lower/array-user-def-assignments.f90
index 97090ff77678c6..e88bc2fb861ba5 100644
--- a/flang/test/Lower/array-user-def-assignments.f90
+++ b/flang/test/Lower/array-user-def-assignments.f90
@@ -442,7 +442,7 @@ elemental subroutine sto_char(a,b)
! CHECK: %[[V_6:[0-9]+]] = fir.do_loop %arg2 = %[[V_2]] to %[[V_3]] step %[[C_1]] unordered iter_args(%arg3 = %[[V_5]]) -> (!fir.array<10x!fir.logical<4>>) {
! CHECK: %[[V_7:[0-9]+]] = fir.convert %arg2 : (index) -> i32
! CHECK: fir.store %[[V_7]] to %[[V_1:[0-9]+]] : !fir.ref<i32>
-! CHECK: %[[V_8:[0-9]+]] = fir.call @_QPreturns_alloc(%[[V_1]]) fastmath<contract> : (!fir.ref<i32>) -> !fir.box<!fir.heap<f32>>
+! CHECK: %[[V_8:[0-9]+]] = fir.call @_QPreturns_alloc(%[[V_1]]) proc_attrs<pure> fastmath<contract> : (!fir.ref<i32>) -> !fir.box<!fir.heap<f32>>
! CHECK: fir.save_result %[[V_8]] to %[[V_0:[0-9]+]] : !fir.box<!fir.heap<f32>>, !fir.ref<!fir.box<!fir.heap<f32>>>
! CHECK: %[[V_9:[0-9]+]] = fir.load %[[V_0:[0-9]+]] : !fir.ref<!fir.box<!fir.heap<f32>>>
! CHECK: %[[V_10:[0-9]+]] = fir.box_addr %[[V_9:[0-9]+]] : (!fir.box<!fir.heap<f32>>) -> !fir.heap<f32>
>From 2b8b11fb4721c444b3d23c5e5c955039bca3339c Mon Sep 17 00:00:00 2001
From: jeanPerier <jean.perier.polytechnique at gmail.com>
Date: Wed, 25 Sep 2024 15:33:18 +0200
Subject: [PATCH 2/2] Update flang/include/flang/Optimizer/Dialect/FIRAttr.td
Co-authored-by: Tom Eccles <t at freedommail.info>
---
flang/include/flang/Optimizer/Dialect/FIRAttr.td | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/flang/include/flang/Optimizer/Dialect/FIRAttr.td b/flang/include/flang/Optimizer/Dialect/FIRAttr.td
index e96e0f5837e157..4e84959a3b3e14 100644
--- a/flang/include/flang/Optimizer/Dialect/FIRAttr.td
+++ b/flang/include/flang/Optimizer/Dialect/FIRAttr.td
@@ -62,7 +62,7 @@ def fir_FortranVariableFlagsAttr : fir_Attr<"FortranVariableFlags"> {
/// Fortran procedure attributes (F2023 15.6.2.1). BIND attribute (18.3.7)
/// is also tracked in the same enum. Recursive (resp. Impure) attribute
/// is implied by the absence of opposite NonRecursive (resp. Pure) attribute.
-/// Beware that "elemental" does not implicitly imply "pure" as is does in
+/// Beware that "elemental" does not implicitly imply "pure" as it does in
/// Fortran, "pure" must be made explicit when generating the FIR attribute.
def FIRfuncNoAttributes : I32BitEnumAttrCaseNone<"none">;
def FIRfuncElemental : I32BitEnumAttrCaseBit<"elemental", 0>;
More information about the flang-commits
mailing list