https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126964
--- Comment #9 from GCC Commits <cvs-commit at gcc dot gnu.org> --- The master branch has been updated by Jerry DeLisle <[email protected]>: https://gcc.gnu.org/g:d6c3e489d368dacfe7958e1dbfedf8cf738a03b3 commit r17-3967-gd6c3e489d368dacfe7958e1dbfedf8cf738a03b3 Author: Jerry DeLisle <[email protected]> Date: Fri Aug 21 16:17:14 2026 -0700 fortran: [PR126964] Reduce the cost of a span addressed dummy Assisted-by: Claude Opus 5 r17-3342 made a TARGET assumed shape or assumed rank dummy be addressed through the span of its descriptor, so that a pointer to it stays valid when its elements are subobjects of larger ones. That costs in two ways, and SPEC 465.tonto pays both. First, addressing every element as offset * span leaves the step of a data reference symbolic, so loop versioning cannot prove that the accesses stay aligned and the loop is never vectorized. Fold the spacing into the strides and the offset on entry instead, so that the elements are addressed by the constant element length as usual. The element length divides the spacing whenever the element size equals the element alignment, which covers integer, real and logical elements of an assumed shape dummy; elsewhere the span is still used to address them. A dummy whose spacing is folded that way is not addressed through its span at all, and the descriptor built for it holds the element length as its span, so is_subref_array must not be true for it: passing it on needs neither a copy nor a test. The predicate is therefore split in two. What lets the elements be spaced by more than the element size is that the actual argument of a TARGET dummy is never copied, which is now gfc_dummy_requires_direct_arg; gfc_is_span_addressed_dummy is that property less the dummies whose spacing is folded into their strides, and moves to trans-array.cc, the element size of the type being a back end property. Second, is_subref_array became true for such a dummy, so passing one on to another procedure takes the copy-in/copy-out path, with the copy made conditional on the actual argument being contiguous. That is more than the receiving dummy needs: a dummy that has a descriptor of its own addresses its elements by the strides held in it, so it accepts an actual argument of any stride; the one thing it cannot do is address elements that are subobjects of larger ones, which is what a span differing from the element length means. Narrow the condition to the span alone when the dummy has a descriptor and is not CONTIGUOUS. A dummy that needs the argument packed still gets the full test. The span test is a different condition from contiguity, so it is a function of its own. This applies to what is left span addressed: character, complex and derived type elements, and an assumed rank dummy, which has no strides to fold into. PR fortran/126964 gcc/fortran/ChangeLog: * gfortran.h (gfc_dummy_requires_direct_arg): New prototype. * symbol.cc (gfc_is_span_addressed_dummy): Rename to... (gfc_dummy_requires_direct_arg): ... this and move the addressing out of the description. * trans.h (struct lang_decl): Add span_normalized. (GFC_DECL_SPAN_NORMALIZED): New macro. (gfc_conv_subref_array_arg): Add span_only argument. * trans-array.h (gfc_span_folds_into_stride): New prototype. (gfc_conv_span_is_elem_len): Likewise. * trans-array.cc (gfc_span_folds_into_stride): New function. (gfc_is_span_addressed_dummy): New function, false for a dummy whose element spacing is folded into its strides. (gfc_conv_span_is_elem_len): New function. (gfc_trans_dummy_array_bias): Fold the element spacing of a span normalized dummy into its strides and its offset on entry. * trans-decl.cc (gfc_build_dummy_array_decl): Mark such a dummy span normalized rather than giving it a span variable. (gfc_get_symbol_decl): Do not set GFC_DECL_PTR_ARRAY_P for it. * trans-expr.cc (is_whole_span_addressed_dummy): New function. (dummy_accepts_strided_arg): New function. (copy_in_out_allowed): Use gfc_dummy_requires_direct_arg, the actual argument of a span normalized dummy being uncopied too. (gfc_conv_subref_array_arg): Take span_only and, with it, test the span of the descriptor instead of contiguity. (gfc_conv_procedure_call): Ask for the span test when a span addressed dummy is passed on to a dummy that has a descriptor. gcc/testsuite/ChangeLog: * gfortran.dg/target_dummy_repack_1.f90: New test. * gfortran.dg/target_dummy_repack_2.f90: New test. * gfortran.dg/target_dummy_span_1.f90: New test. * gfortran.dg/c_loc_test_22.f90: Update for addressing by the element length. * gfortran.dg/gomp/target-span-1.f90: Likewise. * gfortran.dg/class_to_type_9.f90: Likewise, and expect an assumed shape dummy to take no copy of a strided actual argument. libgomp/ChangeLog: * testsuite/libgomp.oacc-fortran/host_data-5.F90: Expect no copy of a span normalized dummy passed to a dummy without a descriptor.
