1 |
694 |
jeremybenn |
! { dg-do compile }
|
2 |
|
|
! { dg-options "-Warray-temporaries -O -fdump-tree-original" }
|
3 |
|
|
!
|
4 |
|
|
! PR fortran/43829
|
5 |
|
|
! Scalarization of reductions.
|
6 |
|
|
! Test that sum is properly inlined.
|
7 |
|
|
|
8 |
|
|
! This is the compile time test only; for the runtime test see inline_sum_2.f90
|
9 |
|
|
! We can't test for temporaries on the run time test directly, as it tries
|
10 |
|
|
! several optimization options among which -Os, and sum inlining is disabled
|
11 |
|
|
! at -Os.
|
12 |
|
|
|
13 |
|
|
|
14 |
|
|
implicit none
|
15 |
|
|
|
16 |
|
|
|
17 |
|
|
integer :: i, j, k
|
18 |
|
|
|
19 |
|
|
integer, parameter :: q = 2
|
20 |
|
|
integer, parameter :: nx=3, ny=2*q, nz=5
|
21 |
|
|
integer, parameter, dimension(nx,ny,nz) :: p = &
|
22 |
|
|
& reshape ((/ (i**2, i=1,size(p)) /), shape(p))
|
23 |
|
|
|
24 |
|
|
integer, parameter, dimension( ny,nz) :: px = &
|
25 |
|
|
& reshape ((/ (( &
|
26 |
|
|
& nx*( nx*j+nx*ny*k+1)*( nx*j+nx*ny*k+1+ (nx-1)) &
|
27 |
|
|
& + nx*(nx-1)*(2*nx-1)/6, &
|
28 |
|
|
& j=0,ny-1), k=0,nz-1) /), shape(px))
|
29 |
|
|
|
30 |
|
|
integer, parameter, dimension(nx, nz) :: py = &
|
31 |
|
|
& reshape ((/ (( &
|
32 |
|
|
& ny*(i +nx*ny*k+1)*(i +nx*ny*k+1+nx *(ny-1)) &
|
33 |
|
|
& +(nx )**2*ny*(ny-1)*(2*ny-1)/6, &
|
34 |
|
|
& i=0,nx-1), k=0,nz-1) /), shape(py))
|
35 |
|
|
|
36 |
|
|
integer, parameter, dimension(nx,ny ) :: pz = &
|
37 |
|
|
& reshape ((/ (( &
|
38 |
|
|
& nz*(i+nx*j +1)*(i+nx*j +1+nx*ny*(nz-1)) &
|
39 |
|
|
& +(nx*ny)**2*nz*(nz-1)*(2*nz-1)/6, &
|
40 |
|
|
& i=0,nx-1), j=0,ny-1) /), shape(pz))
|
41 |
|
|
|
42 |
|
|
|
43 |
|
|
integer, dimension(nx,ny,nz) :: a
|
44 |
|
|
integer, dimension( ny,nz) :: ax
|
45 |
|
|
integer, dimension(nx, nz) :: ay
|
46 |
|
|
integer, dimension(nx,ny ) :: az
|
47 |
|
|
|
48 |
|
|
logical, dimension(nx,ny,nz) :: m, true
|
49 |
|
|
|
50 |
|
|
|
51 |
|
|
integer, dimension(nx,ny) :: b
|
52 |
|
|
|
53 |
|
|
integer, dimension(nx,nx) :: onesx
|
54 |
|
|
integer, dimension(ny,ny) :: onesy
|
55 |
|
|
integer, dimension(nz,nz) :: onesz
|
56 |
|
|
|
57 |
|
|
|
58 |
|
|
a = p
|
59 |
|
|
m = reshape((/ ((/ .true., .false. /), i=1,size(m)/2) /), shape(m))
|
60 |
|
|
true = reshape((/ (.true., i=1,size(true)) /), shape(true))
|
61 |
|
|
|
62 |
|
|
onesx = reshape((/ ((1, j=1,i),(0,j=1,nx-i),i=1,size(onesx,2)) /), shape(onesx))
|
63 |
|
|
onesy = reshape((/ ((1, j=1,i),(0,j=1,ny-i),i=1,size(onesy,2)) /), shape(onesy))
|
64 |
|
|
onesz = reshape((/ ((1, j=1,i),(0,j=1,nz-i),i=1,size(onesz,2)) /), shape(onesz))
|
65 |
|
|
|
66 |
|
|
! Correct results in simple cases
|
67 |
|
|
ax = sum(a,1)
|
68 |
|
|
if (any(ax /= px)) call abort
|
69 |
|
|
|
70 |
|
|
ay = sum(a,2)
|
71 |
|
|
if (any(ay /= py)) call abort
|
72 |
|
|
|
73 |
|
|
az = sum(a,3)
|
74 |
|
|
if (any(az /= pz)) call abort
|
75 |
|
|
|
76 |
|
|
|
77 |
|
|
! Masks work
|
78 |
|
|
if (any(sum(a,1,.false.) /= 0)) call abort
|
79 |
|
|
if (any(sum(a,2,.true.) /= py)) call abort
|
80 |
|
|
if (any(sum(a,3,m) /= merge(pz,0,m(:,:,1)))) call abort
|
81 |
|
|
if (any(sum(a,2,m) /= merge(sum(a(:, ::2,:),2),&
|
82 |
|
|
sum(a(:,2::2,:),2),&
|
83 |
|
|
m(:,1,:)))) call abort
|
84 |
|
|
|
85 |
|
|
|
86 |
|
|
! It works too with array constructors ...
|
87 |
|
|
if (any(sum( &
|
88 |
|
|
reshape((/ (i*i,i=1,size(a)) /), shape(a)), &
|
89 |
|
|
1, &
|
90 |
|
|
true) /= ax)) call abort
|
91 |
|
|
|
92 |
|
|
! ... and with vector subscripts
|
93 |
|
|
if (any(sum( &
|
94 |
|
|
a((/ (i,i=1,nx) /), &
|
95 |
|
|
(/ (i,i=1,ny) /), &
|
96 |
|
|
(/ (i,i=1,nz) /)), &
|
97 |
|
|
1) /= ax)) call abort
|
98 |
|
|
|
99 |
|
|
if (any(sum( &
|
100 |
|
|
a(sum(onesx(:,:),1), & ! unnecessary { dg-warning "Creating array temporary" }
|
101 |
|
|
sum(onesy(:,:),1), & ! unnecessary { dg-warning "Creating array temporary" }
|
102 |
|
|
sum(onesz(:,:),1)), & ! unnecessary { dg-warning "Creating array temporary" }
|
103 |
|
|
1) /= ax)) call abort
|
104 |
|
|
|
105 |
|
|
|
106 |
|
|
! Nested sums work
|
107 |
|
|
if (sum(sum(sum(a,1),1),1) /= sum(a)) call abort
|
108 |
|
|
if (sum(sum(sum(a,1),2),1) /= sum(a)) call abort
|
109 |
|
|
if (sum(sum(sum(a,3),1),1) /= sum(a)) call abort
|
110 |
|
|
if (sum(sum(sum(a,3),2),1) /= sum(a)) call abort
|
111 |
|
|
|
112 |
|
|
if (any(sum(sum(a,1),1) /= sum(sum(a,2),1))) call abort
|
113 |
|
|
if (any(sum(sum(a,1),2) /= sum(sum(a,3),1))) call abort
|
114 |
|
|
if (any(sum(sum(a,2),2) /= sum(sum(a,3),2))) call abort
|
115 |
|
|
|
116 |
|
|
|
117 |
|
|
! Temps are unavoidable here (function call's argument or result)
|
118 |
|
|
ax = sum(neid3(a),1) ! { dg-warning "Creating array temporary" }
|
119 |
|
|
! Sums as part of a bigger expr work
|
120 |
|
|
if (any(1+sum(eid(a),1)+ax+sum( &
|
121 |
|
|
neid3(a), & ! { dg-warning "Creating array temporary" }
|
122 |
|
|
1)+1 /= 3*ax+2)) call abort
|
123 |
|
|
if (any(1+eid(sum(a,2))+ay+ &
|
124 |
|
|
neid2( & ! { dg-warning "Creating array temporary" }
|
125 |
|
|
sum(a,2) & ! { dg-warning "Creating array temporary" }
|
126 |
|
|
)+1 /= 3*ay+2)) call abort
|
127 |
|
|
if (any(sum(eid(sum(a,3))+az+2* &
|
128 |
|
|
neid2(az) & ! { dg-warning "Creating array temporary" }
|
129 |
|
|
,1)+1 /= 4*sum(az,1)+1)) call abort
|
130 |
|
|
|
131 |
|
|
if (any(sum(transpose(sum(a,1)),1)+sum(az,1) /= sum(ax,2)+sum(sum(a,3),1))) call abort
|
132 |
|
|
|
133 |
|
|
|
134 |
|
|
! Creates a temp when needed.
|
135 |
|
|
a(1,:,:) = sum(a,1) ! unnecessary { dg-warning "Creating array temporary" }
|
136 |
|
|
if (any(a(1,:,:) /= ax)) call abort
|
137 |
|
|
|
138 |
|
|
b = p(:,:,1)
|
139 |
|
|
call set(b(2:,1), sum(b(:nx-1,:),2)) ! { dg-warning "Creating array temporary" }
|
140 |
|
|
if (any(b(2:,1) /= ay(1:nx-1,1))) call abort
|
141 |
|
|
|
142 |
|
|
b = p(:,:,1)
|
143 |
|
|
call set(b(:,1), sum(b,2)) ! unnecessary { dg-warning "Creating array temporary" }
|
144 |
|
|
if (any(b(:,1) /= ay(:,1))) call abort
|
145 |
|
|
|
146 |
|
|
b = p(:,:,1)
|
147 |
|
|
call tes(sum(eid(b(:nx-1,:)),2), b(2:,1)) ! { dg-warning "Creating array temporary" }
|
148 |
|
|
if (any(b(2:,1) /= ay(1:nx-1,1))) call abort
|
149 |
|
|
|
150 |
|
|
b = p(:,:,1)
|
151 |
|
|
call tes(eid(sum(b,2)), b(:,1)) ! unnecessary { dg-warning "Creating array temporary" }
|
152 |
|
|
if (any(b(:,1) /= ay(:,1))) call abort
|
153 |
|
|
|
154 |
|
|
contains
|
155 |
|
|
|
156 |
|
|
elemental function eid (x)
|
157 |
|
|
integer, intent(in) :: x
|
158 |
|
|
integer :: eid
|
159 |
|
|
|
160 |
|
|
eid = x
|
161 |
|
|
end function eid
|
162 |
|
|
|
163 |
|
|
function neid2 (x)
|
164 |
|
|
integer, intent(in) :: x(:,:)
|
165 |
|
|
integer :: neid2(size(x,1),size(x,2))
|
166 |
|
|
|
167 |
|
|
neid2 = x
|
168 |
|
|
end function neid2
|
169 |
|
|
|
170 |
|
|
function neid3 (x)
|
171 |
|
|
integer, intent(in) :: x(:,:,:)
|
172 |
|
|
integer :: neid3(size(x,1),size(x,2),size(x,3))
|
173 |
|
|
|
174 |
|
|
neid3 = x
|
175 |
|
|
end function neid3
|
176 |
|
|
|
177 |
|
|
elemental subroutine set (o, i)
|
178 |
|
|
integer, intent(in) :: i
|
179 |
|
|
integer, intent(out) :: o
|
180 |
|
|
|
181 |
|
|
o = i
|
182 |
|
|
end subroutine set
|
183 |
|
|
|
184 |
|
|
elemental subroutine tes (i, o)
|
185 |
|
|
integer, intent(in) :: i
|
186 |
|
|
integer, intent(out) :: o
|
187 |
|
|
|
188 |
|
|
o = i
|
189 |
|
|
end subroutine tes
|
190 |
|
|
end
|
191 |
|
|
! { dg-final { scan-tree-dump-times "struct array._integer\\(kind=4\\) atmp" 13 "original" } }
|
192 |
|
|
! { dg-final { scan-tree-dump-times "struct array\[^\\n\]*atmp" 13 "original" } }
|
193 |
|
|
! { dg-final { scan-tree-dump-times "_gfortran_sum_" 0 "original" } }
|
194 |
|
|
! { dg-final { cleanup-tree-dump "original" } }
|