f18-llvm-project icon indicating copy to clipboard operation
f18-llvm-project copied to clipboard

Scalar derived type inside array expr crash (" 'fir.convert' op invalid type conversion ")

Open jeanPerier opened this issue 4 years ago • 4 comments

  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}>>
  }

jeanPerier avatar Jun 23 '21 12:06 jeanPerier

Note: this is one of the showstopper to compile https://github.com/lanl/NEXMD

oroppas avatar Jul 01 '21 01:07 oroppas

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.

oroppas avatar Aug 16 '21 08:08 oroppas

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

oroppas avatar Aug 29 '21 08:08 oroppas

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

oroppas avatar Aug 29 '21 10:08 oroppas