http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54238
Bug #: 54238 Summary: If possible, TRANSFER should use assignment instead of MEMCPY Classification: Unclassified Product: gcc Version: 4.8.0 Status: UNCONFIRMED Keywords: missed-optimization Severity: normal Priority: P3 Component: fortran AssignedTo: unassig...@gcc.gnu.org ReportedBy: bur...@gcc.gnu.org In some cases TRANSFER can be replaced by a normal assignment (with cast), possibly also a ARRAY_RANGE_REF with cast? Example, the following code – which matches the currently used scalarizer for FINAL: use iso_c_binding, only: c_intptr_t, c_loc, c_ptr, c_int, c_f_pointer integer(c_int), target :: array(4) integer(c_int), pointer :: ptr integer(c_intptr_t) :: addr type(c_ptr) :: cptr array = [11,22,33,44] do i = 0, 3 cptr = c_loc (array) addr = transfer (cptr, addr) + i * storage_size (array)/8 call c_f_pointer (transfer (addr, cptr), ptr) print *, i,': ', ptr end do end Dump of: addr = transfer (cptr, addr) + i * storage_size (array)/8 { struct array1_integer(kind=4) parm.2; integer(kind=8) transfer.1; integer(kind=8) D.1876; integer(kind=8) D.1875; integer(kind=8) D.1874; D.1874 = 8; D.1875 = 8; __builtin_memcpy ((void *) &transfer.1, (void *) &cptr, MAX_EXPR <MIN_EXPR <D.1875, D.1874>, 0>); parm.2.dtype = 265; parm.2.dim[0].lbound = 1; parm.2.dim[0].ubound = 4; parm.2.dim[0].stride = 1; parm.2.data = (void *) &array[0]; parm.2.offset = -1; addr = (integer(kind=8)) ((i * 32) / 8) + transfer.1; } While a simple addr = (intptr_t) cptr; should be sufficient.