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.

Reply via email to