Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmd/compile: unnecessary array copying in for range loop #33838

Closed
marigonzes opened this issue Aug 26, 2019 · 3 comments
Closed

cmd/compile: unnecessary array copying in for range loop #33838

marigonzes opened this issue Aug 26, 2019 · 3 comments

Comments

@marigonzes
Copy link

@marigonzes marigonzes commented Aug 26, 2019

What version of Go are you using (go version)?

$ go version
go version devel +739123c Sun Aug 25 00:27:25 2019 +0000 linux/amd64

Does this issue reproduce with the latest release?

Yes.

What did you do?

I compiled the following program and analyzed the assembly code generated (https://godbolt.org/z/QXblVs):

package test

func f(x [][4]int) [][3]int {
    res := make([][3]int, len(x))

    for i, v := range x {
        res[i][0] = v[0]
        res[i][1] = v[1]
        res[i][2] = v[2]
    }

    return res
}

What did you expect to see?

I expected the looping part of this function to not contain unnecessary instructions, like in (https://godbolt.org/z/L3hIuW):

package test

func f(x [][4]int) [][3]int {
    res := make([][3]int, len(x))

    for i := range x {
        res[i][0] = x[i][0]
        res[i][1] = x[i][1]
        res[i][2] = x[i][2]
    }

    return res
}
        leaq    (BX)(BX*2), SI
        movq    BX, DI
        shlq    $5, BX
        movq    (DX)(BX*1), R8
        movq    R8, (AX)(SI*8)
        movq    8(DX)(BX*1), R8
        movq    R8, 8(AX)(SI*8)
        movq    16(DX)(BX*1), R8
        movq    R8, 16(AX)(SI*8)

What did you see instead?

Instead, it was compiled to all this instructions, most of which are unnecessary (https://godbolt.org/z/QXblVs):

        movups  (DX), X0
        movups  X0, ""..autotmp_10+64(SP)
        movups  16(DX), X0
        movups  X0, ""..autotmp_10+80(SP)
        movups  ""..autotmp_10+64(SP), X0
        movups  X0, "".v+32(SP)
        movups  ""..autotmp_10+80(SP), X0
        movups  X0, "".v+48(SP)
        leaq    (BX)(BX*2), SI
        movq    "".v+32(SP), DI
        movq    DI, (AX)(SI*8)
        movq    "".v+40(SP), DI
        movq    DI, 8(AX)(SI*8)
        movq    "".v+48(SP), DI
        movq    DI, 16(AX)(SI*8)

Note: There are probably open issues about this, but I couldn't find any.

@av86743

This comment has been minimized.

Copy link

@av86743 av86743 commented Aug 26, 2019

Semantics of v being a copy in for i, v := range x presents a challenge. You need either to erase allocations (which is painful and backward), or to have a separate path where v is not copied but just referenced (which is not there.)

With the current overall state of the project, I think the most you will get out of your example is a promise of another future vet warning, as problem can be resolved at the source level.

@randall77

This comment has been minimized.

Copy link
Contributor

@randall77 randall77 commented Aug 26, 2019

I would call this a dup of #24416, as the whole [4]int currently needs to be copied.

@bcmills

This comment has been minimized.

Copy link
Member

@bcmills bcmills commented Aug 26, 2019

Duplicate of #24416

@bcmills bcmills marked this as a duplicate of #24416 Aug 26, 2019
@bcmills bcmills closed this Aug 26, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants
You can’t perform that action at this time.