https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127114
--- Comment #2 from Hongyu Wang <hongyuw at gcc dot gnu.org> ---
With
@@ -28054,8 +28054,15 @@ ix86_optab_supported_p (int op, machine_mode mode1,
machine_mode,
case expm1_optab:
case ldexp_optab:
case scalb_optab:
+ return opt_type == OPTIMIZE_FOR_SPEED;
+
case round_optab:
case lround_optab:
+ /* HFmode round has no libm fallback (no roundf16/lroundf16), so the
+ native vrndscaleph-based sequence is the only implementation; keep it
+ available for both size and speed, like floor/ceil/btrunc below. */
+ if (mode1 == HFmode)
+ return true;
return opt_type == OPTIMIZE_FOR_SPEED;
Could help vectorization at -O2. Now we have
.L4:
vmovdqu16 (%rsi,%rdx), %zmm0
vmovdqa64 %zmm2, %zmm1
vpternlogd $234, %zmm3, %zmm0, %zmm1
vaddph %zmm1, %zmm0, %zmm0
vrndscaleph $3, %zmm0, %zmm0
vmovdqu16 %zmm0, (%rdi,%rdx)
addq $64, %rdx
cmpq %r8, %rdx
jne .L4
sall $5, %eax
cmpl %eax, %ecx
je .L9
But for -Os it is no better.
-Os after change:
.L2: cmpl %eax,%edx ; jle .L5
vmovw (%rsi,%rax,2),%xmm0
vmovdqa %xmm2,%xmm4
vpternlogd $234,%xmm1,%xmm0,%xmm4 ; copysign(0.5,x)
vaddsh %xmm4,%xmm0,%xmm0
vrndscalesh $3,%xmm0,%xmm0,%xmm0 ; trunc
vmovw %xmm0,(%rdi,%rax,2)
incq %rax
jmp .L2
-Os before change:
.L2: cmpl %ebx,%ebp ; jle .L6
vcvtsh2sd 0(%r13,%rbx,2),%xmm0,%xmm0
call round ; ← libcall
vcvtsd2sh %xmm0,%xmm0,%xmm0
vmovw %xmm0,(%r12,%rbx,2)
incq %rbx
jmp .L2
May consider directly emit the original -Os sequence in the expander.