------- Comment #13 from fxcoudert at gcc dot gnu dot org 2008-03-04 23:47 ------- It will probably be useless to others, who have already dug into this PR, but I did have to research a bit to understand it, so I paste here the results of my research... in case it can help.
----------------------------------------- For the following reduced code: integer :: i i = 42 print *, transfer(i, .true.) print *, transfer (transfer(i, .true.), 0) end a.f90.013t.cfg has the (still valid): i.6 = i; transfer.4 = (logical(kind=4)) i.6; transfer.8 = transfer.4; D.876 = transfer.8; D.882 = D.876; transfer.5 = (integer(kind=4)) D.882; transfer.9 = transfer.5; D.878 = transfer.9; a.f90.014t.cplxlower0 has made it into a pair of memcpy, but a.f90.015t.veclower has them back in the form of two casts. a.f90.036t.dce1 has them simplified into: transfer.4_9 = (logical(kind=4)) i_7; transfer.5_11 = (integer(kind=4)) transfer.4_9; D.878 ={v} transfer.5_11; a.f90.055t.copyrename2 still has that same form: transfer.4_9 = (logical(kind=4)) i_7; transfer.5_11 = (integer(kind=4)) transfer.4_9; D.878 = transfer.5_11; but a.f90.056t.ccp2 definitely looses it: transfer.4_9 = 0; transfer.5_11 = 0; D.878 = 0; So, the question is, is cpp2 right to change: i_7 = 42; transfer.4_9 = (logical(kind=4)) i_7; transfer.5_11 = (integer(kind=4)) transfer.4_9; D.878 = transfer.5_11; into transfer.4_9 = 0; transfer.5_11 = 0; D.878 = 0; I'm not sure what the semantics are for the logical kinds in the middle-end, but it may be that only the least significant bit is used (if you change 42 into 43, you don't get the failure). According to the related thread at http://groups.google.com/group/comp.lang.fortran/browse_thread/thread/b29957a2f57fec25/27c2b4eca91c511f?lnk=gst&q=transfer+logical#27c2b4eca91c511f correctly (comp.lang.fortran thread named "Transfer and variables that don't use all their storage space.", started by... Tobias Burnus), TRANSFER(TRANSFER(A,B),A) is legal and it's result should always be A (there are some restrictions, but they are fulfilled in this precise case). ----------------------------------------- Paul, to comment on your patch, it's not only integer and logical that are concerned. You can do the same thing with logical and any other type, I'm sure... and I'm even sure you could manage to do the same thing with a real(kind=10), which has "unused bits" like a real type. (Or maybe, by playing with NaN canonicalization, you could do it with any other floating-point type; ie, choose an integer value that will TRANSFER into a given NaN, and the middle-end might canonicalize this NaN or optimize it in sort weird way.) Also, maybe the optimizer can sometimes be clever enough to see through your added indirection level, can't it? The only one way I see to do that would be to not create intermediate variables. This is, after all, the meaning of the Fortran standard, that although assignment can normalize (and array transfers are excluded from the TRANSFER(TRANSFER(A,B),A) == A rule), scalar TRANSFERs without assignment don't normalize. -- fxcoudert at gcc dot gnu dot org changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |fxcoudert at gcc dot gnu dot | |org http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33759