https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128279

            Bug ID: 128279
           Summary: __builtin_sqrtf16 should be vectorized with -mf16c
           Product: gcc
           Version: 16.2.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: ubizjak at gmail dot com
  Target Milestone: ---

Currently, the compiler vectorizes e.g.:

void
foo (_Float16 *__restrict r, const _Float16 *__restrict x,
     const _Float16 *__restrict y, const _Float16 *__restrict z)
{
  for (int n = 0; n < 128; ++n)
    r[n] = (x[n] + y[n]) / z[n];
}

gcc -O2 -mf16c:

foo:
        xorl    %eax, %eax
        .p2align 4
        .p2align 3
.L2:
        vmovdqu (%rsi,%rax), %ymm3
        vmovdqu (%rdx,%rax), %ymm0
        vmovdqu (%rcx,%rax), %ymm2
        vcvtph2ps       %xmm3, %ymm4
        vcvtph2ps       %xmm0, %ymm1
        vextractf128    $0x1, %ymm3, %xmm3
        vaddps  %ymm4, %ymm1, %ymm1
        vextractf128    $0x1, %ymm0, %xmm0
        vcvtph2ps       %xmm3, %ymm3
        vcvtph2ps       %xmm2, %ymm4
        vextractf128    $0x1, %ymm2, %xmm2
        vcvtph2ps       %xmm0, %ymm0
        vaddps  %ymm3, %ymm0, %ymm0
        vcvtph2ps       %xmm2, %ymm2
        vdivps  %ymm4, %ymm1, %ymm1
        vdivps  %ymm2, %ymm0, %ymm0
        vcvtps2ph       $4, %ymm1, %xmm1
        vcvtps2ph       $4, %ymm0, %xmm0
        vinsertf128     $0x1, %xmm0, %ymm1, %ymm0
        vmovdqu %ymm0, (%rdi,%rax)
        addq    $32, %rax
        cmpq    $256, %rax
        jne     .L2
        vzeroupper
        ret

However, it still doesn't vectorize __builtin_sqrtf16, not even with
-ffast-math:

void
bar (_Float16 *__restrict r, const _Float16 *__restrict x,
     const _Float16 *__restrict y)
{
  for (int n = 0; n < 128; ++n)
    r[n] = __builtin_sqrtf16 (x[n] + y[n]);
}

gcc -O2 -ffast-math -mf16c:

.L6:
        vpxor   %xmm2, %xmm2, %xmm2
        vpinsrw $0, (%r12,%rbx), %xmm2, %xmm1
        vpinsrw $0, 0(%rbp,%rbx), %xmm2, %xmm0
        vcvtph2ps       %xmm1, %xmm1
        vcvtph2ps       %xmm0, %xmm0
        vaddss  %xmm1, %xmm0, %xmm0
        vinsertps       $0xe, %xmm0, %xmm0, %xmm0
        vcvtps2ph       $4, %xmm0, %xmm0
        call    sqrtf16
        vpextrw $0, %xmm0, 0(%r13,%rbx)
        addq    $2, %rbx
        cmpq    $256, %rbx
        jne     .L6

The compiler should convert the call to SFmode and use vectorized VSQRTPS
instead, or ideally VRSQRTPS (perhaps NR step is not needed here)?

FYI: Using -mavx512fp16 instead of -mf16c creates expected code:

.L6:
        vmovdqu16       (%rdx,%rax), %zmm0
        vaddph  (%rsi,%rax), %zmm0, %zmm0
        vsqrtph %zmm0, %zmm0
        vmovdqu16       %zmm0, (%rdi,%rax)
        addq    $64, %rax
        cmpq    $256, %rax
        jne     .L6

Reply via email to