Skip to content

[SLP] suboptimal divrem vectorization #241788

Description

@Andarwinux

noticed from #241758
https://godbolt.org/z/8ofcT8xWE

define void @urem_div_lane0(ptr %a, ptr %b, ptr %r, ptr %q) {
entry:
  %a0 = load i32, ptr %a, align 4
  %pa1 = getelementptr inbounds i32, ptr %a, i64 1
  %a1 = load i32, ptr %pa1, align 4
  %pa2 = getelementptr inbounds i32, ptr %a, i64 2
  %a2 = load i32, ptr %pa2, align 4
  %pa3 = getelementptr inbounds i32, ptr %a, i64 3
  %a3 = load i32, ptr %pa3, align 4
  %b0 = load i32, ptr %b, align 4
  %pb1 = getelementptr inbounds i32, ptr %b, i64 1
  %b1 = load i32, ptr %pb1, align 4
  %pb2 = getelementptr inbounds i32, ptr %b, i64 2
  %b2 = load i32, ptr %pb2, align 4
  %pb3 = getelementptr inbounds i32, ptr %b, i64 3
  %b3 = load i32, ptr %pb3, align 4
  %r0 = urem i32 %a0, %b0
  %r1 = urem i32 %a1, %b1
  %r2 = urem i32 %a2, %b2
  %r3 = urem i32 %a3, %b3
  %d0 = udiv i32 %a0, %b0
  store i32 %d0, ptr %q, align 4
  store i32 %r0, ptr %r, align 4
  %pr1 = getelementptr inbounds i32, ptr %r, i64 1
  store i32 %r1, ptr %pr1, align 4
  %pr2 = getelementptr inbounds i32, ptr %r, i64 2
  store i32 %r2, ptr %pr2, align 4
  %pr3 = getelementptr inbounds i32, ptr %r, i64 3
  store i32 %r3, ptr %pr3, align 4
  ret void
}
define void @urem_div_lane0(ptr nofree readonly captures(none) %a, ptr nofree readonly captures(none) %b, ptr nofree writeonly captures(none) initializes((0, 16)) %r, ptr nofree writeonly captures(none) initializes((0, 4)) %q) local_unnamed_addr {
entry:
  %0 = load <4 x i32>, ptr %a, align 4
  %a0 = load i32, ptr %a, align 4
  %1 = load <4 x i32>, ptr %b, align 4
  %b0 = load i32, ptr %b, align 4
  %2 = urem <4 x i32> %0, %1
  %d0 = udiv i32 %a0, %b0
  store i32 %d0, ptr %q, align 4
  store <4 x i32> %2, ptr %r, align 4
  ret void
}
urem_div_lane0:
        vmovdqu xmm0, xmmword ptr [rdi]
        vmovdqu xmm1, xmmword ptr [rsi]
        mov     eax, dword ptr [rdi]
        mov     r8, rdx
        xor     edx, edx
        div     dword ptr [rsi]
        vcvtudq2pd      ymm2, xmm1
        vcvtudq2pd      ymm3, xmm0
        vdivpd  ymm2, ymm3, ymm2
        mov     dword ptr [rcx], eax
        vcvttpd2udq     xmm2, ymm2
        vpmulld xmm1, xmm2, xmm1
        vpsubd  xmm0, xmm0, xmm1
        vmovdqu xmmword ptr [r8], xmm0
        vzeroupper
        ret

SLP should rewrite rem vectorization candidates with paired divs to div+mul+sub like this one:

define void @tgt(ptr noalias %a, ptr noalias %b, ptr noalias %r, ptr noalias %q) {
entry:
  %0 = load <4 x i32>, ptr %a, align 4
  %1 = load <4 x i32>, ptr %b, align 4
  %div = udiv <4 x i32> %0, %1
  %mul = mul <4 x i32> %div, %1
  %sub = sub <4 x i32> %0, %mul
  store <4 x i32> %sub, ptr %r, align 4
  %vecext22 = extractelement <4 x i32> %div, i64 0
  store i32 %vecext22, ptr %q, align 4
  ret void
}
tgt:
        vmovdqu xmm0, xmmword ptr [rdi]
        vmovdqu xmm1, xmmword ptr [rsi]
        vcvtudq2pd      ymm2, xmm1
        vcvtudq2pd      ymm3, xmm0
        vdivpd  ymm2, ymm3, ymm2
        vcvttpd2udq     xmm2, ymm2
        vpmulld xmm1, xmm2, xmm1
        vmovd   dword ptr [rcx], xmm2
        vpsubd  xmm0, xmm0, xmm1
        vmovdqu xmmword ptr [rdx], xmm0
        vzeroupper
        ret
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions