Skip to content

Commit 27f3ac5

Browse files
authored
[flang] Fix character scalar result for REDUCE intrinsic call (#95076)
The character reduce runtime functions expect a pointer to a scalar character of the correct length for the result of character reduce. A descriptor was passed so far. Fix the lowering so a proper temporary is created and passed to the runtime.
1 parent 41f81ad commit 27f3ac5

File tree

2 files changed

+42
-16
lines changed

2 files changed

+42
-16
lines changed

flang/lib/Optimizer/Builder/IntrinsicCall.cpp

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5778,15 +5778,19 @@ IntrinsicLibrary::genReduce(mlir::Type resultType,
57785778
return builder.create<fir::LoadOp>(loc, result);
57795779
}
57805780
if (fir::isa_char(eleTy)) {
5781-
// Create mutable fir.box to be passed to the runtime for the result.
5782-
fir::MutableBoxValue resultMutableBox =
5783-
fir::factory::createTempMutableBox(builder, loc, eleTy);
5784-
mlir::Value resultIrBox =
5785-
fir::factory::getMutableIRBox(builder, loc, resultMutableBox);
5781+
auto charTy = mlir::dyn_cast_or_null<fir::CharacterType>(resultType);
5782+
assert(charTy && "expect CharacterType");
5783+
fir::factory::CharacterExprHelper charHelper(builder, loc);
5784+
mlir::Value len;
5785+
if (charTy.hasDynamicLen())
5786+
len = charHelper.readLengthFromBox(fir::getBase(arrayTmp), charTy);
5787+
else
5788+
len = builder.createIntegerConstant(loc, builder.getI32Type(),
5789+
charTy.getLen());
5790+
fir::CharBoxValue temp = charHelper.createCharacterTemp(eleTy, len);
57865791
fir::runtime::genReduce(builder, loc, array, operation, mask, identity,
5787-
ordered, resultIrBox);
5788-
// Handle cleanup of allocatable result descriptor and return
5789-
return readAndAddCleanUp(resultMutableBox, resultType, "REDUCE");
5792+
ordered, temp.getBuffer());
5793+
return temp;
57905794
}
57915795
return fir::runtime::genReduce(builder, loc, array, operation, mask,
57925796
identity, ordered);

flang/test/Lower/Intrinsics/reduce.f90

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -348,21 +348,25 @@ subroutine char1(a)
348348
res = reduce(a, red_char1)
349349
end subroutine
350350

351-
! CHECK: fir.call @_FortranAReduceChar1
351+
! CHECK: %[[CHRTMP:.*]] = fir.alloca !fir.char<1> {bindc_name = ".chrtmp"}
352+
! CHECK: %[[RESULT:.*]] = fir.convert %[[CHRTMP]] : (!fir.ref<!fir.char<1>>) -> !fir.ref<i8>
353+
! CHECK: fir.call @_FortranAReduceChar1(%[[RESULT]], {{.*}})
352354

353355
pure function red_char2(a,b)
354-
character(kind=2), intent(in) :: a, b
355-
character(kind=2) :: red_char2
356+
character(kind=2, len=10), intent(in) :: a, b
357+
character(kind=2, len=10) :: red_char2
356358
red_char2 = a // b
357359
end function
358360

359361
subroutine char2(a)
360-
character(kind=2), intent(in) :: a(:)
361-
character(kind=2) :: res
362+
character(kind=2, len=10), intent(in) :: a(:)
363+
character(kind=2, len=10) :: res
362364
res = reduce(a, red_char2)
363365
end subroutine
364366

365-
! CHECK: fir.call @_FortranAReduceChar2
367+
! CHECK: %[[CHRTMP:.*]] = fir.alloca !fir.char<2,10> {bindc_name = ".chrtmp"}
368+
! CHECK: %[[RESULT:.*]] = fir.convert %[[CHRTMP]] : (!fir.ref<!fir.char<2,10>>) -> !fir.ref<i16>
369+
! CHECK: fir.call @_FortranAReduceChar2(%[[RESULT]], {{.*}})
366370

367371
pure function red_char4(a,b)
368372
character(kind=4), intent(in) :: a, b
@@ -598,8 +602,8 @@ subroutine char1dim(a)
598602
! CHECK: fir.call @_FortranAReduceCharacter1Dim
599603

600604
subroutine char2dim(a)
601-
character(kind=2), intent(in) :: a(:, :)
602-
character(kind=2), allocatable :: res(:)
605+
character(kind=2, len=10), intent(in) :: a(:, :)
606+
character(kind=2, len=10), allocatable :: res(:)
603607
res = reduce(a, red_char2, 2)
604608
end subroutine
605609

@@ -613,4 +617,22 @@ subroutine char4dim(a)
613617

614618
! CHECK: fir.call @_FortranAReduceCharacter4Dim
615619

620+
pure function red_char_dyn(a, b)
621+
character(*), intent(In) :: a, b
622+
character(max(len(a),len(b))) :: red_char_dyn
623+
red_char_dyn = max(a, b)
624+
end function
625+
626+
subroutine charDyn()
627+
character(5) :: res
628+
character(:), allocatable :: a(:)
629+
allocate(character(10)::a(10))
630+
res = reduce(a, red_char_dyn)
631+
end subroutine
632+
633+
! CHECK: %[[BOX_ELESIZE:.*]] = fir.box_elesize %{{.*}} : (!fir.box<!fir.heap<!fir.array<?x!fir.char<1,?>>>>) -> index
634+
! CHECK: %[[CHRTMP:.*]] = fir.alloca !fir.char<1,?>(%[[BOX_ELESIZE]] : index) {bindc_name = ".chrtmp"}
635+
! CHECK: %[[RESULT:.*]] = fir.convert %[[CHRTMP]] : (!fir.ref<!fir.char<1,?>>) -> !fir.ref<i8>
636+
! CHECK: fir.call @_FortranAReduceChar1(%[[RESULT]], {{.*}})
637+
616638
end module

0 commit comments

Comments
 (0)