[flang-commits] [flang] [flang] Lower non optional inquired argument in custom intrinsic lowering (PR #93592)
Valentin Clement バレンタイン クレメン via flang-commits
flang-commits at lists.llvm.org
Wed May 29 08:37:09 PDT 2024
https://github.com/clementval updated https://github.com/llvm/llvm-project/pull/93592
>From a38678f0bcdcef6f7ee5b978a22bc71a863ce688 Mon Sep 17 00:00:00 2001
From: Valentin Clement <clementval at gmail.com>
Date: Tue, 28 May 2024 08:34:18 -0700
Subject: [PATCH 1/2] [flang] Lower non optional inquired argument in custom
intrinsic lowering
---
flang/lib/Lower/ConvertCall.cpp | 5 ++--
flang/lib/Lower/CustomIntrinsicCall.cpp | 5 +++-
flang/lib/Optimizer/Builder/IntrinsicCall.cpp | 25 ++++++++++++++++++-
flang/test/Lower/Intrinsics/associated.f90 | 23 +++++++++++++++++
4 files changed, 54 insertions(+), 4 deletions(-)
diff --git a/flang/lib/Lower/ConvertCall.cpp b/flang/lib/Lower/ConvertCall.cpp
index 7ec719a2cb9ec..0d4611118843c 100644
--- a/flang/lib/Lower/ConvertCall.cpp
+++ b/flang/lib/Lower/ConvertCall.cpp
@@ -2436,8 +2436,9 @@ genCustomIntrinsicRef(const Fortran::evaluate::SpecificIntrinsic *intrinsic,
getActualFortranElementType());
break;
case fir::LowerIntrinsicArgAs::Inquired:
- TODO(loc, "Inquired non-optional arg to intrinsic with custom handling");
- return;
+ exv = Fortran::lower::convertToBox(loc, converter, actual, stmtCtx,
+ getActualFortranElementType());
+ break;
}
if (!exv)
llvm_unreachable("bad switch");
diff --git a/flang/lib/Lower/CustomIntrinsicCall.cpp b/flang/lib/Lower/CustomIntrinsicCall.cpp
index 30c6ce7f53b3f..8a3aa452799f2 100644
--- a/flang/lib/Lower/CustomIntrinsicCall.cpp
+++ b/flang/lib/Lower/CustomIntrinsicCall.cpp
@@ -291,7 +291,10 @@ lowerAssociated(fir::FirOpBuilder &builder, mlir::Location loc,
.genIfOp(loc, {boxType}, isPresent,
/*withElseRegion=*/true)
.genThen([&]() {
- mlir::Value box = builder.createBox(loc, targetExv);
+ mlir::Value box =
+ fir::isBoxAddress(targetBase.getType())
+ ? builder.create<fir::LoadOp>(loc, fir::getBase(targetExv))
+ : builder.createBox(loc, targetExv);
mlir::Value cast = builder.createConvert(loc, boxType, box);
builder.create<fir::ResultOp>(loc, cast);
})
diff --git a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
index ad2f9236f0db9..e497f58853703 100644
--- a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
+++ b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
@@ -38,6 +38,7 @@
#include "flang/Optimizer/Dialect/FIROps.h"
#include "flang/Optimizer/Dialect/FIROpsSupport.h"
#include "flang/Optimizer/Dialect/Support/FIRContext.h"
+#include "flang/Optimizer/HLFIR/HLFIROps.h"
#include "flang/Optimizer/Support/FatalError.h"
#include "flang/Optimizer/Support/Utils.h"
#include "flang/Runtime/entry-names.h"
@@ -2486,12 +2487,34 @@ IntrinsicLibrary::genAssociated(mlir::Type resultType,
// In both cases, ASSOCIATED should be false if POINTER is NULL.
return builder.create<mlir::arith::AndIOp>(loc, sameTarget, notNull);
}
+
+ const fir::ExtendedValue &target = args[1];
+
+ if (!args[0].getBoxOf<fir::MutableBoxValue>()) {
+ // Argument was lowered as a EntityWithAttribute. Try to retrieve the box
+ // reference.
+ if (auto declareOp = mlir::dyn_cast_or_null<hlfir::DeclareOp>(
+ fir::getBase(args[0]).getDefiningOp())) {
+ if (auto loadOp = mlir::dyn_cast_or_null<fir::LoadOp>(
+ declareOp.getMemref().getDefiningOp())) {
+ if (isStaticallyAbsent(target)) {
+ auto mutBox = fir::MutableBoxValue(loadOp.getMemref(), {}, {});
+ return fir::factory::genIsAllocatedOrAssociatedTest(builder, loc,
+ mutBox);
+ }
+ mlir::Value targetBox = builder.createBox(loc, target);
+ return fir::runtime::genAssociated(builder, loc, declareOp.getMemref(),
+ targetBox);
+ }
+ }
+ }
+
auto *pointer =
args[0].match([&](const fir::MutableBoxValue &x) { return &x; },
[&](const auto &) -> const fir::MutableBoxValue * {
fir::emitFatalError(loc, "pointer not a MutableBoxValue");
});
- const fir::ExtendedValue &target = args[1];
+
if (isStaticallyAbsent(target))
return fir::factory::genIsAllocatedOrAssociatedTest(builder, loc, *pointer);
mlir::Value targetBox = builder.createBox(loc, target);
diff --git a/flang/test/Lower/Intrinsics/associated.f90 b/flang/test/Lower/Intrinsics/associated.f90
index f09d0546a6514..9308ec7cc1a15 100644
--- a/flang/test/Lower/Intrinsics/associated.f90
+++ b/flang/test/Lower/Intrinsics/associated.f90
@@ -151,3 +151,26 @@ subroutine test_allocatable_target(p, allocatable_ziel)
! CHECK: fir.call @_FortranAPointerIsAssociatedWith(%[[VAL_9]], %[[VAL_10]]) {{.*}}: (!fir.box<none>, !fir.box<none>) -> i1
print *, associated(p, allocatable_ziel)
end subroutine
+
+subroutine test_optional_argument(a, b)
+ integer, pointer :: a
+ integer, optional, pointer :: b
+ logical :: assoc
+
+ assoc = associated(a, b)
+end subroutine
+
+! CHECK-LABEL: func.func @_QPtest_optional_argument(
+! CHECK-SAME: %[[A:.*]]: !fir.ref<!fir.box<!fir.ptr<i32>>> {fir.bindc_name = "a"}, %[[B:.*]]: !fir.ref<!fir.box<!fir.ptr<i32>>> {fir.bindc_name = "b", fir.optional}) {
+! CHECK: %[[IS_PRESENT_B:.*]] = fir.is_present %[[B]] : (!fir.ref<!fir.box<!fir.ptr<i32>>>) -> i1
+! CHECK: %[[BOX_B:.*]] = fir.if %[[IS_PRESENT_B]] -> (!fir.box<!fir.ptr<i32>>) {
+! CHECK: %[[LOADED_B:.*]] = fir.load %[[B]] : !fir.ref<!fir.box<!fir.ptr<i32>>>
+! CHECK: fir.result %[[LOADED_B]] : !fir.box<!fir.ptr<i32>>
+! CHECK: } else {
+! CHECK: %[[ABSENT_B:.*]] = fir.absent !fir.box<!fir.ptr<i32>>
+! CHECK: fir.result %[[ABSENT_B]] : !fir.box<!fir.ptr<i32>>
+! CHECK: }
+! CHECK: %[[LOADED_A:.*]] = fir.load %[[A]] : !fir.ref<!fir.box<!fir.ptr<i32>>>
+! CHECK: %[[BOX_NONE_A:.*]] = fir.convert %[[LOADED_A]] : (!fir.box<!fir.ptr<i32>>) -> !fir.box<none>
+! CHECK: %[[BOX_NONE_B:.*]] = fir.convert %[[BOX_B]] : (!fir.box<!fir.ptr<i32>>) -> !fir.box<none>
+! CHECK: %{{.*}} fir.call @_FortranAPointerIsAssociatedWith(%[[BOX_NONE_A]], %[[BOX_NONE_B]]) fastmath<contract> : (!fir.box<none>, !fir.box<none>) -> i1
>From d4fbf5444b24a4e5e54a1082207d3f58615f8a1d Mon Sep 17 00:00:00 2001
From: Valentin Clement <clementval at gmail.com>
Date: Wed, 29 May 2024 08:36:32 -0700
Subject: [PATCH 2/2] Make it way less hacky
---
flang/lib/Lower/ConvertCall.cpp | 7 +++---
flang/lib/Lower/CustomIntrinsicCall.cpp | 5 +---
flang/lib/Optimizer/Builder/IntrinsicCall.cpp | 24 +------------------
3 files changed, 6 insertions(+), 30 deletions(-)
diff --git a/flang/lib/Lower/ConvertCall.cpp b/flang/lib/Lower/ConvertCall.cpp
index 0d4611118843c..4dc0b469af3ce 100644
--- a/flang/lib/Lower/ConvertCall.cpp
+++ b/flang/lib/Lower/ConvertCall.cpp
@@ -1790,7 +1790,8 @@ static std::optional<hlfir::EntityWithAttributes> genCustomIntrinsicRefCore(
if (loadArg && fir::conformsWithPassByRef(actual.getType())) {
return hlfir::loadTrivialScalar(loc, builder, actual);
}
- return actual;
+ return Fortran::lower::translateToExtendedValue(loc, builder, actual,
+ callContext.stmtCtx);
};
// helper to get the isPresent flag for a particular prepared argument
auto isPresent = [&](std::size_t i) -> std::optional<mlir::Value> {
@@ -2436,8 +2437,8 @@ genCustomIntrinsicRef(const Fortran::evaluate::SpecificIntrinsic *intrinsic,
getActualFortranElementType());
break;
case fir::LowerIntrinsicArgAs::Inquired:
- exv = Fortran::lower::convertToBox(loc, converter, actual, stmtCtx,
- getActualFortranElementType());
+ exv = Fortran::lower::translateToExtendedValue(loc, builder, actual,
+ stmtCtx);
break;
}
if (!exv)
diff --git a/flang/lib/Lower/CustomIntrinsicCall.cpp b/flang/lib/Lower/CustomIntrinsicCall.cpp
index 8a3aa452799f2..30c6ce7f53b3f 100644
--- a/flang/lib/Lower/CustomIntrinsicCall.cpp
+++ b/flang/lib/Lower/CustomIntrinsicCall.cpp
@@ -291,10 +291,7 @@ lowerAssociated(fir::FirOpBuilder &builder, mlir::Location loc,
.genIfOp(loc, {boxType}, isPresent,
/*withElseRegion=*/true)
.genThen([&]() {
- mlir::Value box =
- fir::isBoxAddress(targetBase.getType())
- ? builder.create<fir::LoadOp>(loc, fir::getBase(targetExv))
- : builder.createBox(loc, targetExv);
+ mlir::Value box = builder.createBox(loc, targetExv);
mlir::Value cast = builder.createConvert(loc, boxType, box);
builder.create<fir::ResultOp>(loc, cast);
})
diff --git a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
index e497f58853703..ad962da97a68f 100644
--- a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
+++ b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
@@ -2487,34 +2487,12 @@ IntrinsicLibrary::genAssociated(mlir::Type resultType,
// In both cases, ASSOCIATED should be false if POINTER is NULL.
return builder.create<mlir::arith::AndIOp>(loc, sameTarget, notNull);
}
-
- const fir::ExtendedValue &target = args[1];
-
- if (!args[0].getBoxOf<fir::MutableBoxValue>()) {
- // Argument was lowered as a EntityWithAttribute. Try to retrieve the box
- // reference.
- if (auto declareOp = mlir::dyn_cast_or_null<hlfir::DeclareOp>(
- fir::getBase(args[0]).getDefiningOp())) {
- if (auto loadOp = mlir::dyn_cast_or_null<fir::LoadOp>(
- declareOp.getMemref().getDefiningOp())) {
- if (isStaticallyAbsent(target)) {
- auto mutBox = fir::MutableBoxValue(loadOp.getMemref(), {}, {});
- return fir::factory::genIsAllocatedOrAssociatedTest(builder, loc,
- mutBox);
- }
- mlir::Value targetBox = builder.createBox(loc, target);
- return fir::runtime::genAssociated(builder, loc, declareOp.getMemref(),
- targetBox);
- }
- }
- }
-
auto *pointer =
args[0].match([&](const fir::MutableBoxValue &x) { return &x; },
[&](const auto &) -> const fir::MutableBoxValue * {
fir::emitFatalError(loc, "pointer not a MutableBoxValue");
});
-
+ const fir::ExtendedValue &target = args[1];
if (isStaticallyAbsent(target))
return fir::factory::genIsAllocatedOrAssociatedTest(builder, loc, *pointer);
mlir::Value targetBox = builder.createBox(loc, target);
More information about the flang-commits
mailing list