[OpenACC] OpenACC subarray data alignment in Fortran
diff mbox series

Message ID 20180829162221.31f401f0@squid.athome
State New
Headers show
Series
  • [OpenACC] OpenACC subarray data alignment in Fortran
Related show

Commit Message

Julian Brown Aug. 29, 2018, 8:22 p.m. UTC
This patch (by Cesar) removes several pointer-to-character casts
emitted during OpenMP/OpenACC clause processing in the Fortran front
end.

It's not quite clear to me why these casts were needed to start with,
but they are problematic in that an offload target will create a copy
of the array data with natural alignment for the character type, rather
than for the true element type of the array. That leads to alignment
violations on NVPTX, e.g. with the included new test.

Simply removing the casts appears to work. The data mapping then uses
the natural alignment of the array's element type.

Tested with offloading to NVPTX and bootstrapped. Posted previously as
part of the patch:

https://gcc.gnu.org/ml/gcc-patches/2018-06/msg01896.html

OK?

Julian

ChangeLog

20xx-xx-xx  Cesar Philippidis  <cesar@codesourcery.com>
            Julian Brown  <julian@codesourcery.com>

        gcc/fortran/
        * trans-openmp.c (gfc_omp_finish_clause): Don't cast ptr into a
        character pointer.
        (gfc_trans_omp_clauses_1): Likewise.

        libgomp/
        * testsuite/libgomp.oacc-fortran/data-alignment.f90: New test.

        gcc/testsuite/
        * gfortran.dg/goacc/pr70828.f90: Adjust expected output.

Patch
diff mbox series

commit 1e4c518992560dec161a2d1f65aad560d7b12518
Author: Julian Brown <julian@codesourcery.com>
Date:   Wed Aug 29 12:42:27 2018 -0700

    OpenACC subarray data alignment in fortran
    
    20xx-xx-xx  Cesar Philippidis  <cesar@codesourcery.com>
    	    Julian Brown  <julian@codesourcery.com>
    
    	gcc/fortran/
    	* trans-openmp.c (gfc_omp_finish_clause): Don't cast ptr into a
    	character pointer.
    	(gfc_trans_omp_clauses_1): Likewise.
    
    	libgomp/
    	* testsuite/libgomp.oacc-fortran/data-alignment.f90: New test.
    
    	gcc/testsuite/
    	* gfortran.dg/goacc/pr70828.f90: Adjust expected output.

diff --git a/gcc/fortran/trans-openmp.c b/gcc/fortran/trans-openmp.c
index 86be407..9c7b74b 100644
--- a/gcc/fortran/trans-openmp.c
+++ b/gcc/fortran/trans-openmp.c
@@ -1098,7 +1098,6 @@  gfc_omp_finish_clause (tree c, gimple_seq *pre_p)
       gfc_start_block (&block);
       tree type = TREE_TYPE (decl);
       tree ptr = gfc_conv_descriptor_data_get (decl);
-      ptr = fold_convert (build_pointer_type (char_type_node), ptr);
       ptr = build_fold_indirect_ref (ptr);
       OMP_CLAUSE_DECL (c) = ptr;
       c2 = build_omp_clause (input_location, OMP_CLAUSE_MAP);
@@ -2145,8 +2144,6 @@  gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
 		    {
 		      tree type = TREE_TYPE (decl);
 		      tree ptr = gfc_conv_descriptor_data_get (decl);
-		      ptr = fold_convert (build_pointer_type (char_type_node),
-					  ptr);
 		      ptr = build_fold_indirect_ref (ptr);
 		      OMP_CLAUSE_DECL (node) = ptr;
 		      node2 = build_omp_clause (input_location,
@@ -2239,8 +2236,6 @@  gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
 				       OMP_CLAUSE_SIZE (node), elemsz);
 		    }
 		  gfc_add_block_to_block (block, &se.post);
-		  ptr = fold_convert (build_pointer_type (char_type_node),
-				      ptr);
 		  OMP_CLAUSE_DECL (node) = build_fold_indirect_ref (ptr);
 
 		  if (POINTER_TYPE_P (TREE_TYPE (decl))
diff --git a/gcc/testsuite/gfortran.dg/goacc/pr70828.f90 b/gcc/testsuite/gfortran.dg/goacc/pr70828.f90
index 2e58120..6604fb3 100644
--- a/gcc/testsuite/gfortran.dg/goacc/pr70828.f90
+++ b/gcc/testsuite/gfortran.dg/goacc/pr70828.f90
@@ -18,5 +18,5 @@  program test
   !$acc end data
 end program test
 
-! { dg-final { scan-tree-dump-times "omp target oacc_data map\\(tofrom:MEM\\\[\\(c_char \\*\\)\_\[0-9\]+\\\] \\\[len: _\[0-9\]+\\\]\\) map\\(alloc:data \\\[pointer assign, bias: _\[0-9\]+\\\]\\)" 1 "gimple" } }
-! { dg-final { scan-tree-dump-times "omp target oacc_parallel map\\(force_present:MEM\\\[\\(c_char \\*\\)D\\.\[0-9\]+\\\] \\\[len: D\\.\[0-9\]+\\\]\\) map\\(alloc:data \\\[pointer assign, bias: D\\.\[0-9\]+\\\]\\)" 1 "gimple" } }
+! { dg-final { scan-tree-dump-times "omp target oacc_data map\\(tofrom:MEM\\\[\\(integer\\(kind=\[48\]\\)\\\[0:\\\] \\*\\)\_\[0-9\]+\\\] \\\[len: _\[0-9\]+\\\]\\) map\\(alloc:data \\\[pointer assign, bias: _\[0-9\]+\\\]\\)" 1 "gimple" } }
+! { dg-final { scan-tree-dump-times "omp target oacc_parallel map\\(force_present:MEM\\\[\\(integer\\(kind=\[48\]\\)\\\[0:\\\] \\*\\)D\\.\[0-9\]+\\\] \\\[len: D\\.\[0-9\]+\\\]\\) map\\(alloc:data \\\[pointer assign, bias: D\\.\[0-9\]+\\\]\\)" 1 "gimple" } }
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/data-alignment.f90 b/libgomp/testsuite/libgomp.oacc-fortran/data-alignment.f90
new file mode 100644
index 0000000..38c9005
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-fortran/data-alignment.f90
@@ -0,0 +1,35 @@ 
+! Test if the array data associated with c is properly aligned
+! on the accelerator.  If it is not, this program will crash.
+
+! { dg-do run }
+
+integer function routine_align()
+  implicit none
+  integer, parameter :: n = 10000
+  real*8, dimension(:), allocatable :: c
+  integer :: i, idx
+
+  allocate (c(n))
+  routine_align = 0
+  c = 0.0
+
+  !$acc data copyin(idx) copy(c(1:n))
+
+  !$acc parallel vector_length(32)
+  !$acc loop vector
+  do i=1, n
+     c(i) = i
+  enddo
+  !$acc end parallel
+
+  !$acc end data
+end function routine_align
+
+
+! main driver
+program routine_align_main
+  implicit none
+  integer :: success
+  integer routine_align
+  success = routine_align()
+end program routine_align_main