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: invalid instruction: MOVL $11553462026240, AX #41711

Closed
ALTree opened this issue Sep 30, 2020 · 14 comments
Closed

cmd/compile: invalid instruction: MOVL $11553462026240, AX #41711

ALTree opened this issue Sep 30, 2020 · 14 comments

Comments

@ALTree
Copy link
Member

@ALTree ALTree commented Sep 30, 2020

Filed on behalf of Jan Mercl (from a golang-dev thread).

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

$ go version
go version go1.15.2 linux/amd64

Does this issue reproduce with the latest release?

Yes.

What operating system and processor architecture are you using (go env)?

$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/jnml/.cache/go-build"
GOENV="/home/jnml/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/home/jnml/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/jnml"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/home/jnml/src/go.googlesource.com/go/goroot"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/home/jnml/src/go.googlesource.com/go/goroot/pkg/tool/linux_amd64"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build571607678=/tmp/go-build -gno-record-gcc-switches"

What did you do?

jnml@e5-1650:~/tmp/csmith$ cat main.go
package foo

import "modernc.org/libc"

func safe_div_func_int16_t_s_s(tls *libc.TLS, si1 int16, si2 int16) int16 {
        if (int32(si2) == 0) || ((int32(si1) == (-32767 - 1)) && (int32(si2) == (-1))) {
                return si1
        }
        return (int16(int32(si1) / int32(si2)))
}

func safe_lshift_func_int16_t_s_u(tls *libc.TLS, left int16, right uint32) int16 {
        if ((int32(left) < 0) || ((right) >= uint32(32))) || (int32(left) > (int32((32767)) >> (right))) {
                return left
        }
        return (int16(int32(left) << (right)))
}

func safe_sub_func_int32_t_s_s(tls *libc.TLS, si1 int32, si2 int32) int32 {
        if ((si1 ^ si2) & (((si1 ^ ((si1 ^ si2) & (^int32(libc.Int32FromInt32(2147483647))))) - si2) ^ si2)) < 0 {
                return si1
        }
        return (si1 - si2)
}

func safe_unary_minus_func_int64_t_s(tls *libc.TLS, si int64) int64 {
        if si == (-9223372036854775807 - int64(1)) {
                return si
        }
        return -si
}

func safe_sub_func_uint16_t_u_u(tls *libc.TLS, ui1 uint16, ui2 uint16) uint16 {
        return (uint16(int32(ui1) - int32(ui2)))
}

func func_44(tls *libc.TLS) uint16 {
        return safe_sub_func_uint16_t_u_u(tls, (uint16((int32(safe_div_func_int16_t_s_s(tls, 0, int16(safe_sub_func_int32_t_s_s(tls, 1, int32(safe_lshift_func_int16_t_s_u(tls, int16(0x1504), uint32(safe_unary_minus_func_int64_t_s(tls, int64(libc.Bool32(true))))))))))))), 0)
}
jnml@e5-1650:~/tmp/csmith$ go build main.go

What did you expect to see?

Nothing but a command prompt.

What did you see instead?

# command-line-arguments
./main.go:38:2: invalid instruction: 00105 (/home/jnml/tmp/csmith/main.go:38)   MOVL    $11553462026240, AX
jnml@e5-1650:~/tmp/csmith$
@ALTree ALTree added this to the Go1.16 milestone Sep 30, 2020
@ALTree
Copy link
Member Author

@ALTree ALTree commented Sep 30, 2020

Loading

@dr2chase
Copy link
Contributor

@dr2chase dr2chase commented Sep 30, 2020

I'm trying to reproduce, this has the look and feel of a bug I thought I could create on MIPS, that I (also) encountered with late call expansion. Basically, if you can smuggle a funny constant past the early phases and have it appear "late" (e.g., within late call expansion, which is not in this compiler yet, or in prove, which is), surprising things can happen. I solved it for MIPS by adding some code generation rules, but I don't see the same missing rules on AMD64 so it is not an exact duplicate.

Loading

@dr2chase
Copy link
Contributor

@dr2chase dr2chase commented Sep 30, 2020

No, it's weirder than that. Compare compilation of the two MOVLconst <int32> [0] : AX in the code:

b28: ← b16-
v24 (9) = MOVLconst <int32> [0] : AX
v102 (+9) = DIVL <int32,int32> [false] v24 v85 : <AX,DX>
v106 (+9) = Select0 <int32> v102 : AX
Plain → b30 (+38)
b10: ← b8-
v43 (13) = MOVLconst <int32> [32767] : CX
v42 (13) = SARLconst <int32> [31] v43 : CX
v20 (13) = CMPLconst <flags> [5380] v42
LT v20 → b13 b12 (13)
b12: ← b10-
v105 (16) = MOVLconst <int32> [0] : AX
Plain → b16 (+38)


v42   00030 (+9) XORL AX, AX
v102  00031 (9) CMPL CX, $-1
v102  00032 (9) JEQ 36
v102  00033 (9) CDQ
v102  00034 (9) IDIVL CX
v102  00035 (9) JMP 38
v102  00036 (9) NEGL AX
v102  00037 (9) XORL DX, DX
b28   00038 (+38) JMP 28
v43   00039 (13) MOVL $32767, CX
v42   00040 (13) SARL $31, CX
v20   00041 (13) CMPL CX, $5380
b10   00042 (13) JLT 8
v105  00043 (16) MOVL $11553462026240, AX
b12   00044 (+38) JMP 9

I've got other things to work on, just wanted to be sure that wasn't a variant of the bug I fixed just the other day for MIPS.

Loading

@sam3000
Copy link

@sam3000 sam3000 commented Sep 30, 2020

FWIW, a slightly more contained repro - no imports and simplied where possible:
https://play.golang.org/p/rB2HvJwS5j3

Loading

@mundaym
Copy link
Member

@mundaym mundaym commented Sep 30, 2020

v105 (16) = MOVLconst <int32> [0] : AX
v105  00043 (16) MOVL $11553462026240, AX

This looks to me like a rule isn't sign extending an int32 constant to 64 bits. The pretty printer will just ignore the high bits but the MOVL will get a copy of the raw int64 value. I bet the new typed rules in master will fix it.

I got curious and took a quick look at the AMD64 rules in Go 1.15. This looks like the sort of rule that could cause an issue like this:

(SHLLconst [d] (MOVLconst [c])) -> (MOVLconst [int64(int32(c)) << uint64(d)])

(The sign extension to 64-bits happens before the shift and not after, so the resulting value could be out-of-range for an int32. This particular rule probably doesn't trigger very often because the generic rules do most constant folding.)

Loading

@randall77
Copy link
Contributor

@randall77 randall77 commented Sep 30, 2020

A MOVLconst that doesn't have its high bits sign-extended correctly should fail if the check pass is enabled. Does it?

Loading

@mundaym
Copy link
Member

@mundaym mundaym commented Sep 30, 2020

Yep (based on #41711 (comment)).

$ ./go1.15/bin/go tool compile -d=ssa/check/on example.go 
example.go:37:35: internal compiler error: 'func_44': bad int32 AuxInt value for v43

Please file a bug report including a short program that triggers the error.
https://golang.org/issue/new

Loading

@randall77
Copy link
Contributor

@randall77 randall77 commented Sep 30, 2020

@gopherbot please open a backport issue for 1.15.

Loading

@randall77
Copy link
Contributor

@randall77 randall77 commented Sep 30, 2020

Seems to be ok for 1.14 and earlier.

Loading

@gopherbot
Copy link

@gopherbot gopherbot commented Sep 30, 2020

Backport issue(s) opened: #41720 (for 1.15).

Remember to create the cherry-pick CL(s) as soon as the patch is submitted to master, according to https://golang.org/wiki/MinorReleases.

Loading

@randall77
Copy link
Contributor

@randall77 randall77 commented Sep 30, 2020

Also ok at tip. Just 1.15 needs fixing.

Loading

@gopherbot
Copy link

@gopherbot gopherbot commented Oct 1, 2020

Change https://golang.org/cl/258817 mentions this issue: [release-branch.go1.15] cmd/compile: fix left shift constant folding rule

Loading

gopherbot pushed a commit that referenced this issue Oct 14, 2020
…rule

The 32-bit left shift constant folding rule should keep its result
properly sign extended.

Fixes #41720
Fixes #41711

Change-Id: I0fc74444d444274e911952e1725dab0b7737a846
Reviewed-on: https://go-review.googlesource.com/c/go/+/258817
Trust: Keith Randall <khr@golang.org>
Run-TryBot: Keith Randall <khr@golang.org>
Reviewed-by: David Chase <drchase@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
@aclements
Copy link
Member

@aclements aclements commented Oct 15, 2020

@randall77 , is it okay to close this issue now that the 1.15 CL is in?

Loading

@randall77
Copy link
Contributor

@randall77 randall77 commented Oct 15, 2020

Yes.

Loading

@randall77 randall77 closed this Oct 15, 2020
claucece added a commit to claucece/go that referenced this issue Oct 22, 2020
…rule

The 32-bit left shift constant folding rule should keep its result
properly sign extended.

Fixes golang#41720
Fixes golang#41711

Change-Id: I0fc74444d444274e911952e1725dab0b7737a846
Reviewed-on: https://go-review.googlesource.com/c/go/+/258817
Trust: Keith Randall <khr@golang.org>
Run-TryBot: Keith Randall <khr@golang.org>
Reviewed-by: David Chase <drchase@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
@golang golang locked and limited conversation to collaborators Oct 15, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
7 participants