Skip to content

Commit 2d956d2

Browse files
authored
[flang] fix ICE with ignore_tkr(tk) character in explicit interface (#140885)
Some MPI libraries use character dummies + ignore(TKR) to allow passing any kind of buffer. This was meant to already be handled by #108168 However, when the library interface also had an argument requiring an explicit interface, `builder.convertWithSemantics` was not allowed to properly deal with the actual/dummy type mismatch and generated bad IR causing errors like: `'fir.convert' op invalid type conversion'!fir.ref' / '!fir.boxchar\<1\>'`. This restriction was artificial, lowering should just handle any cases allowed by semantics. Just remove it.
1 parent dc29901 commit 2d956d2

File tree

2 files changed

+27
-2
lines changed

2 files changed

+27
-2
lines changed

flang/lib/Lower/ConvertCall.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -486,7 +486,6 @@ Fortran::lower::genCallOpAndResult(
486486

487487
// Deal with potential mismatches in arguments types. Passing an array to a
488488
// scalar argument should for instance be tolerated here.
489-
bool callingImplicitInterface = caller.canBeCalledViaImplicitInterface();
490489
for (auto [fst, snd] : llvm::zip(caller.getInputs(), funcType.getInputs())) {
491490
// When passing arguments to a procedure that can be called by implicit
492491
// interface, allow any character actual arguments to be passed to dummy
@@ -518,10 +517,17 @@ Fortran::lower::genCallOpAndResult(
518517
// Do not attempt any reboxing here that could break this.
519518
bool legacyLowering =
520519
!converter.getLoweringOptions().getLowerToHighLevelFIR();
520+
// When dealing with a dummy character argument (fir.boxchar), the
521+
// effective argument might be a non-character raw pointer. This may
522+
// happen when calling an implicit interface that was previously called
523+
// with a character argument, or when calling an explicit interface with
524+
// an IgnoreTKR dummy character arguments. Allow creating a fir.boxchar
525+
// from the raw pointer, which requires a non-trivial type conversion.
526+
const bool allowCharacterConversions = true;
521527
bool isVolatile = fir::isa_volatile_type(snd);
522528
cast = builder.createVolatileCast(loc, isVolatile, fst);
523529
cast = builder.convertWithSemantics(loc, snd, cast,
524-
callingImplicitInterface,
530+
allowCharacterConversions,
525531
/*allowRebox=*/legacyLowering);
526532
}
527533
}
@@ -1446,6 +1452,8 @@ static PreparedDummyArgument preparePresentUserCallActualArgument(
14461452
// cause the fir.if results to be assumed-rank in case of OPTIONAL dummy,
14471453
// causing extra runtime costs due to the unknown runtime size of assumed-rank
14481454
// descriptors.
1455+
// For TKR dummy characters, the boxchar creation also happens later when
1456+
// creating the fir.call .
14491457
preparedDummy.dummy =
14501458
builder.createConvert(loc, dummyTypeWithActualRank, addr);
14511459
return preparedDummy;

flang/test/Lower/HLFIR/ignore-type-f77-character.f90

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,13 @@ subroutine foo(c)
88
!dir$ ignore_tkr(tkrdm) c
99
end subroutine
1010
end interface
11+
interface
12+
subroutine foo_requires_explicit_interface(c, i)
13+
character(1)::c(*)
14+
!dir$ ignore_tkr(tkrdm) c
15+
integer, optional :: i
16+
end subroutine
17+
end interface
1118
contains
1219
subroutine test_normal()
1320
character(1) :: c(10)
@@ -32,4 +39,14 @@ subroutine test_weird()
3239
!CHECK: %[[VAL_5:.*]] = fir.convert %{{.*}} : (!fir.ref<!fir.array<10xf32>>) -> !fir.ref<!fir.char<1,?>>
3340
!CHECK: %[[VAL_6:.*]] = fir.emboxchar %[[VAL_5]], %c0{{.*}}: (!fir.ref<!fir.char<1,?>>, index) -> !fir.boxchar<1>
3441
!CHECK: fir.call @_QPfoo(%[[VAL_6]]) fastmath<contract> : (!fir.boxchar<1>) -> ()
42+
43+
subroutine test_requires_explicit_interface(x, i)
44+
real :: x(10)
45+
integer :: i
46+
call foo_requires_explicit_interface(x, i)
47+
end subroutine
48+
!CHECK-LABEL: func.func @_QMtest_char_tkPtest_requires_explicit_interface(
49+
!CHECK: %[[VAL_5:.*]] = fir.convert %{{.*}} : (!fir.ref<!fir.array<10xf32>>) -> !fir.ref<!fir.char<1,?>>
50+
!CHECK: %[[VAL_6:.*]] = fir.emboxchar %[[VAL_5]], %c0{{.*}}: (!fir.ref<!fir.char<1,?>>, index) -> !fir.boxchar<1>
51+
!CHECK: fir.call @_QPfoo_requires_explicit_interface(%[[VAL_6]], %{{.*}})
3552
end module

0 commit comments

Comments
 (0)