https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128431
Bug ID: 128431
Summary: Weird array copy with vectoriztation
Product: gcc
Version: 17.0
Status: UNCONFIRMED
Severity: enhancement
Priority: P3
Component: fortran
Assignee: unassigned at gcc dot gnu.org
Reporter: tkoenig at gcc dot gnu.org
Target Milestone: ---
This is on rocketlake.
The following code
subroutine foo (from_small, to_small, from_buf, to_buf)
implicit none
unsigned(8), value :: from_small, to_small
unsigned(1), dimension(41), intent(out) :: from_buf, to_buf
integer, parameter :: grpsz = 6, tabsz=729
integer :: i, k
unsigned(16), parameter :: base = 3u_16
integer, parameter :: n_grp = int(64 * log(2.0)/log(real(base)) / grpsz) !
rounding down
integer, parameter :: halfsize = n_grp * grpsz
unsigned(kind=1), dimension(0:grpsz-1,0:tabsz-1), parameter :: tab = reshape
([ &
((mod(uint(k)/base**uint(i), base), i=0, grpsz-1), k=0, tabsz-1) &
], shape = [grpsz,tabsz])
unsigned, parameter :: tabszu = uint(tabsz)
unsigned(8) :: from_rem, to_rem
do i=0, halfsize-1, grpsz
to_rem = mod(to_small, tabszu)
to_small = to_small / tabszu
from_rem = mod(from_small, tabszu)
from_small = mod(from_small, tabszu)
to_buf (i:i+grpsz-1) = tab(:,int(to_rem))
from_buf (i:i+grpsz-1) = tab(:,int(from_rem))
end do
end subroutine foo
yields some weird assembly code with
gfortran -fverbose-asm -march=native -mtune=native -fmax-errors=1 -funsigned -S
-O3 tst2.f90
(only weird parts copied):
# tst2.f90:21: to_buf (i:i+grpsz-1) = tab(:,int(to_rem))
vmovd %edx, %xmm0 # tab[_125], tmp377
movzbl tab.0+2(%rbx), %edx # tab[_94], tab[_94]
vpinsrb $1, tab.0+1(%rbx), %xmm0, %xmm0 #, tab[_102], tmp377, tmp378
vmovd %edx, %xmm7 # tab[_94], tmp383
movzbl tab.0+4(%rbx), %edx # tab[_70], tab[_70]
vpinsrb $1, tab.0+3(%rbx), %xmm7, %xmm7 #, tab[_87], tmp383, tmp384
vmovd %edx, %xmm3 # tab[_70], tmp389
movzbl tab.0(%r11), %edx # tab[_69], tab[_69]
vpinsrb $1, tab.0+5(%rbx), %xmm3, %xmm3 #, tab[_41], tmp389, tmp390
vpunpcklwd %xmm7, %xmm0, %xmm0 # tmp384, tmp378, tmp423
vmovd %edx, %xmm6 # tab[_69], tmp395
movzbl tab.0+2(%r11), %edx # tab[_133], tab[_133]
vpinsrb $1, tab.0+1(%r11), %xmm6, %xmm6 #, tab[_77], tmp395, tmp396
vmovd %edx, %xmm1 # tab[_133], tmp401
movzbl tab.0+4(%r11), %edx # tab[_141], tab[_141]
vpinsrb $1, tab.0+3(%r11), %xmm1, %xmm1 #, tab[_137], tmp401, tmp402
vpunpcklwd %xmm6, %xmm3, %xmm3 # tmp396, tmp390, tmp425
vmovd %edx, %xmm5 # tab[_141], tmp407
vpunpckldq %xmm3, %xmm0, %xmm0 # tmp425, tmp423, tmp431
vpinsrb $1, tab.0+5(%r11), %xmm5, %xmm5 #, tab[_145], tmp407, tmp408
movzbl tab.0(%r10), %edx # tab[_179], tab[_179]
vmovd %edx, %xmm2 # tab[_179], tmp413
movzbl tab.0+2(%r10), %edx # tab[_187], tab[_187]
vpunpcklwd %xmm5, %xmm1, %xmm1 # tmp408, tmp402, tmp427
vpinsrb $1, tab.0+1(%r10), %xmm2, %xmm2 #, tab[_183], tmp413, tmp414
vmovd %edx, %xmm4 # tab[_187], tmp419
movzbl tab.0+4(%r10), %edx # tab[_195], tab[_195]
vpinsrb $1, tab.0+3(%r10), %xmm4, %xmm4 #, tab[_191], tmp419, tmp420
vpunpcklwd %xmm4, %xmm2, %xmm2 # tmp420, tmp414, tmp429
vpunpckldq %xmm2, %xmm1, %xmm1 # tmp429, tmp427, tmp433
vpunpcklqdq %xmm1, %xmm0, %xmm0 # tmp433, tmp431, tmp435
vmovd %edx, %xmm1 # tab[_195], tmp438
movzbl tab.0(%r9), %edx # tab[_233], tab[_233]
vpinsrb $1, tab.0+5(%r10), %xmm1, %xmm1 #, tab[_199], tmp438, tmp439
vmovd %edx, %xmm8 # tab[_233], tmp444
movzbl tab.0+2(%r9), %edx # tab[_241], tab[_241]
vpinsrb $1, tab.0+1(%r9), %xmm8, %xmm8 #, tab[_237], tmp444, tmp445
vmovd %edx, %xmm4 # tab[_241], tmp450
movzbl tab.0+4(%r9), %edx # tab[_249], tab[_249]
vpinsrb $1, tab.0+3(%r9), %xmm4, %xmm4 #, tab[_245], tmp450, tmp451
vpunpcklwd %xmm8, %xmm1, %xmm1 # tmp445, tmp439, tmp484
vmovd %edx, %xmm7 # tab[_249], tmp456
movzbl tab.0(%r8), %edx # tab[_287], tab[_287]
vpinsrb $1, tab.0+5(%r9), %xmm7, %xmm7 #, tab[_253], tmp456, tmp457
vmovd %edx, %xmm2 # tab[_287], tmp462
movzbl tab.0+2(%r8), %edx # tab[_295], tab[_295]
vpinsrb $1, tab.0+1(%r8), %xmm2, %xmm2 #, tab[_291], tmp462, tmp463
vpunpcklwd %xmm7, %xmm4, %xmm4 # tmp457, tmp451, tmp486
vmovd %edx, %xmm6 # tab[_295], tmp468
movzbl tab.0+4(%r8), %edx # tab[_303], tab[_303]
vpunpckldq %xmm4, %xmm1, %xmm1 # tmp486, tmp484, tmp492
vpinsrb $1, tab.0+3(%r8), %xmm6, %xmm6 #, tab[_299], tmp468, tmp469
vmovd %edx, %xmm3 # tab[_303], tmp474
movzbl tab.0(%rcx), %edx # tab[_26], tab[_26]
vpinsrb $1, tab.0+5(%r8), %xmm3, %xmm3 #, tab[_307], tmp474, tmp475
vpunpcklwd %xmm6, %xmm2, %xmm2 # tmp469, tmp463, tmp488
vmovd %edx, %xmm5 # tab[_26], tmp480
# tst2.f90:21: to_buf (i:i+grpsz-1) = tab(:,int(to_rem))
movl tab.0+2(%rcx), %edx # MEM <vector(4) unsigned(kind=1)>
[(unsigned(kind=1) *)vectp.12_206], vect__106.13_207
# tst2.f90:21: to_buf (i:i+grpsz-1) = tab(:,int(to_rem))
vpinsrb $1, tab.0+1(%rcx), %xmm5, %xmm5 #, tab[_95], tmp480, tmp481
# tst2.f90:21: to_buf (i:i+grpsz-1) = tab(:,int(to_rem))
movl %edx, 31(%r14) # vect__106.13_207, MEM <vector(4)
unsigned(kind=1)> [(unsigned(kind=1) *)to_buf_27(D) + 31B]
# tst2.f90:21: to_buf (i:i+grpsz-1) = tab(:,int(to_rem))
vpunpcklwd %xmm5, %xmm3, %xmm3 # tmp481, tmp475, tmp490
vpunpckldq %xmm3, %xmm2, %xmm2 # tmp490, tmp488, tmp494
# tst2.f90:22: from_buf (i:i+grpsz-1) = tab(:,int(from_rem))
vmovd %r12d, %xmm3 # _4, tmp512
# tst2.f90:21: to_buf (i:i+grpsz-1) = tab(:,int(to_rem))
vpunpcklqdq %xmm2, %xmm1, %xmm1 # tmp494, tmp492, tmp496
# tst2.f90:22: from_buf (i:i+grpsz-1) = tab(:,int(from_rem))
vpinsrb $1, tab.0+5(%rdi), %xmm3, %xmm3 #, tab[_2], tmp512, tmp513
# tst2.f90:21: to_buf (i:i+grpsz-1) = tab(:,int(to_rem))
vinserti32x4 $0x1, %xmm1, %ymm0, %ymm0 # tmp496, tmp435, _202
# tst2.f90:22: from_buf (i:i+grpsz-1) = tab(:,int(from_rem))
vmovd %esi, %xmm1 # _14, tmp508
# tst2.f90:22: from_buf (i:i+grpsz-1) = tab(:,int(from_rem))
movl -4(%rsp), %esi # %sfp, MEM <vector(4) unsigned(kind=1)>
[(unsigned(kind=1) *)vectp.19_218]
# tst2.f90:21: to_buf (i:i+grpsz-1) = tab(:,int(to_rem))
vmovdqu %ymm0, -1(%r14) # _202, MEM <vector(32) unsigned(kind=1)>
[(unsigned(kind=1) *)to_buf_27(D) + -1B]
# tst2.f90:22: from_buf (i:i+grpsz-1) = tab(:,int(from_rem))
vmovd %eax, %xmm0 # _34, tmp504
vpinsrb $1, tab.0+3(%rdi), %xmm1, %xmm1 #, tab[_8], tmp508, tmp509
vpinsrb $1, tab.0+1(%rdi), %xmm0, %xmm0 #, tab[_29], tmp504, tmp505
# tst2.f90:22: from_buf (i:i+grpsz-1) = tab(:,int(from_rem))
movl %esi, 31(%r13) # MEM <vector(4) unsigned(kind=1)>
[(unsigned(kind=1) *)vectp.19_218], MEM <vector(4) unsigned(kind=1)>
[(unsigned(kind=1) *)from_buf_32(D) + 31B]
# tst2.f90:22: from_buf (i:i+grpsz-1) = tab(:,int(from_rem))
vpunpcklwd %xmm1, %xmm0, %xmm2 # tmp509, tmp505, tmp535
vpunpcklwd %xmm3, %xmm1, %xmm1 # tmp513, tmp509, tmp539
vpunpcklwd %xmm0, %xmm3, %xmm0 # tmp505, tmp513, tmp537
vpunpckldq %xmm0, %xmm2, %xmm3 # tmp537, tmp535, tmp543
vpunpckldq %xmm2, %xmm1, %xmm2 # tmp535, tmp539, tmp545
vpunpckldq %xmm1, %xmm0, %xmm0 # tmp539, tmp537, tmp588
vpunpcklqdq %xmm2, %xmm3, %xmm2 # tmp545, tmp543, tmp547
vpunpcklqdq %xmm3, %xmm0, %xmm0 # tmp543, tmp588, tmp592
vinserti32x4 $0x1, %xmm0, %ymm2, %ymm0 # tmp592, tmp547, _213
vmovdqu %ymm0, -1(%r13) # _213, MEM <vector(32) unsigned(kind=1)>
[(unsigned(kind=1) *)from_buf_32(D) + -1B]
vzeroupper
The line
to_buf (i:i+grpsz-1) = tab(:,int(to_rem))
is a six-byte contiguous copy, which should be done with a a four-byte and a
two-byte load and subsequent store.