[flang-commits] [PATCH] D143270: [flang][hlfir] Turn fir.char<1> results into hlfir.expr<fir.char<1>>
Jean Perier via Phabricator via flang-commits
flang-commits at lists.llvm.org
Sun Feb 5 23:53:51 PST 2023
This revision was automatically updated to reflect the committed changes.
Closed by commit rG219b997ea0f7: [flang][hlfir] Turn fir.char<1> results into hlfir.expr<fir.char<1>> (authored by jeanPerier).
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D143270/new/
https://reviews.llvm.org/D143270
Files:
flang/lib/Lower/ConvertCall.cpp
flang/test/Lower/HLFIR/calls-character-singleton-result.f90
Index: flang/test/Lower/HLFIR/calls-character-singleton-result.f90
===================================================================
--- /dev/null
+++ flang/test/Lower/HLFIR/calls-character-singleton-result.f90
@@ -0,0 +1,57 @@
+! Test handling of intrinsics and BIND(C) functions returning CHARACTER(1).
+! This is a special case because characters are always returned
+! or handled in memory otherwise.
+
+! RUN: bbc -emit-fir -hlfir -o - %s | FileCheck %s
+
+subroutine scalar_char(c, i)
+ character(1) :: c
+ integer(8) :: i
+ c = char(i)
+end subroutine
+! CHECK-LABEL: func.func @_QPscalar_char(
+! CHECK: %[[VAL_2:.*]] = fir.alloca !fir.char<1>
+! CHECK: %[[VAL_5:.*]]:2 = hlfir.declare %{{.*}}#0 typeparams %{{.*}} {{.*}}Ec
+! CHECK: %[[VAL_6:.*]]:2 = hlfir.declare %{{.*}} {{.*}}Ei
+! CHECK: %[[VAL_7:.*]] = fir.load %[[VAL_6]]#1 : !fir.ref<i64>
+! CHECK: %[[VAL_8:.*]] = fir.convert %[[VAL_7]] : (i64) -> i8
+! CHECK: %[[VAL_9:.*]] = fir.undefined !fir.char<1>
+! CHECK: %[[VAL_10:.*]] = fir.insert_value %[[VAL_9]], %[[VAL_8]], [0 : index] : (!fir.char<1>, i8) -> !fir.char<1>
+! CHECK: fir.store %[[VAL_10]] to %[[VAL_2]] : !fir.ref<!fir.char<1>>
+! CHECK: %[[VAL_11:.*]] = arith.constant false
+! CHECK: %[[VAL_12:.*]] = hlfir.as_expr %[[VAL_2]] move %[[VAL_11]] : (!fir.ref<!fir.char<1>>, i1) -> !hlfir.expr<!fir.char<1>>
+! CHECK: hlfir.assign %[[VAL_12]] to %[[VAL_5]]#0 : !hlfir.expr<!fir.char<1>>, !fir.boxchar<1>
+
+subroutine scalar_bindc(c)
+ character(1) :: c
+ interface
+ character(1) function bar() bind(c)
+ end function
+ end interface
+ c = bar()
+end subroutine
+! CHECK-LABEL: func.func @_QPscalar_bindc(
+! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.char<1>
+! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %{{.*}}#0 typeparams %{{.*}} {{.*}}Ec
+! CHECK: %[[VAL_5:.*]] = fir.call @bar() fastmath<contract> : () -> !fir.char<1>
+! CHECK: fir.store %[[VAL_5]] to %[[VAL_1]] : !fir.ref<!fir.char<1>>
+! CHECK: %[[VAL_6:.*]] = arith.constant false
+! CHECK: %[[VAL_7:.*]] = hlfir.as_expr %[[VAL_1]] move %[[VAL_6]] : (!fir.ref<!fir.char<1>>, i1) -> !hlfir.expr<!fir.char<1>>
+! CHECK: hlfir.assign %[[VAL_7]] to %[[VAL_4]]#0 : !hlfir.expr<!fir.char<1>>, !fir.boxchar<1>
+
+subroutine array_char(c, i)
+ character(1) :: c(100)
+ integer(8) :: i(100)
+ c = char(i)
+end subroutine
+! CHECK-LABEL: func.func @_QParray_char(
+! CHECK: %[[VAL_2:.*]] = fir.alloca !fir.char<1>
+! CHECK: %[[VAL_13:.*]] = hlfir.elemental %{{.*}} typeparams %{{.*}} : (!fir.shape<1>, index) -> !hlfir.expr<100x!fir.char<1>> {
+! CHECK: ^bb0(%[[VAL_14:.*]]: index):
+! CHECK: %[[VAL_19:.*]] = fir.insert_value {{.*}} -> !fir.char<1>
+! CHECK: fir.store %[[VAL_19]] to %[[VAL_2]] : !fir.ref<!fir.char<1>>
+! CHECK: %[[VAL_20:.*]] = arith.constant false
+! CHECK: %[[VAL_21:.*]] = hlfir.as_expr %[[VAL_2]] move %[[VAL_20]] : (!fir.ref<!fir.char<1>>, i1) -> !hlfir.expr<!fir.char<1>>
+! CHECK: hlfir.yield_element %[[VAL_21]] : !hlfir.expr<!fir.char<1>>
+! CHECK: }
+! CHECK: hlfir.assign %[[VAL_13]] to %{{.*}} : !hlfir.expr<100x!fir.char<1>>, !fir.ref<!fir.array<100x!fir.char<1>>>
Index: flang/lib/Lower/ConvertCall.cpp
===================================================================
--- flang/lib/Lower/ConvertCall.cpp
+++ flang/lib/Lower/ConvertCall.cpp
@@ -608,6 +608,23 @@
mlir::Value firBase = fir::getBase(exv);
if (fir::isa_trivial(firBase.getType()))
return hlfir::EntityWithAttributes{firBase};
+ if (auto charTy = firBase.getType().dyn_cast<fir::CharacterType>()) {
+ // CHAR() intrinsic and BIND(C) procedures returning CHARACTER(1)
+ // are lowered to a fir.char<kind,1> that is not in memory.
+ // This tends to cause a lot of bugs because the rest of the
+ // infrastructure is mostly tested with characters that are
+ // in memory.
+ // To avoid having to deal with this special case here and there,
+ // place it in memory here. If this turns out to be suboptimal,
+ // this could be fixed, but for now llvm opt -O1 is able to get
+ // rid of the memory indirection in a = char(b), so there is
+ // little incentive to increase the compiler complexity.
+ hlfir::Entity storage{builder.createTemporary(loc, charTy)};
+ builder.create<fir::StoreOp>(loc, firBase, storage);
+ auto asExpr = builder.create<hlfir::AsExprOp>(
+ loc, storage, /*mustFree=*/builder.createBool(loc, false));
+ return hlfir::EntityWithAttributes{asExpr.getResult()};
+ }
return hlfir::genDeclare(loc, builder, exv, name,
fir::FortranVariableFlagsAttr{});
}
@@ -1118,7 +1135,7 @@
loc, builder, resultExv, ".tmp.intrinsic_result");
// Move result into memory into an hlfir.expr since they are immutable from
// that point, and the result storage is some temp.
- if (!fir::isa_trivial(resultEntity.getType())) {
+ if (resultEntity.isVariable()) {
hlfir::AsExprOp asExpr;
// Character/Derived MERGE lowering returns one of its argument address
// (this is the only intrinsic implemented in that way so far). The
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D143270.495009.patch
Type: text/x-patch
Size: 5074 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/flang-commits/attachments/20230206/24d8568d/attachment-0001.bin>
More information about the flang-commits
mailing list