llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
29.07k stars 11.98k forks source link

[flang] Multiple fir.declare in wrong function. #114532

Open abidh opened 1 week ago

abidh commented 1 week ago

Please see the code below. I compiled it with flang -fc1 -emit-mlir -O0. In the resultant mlir, I see that fir.declare is generated 3 times for variable i of str_int (_QMutilsFstr_intEi) and 2 of those fir.declare are in str_real_n which does not seem right to me.

module utils

integer, parameter :: dp=kind(0.d0)

contains

pure integer function str_int_len(i) result(sz)
! Returns the length of the string representation of 'i'
integer, intent(in) :: i
integer, parameter :: MAX_STR = 100
character(MAX_STR) :: s
write(s, '(i0)') i
sz = len_trim(s)
end function

pure function str_int(i) result(s)
! Converts integer "i" to string
integer, intent(in) :: i
character(len=str_int_len(i)) :: s
write(s, '(i0)') i
end function

pure integer function str_real_len(r, fmt) result(sz)
! Returns the length of the string representation of 'i'
real(dp), intent(in) :: r
character(len=*), intent(in) :: fmt
integer, parameter :: MAX_STR = 100
character(MAX_STR) :: s
! If 's' is too short (MAX_STR too small), Fortan will abort with:
! "Fortran runtime error: End of record"
write(s, fmt) r
sz = len_trim(s)
end function

pure function str_real_n(r, n) result(s)
! Converts the real number "r" to string with 'n' decimal digits.
real(dp), intent(in) :: r
integer, intent(in) :: n
character(len=str_real_len(r, "(f0." // str_int(n) // ")")) :: s
write(s, "(f0." // str_int(n) // ")") r
end function

end module
llvmbot commented 1 week ago

@llvm/issue-subscribers-flang-ir

Author: Abid Qadeer (abidh)

Please see the code below. I compiled it with `flang -fc1 -emit-mlir -O0`. In the resultant mlir, I see that fir.declare is generated 3 times for variable `i` of `str_int` (`_QMutilsFstr_intEi`) and 2 of those fir.declare are in `str_real_n` which does not seem right to me. ``` module utils integer, parameter :: dp=kind(0.d0) contains pure integer function str_int_len(i) result(sz) ! Returns the length of the string representation of 'i' integer, intent(in) :: i integer, parameter :: MAX_STR = 100 character(MAX_STR) :: s write(s, '(i0)') i sz = len_trim(s) end function pure function str_int(i) result(s) ! Converts integer "i" to string integer, intent(in) :: i character(len=str_int_len(i)) :: s write(s, '(i0)') i end function pure integer function str_real_len(r, fmt) result(sz) ! Returns the length of the string representation of 'i' real(dp), intent(in) :: r character(len=*), intent(in) :: fmt integer, parameter :: MAX_STR = 100 character(MAX_STR) :: s ! If 's' is too short (MAX_STR too small), Fortan will abort with: ! "Fortran runtime error: End of record" write(s, fmt) r sz = len_trim(s) end function pure function str_real_n(r, n) result(s) ! Converts the real number "r" to string with 'n' decimal digits. real(dp), intent(in) :: r integer, intent(in) :: n character(len=str_real_len(r, "(f0." // str_int(n) // ")")) :: s write(s, "(f0." // str_int(n) // ")") r end function end module ```