This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: optimization removes a __builtin_memcpy?
- From: "Richard Guenther" <richard dot guenther at gmail dot com>
- To: "Steve Kargl" <sgk at troutmask dot apl dot washington dot edu>
- Cc: gcc at gcc dot gnu dot org, fortran at gcc dot gnu dot org
- Date: Sun, 30 Nov 2008 12:26:27 +0100
- Subject: Re: optimization removes a __builtin_memcpy?
- References: <20081130042805.GA64990@troutmask.apl.washington.edu>
On Sun, Nov 30, 2008 at 5:28 AM, Steve Kargl
<sgk@troutmask.apl.washington.edu> wrote:
> First, I'll preface this with "I'm probably doing something wrong."
> I'm adding support to gfortran for the ERRMSG argument to [DE]ALLOCATE.
> Here's, some code to demonstrate:
>
> program a
> call works
> call fails
> end program a
> !
> ! Work with all optimization levels.
> !
> subroutine works
> character(len=70) :: err = 'No error'
> integer, allocatable :: i(:)
> allocate(i(4), errmsg=err) ! err is unchanged.
> print *, err
> deallocate(i)
> allocate(i(4), i(5), errmsg=err) ! err is assigned an error message.
> print *, err
> end subroutine works
> !
> ! Fails at -O[123] due to len=30, works with -O0.
> !
> subroutine fails
> character(len=30) :: err = 'No error'
> integer, allocatable :: i(:)
> allocate(i(4), errmsg=err)
> print *, err
> deallocate(i)
> allocate(i(4), i(5), errmsg=err)
> print *, err
> end subroutine fails
>
> kargl[222] gfc4x -o z -fdump-tree-original a.f90
> kargl[223] ./z
> No error
> Attempt to deallocate an unallocated object
> No error
> Attempt to deallocate an unall
> kargl[224] mv a.f90.003t.original abc
> kargl[225] gfc4x -o z -fdump-tree-original -O a.f90
> a.f90: In function 'fails':
> a.f90:16: error: non-trivial conversion at assignment
> character(kind=1) *
> character(kind=1)[1:30]
> iftmp.17 = err;
>
> a.f90:16: error: non-trivial conversion at assignment
> character(kind=1) *
> character(kind=1)[1:30]
> iftmp.20 = err;
>
> a.f90:16: internal compiler error: verify_gimple failed
> Please submit a full bug report,
> with preprocessed source if appropriate.
> See <http://gcc.gnu.org/bugs.html> for instructions.
>
> Looking at a diff of the two -fdump-tree-original outputs shows:
>
> ERRMSG.12 = &"Attempt to deallocate an unallocated object"[1]{lb: 1 sz: 1};
> - ERRMSG.12 = stat.11 != 0 ? (void) __builtin_memcpy ((void *) &err, (void *) ERRMSG.12, 30) : (void) 0;
> + ERRMSG.12 = stat.11 != 0 ? err = *(character(kind=1)[1:30] * {ref-all}) ERRMSG.12 : (void) 0;
>
> The chunk of code that I've add to trans-stmt.c(gfc_trans_deallocate) looks like
>
> /* A better error message may be possible, but not required. */
> const char *msg = "Attempt to deallocate an unallocated object";
> tree errmsg, slen, dlen;
>
> gfc_init_se (&se, NULL);
> gfc_conv_expr_lhs (&se, code->expr);
>
> errmsg = gfc_create_var (pchar_type_node, "ERRMSG");
>
> /* astat is >= 0. */
> tmp = fold_build2 (NE_EXPR, boolean_type_node, astat,
> build_int_cst (TREE_TYPE (astat), 0));
>
> /* Create tree for msg. */
> gfc_add_modify (&block, errmsg,
> gfc_build_addr_expr (pchar_type_node,
> gfc_build_localized_cstring_const (msg)));
>
> /* Don't overflow the string. slen = min(dlen, len). */
> slen = build_int_cst (gfc_charlen_type_node, 44);
> dlen = gfc_get_expr_charlen (code->expr);
> slen = fold_build2 (MIN_EXPR, TREE_TYPE (slen), dlen, slen);
>
> tmp = fold_build3 (COND_EXPR, pchar_type_node, tmp,
> build_call_expr (built_in_decls[BUILT_IN_MEMCPY], 3,
> se.expr, errmsg, slen),
> build_empty_stmt ());
>
> gfc_add_modify (&block, errmsg, tmp);
>
> The diff shows that the fails case correctly has dlen=30
> and in fact for any value less than slen=44 and -O[123]
> removes the __builtin_memcpy(). So what is missing or
> how to I inhibit this optimization?
You cannot inhibit this optimization, instead the optimization should be
fixed to not generate invalid gimple ;) (see builtins.c:fold_builtin_memory_op)
Richard.