[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.
This commit is contained in:
parent
dc29901efb
commit
2d956d2d4e
@ -486,7 +486,6 @@ Fortran::lower::genCallOpAndResult(
|
|||||||
|
|
||||||
// Deal with potential mismatches in arguments types. Passing an array to a
|
// Deal with potential mismatches in arguments types. Passing an array to a
|
||||||
// scalar argument should for instance be tolerated here.
|
// scalar argument should for instance be tolerated here.
|
||||||
bool callingImplicitInterface = caller.canBeCalledViaImplicitInterface();
|
|
||||||
for (auto [fst, snd] : llvm::zip(caller.getInputs(), funcType.getInputs())) {
|
for (auto [fst, snd] : llvm::zip(caller.getInputs(), funcType.getInputs())) {
|
||||||
// When passing arguments to a procedure that can be called by implicit
|
// When passing arguments to a procedure that can be called by implicit
|
||||||
// interface, allow any character actual arguments to be passed to dummy
|
// interface, allow any character actual arguments to be passed to dummy
|
||||||
@ -518,10 +517,17 @@ Fortran::lower::genCallOpAndResult(
|
|||||||
// Do not attempt any reboxing here that could break this.
|
// Do not attempt any reboxing here that could break this.
|
||||||
bool legacyLowering =
|
bool legacyLowering =
|
||||||
!converter.getLoweringOptions().getLowerToHighLevelFIR();
|
!converter.getLoweringOptions().getLowerToHighLevelFIR();
|
||||||
|
// When dealing with a dummy character argument (fir.boxchar), the
|
||||||
|
// effective argument might be a non-character raw pointer. This may
|
||||||
|
// happen when calling an implicit interface that was previously called
|
||||||
|
// with a character argument, or when calling an explicit interface with
|
||||||
|
// an IgnoreTKR dummy character arguments. Allow creating a fir.boxchar
|
||||||
|
// from the raw pointer, which requires a non-trivial type conversion.
|
||||||
|
const bool allowCharacterConversions = true;
|
||||||
bool isVolatile = fir::isa_volatile_type(snd);
|
bool isVolatile = fir::isa_volatile_type(snd);
|
||||||
cast = builder.createVolatileCast(loc, isVolatile, fst);
|
cast = builder.createVolatileCast(loc, isVolatile, fst);
|
||||||
cast = builder.convertWithSemantics(loc, snd, cast,
|
cast = builder.convertWithSemantics(loc, snd, cast,
|
||||||
callingImplicitInterface,
|
allowCharacterConversions,
|
||||||
/*allowRebox=*/legacyLowering);
|
/*allowRebox=*/legacyLowering);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1446,6 +1452,8 @@ static PreparedDummyArgument preparePresentUserCallActualArgument(
|
|||||||
// cause the fir.if results to be assumed-rank in case of OPTIONAL dummy,
|
// cause the fir.if results to be assumed-rank in case of OPTIONAL dummy,
|
||||||
// causing extra runtime costs due to the unknown runtime size of assumed-rank
|
// causing extra runtime costs due to the unknown runtime size of assumed-rank
|
||||||
// descriptors.
|
// descriptors.
|
||||||
|
// For TKR dummy characters, the boxchar creation also happens later when
|
||||||
|
// creating the fir.call .
|
||||||
preparedDummy.dummy =
|
preparedDummy.dummy =
|
||||||
builder.createConvert(loc, dummyTypeWithActualRank, addr);
|
builder.createConvert(loc, dummyTypeWithActualRank, addr);
|
||||||
return preparedDummy;
|
return preparedDummy;
|
||||||
|
@ -8,6 +8,13 @@ module test_char_tk
|
|||||||
!dir$ ignore_tkr(tkrdm) c
|
!dir$ ignore_tkr(tkrdm) c
|
||||||
end subroutine
|
end subroutine
|
||||||
end interface
|
end interface
|
||||||
|
interface
|
||||||
|
subroutine foo_requires_explicit_interface(c, i)
|
||||||
|
character(1)::c(*)
|
||||||
|
!dir$ ignore_tkr(tkrdm) c
|
||||||
|
integer, optional :: i
|
||||||
|
end subroutine
|
||||||
|
end interface
|
||||||
contains
|
contains
|
||||||
subroutine test_normal()
|
subroutine test_normal()
|
||||||
character(1) :: c(10)
|
character(1) :: c(10)
|
||||||
@ -32,4 +39,14 @@ contains
|
|||||||
!CHECK: %[[VAL_5:.*]] = fir.convert %{{.*}} : (!fir.ref<!fir.array<10xf32>>) -> !fir.ref<!fir.char<1,?>>
|
!CHECK: %[[VAL_5:.*]] = fir.convert %{{.*}} : (!fir.ref<!fir.array<10xf32>>) -> !fir.ref<!fir.char<1,?>>
|
||||||
!CHECK: %[[VAL_6:.*]] = fir.emboxchar %[[VAL_5]], %c0{{.*}}: (!fir.ref<!fir.char<1,?>>, index) -> !fir.boxchar<1>
|
!CHECK: %[[VAL_6:.*]] = fir.emboxchar %[[VAL_5]], %c0{{.*}}: (!fir.ref<!fir.char<1,?>>, index) -> !fir.boxchar<1>
|
||||||
!CHECK: fir.call @_QPfoo(%[[VAL_6]]) fastmath<contract> : (!fir.boxchar<1>) -> ()
|
!CHECK: fir.call @_QPfoo(%[[VAL_6]]) fastmath<contract> : (!fir.boxchar<1>) -> ()
|
||||||
|
|
||||||
|
subroutine test_requires_explicit_interface(x, i)
|
||||||
|
real :: x(10)
|
||||||
|
integer :: i
|
||||||
|
call foo_requires_explicit_interface(x, i)
|
||||||
|
end subroutine
|
||||||
|
!CHECK-LABEL: func.func @_QMtest_char_tkPtest_requires_explicit_interface(
|
||||||
|
!CHECK: %[[VAL_5:.*]] = fir.convert %{{.*}} : (!fir.ref<!fir.array<10xf32>>) -> !fir.ref<!fir.char<1,?>>
|
||||||
|
!CHECK: %[[VAL_6:.*]] = fir.emboxchar %[[VAL_5]], %c0{{.*}}: (!fir.ref<!fir.char<1,?>>, index) -> !fir.boxchar<1>
|
||||||
|
!CHECK: fir.call @_QPfoo_requires_explicit_interface(%[[VAL_6]], %{{.*}})
|
||||||
end module
|
end module
|
||||||
|
Loading…
x
Reference in New Issue
Block a user