f18-llvm-project
f18-llvm-project copied to clipboard
Scalar derived type inside array expr crash (" 'fir.convert' op invalid type conversion ")
type t
integer :: i
end type
type(t) :: scalar, array(10)
array = scalar
end
Crashes bbc with error: 'fir.convert' op invalid type conversion
With --dump-module-on-failure (full dump below), it can be observed that the bad convert happens inside the array expression loop, and tries to convert a (!fir.type<_QTt{i:i32}>) to !fir.ref<!fir.type<_QTt{i:i32}>>. The root cause is that scalar genval() which is called in array expression to lower scalar actually loads derived type values, but array expressions with derived type expect to work in memory (see isAdjustedArrayElementType (here)).
Scalar derived type lowering should probably be updated to also work in memory.
func @_QQmain() {
%0 = fir.address_of(@_QEarray) : !fir.ref<!fir.array<10x!fir.type<_QTt{i:i32}>>>
%c10 = constant 10 : index
%1 = fir.alloca !fir.type<_QTt{i:i32}> {bindc_name = "scalar", uniq_name = "_QEscalar"}
%2 = fir.shape %c10 : (index) -> !fir.shape<1>
%3 = fir.array_load %0(%2) : (!fir.ref<!fir.array<10x!fir.type<_QTt{i:i32}>>>, !fir.shape<1>) -> !fir.array<10x!fir.type<_QTt{i:i32}>>
%4 = fir.load %1 : !fir.ref<!fir.type<_QTt{i:i32}>>
%c0 = constant 0 : index
%c1 = constant 1 : index
%c10_i64 = constant 10 : i64
%5 = fir.convert %c10_i64 : (i64) -> index
%6 = subi %5, %c1 : index
%7 = fir.do_loop %arg0 = %c0 to %6 step %c1 iter_args(%arg1 = %3) -> (!fir.array<10x!fir.type<_QTt{i:i32}>>) {
%8 = fir.convert %4 : (!fir.type<_QTt{i:i32}>) -> !fir.ref<!fir.type<_QTt{i:i32}>>
%9 = fir.array_update %arg1, %8, %arg0 : (!fir.array<10x!fir.type<_QTt{i:i32}>>, !fir.ref<!fir.type<_QTt{i:i32}>>, index) -> !fir.array<10x!fir.type<_QTt{i:i32}>>
fir.result %9 : !fir.array<10x!fir.type<_QTt{i:i32}>>
}
fir.array_merge_store %3, %7 to %0 : !fir.array<10x!fir.type<_QTt{i:i32}>>, !fir.array<10x!fir.type<_QTt{i:i32}>>, !fir.ref<!fir.array<10x!fir.type<_QTt{i:i32}>>>
return
}
fir.global internal @_QEarray : !fir.array<10x!fir.type<_QTt{i:i32}>> {
%0 = fir.undefined !fir.array<10x!fir.type<_QTt{i:i32}>>
fir.has_value %0 : !fir.array<10x!fir.type<_QTt{i:i32}>>
}
Note: this is one of the showstopper to compile https://github.com/lanl/NEXMD
Recent bbc seems to be able to lower the repro.
However, I still see 'fir.convert' op invalid type conversion from
https://github.com/lanl/NEXMD and http://mumps.enseeiht.fr
I will create minimal reproducible code from them.
The following piece of code can replicate the error:
module comm
type:: simulation_t
integer :: id
end type simulation_t
end module
subroutine deriv(sim)
use comm
implicit none
type(simulation_t), target ::sim
type(simulation_t), pointer::simpoint
simpoint => sim
end subroutine
bbc fir_convert.f90
error: loc("./fir_convert.f90":21:3): 'fir.convert' op invalid type conversion
oops, pass manager reported failure
Here's another case
SUBROUTINE MUMPS_GET_PROCE_PER_NODE
IMPLICIT NONE
CHARACTER, DIMENSION(:), ALLOCATABLE :: MyNAME_TAB_RCV
INTEGER :: MyNAME_length_RCV
INTEGER :: COMM, ierr
INTEGER :: MPI_CHARACTER, MPI_INTEGER
PARAMETER (MPI_CHARACTER=7)
PARAMETER (MPI_INTEGER=13)
CALL MPI_BCAST(MyNAME_length_RCV, 1, MPI_INTEGER, 0, COMM, ierr)
CALL MPI_BCAST(MyNAME_TAB_RCV, MyNAME_length_RCV, MPI_CHARACTER,
& 0, COMM, ierr)
END SUBROUTINE MUMPS_GET_PROCE_PER_NODE
bbc op_invalid_type_conversion.F
error: loc("./op_invalid_type_conversion.F":13:7): 'fir.convert' op invalid type conversion
oops, pass manager reported failure