https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90329
--- Comment #35 from Jakub Jelinek <jakub at gcc dot gnu.org> --- One more thing, if I add to start of the DTRTRI function INTERFACE SUBROUTINE DTRTI2( UPLO, DIAG, N, A, LDA, INFO ) CHARACTER DIAG, UPLO INTEGER INFO, LDA, N DOUBLE PRECISION A( LDA, * ) END SUBROUTINE END INTERFACE INTERFACE SUBROUTINE XERBLA( FOO, BAR ) CHARACTER FOO INTEGER BAR END SUBROUTINE END INTERFACE INTERFACE SUBROUTINE DTRMM ( S1, S2, S3, S4, I1, I2, D1, A, I3, D2, I4 ) CHARACTER S1, S2, S3, S4 INTEGER I1, I2, I3, I4 DOUBLE PRECISION D1, D2 DOUBLE PRECISION A( I3, * ) END SUBROUTINE END INTERFACE INTERFACE SUBROUTINE DTRSM ( S1, S2, S3, S4, I1, I2, D1, D2, I3, D3, I4 ) CHARACTER S1, S2, S3, S4 INTEGER I1, I2, I3, I4 DOUBLE PRECISION D1, D2, D3 END SUBROUTINE END INTERFACE INTERFACE FUNCTION LSAME ( S1, S2 ) CHARACTER S1, S2 LOGICAL LSAME END FUNCTION END INTERFACE INTERFACE FUNCTION ILAENV ( I1, S1, S2, I2, I3, I4, I5 ) INTEGER I1, I2, I3, I4, I5, ILAENV CHARACTER S1, S2 END FUNCTION END INTERFACE and remove LOGICAL LSAME INTEGER ILAENV EXTERNAL LSAME, ILAENV EXTERNAL DTRMM, DTRSM, DTRTI2, XERBLA then it is tail call optimized back to somewhere in between r164328 (still doesn't tail call it) and r164450 (already tail calls it). What matters is not whether the exact function/subroutine we are calling in the tail call position has interface or not, tail call optimization doesn't care about that, but the presence or absence of TYPE_ARG_TYPES on the function types that are called matters for the alias analysis (r268991 vs. r268992): -ESCAPED = uplo -ESCAPED = &STRING +callarg(30) = uplo +callarg(30) = callarg(30) + UNKNOWN +callarg(30) = *callarg(30) + UNKNOWN +CALLUSED(28) = callarg(30) +CALLCLOBBERED(29) = callarg(30) +*callarg(30) = NONLOCAL +callarg(31) = &STRING +callarg(31) = callarg(31) + UNKNOWN +callarg(31) = *callarg(31) + UNKNOWN +CALLUSED(28) = callarg(31) +CALLCLOBBERED(29) = callarg(31) +*callarg(31) = NONLOCAL and similarly for many other arguments. So, if we wanted to narrow the workaround more, we could do the DECL_HIDDEN_STRING_LENGTH setting conditional on whether the function has any calls to Fortran implicitly prototyped function. Or if we add a command line switch, have different modes, one which would assume sane callers, another one that would do it only for functions that call implicitly prototyped functions and another that would do it always like the committed workaround does. On the other side, those unprototyped calls could come from inlined calls too, though as a heuristics it could work, usually the codebase either is modern fortran, or is not, and given that the workaround is for undefined behavior, we are always free to do anything we want.