[Pkg-golang-commits] [golang] 01/01: Imported Upstream version 1.8
Michael Hudson-Doyle
mwhudson-guest at moszumanska.debian.org
Thu Mar 2 21:32:27 UTC 2017
This is an automated email from the git hooks/post-receive script.
mwhudson-guest pushed a commit to branch upstream-1.8
in repository golang.
commit e3882f585143f163b31d711e7222480cc03d7625
Author: Michael Hudson-Doyle <michael.hudson at canonical.com>
Date: Thu Mar 2 10:10:06 2017 +1300
Imported Upstream version 1.8
---
VERSION | 2 +-
doc/conduct.html | 36 +-
doc/devel/release.html | 14 +
doc/go1.8.html | 18 +-
doc/install-source.html | 4 +-
src/cmd/compile/internal/gc/sinit.go | 2 +-
src/cmd/compile/internal/s390x/ssa.go | 7 +-
src/cmd/compile/internal/ssa/gen/ARM64.rules | 84 +++-
src/cmd/compile/internal/ssa/gen/PPC64.rules | 6 +-
src/cmd/compile/internal/ssa/gen/S390X.rules | 109 +++--
src/cmd/compile/internal/ssa/gen/S390XOps.go | 3 +
src/cmd/compile/internal/ssa/opGen.go | 28 ++
src/cmd/compile/internal/ssa/rewriteARM64.go | 156 +++---
src/cmd/compile/internal/ssa/rewritePPC64.go | 12 +-
src/cmd/compile/internal/ssa/rewriteS390X.go | 316 ++++++------
src/cmd/compile/internal/syntax/parser.go | 5 +-
src/cmd/dist/test.go | 5 +-
src/cmd/go/alldocs.go | 9 +-
src/cmd/go/get.go | 2 +-
src/cmd/go/go_test.go | 205 +++-----
src/cmd/go/main.go | 2 +-
src/cmd/go/testdata/timeoutbench_test.go | 10 +
src/cmd/link/internal/ld/config.go | 2 +
src/crypto/x509/root_linux.go | 2 +-
src/database/sql/ctxutil.go | 54 +-
src/database/sql/sql.go | 151 ++++--
src/database/sql/sql_test.go | 125 ++++-
src/encoding/xml/marshal.go | 26 +-
src/encoding/xml/marshal_test.go | 544 ++++++++++++++++++++-
src/go/build/build.go | 2 +-
src/reflect/all_test.go | 13 +-
src/reflect/type.go | 1 +
src/runtime/mgc.go | 10 +-
src/runtime/testdata/testprogcgo/threadpprof.go | 2 +-
src/runtime/testdata/testprogcgo/traceback.go | 6 +-
src/testing/testing.go | 1 +
.../golang_org/x/crypto/curve25519/const_amd64.h | 8 +
.../golang_org/x/crypto/curve25519/const_amd64.s | 4 +-
.../golang_org/x/crypto/curve25519/freeze_amd64.s | 4 +-
.../x/crypto/curve25519/ladderstep_amd64.s | 20 +-
.../golang_org/x/crypto/curve25519/mul_amd64.s | 4 +-
.../golang_org/x/crypto/curve25519/square_amd64.s | 4 +-
test/fixedbugs/issue18808.go | 63 +++
test/fixedbugs/issue18906.go | 36 ++
test/fixedbugs/issue18915.go | 21 +
test/fixedbugs/issue6036.go | 2 +-
test/writebarrier.go | 16 +
47 files changed, 1527 insertions(+), 629 deletions(-)
diff --git a/VERSION b/VERSION
index 5f833a0..854106e 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-go1.8rc3
\ No newline at end of file
+go1.8
\ No newline at end of file
diff --git a/doc/conduct.html b/doc/conduct.html
index 5b81681..c40b007 100644
--- a/doc/conduct.html
+++ b/doc/conduct.html
@@ -148,29 +148,26 @@ These actions are explicitly forbidden in Go spaces:
<p>
The Go spaces are not free speech venues; they are for discussion about Go.
-These spaces have moderators.
-The goal of the moderators is to facilitate civil discussion about Go.
+Each of these spaces have their own moderators.
</p>
<p>
When using the official Go spaces you should act in the spirit of the “Gopher
values”.
-If you conduct yourself in a way that is explicitly forbidden by the CoC,
-you will be warned and asked to stop.
-If you do not stop, you will be removed from our community spaces temporarily.
-Repeated, willful breaches of the CoC will result in a permanent ban.
+If a reported conflict cannot be resolved amicably, the CoC Working Group
+may make a recommendation to the relevant forum moderators.
</p>
<p>
-Moderators are held to a higher standard than other community members.
-If a moderator creates an inappropriate situation, they should expect less
-leeway than others, and should expect to be removed from their position if they
-cannot adhere to the CoC.
+CoC Working Group members and forum moderators are held to a higher standard than other community members.
+If a working group member or moderator creates an inappropriate situation, they
+should expect less leeway than others, and should expect to be removed from
+their position if they cannot adhere to the CoC.
</p>
<p>
-Complaints about moderator actions must be handled using the reporting process
-below.
+Complaints about working group member or moderator actions must be handled
+using the reporting process below.
</p>
<h2 id="reporting">Reporting issues</h2>
@@ -185,8 +182,6 @@ satisfaction of all parties. They are:
<ul>
<li>Aditya Mukerjee <dev at chimeracoder.net>
<li>Andrew Gerrand <adg at golang.org>
- <li>Dave Cheney <dave at cheney.net>
- <li>Jason Buberel <jbuberel at google.com>
<li>Peggy Li <peggyli.224 at gmail.com>
<li>Sarah Adams <sadams.codes at gmail.com>
<li>Steve Francia <steve.francia at gmail.com>
@@ -201,13 +196,10 @@ particular individual or group.
</p>
<ul>
-<li>Mail <a href="mailto:conduct at golang.org">conduct at golang.org</a> or
- <a href="https://golang.org/s/conduct-report">submit an anonymous report</a>.
+<li>Mail <a href="mailto:conduct at golang.org">conduct at golang.org</a>.
<ul>
<li>Your message will reach the Working Group.
<li>Reports are confidential within the Working Group.
- <li>Should you choose to remain anonymous then the Working Group cannot
- notify you of the outcome of your report.
<li>You may contact a member of the group directly if you do not feel
comfortable contacting the group as a whole. That member will then raise
the issue with the Working Group as a whole, preserving the privacy of the
@@ -229,11 +221,8 @@ particular individual or group.
<li>The Working Group will reach a decision as to how to act. These may include:
<ul>
<li>Nothing.
- <li>A request for a private or public apology.
- <li>A private or public warning.
- <li>An imposed vacation (for instance, asking someone to abstain for a week
- from a mailing list or IRC).
- <li>A permanent or temporary ban from some or all Go spaces.
+ <li>Passing the report along to the offender.
+ <li>A recommendation of action to the relevant forum moderators.
</ul>
<li>The Working Group will reach out to the original reporter to let them know
the decision.
@@ -246,7 +235,6 @@ particular individual or group.
conflicts in the most harmonious way possible.</b>
We hope that in most cases issues may be resolved through polite discussion and
mutual agreement.
-Bannings and other forceful measures are to be employed only as a last resort.
</p>
<p>
diff --git a/doc/devel/release.html b/doc/devel/release.html
index 51957df..d046149 100644
--- a/doc/devel/release.html
+++ b/doc/devel/release.html
@@ -30,6 +30,13 @@ to fix critical security problems in both Go 1.4 and Go 1.5 as they arise.
See the <a href="/security">security policy</a> for more details.
</p>
+<h2 id="go1.8">go1.8 (released 2017/02/16)</h2>
+
+<p>
+Go 1.8 is a major release of Go.
+Read the <a href="/doc/go1.8">Go 1.8 Release Notes</a> for more information.
+</p>
+
<h2 id="go1.7">go1.7 (released 2016/08/15)</h2>
<p>
@@ -69,6 +76,13 @@ See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.7.4">Go
1.7.4 milestone</a> on our issue tracker for details.
</p>
+<p>
+go1.7.5 (released 2017/01/26) includes fixes to the compiler, runtime,
+and the <code>crypto/x509</code> and <code>time</code> packages.
+See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.7.5">Go
+1.7.5 milestone</a> on our issue tracker for details.
+</p>
+
<h2 id="go1.6">go1.6 (released 2016/02/17)</h2>
<p>
diff --git a/doc/go1.8.html b/doc/go1.8.html
index bc40378..cf4c669 100644
--- a/doc/go1.8.html
+++ b/doc/go1.8.html
@@ -15,12 +15,7 @@ Do not send CLs removing the interior tags from such phrases.
ul li { margin: 0.5em 0; }
</style>
-<h2 id="introduction">DRAFT RELEASE NOTES - Introduction to Go 1.8</h2>
-
-<p><strong>
-Go 1.8 is not yet released. These are work-in-progress
-release notes. Go 1.8 is expected to be released in February 2017.
-</strong></p>
+<h2 id="introduction">Introduction to Go 1.8</h2>
<p>
The latest Go release, version 1.8, arrives six months after <a href="go1.7">Go 1.7</a>.
@@ -799,9 +794,9 @@ Optimizations and minor bug fixes are not listed.
hardware support for AES-GCM is present.
</p>
- <p> <!-- CL 27315 -->
+ <p> <!-- CL 27315, CL 35290 -->
AES-128-CBC cipher suites with SHA-256 are also
- now supported.
+ now supported, but disabled by default.
</p>
</dd>
@@ -859,11 +854,12 @@ crypto/x509: return error for missing SerialNumber (CL 27238)
<p>
The <a href="/pkg/database/sql#IsolationLevel"><code>IsolationLevel</code></a>
can now be set when starting a transaction by setting the isolation level
- on the <code>Context</code> then passing that <code>Context</code> to
- <a href="/pkg/database/sql#DB.BeginContext"><code>DB.BeginContext</code></a>.
+ on <a href="/pkg/database/sql#TxOptions.Isolation"><code>TxOptions.Isolation</code></a> and passing
+ it to <a href="/pkg/database/sql#DB.BeginTx"><code>DB.BeginTx</code></a>.
An error will be returned if an isolation level is selected that the driver
does not support. A read-only attribute may also be set on the transaction
- with <a href="/pkg/database/sql/#ReadOnlyContext"><code>ReadOnlyContext</code></a>.
+ by setting <a href="/pkg/database/sql/#TxOptions.ReadOnly"><code>TxOptions.ReadOnly</code></a>
+ to true.
</p>
<p>
Queries now expose the SQL column type information for drivers that support it.
diff --git a/doc/install-source.html b/doc/install-source.html
index efe864c..45c5bbb 100644
--- a/doc/install-source.html
+++ b/doc/install-source.html
@@ -221,7 +221,7 @@ To build without <code>cgo</code>, set the environment variable
Change to the directory that will be its parent
and make sure the <code>go</code> directory does not exist.
Then clone the repository and check out the latest release tag
-(<code class="versionTag">go1.7.4</code>, for example):</p>
+(<code class="versionTag">go1.8</code>, for example):</p>
<pre>
$ git clone https://go.googlesource.com/go
@@ -409,7 +409,7 @@ New releases are announced on the
<a href="//groups.google.com/group/golang-announce">golang-announce</a>
mailing list.
Each announcement mentions the latest release tag, for instance,
-<code class="versionTag">go1.7.4</code>.
+<code class="versionTag">go1.8</code>.
</p>
<p>
diff --git a/src/cmd/compile/internal/gc/sinit.go b/src/cmd/compile/internal/gc/sinit.go
index 6b3c426..416e2b2 100644
--- a/src/cmd/compile/internal/gc/sinit.go
+++ b/src/cmd/compile/internal/gc/sinit.go
@@ -585,7 +585,7 @@ func isliteral(n *Node) bool {
}
func (n *Node) isSimpleName() bool {
- return n.Op == ONAME && n.Addable && n.Class != PAUTOHEAP
+ return n.Op == ONAME && n.Addable && n.Class != PAUTOHEAP && n.Class != PEXTERN
}
func litas(l *Node, r *Node, init *Nodes) {
diff --git a/src/cmd/compile/internal/s390x/ssa.go b/src/cmd/compile/internal/s390x/ssa.go
index e2d3c28..a9dafa8 100644
--- a/src/cmd/compile/internal/s390x/ssa.go
+++ b/src/cmd/compile/internal/s390x/ssa.go
@@ -424,7 +424,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
p.To.Type = obj.TYPE_MEM
p.To.Reg = v.Args[0].Reg()
gc.AddAux2(&p.To, v, sc.Off())
- case ssa.OpCopy, ssa.OpS390XMOVDconvert:
+ case ssa.OpCopy, ssa.OpS390XMOVDconvert, ssa.OpS390XMOVDreg:
if v.Type.IsMemory() {
return
}
@@ -433,6 +433,11 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
if x != y {
opregreg(moveByType(v.Type), y, x)
}
+ case ssa.OpS390XMOVDnop:
+ if v.Reg() != v.Args[0].Reg() {
+ v.Fatalf("input[0] and output not in same register %s", v.LongString())
+ }
+ // nothing to do
case ssa.OpLoadReg:
if v.Type.IsFlags() {
v.Fatalf("load flags not implemented: %v", v.LongString())
diff --git a/src/cmd/compile/internal/ssa/gen/ARM64.rules b/src/cmd/compile/internal/ssa/gen/ARM64.rules
index c36b6f7..940c060 100644
--- a/src/cmd/compile/internal/ssa/gen/ARM64.rules
+++ b/src/cmd/compile/internal/ssa/gen/ARM64.rules
@@ -529,109 +529,147 @@
// can be encoded in the instructions
// since this rewriting takes place before stack allocation, the offset to SP is unknown,
// so don't do it for args and locals with unaligned offset
-(MOVBload [off1] {sym} (ADDconst [off2] ptr) mem) -> (MOVBload [off1+off2] {sym} ptr mem)
-(MOVBUload [off1] {sym} (ADDconst [off2] ptr) mem) -> (MOVBUload [off1+off2] {sym} ptr mem)
+(MOVBload [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(off1+off2) ->
+ (MOVBload [off1+off2] {sym} ptr mem)
+(MOVBUload [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(off1+off2) ->
+ (MOVBUload [off1+off2] {sym} ptr mem)
(MOVHload [off1] {sym} (ADDconst [off2] ptr) mem)
- && (off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym) ->
+ && is32Bit(off1+off2)
+ && ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)) ->
(MOVHload [off1+off2] {sym} ptr mem)
(MOVHUload [off1] {sym} (ADDconst [off2] ptr) mem)
- && (off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym) ->
+ && is32Bit(off1+off2)
+ && ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)) ->
(MOVHUload [off1+off2] {sym} ptr mem)
(MOVWload [off1] {sym} (ADDconst [off2] ptr) mem)
- && (off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym) ->
+ && is32Bit(off1+off2)
+ && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)) ->
(MOVWload [off1+off2] {sym} ptr mem)
(MOVWUload [off1] {sym} (ADDconst [off2] ptr) mem)
- && (off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym) ->
+ && is32Bit(off1+off2)
+ && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)) ->
(MOVWUload [off1+off2] {sym} ptr mem)
(MOVDload [off1] {sym} (ADDconst [off2] ptr) mem)
- && (off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym) ->
+ && is32Bit(off1+off2)
+ && ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)) ->
(MOVDload [off1+off2] {sym} ptr mem)
(FMOVSload [off1] {sym} (ADDconst [off2] ptr) mem)
- && (off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym) ->
+ && is32Bit(off1+off2)
+ && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)) ->
(FMOVSload [off1+off2] {sym} ptr mem)
(FMOVDload [off1] {sym} (ADDconst [off2] ptr) mem)
- && (off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym) ->
+ && is32Bit(off1+off2)
+ && ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)) ->
(FMOVDload [off1+off2] {sym} ptr mem)
-(MOVBstore [off1] {sym} (ADDconst [off2] ptr) val mem) -> (MOVBstore [off1+off2] {sym} ptr val mem)
+(MOVBstore [off1] {sym} (ADDconst [off2] ptr) val mem) && is32Bit(off1+off2) ->
+ (MOVBstore [off1+off2] {sym} ptr val mem)
(MOVHstore [off1] {sym} (ADDconst [off2] ptr) val mem)
- && (off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym) ->
+ && is32Bit(off1+off2)
+ && ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)) ->
(MOVHstore [off1+off2] {sym} ptr val mem)
(MOVWstore [off1] {sym} (ADDconst [off2] ptr) val mem)
- && (off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym) ->
+ && is32Bit(off1+off2)
+ && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)) ->
(MOVWstore [off1+off2] {sym} ptr val mem)
(MOVDstore [off1] {sym} (ADDconst [off2] ptr) val mem)
- && (off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym) ->
+ && is32Bit(off1+off2)
+ && ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)) ->
(MOVDstore [off1+off2] {sym} ptr val mem)
(FMOVSstore [off1] {sym} (ADDconst [off2] ptr) val mem)
- && (off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym) ->
+ && is32Bit(off1+off2)
+ && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)) ->
(FMOVSstore [off1+off2] {sym} ptr val mem)
(FMOVDstore [off1] {sym} (ADDconst [off2] ptr) val mem)
- && (off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym) ->
+ && is32Bit(off1+off2)
+ && ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)) ->
(FMOVDstore [off1+off2] {sym} ptr val mem)
-(MOVBstorezero [off1] {sym} (ADDconst [off2] ptr) mem) -> (MOVBstorezero [off1+off2] {sym} ptr mem)
+(MOVBstorezero [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(off1+off2) ->
+ (MOVBstorezero [off1+off2] {sym} ptr mem)
(MOVHstorezero [off1] {sym} (ADDconst [off2] ptr) mem)
- && (off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym) ->
+ && is32Bit(off1+off2)
+ && ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)) ->
(MOVHstorezero [off1+off2] {sym} ptr mem)
(MOVWstorezero [off1] {sym} (ADDconst [off2] ptr) mem)
- && (off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym) ->
+ && is32Bit(off1+off2)
+ && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)) ->
(MOVWstorezero [off1+off2] {sym} ptr mem)
(MOVDstorezero [off1] {sym} (ADDconst [off2] ptr) mem)
- && (off1+off2)%2==8 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym) ->
+ && is32Bit(off1+off2)
+ && ((off1+off2)%2==8 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)) ->
(MOVDstorezero [off1+off2] {sym} ptr mem)
-(MOVBload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) ->
+(MOVBload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2)
+ && is32Bit(off1+off2) ->
(MOVBload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
-(MOVBUload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) ->
+(MOVBUload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2)
+ && is32Bit(off1+off2) ->
(MOVBUload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
(MOVHload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2)
+ && is32Bit(off1+off2)
&& ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1)) ->
(MOVHload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
(MOVHUload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2)
+ && is32Bit(off1+off2)
&& ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1)) ->
(MOVHUload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
(MOVWload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2)
+ && is32Bit(off1+off2)
&& ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1)) ->
(MOVWload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
(MOVWUload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2)
+ && is32Bit(off1+off2)
&& ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1)) ->
(MOVWUload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
(MOVDload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2)
+ && is32Bit(off1+off2)
&& ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1)) ->
(MOVDload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
(FMOVSload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2)
+ && is32Bit(off1+off2)
&& ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1)) ->
(FMOVSload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
(FMOVDload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2)
+ && is32Bit(off1+off2)
&& ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1)) ->
(FMOVDload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
-(MOVBstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) ->
+(MOVBstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2)
+ && is32Bit(off1+off2) ->
(MOVBstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
(MOVHstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2)
+ && is32Bit(off1+off2)
&& ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1)) ->
(MOVHstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
(MOVWstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2)
+ && is32Bit(off1+off2)
&& ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1)) ->
(MOVWstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
(MOVDstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2)
+ && is32Bit(off1+off2)
&& ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1)) ->
(MOVDstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
(FMOVSstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2)
+ && is32Bit(off1+off2)
&& ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1)) ->
(FMOVSstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
(FMOVDstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2)
+ && is32Bit(off1+off2)
&& ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1)) ->
(FMOVDstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
-(MOVBstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) ->
+(MOVBstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2)
+ && is32Bit(off1+off2) ->
(MOVBstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
(MOVHstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2)
+ && is32Bit(off1+off2)
&& ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1)) ->
(MOVHstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
(MOVWstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2)
+ && is32Bit(off1+off2)
&& ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1)) ->
(MOVWstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
(MOVDstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2)
+ && is32Bit(off1+off2)
&& ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1)) ->
(MOVDstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
diff --git a/src/cmd/compile/internal/ssa/gen/PPC64.rules b/src/cmd/compile/internal/ssa/gen/PPC64.rules
index 0e0f1f9..cad753e 100644
--- a/src/cmd/compile/internal/ssa/gen/PPC64.rules
+++ b/src/cmd/compile/internal/ssa/gen/PPC64.rules
@@ -338,9 +338,9 @@
(Geq32F x y) -> (FGreaterEqual (FCMPU x y))
(Geq64F x y) -> (FGreaterEqual (FCMPU x y))
-(Geq8U x y) -> (GreaterEqual (CMPU (ZeroExt8to32 x) (ZeroExt8to32 y)))
-(Geq16U x y) -> (GreaterEqual (CMPU (ZeroExt16to32 x) (ZeroExt16to32 y)))
-(Geq32U x y) -> (GreaterEqual (CMPU x y))
+(Geq8U x y) -> (GreaterEqual (CMPWU (ZeroExt8to32 x) (ZeroExt8to32 y)))
+(Geq16U x y) -> (GreaterEqual (CMPWU (ZeroExt16to32 x) (ZeroExt16to32 y)))
+(Geq32U x y) -> (GreaterEqual (CMPWU x y))
(Geq64U x y) -> (GreaterEqual (CMPU x y))
// Absorb pseudo-ops into blocks.
diff --git a/src/cmd/compile/internal/ssa/gen/S390X.rules b/src/cmd/compile/internal/ssa/gen/S390X.rules
index be0d581..c26515c 100644
--- a/src/cmd/compile/internal/ssa/gen/S390X.rules
+++ b/src/cmd/compile/internal/ssa/gen/S390X.rules
@@ -312,9 +312,12 @@
// Lowering loads
(Load <t> ptr mem) && (is64BitInt(t) || isPtr(t)) -> (MOVDload ptr mem)
-(Load <t> ptr mem) && is32BitInt(t) -> (MOVWZload ptr mem)
-(Load <t> ptr mem) && is16BitInt(t) -> (MOVHZload ptr mem)
-(Load <t> ptr mem) && (t.IsBoolean() || is8BitInt(t)) -> (MOVBZload ptr mem)
+(Load <t> ptr mem) && is32BitInt(t) && isSigned(t) -> (MOVWload ptr mem)
+(Load <t> ptr mem) && is32BitInt(t) && !isSigned(t) -> (MOVWZload ptr mem)
+(Load <t> ptr mem) && is16BitInt(t) && isSigned(t) -> (MOVHload ptr mem)
+(Load <t> ptr mem) && is16BitInt(t) && !isSigned(t) -> (MOVHZload ptr mem)
+(Load <t> ptr mem) && is8BitInt(t) && isSigned(t) -> (MOVBload ptr mem)
+(Load <t> ptr mem) && (t.IsBoolean() || (is8BitInt(t) && !isSigned(t))) -> (MOVBZload ptr mem)
(Load <t> ptr mem) && is32BitFloat(t) -> (FMOVSload ptr mem)
(Load <t> ptr mem) && is64BitFloat(t) -> (FMOVDload ptr mem)
@@ -445,16 +448,20 @@
// ***************************
// TODO: Should the optimizations be a separate pass?
+// if a register move has only 1 use, just use the same register without emitting instruction
+// MOVDnop doesn't emit instruction, only for ensuring the type.
+(MOVDreg x) && x.Uses == 1 -> (MOVDnop x)
+
// Fold sign extensions into conditional moves of constants.
// Designed to remove the MOVBZreg inserted by the If lowering.
-(MOVBZreg x:(MOVDLT (MOVDconst [c]) (MOVDconst [d]) _)) && int64(uint8(c)) == c && int64(uint8(d)) == d -> x
-(MOVBZreg x:(MOVDLE (MOVDconst [c]) (MOVDconst [d]) _)) && int64(uint8(c)) == c && int64(uint8(d)) == d -> x
-(MOVBZreg x:(MOVDGT (MOVDconst [c]) (MOVDconst [d]) _)) && int64(uint8(c)) == c && int64(uint8(d)) == d -> x
-(MOVBZreg x:(MOVDGE (MOVDconst [c]) (MOVDconst [d]) _)) && int64(uint8(c)) == c && int64(uint8(d)) == d -> x
-(MOVBZreg x:(MOVDEQ (MOVDconst [c]) (MOVDconst [d]) _)) && int64(uint8(c)) == c && int64(uint8(d)) == d -> x
-(MOVBZreg x:(MOVDNE (MOVDconst [c]) (MOVDconst [d]) _)) && int64(uint8(c)) == c && int64(uint8(d)) == d -> x
-(MOVBZreg x:(MOVDGTnoinv (MOVDconst [c]) (MOVDconst [d]) _)) && int64(uint8(c)) == c && int64(uint8(d)) == d -> x
-(MOVBZreg x:(MOVDGEnoinv (MOVDconst [c]) (MOVDconst [d]) _)) && int64(uint8(c)) == c && int64(uint8(d)) == d -> x
+(MOVBZreg x:(MOVDLT (MOVDconst [c]) (MOVDconst [d]) _)) && int64(uint8(c)) == c && int64(uint8(d)) == d -> (MOVDreg x)
+(MOVBZreg x:(MOVDLE (MOVDconst [c]) (MOVDconst [d]) _)) && int64(uint8(c)) == c && int64(uint8(d)) == d -> (MOVDreg x)
+(MOVBZreg x:(MOVDGT (MOVDconst [c]) (MOVDconst [d]) _)) && int64(uint8(c)) == c && int64(uint8(d)) == d -> (MOVDreg x)
+(MOVBZreg x:(MOVDGE (MOVDconst [c]) (MOVDconst [d]) _)) && int64(uint8(c)) == c && int64(uint8(d)) == d -> (MOVDreg x)
+(MOVBZreg x:(MOVDEQ (MOVDconst [c]) (MOVDconst [d]) _)) && int64(uint8(c)) == c && int64(uint8(d)) == d -> (MOVDreg x)
+(MOVBZreg x:(MOVDNE (MOVDconst [c]) (MOVDconst [d]) _)) && int64(uint8(c)) == c && int64(uint8(d)) == d -> (MOVDreg x)
+(MOVBZreg x:(MOVDGTnoinv (MOVDconst [c]) (MOVDconst [d]) _)) && int64(uint8(c)) == c && int64(uint8(d)) == d -> (MOVDreg x)
+(MOVBZreg x:(MOVDGEnoinv (MOVDconst [c]) (MOVDconst [d]) _)) && int64(uint8(c)) == c && int64(uint8(d)) == d -> (MOVDreg x)
// Fold boolean tests into blocks.
(NE (CMPWconst [0] (MOVDLT (MOVDconst [0]) (MOVDconst [1]) cmp)) yes no) -> (LT cmp yes no)
@@ -572,46 +579,46 @@
(MOVDNE x y (InvertFlags cmp)) -> (MOVDNE x y cmp)
// don't extend after proper load
-(MOVBreg x:(MOVBload _ _)) -> x
-(MOVBZreg x:(MOVBZload _ _)) -> x
-(MOVHreg x:(MOVBload _ _)) -> x
-(MOVHreg x:(MOVBZload _ _)) -> x
-(MOVHreg x:(MOVHload _ _)) -> x
-(MOVHZreg x:(MOVBZload _ _)) -> x
-(MOVHZreg x:(MOVHZload _ _)) -> x
-(MOVWreg x:(MOVBload _ _)) -> x
-(MOVWreg x:(MOVBZload _ _)) -> x
-(MOVWreg x:(MOVHload _ _)) -> x
-(MOVWreg x:(MOVHZload _ _)) -> x
-(MOVWreg x:(MOVWload _ _)) -> x
-(MOVWZreg x:(MOVBZload _ _)) -> x
-(MOVWZreg x:(MOVHZload _ _)) -> x
-(MOVWZreg x:(MOVWZload _ _)) -> x
+(MOVBreg x:(MOVBload _ _)) -> (MOVDreg x)
+(MOVBZreg x:(MOVBZload _ _)) -> (MOVDreg x)
+(MOVHreg x:(MOVBload _ _)) -> (MOVDreg x)
+(MOVHreg x:(MOVBZload _ _)) -> (MOVDreg x)
+(MOVHreg x:(MOVHload _ _)) -> (MOVDreg x)
+(MOVHZreg x:(MOVBZload _ _)) -> (MOVDreg x)
+(MOVHZreg x:(MOVHZload _ _)) -> (MOVDreg x)
+(MOVWreg x:(MOVBload _ _)) -> (MOVDreg x)
+(MOVWreg x:(MOVBZload _ _)) -> (MOVDreg x)
+(MOVWreg x:(MOVHload _ _)) -> (MOVDreg x)
+(MOVWreg x:(MOVHZload _ _)) -> (MOVDreg x)
+(MOVWreg x:(MOVWload _ _)) -> (MOVDreg x)
+(MOVWZreg x:(MOVBZload _ _)) -> (MOVDreg x)
+(MOVWZreg x:(MOVHZload _ _)) -> (MOVDreg x)
+(MOVWZreg x:(MOVWZload _ _)) -> (MOVDreg x)
// don't extend if argument is already extended
-(MOVBreg x:(Arg <t>)) && is8BitInt(t) && isSigned(t) -> x
-(MOVBZreg x:(Arg <t>)) && is8BitInt(t) && !isSigned(t) -> x
-(MOVHreg x:(Arg <t>)) && (is8BitInt(t) || is16BitInt(t)) && isSigned(t) -> x
-(MOVHZreg x:(Arg <t>)) && (is8BitInt(t) || is16BitInt(t)) && !isSigned(t) -> x
-(MOVWreg x:(Arg <t>)) && (is8BitInt(t) || is16BitInt(t) || is32BitInt(t)) && isSigned(t) -> x
-(MOVWZreg x:(Arg <t>)) && (is8BitInt(t) || is16BitInt(t) || is32BitInt(t)) && !isSigned(t) -> x
+(MOVBreg x:(Arg <t>)) && is8BitInt(t) && isSigned(t) -> (MOVDreg x)
+(MOVBZreg x:(Arg <t>)) && is8BitInt(t) && !isSigned(t) -> (MOVDreg x)
+(MOVHreg x:(Arg <t>)) && (is8BitInt(t) || is16BitInt(t)) && isSigned(t) -> (MOVDreg x)
+(MOVHZreg x:(Arg <t>)) && (is8BitInt(t) || is16BitInt(t)) && !isSigned(t) -> (MOVDreg x)
+(MOVWreg x:(Arg <t>)) && (is8BitInt(t) || is16BitInt(t) || is32BitInt(t)) && isSigned(t) -> (MOVDreg x)
+(MOVWZreg x:(Arg <t>)) && (is8BitInt(t) || is16BitInt(t) || is32BitInt(t)) && !isSigned(t) -> (MOVDreg x)
// fold double extensions
-(MOVBreg x:(MOVBreg _)) -> x
-(MOVBZreg x:(MOVBZreg _)) -> x
-(MOVHreg x:(MOVBreg _)) -> x
-(MOVHreg x:(MOVBZreg _)) -> x
-(MOVHreg x:(MOVHreg _)) -> x
-(MOVHZreg x:(MOVBZreg _)) -> x
-(MOVHZreg x:(MOVHZreg _)) -> x
-(MOVWreg x:(MOVBreg _)) -> x
-(MOVWreg x:(MOVBZreg _)) -> x
-(MOVWreg x:(MOVHreg _)) -> x
-(MOVWreg x:(MOVHreg _)) -> x
-(MOVWreg x:(MOVWreg _)) -> x
-(MOVWZreg x:(MOVBZreg _)) -> x
-(MOVWZreg x:(MOVHZreg _)) -> x
-(MOVWZreg x:(MOVWZreg _)) -> x
+(MOVBreg x:(MOVBreg _)) -> (MOVDreg x)
+(MOVBZreg x:(MOVBZreg _)) -> (MOVDreg x)
+(MOVHreg x:(MOVBreg _)) -> (MOVDreg x)
+(MOVHreg x:(MOVBZreg _)) -> (MOVDreg x)
+(MOVHreg x:(MOVHreg _)) -> (MOVDreg x)
+(MOVHZreg x:(MOVBZreg _)) -> (MOVDreg x)
+(MOVHZreg x:(MOVHZreg _)) -> (MOVDreg x)
+(MOVWreg x:(MOVBreg _)) -> (MOVDreg x)
+(MOVWreg x:(MOVBZreg _)) -> (MOVDreg x)
+(MOVWreg x:(MOVHreg _)) -> (MOVDreg x)
+(MOVWreg x:(MOVHreg _)) -> (MOVDreg x)
+(MOVWreg x:(MOVWreg _)) -> (MOVDreg x)
+(MOVWZreg x:(MOVBZreg _)) -> (MOVDreg x)
+(MOVWZreg x:(MOVHZreg _)) -> (MOVDreg x)
+(MOVWZreg x:(MOVWZreg _)) -> (MOVDreg x)
// fold extensions into constants
(MOVBreg (MOVDconst [c])) -> (MOVDconst [int64(int8(c))])
@@ -641,10 +648,10 @@
(MOVWZreg x:(MOVWZloadidx [off] {sym} ptr idx mem)) && x.Uses == 1 && clobber(x) -> @x.Block (MOVWZloadidx <v.Type> [off] {sym} ptr idx mem)
// replace load from same location as preceding store with copy
-(MOVBZload [off] {sym} ptr (MOVBstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) -> x
-(MOVHZload [off] {sym} ptr (MOVHstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) -> x
-(MOVWZload [off] {sym} ptr (MOVWstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) -> x
-(MOVDload [off] {sym} ptr (MOVDstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) -> x
+(MOVBZload [off] {sym} ptr (MOVBstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) -> (MOVDreg x)
+(MOVHZload [off] {sym} ptr (MOVHstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) -> (MOVDreg x)
+(MOVWZload [off] {sym} ptr (MOVWstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) -> (MOVDreg x)
+(MOVDload [off] {sym} ptr (MOVDstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) -> (MOVDreg x)
// Don't extend before storing
(MOVWstore [off] {sym} ptr (MOVWreg x) mem) -> (MOVWstore [off] {sym} ptr x mem)
diff --git a/src/cmd/compile/internal/ssa/gen/S390XOps.go b/src/cmd/compile/internal/ssa/gen/S390XOps.go
index 7a25c26..29383f6 100644
--- a/src/cmd/compile/internal/ssa/gen/S390XOps.go
+++ b/src/cmd/compile/internal/ssa/gen/S390XOps.go
@@ -311,6 +311,9 @@ func init() {
{name: "MOVHZreg", argLength: 1, reg: gp11sp, asm: "MOVHZ", typ: "UInt64"}, // zero extend arg0 from int16 to int64
{name: "MOVWreg", argLength: 1, reg: gp11sp, asm: "MOVW", typ: "Int64"}, // sign extend arg0 from int32 to int64
{name: "MOVWZreg", argLength: 1, reg: gp11sp, asm: "MOVWZ", typ: "UInt64"}, // zero extend arg0 from int32 to int64
+ {name: "MOVDreg", argLength: 1, reg: gp11sp, asm: "MOVD"}, // move from arg0
+
+ {name: "MOVDnop", argLength: 1, reg: gp11, resultInArg0: true}, // nop, return arg0 in same register
{name: "MOVDconst", reg: gp01, asm: "MOVD", typ: "UInt64", aux: "Int64", rematerializeable: true}, // auxint
diff --git a/src/cmd/compile/internal/ssa/opGen.go b/src/cmd/compile/internal/ssa/opGen.go
index a63c5b9..9d11d03 100644
--- a/src/cmd/compile/internal/ssa/opGen.go
+++ b/src/cmd/compile/internal/ssa/opGen.go
@@ -1473,6 +1473,8 @@ const (
OpS390XMOVHZreg
OpS390XMOVWreg
OpS390XMOVWZreg
+ OpS390XMOVDreg
+ OpS390XMOVDnop
OpS390XMOVDconst
OpS390XCFDBRA
OpS390XCGDBRA
@@ -18571,6 +18573,32 @@ var opcodeTable = [...]opInfo{
},
},
{
+ name: "MOVDreg",
+ argLen: 1,
+ asm: s390x.AMOVD,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 54271}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14 SP
+ },
+ outputs: []outputInfo{
+ {0, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+ },
+ },
+ },
+ {
+ name: "MOVDnop",
+ argLen: 1,
+ resultInArg0: true,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+ },
+ outputs: []outputInfo{
+ {0, 21503}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14
+ },
+ },
+ },
+ {
name: "MOVDconst",
auxType: auxInt64,
argLen: 0,
diff --git a/src/cmd/compile/internal/ssa/rewriteARM64.go b/src/cmd/compile/internal/ssa/rewriteARM64.go
index dd5aa28..862c645 100644
--- a/src/cmd/compile/internal/ssa/rewriteARM64.go
+++ b/src/cmd/compile/internal/ssa/rewriteARM64.go
@@ -2625,7 +2625,7 @@ func rewriteValueARM64_OpARM64FMOVDload(v *Value, config *Config) bool {
b := v.Block
_ = b
// match: (FMOVDload [off1] {sym} (ADDconst [off2] ptr) mem)
- // cond: (off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)
+ // cond: is32Bit(off1+off2) && ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym))
// result: (FMOVDload [off1+off2] {sym} ptr mem)
for {
off1 := v.AuxInt
@@ -2637,7 +2637,7 @@ func rewriteValueARM64_OpARM64FMOVDload(v *Value, config *Config) bool {
off2 := v_0.AuxInt
ptr := v_0.Args[0]
mem := v.Args[1]
- if !((off1+off2)%8 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym) && !isAuto(sym)) {
+ if !(is32Bit(off1+off2) && ((off1+off2)%8 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym) && !isAuto(sym))) {
break
}
v.reset(OpARM64FMOVDload)
@@ -2648,7 +2648,7 @@ func rewriteValueARM64_OpARM64FMOVDload(v *Value, config *Config) bool {
return true
}
// match: (FMOVDload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
- // cond: canMergeSym(sym1,sym2) && ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1))
+ // cond: canMergeSym(sym1,sym2) && is32Bit(off1+off2) && ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1))
// result: (FMOVDload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
for {
off1 := v.AuxInt
@@ -2661,7 +2661,7 @@ func rewriteValueARM64_OpARM64FMOVDload(v *Value, config *Config) bool {
sym2 := v_0.Aux
ptr := v_0.Args[0]
mem := v.Args[1]
- if !(canMergeSym(sym1, sym2) && ((off1+off2)%8 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym1) && !isAuto(sym1))) {
+ if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2) && ((off1+off2)%8 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym1) && !isAuto(sym1))) {
break
}
v.reset(OpARM64FMOVDload)
@@ -2677,7 +2677,7 @@ func rewriteValueARM64_OpARM64FMOVDstore(v *Value, config *Config) bool {
b := v.Block
_ = b
// match: (FMOVDstore [off1] {sym} (ADDconst [off2] ptr) val mem)
- // cond: (off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)
+ // cond: is32Bit(off1+off2) && ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym))
// result: (FMOVDstore [off1+off2] {sym} ptr val mem)
for {
off1 := v.AuxInt
@@ -2690,7 +2690,7 @@ func rewriteValueARM64_OpARM64FMOVDstore(v *Value, config *Config) bool {
ptr := v_0.Args[0]
val := v.Args[1]
mem := v.Args[2]
- if !((off1+off2)%8 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym) && !isAuto(sym)) {
+ if !(is32Bit(off1+off2) && ((off1+off2)%8 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym) && !isAuto(sym))) {
break
}
v.reset(OpARM64FMOVDstore)
@@ -2702,7 +2702,7 @@ func rewriteValueARM64_OpARM64FMOVDstore(v *Value, config *Config) bool {
return true
}
// match: (FMOVDstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
- // cond: canMergeSym(sym1,sym2) && ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1))
+ // cond: canMergeSym(sym1,sym2) && is32Bit(off1+off2) && ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1))
// result: (FMOVDstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
for {
off1 := v.AuxInt
@@ -2716,7 +2716,7 @@ func rewriteValueARM64_OpARM64FMOVDstore(v *Value, config *Config) bool {
ptr := v_0.Args[0]
val := v.Args[1]
mem := v.Args[2]
- if !(canMergeSym(sym1, sym2) && ((off1+off2)%8 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym1) && !isAuto(sym1))) {
+ if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2) && ((off1+off2)%8 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym1) && !isAuto(sym1))) {
break
}
v.reset(OpARM64FMOVDstore)
@@ -2733,7 +2733,7 @@ func rewriteValueARM64_OpARM64FMOVSload(v *Value, config *Config) bool {
b := v.Block
_ = b
// match: (FMOVSload [off1] {sym} (ADDconst [off2] ptr) mem)
- // cond: (off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)
+ // cond: is32Bit(off1+off2) && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym))
// result: (FMOVSload [off1+off2] {sym} ptr mem)
for {
off1 := v.AuxInt
@@ -2745,7 +2745,7 @@ func rewriteValueARM64_OpARM64FMOVSload(v *Value, config *Config) bool {
off2 := v_0.AuxInt
ptr := v_0.Args[0]
mem := v.Args[1]
- if !((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym) && !isAuto(sym)) {
+ if !(is32Bit(off1+off2) && ((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym) && !isAuto(sym))) {
break
}
v.reset(OpARM64FMOVSload)
@@ -2756,7 +2756,7 @@ func rewriteValueARM64_OpARM64FMOVSload(v *Value, config *Config) bool {
return true
}
// match: (FMOVSload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
- // cond: canMergeSym(sym1,sym2) && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1))
+ // cond: canMergeSym(sym1,sym2) && is32Bit(off1+off2) && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1))
// result: (FMOVSload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
for {
off1 := v.AuxInt
@@ -2769,7 +2769,7 @@ func rewriteValueARM64_OpARM64FMOVSload(v *Value, config *Config) bool {
sym2 := v_0.Aux
ptr := v_0.Args[0]
mem := v.Args[1]
- if !(canMergeSym(sym1, sym2) && ((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym1) && !isAuto(sym1))) {
+ if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2) && ((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym1) && !isAuto(sym1))) {
break
}
v.reset(OpARM64FMOVSload)
@@ -2785,7 +2785,7 @@ func rewriteValueARM64_OpARM64FMOVSstore(v *Value, config *Config) bool {
b := v.Block
_ = b
// match: (FMOVSstore [off1] {sym} (ADDconst [off2] ptr) val mem)
- // cond: (off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)
+ // cond: is32Bit(off1+off2) && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym))
// result: (FMOVSstore [off1+off2] {sym} ptr val mem)
for {
off1 := v.AuxInt
@@ -2798,7 +2798,7 @@ func rewriteValueARM64_OpARM64FMOVSstore(v *Value, config *Config) bool {
ptr := v_0.Args[0]
val := v.Args[1]
mem := v.Args[2]
- if !((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym) && !isAuto(sym)) {
+ if !(is32Bit(off1+off2) && ((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym) && !isAuto(sym))) {
break
}
v.reset(OpARM64FMOVSstore)
@@ -2810,7 +2810,7 @@ func rewriteValueARM64_OpARM64FMOVSstore(v *Value, config *Config) bool {
return true
}
// match: (FMOVSstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
- // cond: canMergeSym(sym1,sym2) && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1))
+ // cond: canMergeSym(sym1,sym2) && is32Bit(off1+off2) && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1))
// result: (FMOVSstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
for {
off1 := v.AuxInt
@@ -2824,7 +2824,7 @@ func rewriteValueARM64_OpARM64FMOVSstore(v *Value, config *Config) bool {
ptr := v_0.Args[0]
val := v.Args[1]
mem := v.Args[2]
- if !(canMergeSym(sym1, sym2) && ((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym1) && !isAuto(sym1))) {
+ if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2) && ((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym1) && !isAuto(sym1))) {
break
}
v.reset(OpARM64FMOVSstore)
@@ -3511,7 +3511,7 @@ func rewriteValueARM64_OpARM64MOVBUload(v *Value, config *Config) bool {
b := v.Block
_ = b
// match: (MOVBUload [off1] {sym} (ADDconst [off2] ptr) mem)
- // cond:
+ // cond: is32Bit(off1+off2)
// result: (MOVBUload [off1+off2] {sym} ptr mem)
for {
off1 := v.AuxInt
@@ -3523,6 +3523,9 @@ func rewriteValueARM64_OpARM64MOVBUload(v *Value, config *Config) bool {
off2 := v_0.AuxInt
ptr := v_0.Args[0]
mem := v.Args[1]
+ if !(is32Bit(off1 + off2)) {
+ break
+ }
v.reset(OpARM64MOVBUload)
v.AuxInt = off1 + off2
v.Aux = sym
@@ -3531,7 +3534,7 @@ func rewriteValueARM64_OpARM64MOVBUload(v *Value, config *Config) bool {
return true
}
// match: (MOVBUload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
- // cond: canMergeSym(sym1,sym2)
+ // cond: canMergeSym(sym1,sym2) && is32Bit(off1+off2)
// result: (MOVBUload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
for {
off1 := v.AuxInt
@@ -3544,7 +3547,7 @@ func rewriteValueARM64_OpARM64MOVBUload(v *Value, config *Config) bool {
sym2 := v_0.Aux
ptr := v_0.Args[0]
mem := v.Args[1]
- if !(canMergeSym(sym1, sym2)) {
+ if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2)) {
break
}
v.reset(OpARM64MOVBUload)
@@ -3623,7 +3626,7 @@ func rewriteValueARM64_OpARM64MOVBload(v *Value, config *Config) bool {
b := v.Block
_ = b
// match: (MOVBload [off1] {sym} (ADDconst [off2] ptr) mem)
- // cond:
+ // cond: is32Bit(off1+off2)
// result: (MOVBload [off1+off2] {sym} ptr mem)
for {
off1 := v.AuxInt
@@ -3635,6 +3638,9 @@ func rewriteValueARM64_OpARM64MOVBload(v *Value, config *Config) bool {
off2 := v_0.AuxInt
ptr := v_0.Args[0]
mem := v.Args[1]
+ if !(is32Bit(off1 + off2)) {
+ break
+ }
v.reset(OpARM64MOVBload)
v.AuxInt = off1 + off2
v.Aux = sym
@@ -3643,7 +3649,7 @@ func rewriteValueARM64_OpARM64MOVBload(v *Value, config *Config) bool {
return true
}
// match: (MOVBload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
- // cond: canMergeSym(sym1,sym2)
+ // cond: canMergeSym(sym1,sym2) && is32Bit(off1+off2)
// result: (MOVBload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
for {
off1 := v.AuxInt
@@ -3656,7 +3662,7 @@ func rewriteValueARM64_OpARM64MOVBload(v *Value, config *Config) bool {
sym2 := v_0.Aux
ptr := v_0.Args[0]
mem := v.Args[1]
- if !(canMergeSym(sym1, sym2)) {
+ if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2)) {
break
}
v.reset(OpARM64MOVBload)
@@ -3735,7 +3741,7 @@ func rewriteValueARM64_OpARM64MOVBstore(v *Value, config *Config) bool {
b := v.Block
_ = b
// match: (MOVBstore [off1] {sym} (ADDconst [off2] ptr) val mem)
- // cond:
+ // cond: is32Bit(off1+off2)
// result: (MOVBstore [off1+off2] {sym} ptr val mem)
for {
off1 := v.AuxInt
@@ -3748,6 +3754,9 @@ func rewriteValueARM64_OpARM64MOVBstore(v *Value, config *Config) bool {
ptr := v_0.Args[0]
val := v.Args[1]
mem := v.Args[2]
+ if !(is32Bit(off1 + off2)) {
+ break
+ }
v.reset(OpARM64MOVBstore)
v.AuxInt = off1 + off2
v.Aux = sym
@@ -3757,7 +3766,7 @@ func rewriteValueARM64_OpARM64MOVBstore(v *Value, config *Config) bool {
return true
}
// match: (MOVBstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
- // cond: canMergeSym(sym1,sym2)
+ // cond: canMergeSym(sym1,sym2) && is32Bit(off1+off2)
// result: (MOVBstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
for {
off1 := v.AuxInt
@@ -3771,7 +3780,7 @@ func rewriteValueARM64_OpARM64MOVBstore(v *Value, config *Config) bool {
ptr := v_0.Args[0]
val := v.Args[1]
mem := v.Args[2]
- if !(canMergeSym(sym1, sym2)) {
+ if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2)) {
break
}
v.reset(OpARM64MOVBstore)
@@ -3936,7 +3945,7 @@ func rewriteValueARM64_OpARM64MOVBstorezero(v *Value, config *Config) bool {
b := v.Block
_ = b
// match: (MOVBstorezero [off1] {sym} (ADDconst [off2] ptr) mem)
- // cond:
+ // cond: is32Bit(off1+off2)
// result: (MOVBstorezero [off1+off2] {sym} ptr mem)
for {
off1 := v.AuxInt
@@ -3948,6 +3957,9 @@ func rewriteValueARM64_OpARM64MOVBstorezero(v *Value, config *Config) bool {
off2 := v_0.AuxInt
ptr := v_0.Args[0]
mem := v.Args[1]
+ if !(is32Bit(off1 + off2)) {
+ break
+ }
v.reset(OpARM64MOVBstorezero)
v.AuxInt = off1 + off2
v.Aux = sym
@@ -3956,7 +3968,7 @@ func rewriteValueARM64_OpARM64MOVBstorezero(v *Value, config *Config) bool {
return true
}
// match: (MOVBstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
- // cond: canMergeSym(sym1,sym2)
+ // cond: canMergeSym(sym1,sym2) && is32Bit(off1+off2)
// result: (MOVBstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
for {
off1 := v.AuxInt
@@ -3969,7 +3981,7 @@ func rewriteValueARM64_OpARM64MOVBstorezero(v *Value, config *Config) bool {
sym2 := v_0.Aux
ptr := v_0.Args[0]
mem := v.Args[1]
- if !(canMergeSym(sym1, sym2)) {
+ if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2)) {
break
}
v.reset(OpARM64MOVBstorezero)
@@ -3985,7 +3997,7 @@ func rewriteValueARM64_OpARM64MOVDload(v *Value, config *Config) bool {
b := v.Block
_ = b
// match: (MOVDload [off1] {sym} (ADDconst [off2] ptr) mem)
- // cond: (off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)
+ // cond: is32Bit(off1+off2) && ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym))
// result: (MOVDload [off1+off2] {sym} ptr mem)
for {
off1 := v.AuxInt
@@ -3997,7 +4009,7 @@ func rewriteValueARM64_OpARM64MOVDload(v *Value, config *Config) bool {
off2 := v_0.AuxInt
ptr := v_0.Args[0]
mem := v.Args[1]
- if !((off1+off2)%8 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym) && !isAuto(sym)) {
+ if !(is32Bit(off1+off2) && ((off1+off2)%8 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym) && !isAuto(sym))) {
break
}
v.reset(OpARM64MOVDload)
@@ -4008,7 +4020,7 @@ func rewriteValueARM64_OpARM64MOVDload(v *Value, config *Config) bool {
return true
}
// match: (MOVDload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
- // cond: canMergeSym(sym1,sym2) && ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1))
+ // cond: canMergeSym(sym1,sym2) && is32Bit(off1+off2) && ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1))
// result: (MOVDload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
for {
off1 := v.AuxInt
@@ -4021,7 +4033,7 @@ func rewriteValueARM64_OpARM64MOVDload(v *Value, config *Config) bool {
sym2 := v_0.Aux
ptr := v_0.Args[0]
mem := v.Args[1]
- if !(canMergeSym(sym1, sym2) && ((off1+off2)%8 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym1) && !isAuto(sym1))) {
+ if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2) && ((off1+off2)%8 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym1) && !isAuto(sym1))) {
break
}
v.reset(OpARM64MOVDload)
@@ -4088,7 +4100,7 @@ func rewriteValueARM64_OpARM64MOVDstore(v *Value, config *Config) bool {
b := v.Block
_ = b
// match: (MOVDstore [off1] {sym} (ADDconst [off2] ptr) val mem)
- // cond: (off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)
+ // cond: is32Bit(off1+off2) && ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym))
// result: (MOVDstore [off1+off2] {sym} ptr val mem)
for {
off1 := v.AuxInt
@@ -4101,7 +4113,7 @@ func rewriteValueARM64_OpARM64MOVDstore(v *Value, config *Config) bool {
ptr := v_0.Args[0]
val := v.Args[1]
mem := v.Args[2]
- if !((off1+off2)%8 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym) && !isAuto(sym)) {
+ if !(is32Bit(off1+off2) && ((off1+off2)%8 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym) && !isAuto(sym))) {
break
}
v.reset(OpARM64MOVDstore)
@@ -4113,7 +4125,7 @@ func rewriteValueARM64_OpARM64MOVDstore(v *Value, config *Config) bool {
return true
}
// match: (MOVDstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
- // cond: canMergeSym(sym1,sym2) && ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1))
+ // cond: canMergeSym(sym1,sym2) && is32Bit(off1+off2) && ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1))
// result: (MOVDstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
for {
off1 := v.AuxInt
@@ -4127,7 +4139,7 @@ func rewriteValueARM64_OpARM64MOVDstore(v *Value, config *Config) bool {
ptr := v_0.Args[0]
val := v.Args[1]
mem := v.Args[2]
- if !(canMergeSym(sym1, sym2) && ((off1+off2)%8 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym1) && !isAuto(sym1))) {
+ if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2) && ((off1+off2)%8 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym1) && !isAuto(sym1))) {
break
}
v.reset(OpARM64MOVDstore)
@@ -4166,7 +4178,7 @@ func rewriteValueARM64_OpARM64MOVDstorezero(v *Value, config *Config) bool {
b := v.Block
_ = b
// match: (MOVDstorezero [off1] {sym} (ADDconst [off2] ptr) mem)
- // cond: (off1+off2)%2==8 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)
+ // cond: is32Bit(off1+off2) && ((off1+off2)%2==8 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym))
// result: (MOVDstorezero [off1+off2] {sym} ptr mem)
for {
off1 := v.AuxInt
@@ -4178,7 +4190,7 @@ func rewriteValueARM64_OpARM64MOVDstorezero(v *Value, config *Config) bool {
off2 := v_0.AuxInt
ptr := v_0.Args[0]
mem := v.Args[1]
- if !((off1+off2)%2 == 8 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym) && !isAuto(sym)) {
+ if !(is32Bit(off1+off2) && ((off1+off2)%2 == 8 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym) && !isAuto(sym))) {
break
}
v.reset(OpARM64MOVDstorezero)
@@ -4189,7 +4201,7 @@ func rewriteValueARM64_OpARM64MOVDstorezero(v *Value, config *Config) bool {
return true
}
// match: (MOVDstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
- // cond: canMergeSym(sym1,sym2) && ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1))
+ // cond: canMergeSym(sym1,sym2) && is32Bit(off1+off2) && ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1))
// result: (MOVDstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
for {
off1 := v.AuxInt
@@ -4202,7 +4214,7 @@ func rewriteValueARM64_OpARM64MOVDstorezero(v *Value, config *Config) bool {
sym2 := v_0.Aux
ptr := v_0.Args[0]
mem := v.Args[1]
- if !(canMergeSym(sym1, sym2) && ((off1+off2)%8 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym1) && !isAuto(sym1))) {
+ if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2) && ((off1+off2)%8 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym1) && !isAuto(sym1))) {
break
}
v.reset(OpARM64MOVDstorezero)
@@ -4218,7 +4230,7 @@ func rewriteValueARM64_OpARM64MOVHUload(v *Value, config *Config) bool {
b := v.Block
_ = b
// match: (MOVHUload [off1] {sym} (ADDconst [off2] ptr) mem)
- // cond: (off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)
+ // cond: is32Bit(off1+off2) && ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym))
// result: (MOVHUload [off1+off2] {sym} ptr mem)
for {
off1 := v.AuxInt
@@ -4230,7 +4242,7 @@ func rewriteValueARM64_OpARM64MOVHUload(v *Value, config *Config) bool {
off2 := v_0.AuxInt
ptr := v_0.Args[0]
mem := v.Args[1]
- if !((off1+off2)%2 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym) && !isAuto(sym)) {
+ if !(is32Bit(off1+off2) && ((off1+off2)%2 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym) && !isAuto(sym))) {
break
}
v.reset(OpARM64MOVHUload)
@@ -4241,7 +4253,7 @@ func rewriteValueARM64_OpARM64MOVHUload(v *Value, config *Config) bool {
return true
}
// match: (MOVHUload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
- // cond: canMergeSym(sym1,sym2) && ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1))
+ // cond: canMergeSym(sym1,sym2) && is32Bit(off1+off2) && ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1))
// result: (MOVHUload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
for {
off1 := v.AuxInt
@@ -4254,7 +4266,7 @@ func rewriteValueARM64_OpARM64MOVHUload(v *Value, config *Config) bool {
sym2 := v_0.Aux
ptr := v_0.Args[0]
mem := v.Args[1]
- if !(canMergeSym(sym1, sym2) && ((off1+off2)%2 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym1) && !isAuto(sym1))) {
+ if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2) && ((off1+off2)%2 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym1) && !isAuto(sym1))) {
break
}
v.reset(OpARM64MOVHUload)
@@ -4357,7 +4369,7 @@ func rewriteValueARM64_OpARM64MOVHload(v *Value, config *Config) bool {
b := v.Block
_ = b
// match: (MOVHload [off1] {sym} (ADDconst [off2] ptr) mem)
- // cond: (off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)
+ // cond: is32Bit(off1+off2) && ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym))
// result: (MOVHload [off1+off2] {sym} ptr mem)
for {
off1 := v.AuxInt
@@ -4369,7 +4381,7 @@ func rewriteValueARM64_OpARM64MOVHload(v *Value, config *Config) bool {
off2 := v_0.AuxInt
ptr := v_0.Args[0]
mem := v.Args[1]
- if !((off1+off2)%2 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym) && !isAuto(sym)) {
+ if !(is32Bit(off1+off2) && ((off1+off2)%2 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym) && !isAuto(sym))) {
break
}
v.reset(OpARM64MOVHload)
@@ -4380,7 +4392,7 @@ func rewriteValueARM64_OpARM64MOVHload(v *Value, config *Config) bool {
return true
}
// match: (MOVHload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
- // cond: canMergeSym(sym1,sym2) && ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1))
+ // cond: canMergeSym(sym1,sym2) && is32Bit(off1+off2) && ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1))
// result: (MOVHload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
for {
off1 := v.AuxInt
@@ -4393,7 +4405,7 @@ func rewriteValueARM64_OpARM64MOVHload(v *Value, config *Config) bool {
sym2 := v_0.Aux
ptr := v_0.Args[0]
mem := v.Args[1]
- if !(canMergeSym(sym1, sym2) && ((off1+off2)%2 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym1) && !isAuto(sym1))) {
+ if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2) && ((off1+off2)%2 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym1) && !isAuto(sym1))) {
break
}
v.reset(OpARM64MOVHload)
@@ -4520,7 +4532,7 @@ func rewriteValueARM64_OpARM64MOVHstore(v *Value, config *Config) bool {
b := v.Block
_ = b
// match: (MOVHstore [off1] {sym} (ADDconst [off2] ptr) val mem)
- // cond: (off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)
+ // cond: is32Bit(off1+off2) && ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym))
// result: (MOVHstore [off1+off2] {sym} ptr val mem)
for {
off1 := v.AuxInt
@@ -4533,7 +4545,7 @@ func rewriteValueARM64_OpARM64MOVHstore(v *Value, config *Config) bool {
ptr := v_0.Args[0]
val := v.Args[1]
mem := v.Args[2]
- if !((off1+off2)%2 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym) && !isAuto(sym)) {
+ if !(is32Bit(off1+off2) && ((off1+off2)%2 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym) && !isAuto(sym))) {
break
}
v.reset(OpARM64MOVHstore)
@@ -4545,7 +4557,7 @@ func rewriteValueARM64_OpARM64MOVHstore(v *Value, config *Config) bool {
return true
}
// match: (MOVHstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
- // cond: canMergeSym(sym1,sym2) && ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1))
+ // cond: canMergeSym(sym1,sym2) && is32Bit(off1+off2) && ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1))
// result: (MOVHstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
for {
off1 := v.AuxInt
@@ -4559,7 +4571,7 @@ func rewriteValueARM64_OpARM64MOVHstore(v *Value, config *Config) bool {
ptr := v_0.Args[0]
val := v.Args[1]
mem := v.Args[2]
- if !(canMergeSym(sym1, sym2) && ((off1+off2)%2 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym1) && !isAuto(sym1))) {
+ if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2) && ((off1+off2)%2 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym1) && !isAuto(sym1))) {
break
}
v.reset(OpARM64MOVHstore)
@@ -4682,7 +4694,7 @@ func rewriteValueARM64_OpARM64MOVHstorezero(v *Value, config *Config) bool {
b := v.Block
_ = b
// match: (MOVHstorezero [off1] {sym} (ADDconst [off2] ptr) mem)
- // cond: (off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)
+ // cond: is32Bit(off1+off2) && ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym))
// result: (MOVHstorezero [off1+off2] {sym} ptr mem)
for {
off1 := v.AuxInt
@@ -4694,7 +4706,7 @@ func rewriteValueARM64_OpARM64MOVHstorezero(v *Value, config *Config) bool {
off2 := v_0.AuxInt
ptr := v_0.Args[0]
mem := v.Args[1]
- if !((off1+off2)%2 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym) && !isAuto(sym)) {
+ if !(is32Bit(off1+off2) && ((off1+off2)%2 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym) && !isAuto(sym))) {
break
}
v.reset(OpARM64MOVHstorezero)
@@ -4705,7 +4717,7 @@ func rewriteValueARM64_OpARM64MOVHstorezero(v *Value, config *Config) bool {
return true
}
// match: (MOVHstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
- // cond: canMergeSym(sym1,sym2) && ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1))
+ // cond: canMergeSym(sym1,sym2) && is32Bit(off1+off2) && ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1))
// result: (MOVHstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
for {
off1 := v.AuxInt
@@ -4718,7 +4730,7 @@ func rewriteValueARM64_OpARM64MOVHstorezero(v *Value, config *Config) bool {
sym2 := v_0.Aux
ptr := v_0.Args[0]
mem := v.Args[1]
- if !(canMergeSym(sym1, sym2) && ((off1+off2)%2 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym1) && !isAuto(sym1))) {
+ if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2) && ((off1+off2)%2 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym1) && !isAuto(sym1))) {
break
}
v.reset(OpARM64MOVHstorezero)
@@ -4734,7 +4746,7 @@ func rewriteValueARM64_OpARM64MOVWUload(v *Value, config *Config) bool {
b := v.Block
_ = b
// match: (MOVWUload [off1] {sym} (ADDconst [off2] ptr) mem)
- // cond: (off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)
+ // cond: is32Bit(off1+off2) && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym))
// result: (MOVWUload [off1+off2] {sym} ptr mem)
for {
off1 := v.AuxInt
@@ -4746,7 +4758,7 @@ func rewriteValueARM64_OpARM64MOVWUload(v *Value, config *Config) bool {
off2 := v_0.AuxInt
ptr := v_0.Args[0]
mem := v.Args[1]
- if !((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym) && !isAuto(sym)) {
+ if !(is32Bit(off1+off2) && ((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym) && !isAuto(sym))) {
break
}
v.reset(OpARM64MOVWUload)
@@ -4757,7 +4769,7 @@ func rewriteValueARM64_OpARM64MOVWUload(v *Value, config *Config) bool {
return true
}
// match: (MOVWUload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
- // cond: canMergeSym(sym1,sym2) && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1))
+ // cond: canMergeSym(sym1,sym2) && is32Bit(off1+off2) && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1))
// result: (MOVWUload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
for {
off1 := v.AuxInt
@@ -4770,7 +4782,7 @@ func rewriteValueARM64_OpARM64MOVWUload(v *Value, config *Config) bool {
sym2 := v_0.Aux
ptr := v_0.Args[0]
mem := v.Args[1]
- if !(canMergeSym(sym1, sym2) && ((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym1) && !isAuto(sym1))) {
+ if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2) && ((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym1) && !isAuto(sym1))) {
break
}
v.reset(OpARM64MOVWUload)
@@ -4897,7 +4909,7 @@ func rewriteValueARM64_OpARM64MOVWload(v *Value, config *Config) bool {
b := v.Block
_ = b
// match: (MOVWload [off1] {sym} (ADDconst [off2] ptr) mem)
- // cond: (off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)
+ // cond: is32Bit(off1+off2) && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym))
// result: (MOVWload [off1+off2] {sym} ptr mem)
for {
off1 := v.AuxInt
@@ -4909,7 +4921,7 @@ func rewriteValueARM64_OpARM64MOVWload(v *Value, config *Config) bool {
off2 := v_0.AuxInt
ptr := v_0.Args[0]
mem := v.Args[1]
- if !((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym) && !isAuto(sym)) {
+ if !(is32Bit(off1+off2) && ((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym) && !isAuto(sym))) {
break
}
v.reset(OpARM64MOVWload)
@@ -4920,7 +4932,7 @@ func rewriteValueARM64_OpARM64MOVWload(v *Value, config *Config) bool {
return true
}
// match: (MOVWload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
- // cond: canMergeSym(sym1,sym2) && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1))
+ // cond: canMergeSym(sym1,sym2) && is32Bit(off1+off2) && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1))
// result: (MOVWload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
for {
off1 := v.AuxInt
@@ -4933,7 +4945,7 @@ func rewriteValueARM64_OpARM64MOVWload(v *Value, config *Config) bool {
sym2 := v_0.Aux
ptr := v_0.Args[0]
mem := v.Args[1]
- if !(canMergeSym(sym1, sym2) && ((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym1) && !isAuto(sym1))) {
+ if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2) && ((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym1) && !isAuto(sym1))) {
break
}
v.reset(OpARM64MOVWload)
@@ -5108,7 +5120,7 @@ func rewriteValueARM64_OpARM64MOVWstore(v *Value, config *Config) bool {
b := v.Block
_ = b
// match: (MOVWstore [off1] {sym} (ADDconst [off2] ptr) val mem)
- // cond: (off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)
+ // cond: is32Bit(off1+off2) && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym))
// result: (MOVWstore [off1+off2] {sym} ptr val mem)
for {
off1 := v.AuxInt
@@ -5121,7 +5133,7 @@ func rewriteValueARM64_OpARM64MOVWstore(v *Value, config *Config) bool {
ptr := v_0.Args[0]
val := v.Args[1]
mem := v.Args[2]
- if !((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym) && !isAuto(sym)) {
+ if !(is32Bit(off1+off2) && ((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym) && !isAuto(sym))) {
break
}
v.reset(OpARM64MOVWstore)
@@ -5133,7 +5145,7 @@ func rewriteValueARM64_OpARM64MOVWstore(v *Value, config *Config) bool {
return true
}
// match: (MOVWstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
- // cond: canMergeSym(sym1,sym2) && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1))
+ // cond: canMergeSym(sym1,sym2) && is32Bit(off1+off2) && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1))
// result: (MOVWstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
for {
off1 := v.AuxInt
@@ -5147,7 +5159,7 @@ func rewriteValueARM64_OpARM64MOVWstore(v *Value, config *Config) bool {
ptr := v_0.Args[0]
val := v.Args[1]
mem := v.Args[2]
- if !(canMergeSym(sym1, sym2) && ((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym1) && !isAuto(sym1))) {
+ if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2) && ((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym1) && !isAuto(sym1))) {
break
}
v.reset(OpARM64MOVWstore)
@@ -5228,7 +5240,7 @@ func rewriteValueARM64_OpARM64MOVWstorezero(v *Value, config *Config) bool {
b := v.Block
_ = b
// match: (MOVWstorezero [off1] {sym} (ADDconst [off2] ptr) mem)
- // cond: (off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)
+ // cond: is32Bit(off1+off2) && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym))
// result: (MOVWstorezero [off1+off2] {sym} ptr mem)
for {
off1 := v.AuxInt
@@ -5240,7 +5252,7 @@ func rewriteValueARM64_OpARM64MOVWstorezero(v *Value, config *Config) bool {
off2 := v_0.AuxInt
ptr := v_0.Args[0]
mem := v.Args[1]
- if !((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym) && !isAuto(sym)) {
+ if !(is32Bit(off1+off2) && ((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym) && !isAuto(sym))) {
break
}
v.reset(OpARM64MOVWstorezero)
@@ -5251,7 +5263,7 @@ func rewriteValueARM64_OpARM64MOVWstorezero(v *Value, config *Config) bool {
return true
}
// match: (MOVWstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
- // cond: canMergeSym(sym1,sym2) && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1))
+ // cond: canMergeSym(sym1,sym2) && is32Bit(off1+off2) && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym1) && !isAuto(sym1))
// result: (MOVWstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
for {
off1 := v.AuxInt
@@ -5264,7 +5276,7 @@ func rewriteValueARM64_OpARM64MOVWstorezero(v *Value, config *Config) bool {
sym2 := v_0.Aux
ptr := v_0.Args[0]
mem := v.Args[1]
- if !(canMergeSym(sym1, sym2) && ((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym1) && !isAuto(sym1))) {
+ if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2) && ((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym1) && !isAuto(sym1))) {
break
}
v.reset(OpARM64MOVWstorezero)
diff --git a/src/cmd/compile/internal/ssa/rewritePPC64.go b/src/cmd/compile/internal/ssa/rewritePPC64.go
index 8c8373b..031459c 100644
--- a/src/cmd/compile/internal/ssa/rewritePPC64.go
+++ b/src/cmd/compile/internal/ssa/rewritePPC64.go
@@ -1543,12 +1543,12 @@ func rewriteValuePPC64_OpGeq16U(v *Value, config *Config) bool {
_ = b
// match: (Geq16U x y)
// cond:
- // result: (GreaterEqual (CMPU (ZeroExt16to32 x) (ZeroExt16to32 y)))
+ // result: (GreaterEqual (CMPWU (ZeroExt16to32 x) (ZeroExt16to32 y)))
for {
x := v.Args[0]
y := v.Args[1]
v.reset(OpPPC64GreaterEqual)
- v0 := b.NewValue0(v.Line, OpPPC64CMPU, TypeFlags)
+ v0 := b.NewValue0(v.Line, OpPPC64CMPWU, TypeFlags)
v1 := b.NewValue0(v.Line, OpZeroExt16to32, config.fe.TypeUInt32())
v1.AddArg(x)
v0.AddArg(v1)
@@ -1598,12 +1598,12 @@ func rewriteValuePPC64_OpGeq32U(v *Value, config *Config) bool {
_ = b
// match: (Geq32U x y)
// cond:
- // result: (GreaterEqual (CMPU x y))
+ // result: (GreaterEqual (CMPWU x y))
for {
x := v.Args[0]
y := v.Args[1]
v.reset(OpPPC64GreaterEqual)
- v0 := b.NewValue0(v.Line, OpPPC64CMPU, TypeFlags)
+ v0 := b.NewValue0(v.Line, OpPPC64CMPWU, TypeFlags)
v0.AddArg(x)
v0.AddArg(y)
v.AddArg(v0)
@@ -1687,12 +1687,12 @@ func rewriteValuePPC64_OpGeq8U(v *Value, config *Config) bool {
_ = b
// match: (Geq8U x y)
// cond:
- // result: (GreaterEqual (CMPU (ZeroExt8to32 x) (ZeroExt8to32 y)))
+ // result: (GreaterEqual (CMPWU (ZeroExt8to32 x) (ZeroExt8to32 y)))
for {
x := v.Args[0]
y := v.Args[1]
v.reset(OpPPC64GreaterEqual)
- v0 := b.NewValue0(v.Line, OpPPC64CMPU, TypeFlags)
+ v0 := b.NewValue0(v.Line, OpPPC64CMPWU, TypeFlags)
v1 := b.NewValue0(v.Line, OpZeroExt8to32, config.fe.TypeUInt32())
v1.AddArg(x)
v0.AddArg(v1)
diff --git a/src/cmd/compile/internal/ssa/rewriteS390X.go b/src/cmd/compile/internal/ssa/rewriteS390X.go
index 5acaf2d..0425ced 100644
--- a/src/cmd/compile/internal/ssa/rewriteS390X.go
+++ b/src/cmd/compile/internal/ssa/rewriteS390X.go
@@ -524,6 +524,8 @@ func rewriteValueS390X(v *Value, config *Config) bool {
return rewriteValueS390X_OpS390XMOVDload(v, config)
case OpS390XMOVDloadidx:
return rewriteValueS390X_OpS390XMOVDloadidx(v, config)
+ case OpS390XMOVDreg:
+ return rewriteValueS390X_OpS390XMOVDreg(v, config)
case OpS390XMOVDstore:
return rewriteValueS390X_OpS390XMOVDstore(v, config)
case OpS390XMOVDstoreconst:
@@ -3236,13 +3238,28 @@ func rewriteValueS390X_OpLoad(v *Value, config *Config) bool {
return true
}
// match: (Load <t> ptr mem)
- // cond: is32BitInt(t)
+ // cond: is32BitInt(t) && isSigned(t)
+ // result: (MOVWload ptr mem)
+ for {
+ t := v.Type
+ ptr := v.Args[0]
+ mem := v.Args[1]
+ if !(is32BitInt(t) && isSigned(t)) {
+ break
+ }
+ v.reset(OpS390XMOVWload)
+ v.AddArg(ptr)
+ v.AddArg(mem)
+ return true
+ }
+ // match: (Load <t> ptr mem)
+ // cond: is32BitInt(t) && !isSigned(t)
// result: (MOVWZload ptr mem)
for {
t := v.Type
ptr := v.Args[0]
mem := v.Args[1]
- if !(is32BitInt(t)) {
+ if !(is32BitInt(t) && !isSigned(t)) {
break
}
v.reset(OpS390XMOVWZload)
@@ -3251,13 +3268,28 @@ func rewriteValueS390X_OpLoad(v *Value, config *Config) bool {
return true
}
// match: (Load <t> ptr mem)
- // cond: is16BitInt(t)
+ // cond: is16BitInt(t) && isSigned(t)
+ // result: (MOVHload ptr mem)
+ for {
+ t := v.Type
+ ptr := v.Args[0]
+ mem := v.Args[1]
+ if !(is16BitInt(t) && isSigned(t)) {
+ break
+ }
+ v.reset(OpS390XMOVHload)
+ v.AddArg(ptr)
+ v.AddArg(mem)
+ return true
+ }
+ // match: (Load <t> ptr mem)
+ // cond: is16BitInt(t) && !isSigned(t)
// result: (MOVHZload ptr mem)
for {
t := v.Type
ptr := v.Args[0]
mem := v.Args[1]
- if !(is16BitInt(t)) {
+ if !(is16BitInt(t) && !isSigned(t)) {
break
}
v.reset(OpS390XMOVHZload)
@@ -3266,13 +3298,28 @@ func rewriteValueS390X_OpLoad(v *Value, config *Config) bool {
return true
}
// match: (Load <t> ptr mem)
- // cond: (t.IsBoolean() || is8BitInt(t))
+ // cond: is8BitInt(t) && isSigned(t)
+ // result: (MOVBload ptr mem)
+ for {
+ t := v.Type
+ ptr := v.Args[0]
+ mem := v.Args[1]
+ if !(is8BitInt(t) && isSigned(t)) {
+ break
+ }
+ v.reset(OpS390XMOVBload)
+ v.AddArg(ptr)
+ v.AddArg(mem)
+ return true
+ }
+ // match: (Load <t> ptr mem)
+ // cond: (t.IsBoolean() || (is8BitInt(t) && !isSigned(t)))
// result: (MOVBZload ptr mem)
for {
t := v.Type
ptr := v.Args[0]
mem := v.Args[1]
- if !(t.IsBoolean() || is8BitInt(t)) {
+ if !(t.IsBoolean() || (is8BitInt(t) && !isSigned(t))) {
break
}
v.reset(OpS390XMOVBZload)
@@ -7802,7 +7849,7 @@ func rewriteValueS390X_OpS390XMOVBZload(v *Value, config *Config) bool {
_ = b
// match: (MOVBZload [off] {sym} ptr (MOVBstore [off2] {sym2} ptr2 x _))
// cond: sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)
- // result: x
+ // result: (MOVDreg x)
for {
off := v.AuxInt
sym := v.Aux
@@ -7818,8 +7865,7 @@ func rewriteValueS390X_OpS390XMOVBZload(v *Value, config *Config) bool {
if !(sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)) {
break
}
- v.reset(OpCopy)
- v.Type = x.Type
+ v.reset(OpS390XMOVDreg)
v.AddArg(x)
return true
}
@@ -7976,7 +8022,7 @@ func rewriteValueS390X_OpS390XMOVBZreg(v *Value, config *Config) bool {
_ = b
// match: (MOVBZreg x:(MOVDLT (MOVDconst [c]) (MOVDconst [d]) _))
// cond: int64(uint8(c)) == c && int64(uint8(d)) == d
- // result: x
+ // result: (MOVDreg x)
for {
x := v.Args[0]
if x.Op != OpS390XMOVDLT {
@@ -7995,14 +8041,13 @@ func rewriteValueS390X_OpS390XMOVBZreg(v *Value, config *Config) bool {
if !(int64(uint8(c)) == c && int64(uint8(d)) == d) {
break
}
- v.reset(OpCopy)
- v.Type = x.Type
+ v.reset(OpS390XMOVDreg)
v.AddArg(x)
return true
}
// match: (MOVBZreg x:(MOVDLE (MOVDconst [c]) (MOVDconst [d]) _))
// cond: int64(uint8(c)) == c && int64(uint8(d)) == d
- // result: x
+ // result: (MOVDreg x)
for {
x := v.Args[0]
if x.Op != OpS390XMOVDLE {
@@ -8021,14 +8066,13 @@ func rewriteValueS390X_OpS390XMOVBZreg(v *Value, config *Config) bool {
if !(int64(uint8(c)) == c && int64(uint8(d)) == d) {
break
}
- v.reset(OpCopy)
- v.Type = x.Type
+ v.reset(OpS390XMOVDreg)
v.AddArg(x)
return true
}
// match: (MOVBZreg x:(MOVDGT (MOVDconst [c]) (MOVDconst [d]) _))
// cond: int64(uint8(c)) == c && int64(uint8(d)) == d
- // result: x
+ // result: (MOVDreg x)
for {
x := v.Args[0]
if x.Op != OpS390XMOVDGT {
@@ -8047,14 +8091,13 @@ func rewriteValueS390X_OpS390XMOVBZreg(v *Value, config *Config) bool {
if !(int64(uint8(c)) == c && int64(uint8(d)) == d) {
break
}
- v.reset(OpCopy)
- v.Type = x.Type
+ v.reset(OpS390XMOVDreg)
v.AddArg(x)
return true
}
// match: (MOVBZreg x:(MOVDGE (MOVDconst [c]) (MOVDconst [d]) _))
// cond: int64(uint8(c)) == c && int64(uint8(d)) == d
- // result: x
+ // result: (MOVDreg x)
for {
x := v.Args[0]
if x.Op != OpS390XMOVDGE {
@@ -8073,14 +8116,13 @@ func rewriteValueS390X_OpS390XMOVBZreg(v *Value, config *Config) bool {
if !(int64(uint8(c)) == c && int64(uint8(d)) == d) {
break
}
- v.reset(OpCopy)
- v.Type = x.Type
+ v.reset(OpS390XMOVDreg)
v.AddArg(x)
return true
}
// match: (MOVBZreg x:(MOVDEQ (MOVDconst [c]) (MOVDconst [d]) _))
// cond: int64(uint8(c)) == c && int64(uint8(d)) == d
- // result: x
+ // result: (MOVDreg x)
for {
x := v.Args[0]
if x.Op != OpS390XMOVDEQ {
@@ -8099,14 +8141,13 @@ func rewriteValueS390X_OpS390XMOVBZreg(v *Value, config *Config) bool {
if !(int64(uint8(c)) == c && int64(uint8(d)) == d) {
break
}
- v.reset(OpCopy)
- v.Type = x.Type
+ v.reset(OpS390XMOVDreg)
v.AddArg(x)
return true
}
// match: (MOVBZreg x:(MOVDNE (MOVDconst [c]) (MOVDconst [d]) _))
// cond: int64(uint8(c)) == c && int64(uint8(d)) == d
- // result: x
+ // result: (MOVDreg x)
for {
x := v.Args[0]
if x.Op != OpS390XMOVDNE {
@@ -8125,14 +8166,13 @@ func rewriteValueS390X_OpS390XMOVBZreg(v *Value, config *Config) bool {
if !(int64(uint8(c)) == c && int64(uint8(d)) == d) {
break
}
- v.reset(OpCopy)
- v.Type = x.Type
+ v.reset(OpS390XMOVDreg)
v.AddArg(x)
return true
}
// match: (MOVBZreg x:(MOVDGTnoinv (MOVDconst [c]) (MOVDconst [d]) _))
// cond: int64(uint8(c)) == c && int64(uint8(d)) == d
- // result: x
+ // result: (MOVDreg x)
for {
x := v.Args[0]
if x.Op != OpS390XMOVDGTnoinv {
@@ -8151,14 +8191,13 @@ func rewriteValueS390X_OpS390XMOVBZreg(v *Value, config *Config) bool {
if !(int64(uint8(c)) == c && int64(uint8(d)) == d) {
break
}
- v.reset(OpCopy)
- v.Type = x.Type
+ v.reset(OpS390XMOVDreg)
v.AddArg(x)
return true
}
// match: (MOVBZreg x:(MOVDGEnoinv (MOVDconst [c]) (MOVDconst [d]) _))
// cond: int64(uint8(c)) == c && int64(uint8(d)) == d
- // result: x
+ // result: (MOVDreg x)
for {
x := v.Args[0]
if x.Op != OpS390XMOVDGEnoinv {
@@ -8177,27 +8216,25 @@ func rewriteValueS390X_OpS390XMOVBZreg(v *Value, config *Config) bool {
if !(int64(uint8(c)) == c && int64(uint8(d)) == d) {
break
}
- v.reset(OpCopy)
- v.Type = x.Type
+ v.reset(OpS390XMOVDreg)
v.AddArg(x)
return true
}
// match: (MOVBZreg x:(MOVBZload _ _))
// cond:
- // result: x
+ // result: (MOVDreg x)
for {
x := v.Args[0]
if x.Op != OpS390XMOVBZload {
break
}
- v.reset(OpCopy)
- v.Type = x.Type
+ v.reset(OpS390XMOVDreg)
v.AddArg(x)
return true
}
// match: (MOVBZreg x:(Arg <t>))
// cond: is8BitInt(t) && !isSigned(t)
- // result: x
+ // result: (MOVDreg x)
for {
x := v.Args[0]
if x.Op != OpArg {
@@ -8207,21 +8244,19 @@ func rewriteValueS390X_OpS390XMOVBZreg(v *Value, config *Config) bool {
if !(is8BitInt(t) && !isSigned(t)) {
break
}
- v.reset(OpCopy)
- v.Type = x.Type
+ v.reset(OpS390XMOVDreg)
v.AddArg(x)
return true
}
// match: (MOVBZreg x:(MOVBZreg _))
// cond:
- // result: x
+ // result: (MOVDreg x)
for {
x := v.Args[0]
if x.Op != OpS390XMOVBZreg {
break
}
- v.reset(OpCopy)
- v.Type = x.Type
+ v.reset(OpS390XMOVDreg)
v.AddArg(x)
return true
}
@@ -8349,20 +8384,19 @@ func rewriteValueS390X_OpS390XMOVBreg(v *Value, config *Config) bool {
_ = b
// match: (MOVBreg x:(MOVBload _ _))
// cond:
- // result: x
+ // result: (MOVDreg x)
for {
x := v.Args[0]
if x.Op != OpS390XMOVBload {
break
}
- v.reset(OpCopy)
- v.Type = x.Type
+ v.reset(OpS390XMOVDreg)
v.AddArg(x)
return true
}
// match: (MOVBreg x:(Arg <t>))
// cond: is8BitInt(t) && isSigned(t)
- // result: x
+ // result: (MOVDreg x)
for {
x := v.Args[0]
if x.Op != OpArg {
@@ -8372,21 +8406,19 @@ func rewriteValueS390X_OpS390XMOVBreg(v *Value, config *Config) bool {
if !(is8BitInt(t) && isSigned(t)) {
break
}
- v.reset(OpCopy)
- v.Type = x.Type
+ v.reset(OpS390XMOVDreg)
v.AddArg(x)
return true
}
// match: (MOVBreg x:(MOVBreg _))
// cond:
- // result: x
+ // result: (MOVDreg x)
for {
x := v.Args[0]
if x.Op != OpS390XMOVBreg {
break
}
- v.reset(OpCopy)
- v.Type = x.Type
+ v.reset(OpS390XMOVDreg)
v.AddArg(x)
return true
}
@@ -9995,7 +10027,7 @@ func rewriteValueS390X_OpS390XMOVDload(v *Value, config *Config) bool {
_ = b
// match: (MOVDload [off] {sym} ptr (MOVDstore [off2] {sym2} ptr2 x _))
// cond: sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)
- // result: x
+ // result: (MOVDreg x)
for {
off := v.AuxInt
sym := v.Aux
@@ -10011,8 +10043,7 @@ func rewriteValueS390X_OpS390XMOVDload(v *Value, config *Config) bool {
if !(sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)) {
break
}
- v.reset(OpCopy)
- v.Type = x.Type
+ v.reset(OpS390XMOVDreg)
v.AddArg(x)
return true
}
@@ -10164,6 +10195,23 @@ func rewriteValueS390X_OpS390XMOVDloadidx(v *Value, config *Config) bool {
}
return false
}
+func rewriteValueS390X_OpS390XMOVDreg(v *Value, config *Config) bool {
+ b := v.Block
+ _ = b
+ // match: (MOVDreg x)
+ // cond: x.Uses == 1
+ // result: (MOVDnop x)
+ for {
+ x := v.Args[0]
+ if !(x.Uses == 1) {
+ break
+ }
+ v.reset(OpS390XMOVDnop)
+ v.AddArg(x)
+ return true
+ }
+ return false
+}
func rewriteValueS390X_OpS390XMOVDstore(v *Value, config *Config) bool {
b := v.Block
_ = b
@@ -10912,7 +10960,7 @@ func rewriteValueS390X_OpS390XMOVHZload(v *Value, config *Config) bool {
_ = b
// match: (MOVHZload [off] {sym} ptr (MOVHstore [off2] {sym2} ptr2 x _))
// cond: sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)
- // result: x
+ // result: (MOVDreg x)
for {
off := v.AuxInt
sym := v.Aux
@@ -10928,8 +10976,7 @@ func rewriteValueS390X_OpS390XMOVHZload(v *Value, config *Config) bool {
if !(sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)) {
break
}
- v.reset(OpCopy)
- v.Type = x.Type
+ v.reset(OpS390XMOVDreg)
v.AddArg(x)
return true
}
@@ -11086,33 +11133,31 @@ func rewriteValueS390X_OpS390XMOVHZreg(v *Value, config *Config) bool {
_ = b
// match: (MOVHZreg x:(MOVBZload _ _))
// cond:
- // result: x
+ // result: (MOVDreg x)
for {
x := v.Args[0]
if x.Op != OpS390XMOVBZload {
break
}
- v.reset(OpCopy)
- v.Type = x.Type
+ v.reset(OpS390XMOVDreg)
v.AddArg(x)
return true
}
// match: (MOVHZreg x:(MOVHZload _ _))
// cond:
- // result: x
+ // result: (MOVDreg x)
for {
x := v.Args[0]
if x.Op != OpS390XMOVHZload {
break
}
- v.reset(OpCopy)
- v.Type = x.Type
+ v.reset(OpS390XMOVDreg)
v.AddArg(x)
return true
}
// match: (MOVHZreg x:(Arg <t>))
// cond: (is8BitInt(t) || is16BitInt(t)) && !isSigned(t)
- // result: x
+ // result: (MOVDreg x)
for {
x := v.Args[0]
if x.Op != OpArg {
@@ -11122,34 +11167,31 @@ func rewriteValueS390X_OpS390XMOVHZreg(v *Value, config *Config) bool {
if !((is8BitInt(t) || is16BitInt(t)) && !isSigned(t)) {
break
}
- v.reset(OpCopy)
- v.Type = x.Type
+ v.reset(OpS390XMOVDreg)
v.AddArg(x)
return true
}
// match: (MOVHZreg x:(MOVBZreg _))
// cond:
- // result: x
+ // result: (MOVDreg x)
for {
x := v.Args[0]
if x.Op != OpS390XMOVBZreg {
break
}
- v.reset(OpCopy)
- v.Type = x.Type
+ v.reset(OpS390XMOVDreg)
v.AddArg(x)
return true
}
// match: (MOVHZreg x:(MOVHZreg _))
// cond:
- // result: x
+ // result: (MOVDreg x)
for {
x := v.Args[0]
if x.Op != OpS390XMOVHZreg {
break
}
- v.reset(OpCopy)
- v.Type = x.Type
+ v.reset(OpS390XMOVDreg)
v.AddArg(x)
return true
}
@@ -11277,46 +11319,43 @@ func rewriteValueS390X_OpS390XMOVHreg(v *Value, config *Config) bool {
_ = b
// match: (MOVHreg x:(MOVBload _ _))
// cond:
- // result: x
+ // result: (MOVDreg x)
for {
x := v.Args[0]
if x.Op != OpS390XMOVBload {
break
}
- v.reset(OpCopy)
- v.Type = x.Type
+ v.reset(OpS390XMOVDreg)
v.AddArg(x)
return true
}
// match: (MOVHreg x:(MOVBZload _ _))
// cond:
- // result: x
+ // result: (MOVDreg x)
for {
x := v.Args[0]
if x.Op != OpS390XMOVBZload {
break
}
- v.reset(OpCopy)
- v.Type = x.Type
+ v.reset(OpS390XMOVDreg)
v.AddArg(x)
return true
}
// match: (MOVHreg x:(MOVHload _ _))
// cond:
- // result: x
+ // result: (MOVDreg x)
for {
x := v.Args[0]
if x.Op != OpS390XMOVHload {
break
}
- v.reset(OpCopy)
- v.Type = x.Type
+ v.reset(OpS390XMOVDreg)
v.AddArg(x)
return true
}
// match: (MOVHreg x:(Arg <t>))
// cond: (is8BitInt(t) || is16BitInt(t)) && isSigned(t)
- // result: x
+ // result: (MOVDreg x)
for {
x := v.Args[0]
if x.Op != OpArg {
@@ -11326,47 +11365,43 @@ func rewriteValueS390X_OpS390XMOVHreg(v *Value, config *Config) bool {
if !((is8BitInt(t) || is16BitInt(t)) && isSigned(t)) {
break
}
- v.reset(OpCopy)
- v.Type = x.Type
+ v.reset(OpS390XMOVDreg)
v.AddArg(x)
return true
}
// match: (MOVHreg x:(MOVBreg _))
// cond:
- // result: x
+ // result: (MOVDreg x)
for {
x := v.Args[0]
if x.Op != OpS390XMOVBreg {
break
}
- v.reset(OpCopy)
- v.Type = x.Type
+ v.reset(OpS390XMOVDreg)
v.AddArg(x)
return true
}
// match: (MOVHreg x:(MOVBZreg _))
// cond:
- // result: x
+ // result: (MOVDreg x)
for {
x := v.Args[0]
if x.Op != OpS390XMOVBZreg {
break
}
- v.reset(OpCopy)
- v.Type = x.Type
+ v.reset(OpS390XMOVDreg)
v.AddArg(x)
return true
}
// match: (MOVHreg x:(MOVHreg _))
// cond:
- // result: x
+ // result: (MOVDreg x)
for {
x := v.Args[0]
if x.Op != OpS390XMOVHreg {
break
}
- v.reset(OpCopy)
- v.Type = x.Type
+ v.reset(OpS390XMOVDreg)
v.AddArg(x)
return true
}
@@ -12310,7 +12345,7 @@ func rewriteValueS390X_OpS390XMOVWZload(v *Value, config *Config) bool {
_ = b
// match: (MOVWZload [off] {sym} ptr (MOVWstore [off2] {sym2} ptr2 x _))
// cond: sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)
- // result: x
+ // result: (MOVDreg x)
for {
off := v.AuxInt
sym := v.Aux
@@ -12326,8 +12361,7 @@ func rewriteValueS390X_OpS390XMOVWZload(v *Value, config *Config) bool {
if !(sym == sym2 && off == off2 && isSamePtr(ptr, ptr2)) {
break
}
- v.reset(OpCopy)
- v.Type = x.Type
+ v.reset(OpS390XMOVDreg)
v.AddArg(x)
return true
}
@@ -12484,46 +12518,43 @@ func rewriteValueS390X_OpS390XMOVWZreg(v *Value, config *Config) bool {
_ = b
// match: (MOVWZreg x:(MOVBZload _ _))
// cond:
- // result: x
+ // result: (MOVDreg x)
for {
x := v.Args[0]
if x.Op != OpS390XMOVBZload {
break
}
- v.reset(OpCopy)
- v.Type = x.Type
+ v.reset(OpS390XMOVDreg)
v.AddArg(x)
return true
}
// match: (MOVWZreg x:(MOVHZload _ _))
// cond:
- // result: x
+ // result: (MOVDreg x)
for {
x := v.Args[0]
if x.Op != OpS390XMOVHZload {
break
}
- v.reset(OpCopy)
- v.Type = x.Type
+ v.reset(OpS390XMOVDreg)
v.AddArg(x)
return true
}
// match: (MOVWZreg x:(MOVWZload _ _))
// cond:
- // result: x
+ // result: (MOVDreg x)
for {
x := v.Args[0]
if x.Op != OpS390XMOVWZload {
break
}
- v.reset(OpCopy)
- v.Type = x.Type
+ v.reset(OpS390XMOVDreg)
v.AddArg(x)
return true
}
// match: (MOVWZreg x:(Arg <t>))
// cond: (is8BitInt(t) || is16BitInt(t) || is32BitInt(t)) && !isSigned(t)
- // result: x
+ // result: (MOVDreg x)
for {
x := v.Args[0]
if x.Op != OpArg {
@@ -12533,47 +12564,43 @@ func rewriteValueS390X_OpS390XMOVWZreg(v *Value, config *Config) bool {
if !((is8BitInt(t) || is16BitInt(t) || is32BitInt(t)) && !isSigned(t)) {
break
}
- v.reset(OpCopy)
- v.Type = x.Type
+ v.reset(OpS390XMOVDreg)
v.AddArg(x)
return true
}
// match: (MOVWZreg x:(MOVBZreg _))
// cond:
- // result: x
+ // result: (MOVDreg x)
for {
x := v.Args[0]
if x.Op != OpS390XMOVBZreg {
break
}
- v.reset(OpCopy)
- v.Type = x.Type
+ v.reset(OpS390XMOVDreg)
v.AddArg(x)
return true
}
// match: (MOVWZreg x:(MOVHZreg _))
// cond:
- // result: x
+ // result: (MOVDreg x)
for {
x := v.Args[0]
if x.Op != OpS390XMOVHZreg {
break
}
- v.reset(OpCopy)
- v.Type = x.Type
+ v.reset(OpS390XMOVDreg)
v.AddArg(x)
return true
}
// match: (MOVWZreg x:(MOVWZreg _))
// cond:
- // result: x
+ // result: (MOVDreg x)
for {
x := v.Args[0]
if x.Op != OpS390XMOVWZreg {
break
}
- v.reset(OpCopy)
- v.Type = x.Type
+ v.reset(OpS390XMOVDreg)
v.AddArg(x)
return true
}
@@ -12701,72 +12728,67 @@ func rewriteValueS390X_OpS390XMOVWreg(v *Value, config *Config) bool {
_ = b
// match: (MOVWreg x:(MOVBload _ _))
// cond:
- // result: x
+ // result: (MOVDreg x)
for {
x := v.Args[0]
if x.Op != OpS390XMOVBload {
break
}
- v.reset(OpCopy)
- v.Type = x.Type
+ v.reset(OpS390XMOVDreg)
v.AddArg(x)
return true
}
// match: (MOVWreg x:(MOVBZload _ _))
// cond:
- // result: x
+ // result: (MOVDreg x)
for {
x := v.Args[0]
if x.Op != OpS390XMOVBZload {
break
}
- v.reset(OpCopy)
- v.Type = x.Type
+ v.reset(OpS390XMOVDreg)
v.AddArg(x)
return true
}
// match: (MOVWreg x:(MOVHload _ _))
// cond:
- // result: x
+ // result: (MOVDreg x)
for {
x := v.Args[0]
if x.Op != OpS390XMOVHload {
break
}
- v.reset(OpCopy)
- v.Type = x.Type
+ v.reset(OpS390XMOVDreg)
v.AddArg(x)
return true
}
// match: (MOVWreg x:(MOVHZload _ _))
// cond:
- // result: x
+ // result: (MOVDreg x)
for {
x := v.Args[0]
if x.Op != OpS390XMOVHZload {
break
}
- v.reset(OpCopy)
- v.Type = x.Type
+ v.reset(OpS390XMOVDreg)
v.AddArg(x)
return true
}
// match: (MOVWreg x:(MOVWload _ _))
// cond:
- // result: x
+ // result: (MOVDreg x)
for {
x := v.Args[0]
if x.Op != OpS390XMOVWload {
break
}
- v.reset(OpCopy)
- v.Type = x.Type
+ v.reset(OpS390XMOVDreg)
v.AddArg(x)
return true
}
// match: (MOVWreg x:(Arg <t>))
// cond: (is8BitInt(t) || is16BitInt(t) || is32BitInt(t)) && isSigned(t)
- // result: x
+ // result: (MOVDreg x)
for {
x := v.Args[0]
if x.Op != OpArg {
@@ -12776,73 +12798,67 @@ func rewriteValueS390X_OpS390XMOVWreg(v *Value, config *Config) bool {
if !((is8BitInt(t) || is16BitInt(t) || is32BitInt(t)) && isSigned(t)) {
break
}
- v.reset(OpCopy)
- v.Type = x.Type
+ v.reset(OpS390XMOVDreg)
v.AddArg(x)
return true
}
// match: (MOVWreg x:(MOVBreg _))
// cond:
- // result: x
+ // result: (MOVDreg x)
for {
x := v.Args[0]
if x.Op != OpS390XMOVBreg {
break
}
- v.reset(OpCopy)
- v.Type = x.Type
+ v.reset(OpS390XMOVDreg)
v.AddArg(x)
return true
}
// match: (MOVWreg x:(MOVBZreg _))
// cond:
- // result: x
+ // result: (MOVDreg x)
for {
x := v.Args[0]
if x.Op != OpS390XMOVBZreg {
break
}
- v.reset(OpCopy)
- v.Type = x.Type
+ v.reset(OpS390XMOVDreg)
v.AddArg(x)
return true
}
// match: (MOVWreg x:(MOVHreg _))
// cond:
- // result: x
+ // result: (MOVDreg x)
for {
x := v.Args[0]
if x.Op != OpS390XMOVHreg {
break
}
- v.reset(OpCopy)
- v.Type = x.Type
+ v.reset(OpS390XMOVDreg)
v.AddArg(x)
return true
}
// match: (MOVWreg x:(MOVHreg _))
// cond:
- // result: x
+ // result: (MOVDreg x)
for {
x := v.Args[0]
if x.Op != OpS390XMOVHreg {
break
}
- v.reset(OpCopy)
- v.Type = x.Type
+ v.reset(OpS390XMOVDreg)
v.AddArg(x)
return true
}
// match: (MOVWreg x:(MOVWreg _))
// cond:
- // result: x
+ // result: (MOVDreg x)
for {
x := v.Args[0]
if x.Op != OpS390XMOVWreg {
break
}
- v.reset(OpCopy)
- v.Type = x.Type
+ v.reset(OpS390XMOVDreg)
v.AddArg(x)
return true
}
diff --git a/src/cmd/compile/internal/syntax/parser.go b/src/cmd/compile/internal/syntax/parser.go
index 121dfb7..e45ca05 100644
--- a/src/cmd/compile/internal/syntax/parser.go
+++ b/src/cmd/compile/internal/syntax/parser.go
@@ -1634,6 +1634,8 @@ func (p *parser) stmtBody(context string) []Stmt {
return body
}
+var dummyCond = &Name{Value: "false"}
+
func (p *parser) header(forStmt bool) (init SimpleStmt, cond Expr, post SimpleStmt) {
if p.tok == _Lbrace {
return
@@ -1680,7 +1682,8 @@ func (p *parser) header(forStmt bool) (init SimpleStmt, cond Expr, post SimpleSt
case *ExprStmt:
cond = s.X
default:
- p.error("invalid condition, tag, or type switch guard")
+ p.syntax_error(fmt.Sprintf("%s used as value", String(s)))
+ cond = dummyCond // avoid follow-up error for if statements
}
p.xnest = outer
diff --git a/src/cmd/dist/test.go b/src/cmd/dist/test.go
index 7d5f79f..c51dcea 100644
--- a/src/cmd/dist/test.go
+++ b/src/cmd/dist/test.go
@@ -15,7 +15,6 @@ import (
"os/exec"
"path/filepath"
"regexp"
- "runtime"
"strconv"
"strings"
"sync"
@@ -354,7 +353,7 @@ func (t *tester) registerTests() {
// This test needs its stdout/stderr to be terminals, so we don't run it from cmd/go's tests.
// See issue 18153.
- if runtime.GOOS == "linux" {
+ if t.goos == "linux" {
t.tests = append(t.tests, distTest{
name: "cmd_go_test_terminal",
heading: "cmd/go terminal test",
@@ -568,7 +567,7 @@ func (t *tester) registerTests() {
if t.gohostos == "linux" && t.goarch == "amd64" {
t.registerTest("testasan", "../misc/cgo/testasan", "go", "run", "main.go")
}
- if t.gohostos == "linux" && t.goarch == "amd64" {
+ if t.goos == "linux" && t.goarch == "amd64" {
t.registerTest("testsanitizers", "../misc/cgo/testsanitizers", "./test.bash")
}
if t.hasBash() && t.goos != "android" && !t.iOS() && t.gohostos != "windows" {
diff --git a/src/cmd/go/alldocs.go b/src/cmd/go/alldocs.go
index e93fd6e..3d5dd2b 100644
--- a/src/cmd/go/alldocs.go
+++ b/src/cmd/go/alldocs.go
@@ -17,7 +17,7 @@
// clean remove object files
// doc show documentation for package or symbol
// env print Go environment information
-// bug print information for bug reports
+// bug start a bug report
// fix run go tool fix on packages
// fmt run gofmt on package sources
// generate generate Go files by processing source
@@ -324,15 +324,14 @@
// each named variable on its own line.
//
//
-// Print information for bug reports
+// Start a bug report
//
// Usage:
//
// go bug
//
-// Bug prints information that helps file effective bug reports.
-//
-// Bugs may be reported at https://golang.org/issue/new.
+// Bug opens the default browser and starts a new bug report.
+// The report includes useful system information.
//
//
// Run go tool fix on packages
diff --git a/src/cmd/go/get.go b/src/cmd/go/get.go
index 1d7677c..6fb4235 100644
--- a/src/cmd/go/get.go
+++ b/src/cmd/go/get.go
@@ -428,7 +428,7 @@ func downloadPackage(p *Package) error {
return fmt.Errorf("cannot download, $GOPATH not set. For more details see: 'go help gopath'")
}
// Guard against people setting GOPATH=$GOROOT.
- if list[0] == goroot {
+ if filepath.Clean(list[0]) == filepath.Clean(goroot) {
return fmt.Errorf("cannot download, $GOPATH must not be set to $GOROOT. For more details see: 'go help gopath'")
}
if _, err := os.Stat(filepath.Join(list[0], "src/cmd/go/alldocs.go")); err == nil {
diff --git a/src/cmd/go/go_test.go b/src/cmd/go/go_test.go
index f26c366..56de65c 100644
--- a/src/cmd/go/go_test.go
+++ b/src/cmd/go/go_test.go
@@ -1683,173 +1683,111 @@ func homeEnvName() string {
}
}
-// Test go env missing GOPATH shows default.
-func TestMissingGOPATHEnvShowsDefault(t *testing.T) {
+func TestDefaultGOPATH(t *testing.T) {
tg := testgo(t)
defer tg.cleanup()
tg.parallel()
- tg.setenv("GOPATH", "")
- tg.run("env", "GOPATH")
+ tg.tempDir("home/go")
+ tg.setenv(homeEnvName(), tg.path("home"))
- want := filepath.Join(os.Getenv(homeEnvName()), "go")
- got := strings.TrimSpace(tg.getStdout())
- if got != want {
- t.Errorf("got %q; want %q", got, want)
- }
-}
-
-// Test go get missing GOPATH causes go get to warn if directory doesn't exist.
-func TestMissingGOPATHGetWarnsIfNotExists(t *testing.T) {
- testenv.MustHaveExternalNetwork(t)
-
- if _, err := exec.LookPath("git"); err != nil {
- t.Skip("skipping because git binary not found")
- }
-
- tg := testgo(t)
- defer tg.cleanup()
-
- // setenv variables for test and defer deleting temporary home directory.
- tg.setenv("GOPATH", "")
- tmp, err := ioutil.TempDir("", "")
- if err != nil {
- t.Fatalf("could not create tmp home: %v", err)
- }
- defer os.RemoveAll(tmp)
- tg.setenv(homeEnvName(), tmp)
+ tg.run("env", "GOPATH")
+ tg.grepStdout(regexp.QuoteMeta(tg.path("home/go")), "want GOPATH=$HOME/go")
- tg.run("get", "-v", "github.com/golang/example/hello")
+ tg.setenv("GOROOT", tg.path("home/go"))
+ tg.run("env", "GOPATH")
+ tg.grepStdoutNot(".", "want unset GOPATH because GOROOT=$HOME/go")
- want := fmt.Sprintf("created GOPATH=%s; see 'go help gopath'", filepath.Join(tmp, "go"))
- got := strings.TrimSpace(tg.getStderr())
- if !strings.Contains(got, want) {
- t.Errorf("got %q; want %q", got, want)
- }
+ tg.setenv("GOROOT", tg.path("home/go")+"/")
+ tg.run("env", "GOPATH")
+ tg.grepStdoutNot(".", "want unset GOPATH because GOROOT=$HOME/go/")
}
-// Test go get missing GOPATH causes no warning if directory exists.
-func TestMissingGOPATHGetDoesntWarnIfExists(t *testing.T) {
+func TestDefaultGOPATHGet(t *testing.T) {
testenv.MustHaveExternalNetwork(t)
- if _, err := exec.LookPath("git"); err != nil {
- t.Skip("skipping because git binary not found")
- }
-
tg := testgo(t)
defer tg.cleanup()
-
- // setenv variables for test and defer resetting them.
tg.setenv("GOPATH", "")
- tmp, err := ioutil.TempDir("", "")
- if err != nil {
- t.Fatalf("could not create tmp home: %v", err)
- }
- defer os.RemoveAll(tmp)
- if err := os.Mkdir(filepath.Join(tmp, "go"), 0777); err != nil {
- t.Fatalf("could not create $HOME/go: %v", err)
- }
+ tg.tempDir("home")
+ tg.setenv(homeEnvName(), tg.path("home"))
- tg.setenv(homeEnvName(), tmp)
+ // warn for creating directory
+ tg.run("get", "-v", "github.com/golang/example/hello")
+ tg.grepStderr("created GOPATH="+regexp.QuoteMeta(tg.path("home/go"))+"; see 'go help gopath'", "did not create GOPATH")
+ // no warning if directory already exists
+ tg.must(os.RemoveAll(tg.path("home/go")))
+ tg.tempDir("home/go")
tg.run("get", "github.com/golang/example/hello")
+ tg.grepStderrNot(".", "expected no output on standard error")
- got := strings.TrimSpace(tg.getStderr())
- if got != "" {
- t.Errorf("got %q; wants empty", got)
- }
-}
-
-// Test go get missing GOPATH fails if pointed file is not a directory.
-func TestMissingGOPATHGetFailsIfItsNotDirectory(t *testing.T) {
- testenv.MustHaveExternalNetwork(t)
-
- tg := testgo(t)
- defer tg.cleanup()
-
- // setenv variables for test and defer resetting them.
- tg.setenv("GOPATH", "")
- tmp, err := ioutil.TempDir("", "")
- if err != nil {
- t.Fatalf("could not create tmp home: %v", err)
- }
- defer os.RemoveAll(tmp)
-
- path := filepath.Join(tmp, "go")
- if err := ioutil.WriteFile(path, nil, 0777); err != nil {
- t.Fatalf("could not create GOPATH at %s: %v", path, err)
- }
- tg.setenv(homeEnvName(), tmp)
-
- const pkg = "github.com/golang/example/hello"
- tg.runFail("get", pkg)
-
- msg := "not a directory"
- if runtime.GOOS == "windows" {
- msg = "The system cannot find the path specified."
- }
- want := fmt.Sprintf("package %s: mkdir %s: %s", pkg, filepath.Join(tmp, "go"), msg)
- got := strings.TrimSpace(tg.getStderr())
- if got != want {
- t.Errorf("got %q; wants %q", got, want)
- }
+ // error if $HOME/go is a file
+ tg.must(os.RemoveAll(tg.path("home/go")))
+ tg.tempFile("home/go", "")
+ tg.runFail("get", "github.com/golang/example/hello")
+ tg.grepStderr(`mkdir .*[/\\]go: .*(not a directory|cannot find the path)`, "expected error because $HOME/go is a file")
}
-// Test go install of missing package when missing GOPATH fails and shows default GOPATH.
-func TestMissingGOPATHInstallMissingPackageFailsAndShowsDefault(t *testing.T) {
+func TestDefaultGOPATHPrintedSearchList(t *testing.T) {
tg := testgo(t)
defer tg.cleanup()
-
- // setenv variables for test and defer resetting them.
tg.setenv("GOPATH", "")
- tmp, err := ioutil.TempDir("", "")
- if err != nil {
- t.Fatalf("could not create tmp home: %v", err)
- }
- defer os.RemoveAll(tmp)
- if err := os.Mkdir(filepath.Join(tmp, "go"), 0777); err != nil {
- t.Fatalf("could not create $HOME/go: %v", err)
- }
- tg.setenv(homeEnvName(), tmp)
-
- const pkg = "github.com/golang/example/hello"
- tg.runFail("install", pkg)
-
- pkgPath := filepath.Join(strings.Split(pkg, "/")...)
- want := fmt.Sprintf("can't load package: package %s: cannot find package \"%s\" in any of:", pkg, pkg) +
- fmt.Sprintf("\n\t%s (from $GOROOT)", filepath.Join(runtime.GOROOT(), "src", pkgPath)) +
- fmt.Sprintf("\n\t%s (from $GOPATH)", filepath.Join(tmp, "go", "src", pkgPath))
+ tg.tempDir("home")
+ tg.setenv(homeEnvName(), tg.path("home"))
- got := strings.TrimSpace(tg.getStderr())
- if got != want {
- t.Errorf("got %q; wants %q", got, want)
- }
+ tg.runFail("install", "github.com/golang/example/hello")
+ tg.grepStderr(regexp.QuoteMeta(tg.path("home/go/src/github.com/golang/example/hello"))+`.*from \$GOPATH`, "expected default GOPATH")
}
// Issue 4186. go get cannot be used to download packages to $GOROOT.
// Test that without GOPATH set, go get should fail.
-func TestWithoutGOPATHGoGetFails(t *testing.T) {
+func TestGoGetIntoGOROOT(t *testing.T) {
testenv.MustHaveExternalNetwork(t)
tg := testgo(t)
defer tg.cleanup()
tg.parallel()
tg.tempDir("src")
- tg.setenv("GOPATH", "")
+
+ // Fails because GOROOT=GOPATH
+ tg.setenv("GOPATH", tg.path("."))
tg.setenv("GOROOT", tg.path("."))
- tg.runFail("get", "-d", "golang.org/x/codereview/cmd/hgpatch")
-}
+ tg.runFail("get", "-d", "github.com/golang/example/hello")
+ tg.grepStderr("warning: GOPATH set to GOROOT", "go should detect GOPATH=GOROOT")
+ tg.grepStderr(`\$GOPATH must not be set to \$GOROOT`, "go should detect GOPATH=GOROOT")
-// Test that with GOPATH=$GOROOT, go get should fail.
-func TestWithGOPATHEqualsGOROOTGoGetFails(t *testing.T) {
- testenv.MustHaveExternalNetwork(t)
+ // Fails because GOROOT=GOPATH after cleaning.
+ tg.setenv("GOPATH", tg.path(".")+"/")
+ tg.setenv("GOROOT", tg.path("."))
+ tg.runFail("get", "-d", "github.com/golang/example/hello")
+ tg.grepStderr("warning: GOPATH set to GOROOT", "go should detect GOPATH=GOROOT")
+ tg.grepStderr(`\$GOPATH must not be set to \$GOROOT`, "go should detect GOPATH=GOROOT")
- tg := testgo(t)
- defer tg.cleanup()
- tg.parallel()
- tg.tempDir("src")
tg.setenv("GOPATH", tg.path("."))
- tg.setenv("GOROOT", tg.path("."))
- tg.runFail("get", "-d", "golang.org/x/codereview/cmd/hgpatch")
+ tg.setenv("GOROOT", tg.path(".")+"/")
+ tg.runFail("get", "-d", "github.com/golang/example/hello")
+ tg.grepStderr("warning: GOPATH set to GOROOT", "go should detect GOPATH=GOROOT")
+ tg.grepStderr(`\$GOPATH must not be set to \$GOROOT`, "go should detect GOPATH=GOROOT")
+
+ // Fails because GOROOT=$HOME/go so default GOPATH unset.
+ tg.tempDir("home/go")
+ tg.setenv(homeEnvName(), tg.path("home"))
+ tg.setenv("GOPATH", "")
+ tg.setenv("GOROOT", tg.path("home/go"))
+ tg.runFail("get", "-d", "github.com/golang/example/hello")
+ tg.grepStderr(`\$GOPATH not set`, "expected GOPATH not set")
+
+ tg.setenv(homeEnvName(), tg.path("home")+"/")
+ tg.setenv("GOPATH", "")
+ tg.setenv("GOROOT", tg.path("home/go"))
+ tg.runFail("get", "-d", "github.com/golang/example/hello")
+ tg.grepStderr(`\$GOPATH not set`, "expected GOPATH not set")
+
+ tg.setenv(homeEnvName(), tg.path("home"))
+ tg.setenv("GOPATH", "")
+ tg.setenv("GOROOT", tg.path("home/go")+"/")
+ tg.runFail("get", "-d", "github.com/golang/example/hello")
+ tg.grepStderr(`\$GOPATH not set`, "expected GOPATH not set")
}
func TestLdflagsArgumentsWithSpacesIssue3941(t *testing.T) {
@@ -3744,6 +3682,13 @@ func TestMatchesOnlySubtestParallelIsOK(t *testing.T) {
tg.grepBoth(okPattern, "go test did not say ok")
}
+// Issue 18845
+func TestBenchTimeout(t *testing.T) {
+ tg := testgo(t)
+ defer tg.cleanup()
+ tg.run("test", "-bench", ".", "-timeout", "750ms", "testdata/timeoutbench_test.go")
+}
+
func TestLinkXImportPathEscape(t *testing.T) {
// golang.org/issue/16710
tg := testgo(t)
diff --git a/src/cmd/go/main.go b/src/cmd/go/main.go
index 07fc4e2..d80ff2d 100644
--- a/src/cmd/go/main.go
+++ b/src/cmd/go/main.go
@@ -136,7 +136,7 @@ func main() {
// Diagnose common mistake: GOPATH==GOROOT.
// This setting is equivalent to not setting GOPATH at all,
// which is not what most people want when they do it.
- if gopath := buildContext.GOPATH; gopath == runtime.GOROOT() {
+ if gopath := buildContext.GOPATH; filepath.Clean(gopath) == filepath.Clean(runtime.GOROOT()) {
fmt.Fprintf(os.Stderr, "warning: GOPATH set to GOROOT (%s) has no effect\n", gopath)
} else {
for _, p := range filepath.SplitList(gopath) {
diff --git a/src/cmd/go/testdata/timeoutbench_test.go b/src/cmd/go/testdata/timeoutbench_test.go
new file mode 100644
index 0000000..57a8888
--- /dev/null
+++ b/src/cmd/go/testdata/timeoutbench_test.go
@@ -0,0 +1,10 @@
+package timeoutbench_test
+
+import (
+ "testing"
+ "time"
+)
+
+func BenchmarkSleep1s(b *testing.B) {
+ time.Sleep(1 * time.Second)
+}
diff --git a/src/cmd/link/internal/ld/config.go b/src/cmd/link/internal/ld/config.go
index 7d00ff1..2656c24 100644
--- a/src/cmd/link/internal/ld/config.go
+++ b/src/cmd/link/internal/ld/config.go
@@ -238,6 +238,8 @@ func determineLinkMode(ctxt *Link) {
Linkmode = LinkExternal
} else if iscgo && externalobj {
Linkmode = LinkExternal
+ } else if Buildmode == BuildmodePIE {
+ Linkmode = LinkExternal // https://golang.org/issue/18968
} else {
Linkmode = LinkInternal
}
diff --git a/src/crypto/x509/root_linux.go b/src/crypto/x509/root_linux.go
index 38dd72d..aa1785e 100644
--- a/src/crypto/x509/root_linux.go
+++ b/src/crypto/x509/root_linux.go
@@ -7,8 +7,8 @@ package x509
// Possible certificate files; stop after finding one.
var certFiles = []string{
"/etc/ssl/certs/ca-certificates.crt", // Debian/Ubuntu/Gentoo etc.
- "/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem", // CentOS/RHEL 7
"/etc/pki/tls/certs/ca-bundle.crt", // Fedora/RHEL 6
"/etc/ssl/ca-bundle.pem", // OpenSUSE
"/etc/pki/tls/cacert.pem", // OpenELEC
+ "/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem", // CentOS/RHEL 7
}
diff --git a/src/database/sql/ctxutil.go b/src/database/sql/ctxutil.go
index 1071446..bd652b5 100644
--- a/src/database/sql/ctxutil.go
+++ b/src/database/sql/ctxutil.go
@@ -35,15 +35,12 @@ func ctxDriverExec(ctx context.Context, execer driver.Execer, query string, nvda
return nil, err
}
- resi, err := execer.Exec(query, dargs)
- if err == nil {
- select {
- default:
- case <-ctx.Done():
- return resi, ctx.Err()
- }
+ select {
+ default:
+ case <-ctx.Done():
+ return nil, ctx.Err()
}
- return resi, err
+ return execer.Exec(query, dargs)
}
func ctxDriverQuery(ctx context.Context, queryer driver.Queryer, query string, nvdargs []driver.NamedValue) (driver.Rows, error) {
@@ -56,16 +53,12 @@ func ctxDriverQuery(ctx context.Context, queryer driver.Queryer, query string, n
return nil, err
}
- rowsi, err := queryer.Query(query, dargs)
- if err == nil {
- select {
- default:
- case <-ctx.Done():
- rowsi.Close()
- return nil, ctx.Err()
- }
+ select {
+ default:
+ case <-ctx.Done():
+ return nil, ctx.Err()
}
- return rowsi, err
+ return queryer.Query(query, dargs)
}
func ctxDriverStmtExec(ctx context.Context, si driver.Stmt, nvdargs []driver.NamedValue) (driver.Result, error) {
@@ -77,15 +70,12 @@ func ctxDriverStmtExec(ctx context.Context, si driver.Stmt, nvdargs []driver.Nam
return nil, err
}
- resi, err := si.Exec(dargs)
- if err == nil {
- select {
- default:
- case <-ctx.Done():
- return resi, ctx.Err()
- }
+ select {
+ default:
+ case <-ctx.Done():
+ return nil, ctx.Err()
}
- return resi, err
+ return si.Exec(dargs)
}
func ctxDriverStmtQuery(ctx context.Context, si driver.Stmt, nvdargs []driver.NamedValue) (driver.Rows, error) {
@@ -97,16 +87,12 @@ func ctxDriverStmtQuery(ctx context.Context, si driver.Stmt, nvdargs []driver.Na
return nil, err
}
- rowsi, err := si.Query(dargs)
- if err == nil {
- select {
- default:
- case <-ctx.Done():
- rowsi.Close()
- return nil, ctx.Err()
- }
+ select {
+ default:
+ case <-ctx.Done():
+ return nil, ctx.Err()
}
- return rowsi, err
+ return si.Query(dargs)
}
var errLevelNotSupported = errors.New("sql: selected isolation level is not supported")
diff --git a/src/database/sql/sql.go b/src/database/sql/sql.go
index feb9122..c016681 100644
--- a/src/database/sql/sql.go
+++ b/src/database/sql/sql.go
@@ -305,8 +305,9 @@ type DB struct {
mu sync.Mutex // protects following fields
freeConn []*driverConn
- connRequests []chan connRequest
- numOpen int // number of opened and pending open connections
+ connRequests map[uint64]chan connRequest
+ nextRequest uint64 // Next key to use in connRequests.
+ numOpen int // number of opened and pending open connections
// Used to signal the need for new connections
// a goroutine running connectionOpener() reads on this chan and
// maybeOpenNewConnections sends on the chan (one send per needed connection)
@@ -572,10 +573,11 @@ func Open(driverName, dataSourceName string) (*DB, error) {
return nil, fmt.Errorf("sql: unknown driver %q (forgotten import?)", driverName)
}
db := &DB{
- driver: driveri,
- dsn: dataSourceName,
- openerCh: make(chan struct{}, connectionRequestQueueSize),
- lastPut: make(map[*driverConn]string),
+ driver: driveri,
+ dsn: dataSourceName,
+ openerCh: make(chan struct{}, connectionRequestQueueSize),
+ lastPut: make(map[*driverConn]string),
+ connRequests: make(map[uint64]chan connRequest),
}
go db.connectionOpener()
return db, nil
@@ -881,6 +883,14 @@ type connRequest struct {
var errDBClosed = errors.New("sql: database is closed")
+// nextRequestKeyLocked returns the next connection request key.
+// It is assumed that nextRequest will not overflow.
+func (db *DB) nextRequestKeyLocked() uint64 {
+ next := db.nextRequest
+ db.nextRequest++
+ return next
+}
+
// conn returns a newly-opened or cached *driverConn.
func (db *DB) conn(ctx context.Context, strategy connReuseStrategy) (*driverConn, error) {
db.mu.Lock()
@@ -918,12 +928,25 @@ func (db *DB) conn(ctx context.Context, strategy connReuseStrategy) (*driverConn
// Make the connRequest channel. It's buffered so that the
// connectionOpener doesn't block while waiting for the req to be read.
req := make(chan connRequest, 1)
- db.connRequests = append(db.connRequests, req)
+ reqKey := db.nextRequestKeyLocked()
+ db.connRequests[reqKey] = req
db.mu.Unlock()
// Timeout the connection request with the context.
select {
case <-ctx.Done():
+ // Remove the connection request and ensure no value has been sent
+ // on it after removing.
+ db.mu.Lock()
+ delete(db.connRequests, reqKey)
+ db.mu.Unlock()
+ select {
+ default:
+ case ret, ok := <-req:
+ if ok {
+ db.putConn(ret.conn, ret.err)
+ }
+ }
return nil, ctx.Err()
case ret, ok := <-req:
if !ok {
@@ -1044,12 +1067,12 @@ func (db *DB) putConnDBLocked(dc *driverConn, err error) bool {
return false
}
if c := len(db.connRequests); c > 0 {
- req := db.connRequests[0]
- // This copy is O(n) but in practice faster than a linked list.
- // TODO: consider compacting it down less often and
- // moving the base instead?
- copy(db.connRequests, db.connRequests[1:])
- db.connRequests = db.connRequests[:c-1]
+ var req chan connRequest
+ var reqKey uint64
+ for reqKey, req = range db.connRequests {
+ break
+ }
+ delete(db.connRequests, reqKey) // Remove from pending requests.
if err == nil {
dc.inUse = true
}
@@ -2071,14 +2094,21 @@ type Rows struct {
dc *driverConn // owned; must call releaseConn when closed to release
releaseConn func(error)
rowsi driver.Rows
+ cancel func() // called when Rows is closed, may be nil.
+ closeStmt *driverStmt // if non-nil, statement to Close on close
- // closed value is 1 when the Rows is closed.
- // Use atomic operations on value when checking value.
- closed int32
- cancel func() // called when Rows is closed, may be nil.
- lastcols []driver.Value
- lasterr error // non-nil only if closed is true
- closeStmt *driverStmt // if non-nil, statement to Close on close
+ // closemu prevents Rows from closing while there
+ // is an active streaming result. It is held for read during non-close operations
+ // and exclusively during close.
+ //
+ // closemu guards lasterr and closed.
+ closemu sync.RWMutex
+ closed bool
+ lasterr error // non-nil only if closed is true
+
+ // lastcols is only used in Scan, Next, and NextResultSet which are expected
+ // not not be called concurrently.
+ lastcols []driver.Value
}
func (rs *Rows) initContextClose(ctx context.Context) {
@@ -2089,7 +2119,7 @@ func (rs *Rows) initContextClose(ctx context.Context) {
// awaitDone blocks until the rows are closed or the context canceled.
func (rs *Rows) awaitDone(ctx context.Context) {
<-ctx.Done()
- rs.Close()
+ rs.close(ctx.Err())
}
// Next prepares the next result row for reading with the Scan method. It
@@ -2099,8 +2129,19 @@ func (rs *Rows) awaitDone(ctx context.Context) {
//
// Every call to Scan, even the first one, must be preceded by a call to Next.
func (rs *Rows) Next() bool {
- if rs.isClosed() {
- return false
+ var doClose, ok bool
+ withLock(rs.closemu.RLocker(), func() {
+ doClose, ok = rs.nextLocked()
+ })
+ if doClose {
+ rs.Close()
+ }
+ return ok
+}
+
+func (rs *Rows) nextLocked() (doClose, ok bool) {
+ if rs.closed {
+ return false, false
}
if rs.lastcols == nil {
rs.lastcols = make([]driver.Value, len(rs.rowsi.Columns()))
@@ -2109,23 +2150,21 @@ func (rs *Rows) Next() bool {
if rs.lasterr != nil {
// Close the connection if there is a driver error.
if rs.lasterr != io.EOF {
- rs.Close()
- return false
+ return true, false
}
nextResultSet, ok := rs.rowsi.(driver.RowsNextResultSet)
if !ok {
- rs.Close()
- return false
+ return true, false
}
// The driver is at the end of the current result set.
// Test to see if there is another result set after the current one.
// Only close Rows if there is no further result sets to read.
if !nextResultSet.HasNextResultSet() {
- rs.Close()
+ doClose = true
}
- return false
+ return doClose, false
}
- return true
+ return false, true
}
// NextResultSet prepares the next result set for reading. It returns true if
@@ -2137,18 +2176,28 @@ func (rs *Rows) Next() bool {
// scanning. If there are further result sets they may not have rows in the result
// set.
func (rs *Rows) NextResultSet() bool {
- if rs.isClosed() {
+ var doClose bool
+ defer func() {
+ if doClose {
+ rs.Close()
+ }
+ }()
+ rs.closemu.RLock()
+ defer rs.closemu.RUnlock()
+
+ if rs.closed {
return false
}
+
rs.lastcols = nil
nextResultSet, ok := rs.rowsi.(driver.RowsNextResultSet)
if !ok {
- rs.Close()
+ doClose = true
return false
}
rs.lasterr = nextResultSet.NextResultSet()
if rs.lasterr != nil {
- rs.Close()
+ doClose = true
return false
}
return true
@@ -2157,6 +2206,8 @@ func (rs *Rows) NextResultSet() bool {
// Err returns the error, if any, that was encountered during iteration.
// Err may be called after an explicit or implicit Close.
func (rs *Rows) Err() error {
+ rs.closemu.RLock()
+ defer rs.closemu.RUnlock()
if rs.lasterr == io.EOF {
return nil
}
@@ -2167,7 +2218,9 @@ func (rs *Rows) Err() error {
// Columns returns an error if the rows are closed, or if the rows
// are from QueryRow and there was a deferred error.
func (rs *Rows) Columns() ([]string, error) {
- if rs.isClosed() {
+ rs.closemu.RLock()
+ defer rs.closemu.RUnlock()
+ if rs.closed {
return nil, errors.New("sql: Rows are closed")
}
if rs.rowsi == nil {
@@ -2179,7 +2232,9 @@ func (rs *Rows) Columns() ([]string, error) {
// ColumnTypes returns column information such as column type, length,
// and nullable. Some information may not be available from some drivers.
func (rs *Rows) ColumnTypes() ([]*ColumnType, error) {
- if rs.isClosed() {
+ rs.closemu.RLock()
+ defer rs.closemu.RUnlock()
+ if rs.closed {
return nil, errors.New("sql: Rows are closed")
}
if rs.rowsi == nil {
@@ -2329,9 +2384,13 @@ func rowsColumnInfoSetup(rowsi driver.Rows) []*ColumnType {
// For scanning into *bool, the source may be true, false, 1, 0, or
// string inputs parseable by strconv.ParseBool.
func (rs *Rows) Scan(dest ...interface{}) error {
- if rs.isClosed() {
+ rs.closemu.RLock()
+ if rs.closed {
+ rs.closemu.RUnlock()
return errors.New("sql: Rows are closed")
}
+ rs.closemu.RUnlock()
+
if rs.lastcols == nil {
return errors.New("sql: Scan called without calling Next")
}
@@ -2351,20 +2410,28 @@ func (rs *Rows) Scan(dest ...interface{}) error {
// hook throug a test only mutex.
var rowsCloseHook = func() func(*Rows, *error) { return nil }
-func (rs *Rows) isClosed() bool {
- return atomic.LoadInt32(&rs.closed) != 0
-}
-
// Close closes the Rows, preventing further enumeration. If Next is called
// and returns false and there are no further result sets,
// the Rows are closed automatically and it will suffice to check the
// result of Err. Close is idempotent and does not affect the result of Err.
func (rs *Rows) Close() error {
- if !atomic.CompareAndSwapInt32(&rs.closed, 0, 1) {
+ return rs.close(nil)
+}
+
+func (rs *Rows) close(err error) error {
+ rs.closemu.Lock()
+ defer rs.closemu.Unlock()
+
+ if rs.closed {
return nil
}
+ rs.closed = true
+
+ if rs.lasterr == nil {
+ rs.lasterr = err
+ }
- err := rs.rowsi.Close()
+ err = rs.rowsi.Close()
if fn := rowsCloseHook(); fn != nil {
fn(rs, &err)
}
diff --git a/src/database/sql/sql_test.go b/src/database/sql/sql_test.go
index 898df3b..450e5f1 100644
--- a/src/database/sql/sql_test.go
+++ b/src/database/sql/sql_test.go
@@ -153,8 +153,13 @@ func closeDB(t testing.TB, db *DB) {
if err != nil {
t.Fatalf("error closing DB: %v", err)
}
- if count := db.numOpenConns(); count != 0 {
- t.Fatalf("%d connections still open after closing DB", count)
+
+ var numOpen int
+ if !waitCondition(5*time.Second, 5*time.Millisecond, func() bool {
+ numOpen = db.numOpenConns()
+ return numOpen == 0
+ }) {
+ t.Fatalf("%d connections still open after closing DB", numOpen)
}
}
@@ -276,6 +281,7 @@ func TestQuery(t *testing.T) {
}
}
+// TestQueryContext tests canceling the context while scanning the rows.
func TestQueryContext(t *testing.T) {
db := newTestDB(t, "people")
defer closeDB(t, db)
@@ -297,7 +303,7 @@ func TestQueryContext(t *testing.T) {
for rows.Next() {
if index == 2 {
cancel()
- time.Sleep(10 * time.Millisecond)
+ waitForRowsClose(t, rows, 5*time.Second)
}
var r row
err = rows.Scan(&r.age, &r.name)
@@ -313,9 +319,13 @@ func TestQueryContext(t *testing.T) {
got = append(got, r)
index++
}
- err = rows.Err()
- if err != nil {
- t.Fatalf("Err: %v", err)
+ select {
+ case <-ctx.Done():
+ if err := ctx.Err(); err != context.Canceled {
+ t.Fatalf("context err = %v; want context.Canceled")
+ }
+ default:
+ t.Fatalf("context err = nil; want context.Canceled")
}
want := []row{
{age: 1, name: "Alice"},
@@ -327,6 +337,7 @@ func TestQueryContext(t *testing.T) {
// And verify that the final rows.Next() call, which hit EOF,
// also closed the rows connection.
+ waitForRowsClose(t, rows, 5*time.Second)
waitForFree(t, db, 5*time.Second, 1)
if prepares := numPrepares(t, db) - prepares0; prepares != 1 {
t.Errorf("executed %d Prepare statements; want 1", prepares)
@@ -356,12 +367,27 @@ func waitForFree(t *testing.T, db *DB, maxWait time.Duration, want int) {
}
}
+func waitForRowsClose(t *testing.T, rows *Rows, maxWait time.Duration) {
+ if !waitCondition(maxWait, 5*time.Millisecond, func() bool {
+ rows.closemu.RLock()
+ defer rows.closemu.RUnlock()
+ return rows.closed
+ }) {
+ t.Fatal("failed to close rows")
+ }
+}
+
+// TestQueryContextWait ensures that rows and all internal statements are closed when
+// a query context is closed during execution.
func TestQueryContextWait(t *testing.T) {
db := newTestDB(t, "people")
defer closeDB(t, db)
prepares0 := numPrepares(t, db)
- ctx, _ := context.WithTimeout(context.Background(), time.Millisecond*15)
+ // TODO(kardianos): convert this from using a timeout to using an explicit
+ // cancel when the query signals that is is "executing" the query.
+ ctx, cancel := context.WithTimeout(context.Background(), 300*time.Millisecond)
+ defer cancel()
// This will trigger the *fakeConn.Prepare method which will take time
// performing the query. The ctxDriverPrepare func will check the context
@@ -374,10 +400,15 @@ func TestQueryContextWait(t *testing.T) {
// Verify closed rows connection after error condition.
waitForFree(t, db, 5*time.Second, 1)
if prepares := numPrepares(t, db) - prepares0; prepares != 1 {
- t.Errorf("executed %d Prepare statements; want 1", prepares)
+ // TODO(kardianos): if the context timeouts before the db.QueryContext
+ // executes this check may fail. After adjusting how the context
+ // is canceled above revert this back to a Fatal error.
+ t.Logf("executed %d Prepare statements; want 1", prepares)
}
}
+// TestTxContextWait tests the transaction behavior when the tx context is canceled
+// during execution of the query.
func TestTxContextWait(t *testing.T) {
db := newTestDB(t, "people")
defer closeDB(t, db)
@@ -386,6 +417,10 @@ func TestTxContextWait(t *testing.T) {
tx, err := db.BeginTx(ctx, nil)
if err != nil {
+ // Guard against the context being canceled before BeginTx completes.
+ if err == context.DeadlineExceeded {
+ t.Skip("tx context canceled prior to first use")
+ }
t.Fatal(err)
}
@@ -398,12 +433,6 @@ func TestTxContextWait(t *testing.T) {
}
waitForFree(t, db, 5*time.Second, 0)
-
- // Ensure the dropped connection allows more connections to be made.
- // Checked on DB Close.
- waitCondition(5*time.Second, 5*time.Millisecond, func() bool {
- return db.numOpenConns() == 0
- })
}
func TestMultiResultSetQuery(t *testing.T) {
@@ -527,6 +556,63 @@ func TestQueryNamedArg(t *testing.T) {
}
}
+func TestPoolExhaustOnCancel(t *testing.T) {
+ if testing.Short() {
+ t.Skip("long test")
+ }
+ db := newTestDB(t, "people")
+ defer closeDB(t, db)
+
+ max := 3
+
+ db.SetMaxOpenConns(max)
+
+ // First saturate the connection pool.
+ // Then start new requests for a connection that is cancelled after it is requested.
+
+ var saturate, saturateDone sync.WaitGroup
+ saturate.Add(max)
+ saturateDone.Add(max)
+
+ for i := 0; i < max; i++ {
+ go func() {
+ saturate.Done()
+ rows, err := db.Query("WAIT|500ms|SELECT|people|name,photo|")
+ if err != nil {
+ t.Fatalf("Query: %v", err)
+ }
+ rows.Close()
+ saturateDone.Done()
+ }()
+ }
+
+ saturate.Wait()
+
+ // Now cancel the request while it is waiting.
+ ctx, cancel := context.WithTimeout(context.Background(), time.Second*2)
+ defer cancel()
+
+ for i := 0; i < max; i++ {
+ ctxReq, cancelReq := context.WithCancel(ctx)
+ go func() {
+ time.Sleep(time.Millisecond * 100)
+ cancelReq()
+ }()
+ err := db.PingContext(ctxReq)
+ if err != context.Canceled {
+ t.Fatalf("PingContext (Exhaust): %v", err)
+ }
+ }
+
+ saturateDone.Wait()
+
+ // Now try to open a normal connection.
+ err := db.PingContext(ctx)
+ if err != nil {
+ t.Fatalf("PingContext (Normal): %v", err)
+ }
+}
+
func TestByteOwnership(t *testing.T) {
db := newTestDB(t, "people")
defer closeDB(t, db)
@@ -2677,7 +2763,6 @@ func TestIssue18429(t *testing.T) {
}()
}
wg.Wait()
- time.Sleep(milliWait * 3 * time.Millisecond)
}
// TestIssue18719 closes the context right before use. The sql.driverConn
@@ -2720,14 +2805,8 @@ func TestIssue18719(t *testing.T) {
// Do not explicitly rollback. The rollback will happen from the
// canceled context.
- // Wait for connections to return to pool.
- var numOpen int
- if !waitCondition(5*time.Second, 5*time.Millisecond, func() bool {
- numOpen = db.numOpenConns()
- return numOpen == 0
- }) {
- t.Fatalf("open conns after hitting EOF = %d; want 0", numOpen)
- }
+ cancel()
+ waitForRowsClose(t, rows, 5*time.Second)
}
func TestConcurrency(t *testing.T) {
diff --git a/src/encoding/xml/marshal.go b/src/encoding/xml/marshal.go
index 1176f5d..4c6ba8c 100644
--- a/src/encoding/xml/marshal.go
+++ b/src/encoding/xml/marshal.go
@@ -775,6 +775,20 @@ func (p *printer) marshalSimple(typ reflect.Type, val reflect.Value) (string, []
var ddBytes = []byte("--")
+// indirect drills into interfaces and pointers, returning the pointed-at value.
+// If it encounters a nil interface or pointer, indirect returns that nil value.
+// This can turn into an infinite loop given a cyclic chain,
+// but it matches the Go 1 behavior.
+func indirect(vf reflect.Value) reflect.Value {
+ for vf.Kind() == reflect.Interface || vf.Kind() == reflect.Ptr {
+ if vf.IsNil() {
+ return vf
+ }
+ vf = vf.Elem()
+ }
+ return vf
+}
+
func (p *printer) marshalStruct(tinfo *typeInfo, val reflect.Value) error {
s := parentStack{p: p}
for i := range tinfo.fields {
@@ -816,17 +830,9 @@ func (p *printer) marshalStruct(tinfo *typeInfo, val reflect.Value) error {
continue
}
}
- // Drill into interfaces and pointers.
- // This can turn into an infinite loop given a cyclic chain,
- // but it matches the Go 1 behavior.
- for vf.Kind() == reflect.Interface || vf.Kind() == reflect.Ptr {
- if vf.IsNil() {
- return nil
- }
- vf = vf.Elem()
- }
var scratch [64]byte
+ vf = indirect(vf)
switch vf.Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
if err := emit(p, strconv.AppendInt(scratch[:0], vf.Int(), 10)); err != nil {
@@ -861,6 +867,7 @@ func (p *printer) marshalStruct(tinfo *typeInfo, val reflect.Value) error {
if err := s.trim(finfo.parents); err != nil {
return err
}
+ vf = indirect(vf)
k := vf.Kind()
if !(k == reflect.String || k == reflect.Slice && vf.Type().Elem().Kind() == reflect.Uint8) {
return fmt.Errorf("xml: bad type for comment field of %s", val.Type())
@@ -901,6 +908,7 @@ func (p *printer) marshalStruct(tinfo *typeInfo, val reflect.Value) error {
continue
case fInnerXml:
+ vf = indirect(vf)
iface := vf.Interface()
switch raw := iface.(type) {
case []byte:
diff --git a/src/encoding/xml/marshal_test.go b/src/encoding/xml/marshal_test.go
index d79b99a..5ec7ece 100644
--- a/src/encoding/xml/marshal_test.go
+++ b/src/encoding/xml/marshal_test.go
@@ -386,6 +386,140 @@ func ifaceptr(x interface{}) interface{} {
return &x
}
+func stringptr(x string) *string {
+ return &x
+}
+
+type T1 struct{}
+type T2 struct{}
+type T3 struct{}
+
+type IndirComment struct {
+ T1 T1
+ Comment *string `xml:",comment"`
+ T2 T2
+}
+
+type DirectComment struct {
+ T1 T1
+ Comment string `xml:",comment"`
+ T2 T2
+}
+
+type IfaceComment struct {
+ T1 T1
+ Comment interface{} `xml:",comment"`
+ T2 T2
+}
+
+type IndirChardata struct {
+ T1 T1
+ Chardata *string `xml:",chardata"`
+ T2 T2
+}
+
+type DirectChardata struct {
+ T1 T1
+ Chardata string `xml:",chardata"`
+ T2 T2
+}
+
+type IfaceChardata struct {
+ T1 T1
+ Chardata interface{} `xml:",chardata"`
+ T2 T2
+}
+
+type IndirCDATA struct {
+ T1 T1
+ CDATA *string `xml:",cdata"`
+ T2 T2
+}
+
+type DirectCDATA struct {
+ T1 T1
+ CDATA string `xml:",cdata"`
+ T2 T2
+}
+
+type IfaceCDATA struct {
+ T1 T1
+ CDATA interface{} `xml:",cdata"`
+ T2 T2
+}
+
+type IndirInnerXML struct {
+ T1 T1
+ InnerXML *string `xml:",innerxml"`
+ T2 T2
+}
+
+type DirectInnerXML struct {
+ T1 T1
+ InnerXML string `xml:",innerxml"`
+ T2 T2
+}
+
+type IfaceInnerXML struct {
+ T1 T1
+ InnerXML interface{} `xml:",innerxml"`
+ T2 T2
+}
+
+type IndirElement struct {
+ T1 T1
+ Element *string
+ T2 T2
+}
+
+type DirectElement struct {
+ T1 T1
+ Element string
+ T2 T2
+}
+
+type IfaceElement struct {
+ T1 T1
+ Element interface{}
+ T2 T2
+}
+
+type IndirOmitEmpty struct {
+ T1 T1
+ OmitEmpty *string `xml:",omitempty"`
+ T2 T2
+}
+
+type DirectOmitEmpty struct {
+ T1 T1
+ OmitEmpty string `xml:",omitempty"`
+ T2 T2
+}
+
+type IfaceOmitEmpty struct {
+ T1 T1
+ OmitEmpty interface{} `xml:",omitempty"`
+ T2 T2
+}
+
+type IndirAny struct {
+ T1 T1
+ Any *string `xml:",any"`
+ T2 T2
+}
+
+type DirectAny struct {
+ T1 T1
+ Any string `xml:",any"`
+ T2 T2
+}
+
+type IfaceAny struct {
+ T1 T1
+ Any interface{} `xml:",any"`
+ T2 T2
+}
+
var (
nameAttr = "Sarah"
ageAttr = uint(12)
@@ -398,10 +532,12 @@ var (
// please try to make them two-way as well to ensure that
// marshaling and unmarshaling are as symmetrical as feasible.
var marshalTests = []struct {
- Value interface{}
- ExpectXML string
- MarshalOnly bool
- UnmarshalOnly bool
+ Value interface{}
+ ExpectXML string
+ MarshalOnly bool
+ MarshalError string
+ UnmarshalOnly bool
+ UnmarshalError string
}{
// Test nil marshals to nothing
{Value: nil, ExpectXML: ``, MarshalOnly: true},
@@ -1133,6 +1269,382 @@ var marshalTests = []struct {
ExpectXML: `<NestedAndCData><A><B></B><B></B></A><![CDATA[test]]></NestedAndCData>`,
Value: &NestedAndCData{AB: make([]string, 2), CDATA: "test"},
},
+ // Test pointer indirection in various kinds of fields.
+ // https://golang.org/issue/19063
+ {
+ ExpectXML: `<IndirComment><T1></T1><!--hi--><T2></T2></IndirComment>`,
+ Value: &IndirComment{Comment: stringptr("hi")},
+ MarshalOnly: true,
+ },
+ {
+ ExpectXML: `<IndirComment><T1></T1><T2></T2></IndirComment>`,
+ Value: &IndirComment{Comment: stringptr("")},
+ MarshalOnly: true,
+ },
+ {
+ ExpectXML: `<IndirComment><T1></T1><T2></T2></IndirComment>`,
+ Value: &IndirComment{Comment: nil},
+ MarshalError: "xml: bad type for comment field of xml.IndirComment",
+ },
+ {
+ ExpectXML: `<IndirComment><T1></T1><!--hi--><T2></T2></IndirComment>`,
+ Value: &IndirComment{Comment: nil},
+ UnmarshalOnly: true,
+ },
+ {
+ ExpectXML: `<IfaceComment><T1></T1><!--hi--><T2></T2></IfaceComment>`,
+ Value: &IfaceComment{Comment: "hi"},
+ MarshalOnly: true,
+ },
+ {
+ ExpectXML: `<IfaceComment><T1></T1><!--hi--><T2></T2></IfaceComment>`,
+ Value: &IfaceComment{Comment: nil},
+ UnmarshalOnly: true,
+ },
+ {
+ ExpectXML: `<IfaceComment><T1></T1><T2></T2></IfaceComment>`,
+ Value: &IfaceComment{Comment: nil},
+ MarshalError: "xml: bad type for comment field of xml.IfaceComment",
+ },
+ {
+ ExpectXML: `<IfaceComment><T1></T1><T2></T2></IfaceComment>`,
+ Value: &IfaceComment{Comment: nil},
+ UnmarshalOnly: true,
+ },
+ {
+ ExpectXML: `<DirectComment><T1></T1><!--hi--><T2></T2></DirectComment>`,
+ Value: &DirectComment{Comment: string("hi")},
+ },
+ {
+ ExpectXML: `<DirectComment><T1></T1><T2></T2></DirectComment>`,
+ Value: &DirectComment{Comment: string("")},
+ },
+ {
+ ExpectXML: `<IndirChardata><T1></T1>hi<T2></T2></IndirChardata>`,
+ Value: &IndirChardata{Chardata: stringptr("hi")},
+ },
+ {
+ ExpectXML: `<IndirChardata><T1></T1><![CDATA[hi]]><T2></T2></IndirChardata>`,
+ Value: &IndirChardata{Chardata: stringptr("hi")},
+ UnmarshalOnly: true, // marshals without CDATA
+ },
+ {
+ ExpectXML: `<IndirChardata><T1></T1><T2></T2></IndirChardata>`,
+ Value: &IndirChardata{Chardata: stringptr("")},
+ },
+ {
+ ExpectXML: `<IndirChardata><T1></T1><T2></T2></IndirChardata>`,
+ Value: &IndirChardata{Chardata: nil},
+ MarshalOnly: true, // unmarshal leaves Chardata=stringptr("")
+ },
+ {
+ ExpectXML: `<IfaceChardata><T1></T1>hi<T2></T2></IfaceChardata>`,
+ Value: &IfaceChardata{Chardata: string("hi")},
+ UnmarshalError: "cannot unmarshal into interface {}",
+ },
+ {
+ ExpectXML: `<IfaceChardata><T1></T1><![CDATA[hi]]><T2></T2></IfaceChardata>`,
+ Value: &IfaceChardata{Chardata: string("hi")},
+ UnmarshalOnly: true, // marshals without CDATA
+ UnmarshalError: "cannot unmarshal into interface {}",
+ },
+ {
+ ExpectXML: `<IfaceChardata><T1></T1><T2></T2></IfaceChardata>`,
+ Value: &IfaceChardata{Chardata: string("")},
+ UnmarshalError: "cannot unmarshal into interface {}",
+ },
+ {
+ ExpectXML: `<IfaceChardata><T1></T1><T2></T2></IfaceChardata>`,
+ Value: &IfaceChardata{Chardata: nil},
+ UnmarshalError: "cannot unmarshal into interface {}",
+ },
+ {
+ ExpectXML: `<DirectChardata><T1></T1>hi<T2></T2></DirectChardata>`,
+ Value: &DirectChardata{Chardata: string("hi")},
+ },
+ {
+ ExpectXML: `<DirectChardata><T1></T1><![CDATA[hi]]><T2></T2></DirectChardata>`,
+ Value: &DirectChardata{Chardata: string("hi")},
+ UnmarshalOnly: true, // marshals without CDATA
+ },
+ {
+ ExpectXML: `<DirectChardata><T1></T1><T2></T2></DirectChardata>`,
+ Value: &DirectChardata{Chardata: string("")},
+ },
+ {
+ ExpectXML: `<IndirCDATA><T1></T1><![CDATA[hi]]><T2></T2></IndirCDATA>`,
+ Value: &IndirCDATA{CDATA: stringptr("hi")},
+ },
+ {
+ ExpectXML: `<IndirCDATA><T1></T1>hi<T2></T2></IndirCDATA>`,
+ Value: &IndirCDATA{CDATA: stringptr("hi")},
+ UnmarshalOnly: true, // marshals with CDATA
+ },
+ {
+ ExpectXML: `<IndirCDATA><T1></T1><T2></T2></IndirCDATA>`,
+ Value: &IndirCDATA{CDATA: stringptr("")},
+ },
+ {
+ ExpectXML: `<IndirCDATA><T1></T1><T2></T2></IndirCDATA>`,
+ Value: &IndirCDATA{CDATA: nil},
+ MarshalOnly: true, // unmarshal leaves CDATA=stringptr("")
+ },
+ {
+ ExpectXML: `<IfaceCDATA><T1></T1><![CDATA[hi]]><T2></T2></IfaceCDATA>`,
+ Value: &IfaceCDATA{CDATA: string("hi")},
+ UnmarshalError: "cannot unmarshal into interface {}",
+ },
+ {
+ ExpectXML: `<IfaceCDATA><T1></T1>hi<T2></T2></IfaceCDATA>`,
+ Value: &IfaceCDATA{CDATA: string("hi")},
+ UnmarshalOnly: true, // marshals with CDATA
+ UnmarshalError: "cannot unmarshal into interface {}",
+ },
+ {
+ ExpectXML: `<IfaceCDATA><T1></T1><T2></T2></IfaceCDATA>`,
+ Value: &IfaceCDATA{CDATA: string("")},
+ UnmarshalError: "cannot unmarshal into interface {}",
+ },
+ {
+ ExpectXML: `<IfaceCDATA><T1></T1><T2></T2></IfaceCDATA>`,
+ Value: &IfaceCDATA{CDATA: nil},
+ UnmarshalError: "cannot unmarshal into interface {}",
+ },
+ {
+ ExpectXML: `<DirectCDATA><T1></T1><![CDATA[hi]]><T2></T2></DirectCDATA>`,
+ Value: &DirectCDATA{CDATA: string("hi")},
+ },
+ {
+ ExpectXML: `<DirectCDATA><T1></T1>hi<T2></T2></DirectCDATA>`,
+ Value: &DirectCDATA{CDATA: string("hi")},
+ UnmarshalOnly: true, // marshals with CDATA
+ },
+ {
+ ExpectXML: `<DirectCDATA><T1></T1><T2></T2></DirectCDATA>`,
+ Value: &DirectCDATA{CDATA: string("")},
+ },
+ {
+ ExpectXML: `<IndirInnerXML><T1></T1><hi/><T2></T2></IndirInnerXML>`,
+ Value: &IndirInnerXML{InnerXML: stringptr("<hi/>")},
+ MarshalOnly: true,
+ },
+ {
+ ExpectXML: `<IndirInnerXML><T1></T1><T2></T2></IndirInnerXML>`,
+ Value: &IndirInnerXML{InnerXML: stringptr("")},
+ MarshalOnly: true,
+ },
+ {
+ ExpectXML: `<IndirInnerXML><T1></T1><T2></T2></IndirInnerXML>`,
+ Value: &IndirInnerXML{InnerXML: nil},
+ },
+ {
+ ExpectXML: `<IndirInnerXML><T1></T1><hi/><T2></T2></IndirInnerXML>`,
+ Value: &IndirInnerXML{InnerXML: nil},
+ UnmarshalOnly: true,
+ },
+ {
+ ExpectXML: `<IfaceInnerXML><T1></T1><hi/><T2></T2></IfaceInnerXML>`,
+ Value: &IfaceInnerXML{InnerXML: "<hi/>"},
+ MarshalOnly: true,
+ },
+ {
+ ExpectXML: `<IfaceInnerXML><T1></T1><hi/><T2></T2></IfaceInnerXML>`,
+ Value: &IfaceInnerXML{InnerXML: nil},
+ UnmarshalOnly: true,
+ },
+ {
+ ExpectXML: `<IfaceInnerXML><T1></T1><T2></T2></IfaceInnerXML>`,
+ Value: &IfaceInnerXML{InnerXML: nil},
+ },
+ {
+ ExpectXML: `<IfaceInnerXML><T1></T1><T2></T2></IfaceInnerXML>`,
+ Value: &IfaceInnerXML{InnerXML: nil},
+ UnmarshalOnly: true,
+ },
+ {
+ ExpectXML: `<DirectInnerXML><T1></T1><hi/><T2></T2></DirectInnerXML>`,
+ Value: &DirectInnerXML{InnerXML: string("<hi/>")},
+ MarshalOnly: true,
+ },
+ {
+ ExpectXML: `<DirectInnerXML><T1></T1><hi/><T2></T2></DirectInnerXML>`,
+ Value: &DirectInnerXML{InnerXML: string("<T1></T1><hi/><T2></T2>")},
+ UnmarshalOnly: true,
+ },
+ {
+ ExpectXML: `<DirectInnerXML><T1></T1><T2></T2></DirectInnerXML>`,
+ Value: &DirectInnerXML{InnerXML: string("")},
+ MarshalOnly: true,
+ },
+ {
+ ExpectXML: `<DirectInnerXML><T1></T1><T2></T2></DirectInnerXML>`,
+ Value: &DirectInnerXML{InnerXML: string("<T1></T1><T2></T2>")},
+ UnmarshalOnly: true,
+ },
+ {
+ ExpectXML: `<IndirElement><T1></T1><Element>hi</Element><T2></T2></IndirElement>`,
+ Value: &IndirElement{Element: stringptr("hi")},
+ },
+ {
+ ExpectXML: `<IndirElement><T1></T1><Element></Element><T2></T2></IndirElement>`,
+ Value: &IndirElement{Element: stringptr("")},
+ },
+ {
+ ExpectXML: `<IndirElement><T1></T1><T2></T2></IndirElement>`,
+ Value: &IndirElement{Element: nil},
+ },
+ {
+ ExpectXML: `<IfaceElement><T1></T1><Element>hi</Element><T2></T2></IfaceElement>`,
+ Value: &IfaceElement{Element: "hi"},
+ MarshalOnly: true,
+ },
+ {
+ ExpectXML: `<IfaceElement><T1></T1><Element>hi</Element><T2></T2></IfaceElement>`,
+ Value: &IfaceElement{Element: nil},
+ UnmarshalOnly: true,
+ },
+ {
+ ExpectXML: `<IfaceElement><T1></T1><T2></T2></IfaceElement>`,
+ Value: &IfaceElement{Element: nil},
+ },
+ {
+ ExpectXML: `<IfaceElement><T1></T1><T2></T2></IfaceElement>`,
+ Value: &IfaceElement{Element: nil},
+ UnmarshalOnly: true,
+ },
+ {
+ ExpectXML: `<DirectElement><T1></T1><Element>hi</Element><T2></T2></DirectElement>`,
+ Value: &DirectElement{Element: string("hi")},
+ },
+ {
+ ExpectXML: `<DirectElement><T1></T1><Element></Element><T2></T2></DirectElement>`,
+ Value: &DirectElement{Element: string("")},
+ },
+ {
+ ExpectXML: `<IndirOmitEmpty><T1></T1><OmitEmpty>hi</OmitEmpty><T2></T2></IndirOmitEmpty>`,
+ Value: &IndirOmitEmpty{OmitEmpty: stringptr("hi")},
+ },
+ {
+ // Note: Changed in Go 1.8 to include <OmitEmpty> element (because x.OmitEmpty != nil).
+ ExpectXML: `<IndirOmitEmpty><T1></T1><OmitEmpty></OmitEmpty><T2></T2></IndirOmitEmpty>`,
+ Value: &IndirOmitEmpty{OmitEmpty: stringptr("")},
+ MarshalOnly: true,
+ },
+ {
+ ExpectXML: `<IndirOmitEmpty><T1></T1><OmitEmpty></OmitEmpty><T2></T2></IndirOmitEmpty>`,
+ Value: &IndirOmitEmpty{OmitEmpty: stringptr("")},
+ UnmarshalOnly: true,
+ },
+ {
+ ExpectXML: `<IndirOmitEmpty><T1></T1><T2></T2></IndirOmitEmpty>`,
+ Value: &IndirOmitEmpty{OmitEmpty: nil},
+ },
+ {
+ ExpectXML: `<IfaceOmitEmpty><T1></T1><OmitEmpty>hi</OmitEmpty><T2></T2></IfaceOmitEmpty>`,
+ Value: &IfaceOmitEmpty{OmitEmpty: "hi"},
+ MarshalOnly: true,
+ },
+ {
+ ExpectXML: `<IfaceOmitEmpty><T1></T1><OmitEmpty>hi</OmitEmpty><T2></T2></IfaceOmitEmpty>`,
+ Value: &IfaceOmitEmpty{OmitEmpty: nil},
+ UnmarshalOnly: true,
+ },
+ {
+ ExpectXML: `<IfaceOmitEmpty><T1></T1><T2></T2></IfaceOmitEmpty>`,
+ Value: &IfaceOmitEmpty{OmitEmpty: nil},
+ },
+ {
+ ExpectXML: `<IfaceOmitEmpty><T1></T1><T2></T2></IfaceOmitEmpty>`,
+ Value: &IfaceOmitEmpty{OmitEmpty: nil},
+ UnmarshalOnly: true,
+ },
+ {
+ ExpectXML: `<DirectOmitEmpty><T1></T1><OmitEmpty>hi</OmitEmpty><T2></T2></DirectOmitEmpty>`,
+ Value: &DirectOmitEmpty{OmitEmpty: string("hi")},
+ },
+ {
+ ExpectXML: `<DirectOmitEmpty><T1></T1><T2></T2></DirectOmitEmpty>`,
+ Value: &DirectOmitEmpty{OmitEmpty: string("")},
+ },
+ {
+ ExpectXML: `<IndirAny><T1></T1><Any>hi</Any><T2></T2></IndirAny>`,
+ Value: &IndirAny{Any: stringptr("hi")},
+ },
+ {
+ ExpectXML: `<IndirAny><T1></T1><Any></Any><T2></T2></IndirAny>`,
+ Value: &IndirAny{Any: stringptr("")},
+ },
+ {
+ ExpectXML: `<IndirAny><T1></T1><T2></T2></IndirAny>`,
+ Value: &IndirAny{Any: nil},
+ },
+ {
+ ExpectXML: `<IfaceAny><T1></T1><Any>hi</Any><T2></T2></IfaceAny>`,
+ Value: &IfaceAny{Any: "hi"},
+ MarshalOnly: true,
+ },
+ {
+ ExpectXML: `<IfaceAny><T1></T1><Any>hi</Any><T2></T2></IfaceAny>`,
+ Value: &IfaceAny{Any: nil},
+ UnmarshalOnly: true,
+ },
+ {
+ ExpectXML: `<IfaceAny><T1></T1><T2></T2></IfaceAny>`,
+ Value: &IfaceAny{Any: nil},
+ },
+ {
+ ExpectXML: `<IfaceAny><T1></T1><T2></T2></IfaceAny>`,
+ Value: &IfaceAny{Any: nil},
+ UnmarshalOnly: true,
+ },
+ {
+ ExpectXML: `<DirectAny><T1></T1><Any>hi</Any><T2></T2></DirectAny>`,
+ Value: &DirectAny{Any: string("hi")},
+ },
+ {
+ ExpectXML: `<DirectAny><T1></T1><Any></Any><T2></T2></DirectAny>`,
+ Value: &DirectAny{Any: string("")},
+ },
+ {
+ ExpectXML: `<IndirFoo><T1></T1><Foo>hi</Foo><T2></T2></IndirFoo>`,
+ Value: &IndirAny{Any: stringptr("hi")},
+ UnmarshalOnly: true,
+ },
+ {
+ ExpectXML: `<IndirFoo><T1></T1><Foo></Foo><T2></T2></IndirFoo>`,
+ Value: &IndirAny{Any: stringptr("")},
+ UnmarshalOnly: true,
+ },
+ {
+ ExpectXML: `<IndirFoo><T1></T1><T2></T2></IndirFoo>`,
+ Value: &IndirAny{Any: nil},
+ UnmarshalOnly: true,
+ },
+ {
+ ExpectXML: `<IfaceFoo><T1></T1><Foo>hi</Foo><T2></T2></IfaceFoo>`,
+ Value: &IfaceAny{Any: nil},
+ UnmarshalOnly: true,
+ },
+ {
+ ExpectXML: `<IfaceFoo><T1></T1><T2></T2></IfaceFoo>`,
+ Value: &IfaceAny{Any: nil},
+ UnmarshalOnly: true,
+ },
+ {
+ ExpectXML: `<IfaceFoo><T1></T1><T2></T2></IfaceFoo>`,
+ Value: &IfaceAny{Any: nil},
+ UnmarshalOnly: true,
+ },
+ {
+ ExpectXML: `<DirectFoo><T1></T1><Foo>hi</Foo><T2></T2></DirectFoo>`,
+ Value: &DirectAny{Any: string("hi")},
+ UnmarshalOnly: true,
+ },
+ {
+ ExpectXML: `<DirectFoo><T1></T1><Foo></Foo><T2></T2></DirectFoo>`,
+ Value: &DirectAny{Any: string("")},
+ UnmarshalOnly: true,
+ },
}
func TestMarshal(t *testing.T) {
@@ -1142,7 +1654,17 @@ func TestMarshal(t *testing.T) {
}
data, err := Marshal(test.Value)
if err != nil {
- t.Errorf("#%d: marshal(%#v): %s", idx, test.Value, err)
+ if test.MarshalError == "" {
+ t.Errorf("#%d: marshal(%#v): %s", idx, test.Value, err)
+ continue
+ }
+ if !strings.Contains(err.Error(), test.MarshalError) {
+ t.Errorf("#%d: marshal(%#v): %s, want %q", idx, test.Value, err, test.MarshalError)
+ }
+ continue
+ }
+ if test.MarshalError != "" {
+ t.Errorf("#%d: Marshal succeeded, want error %q", idx, test.MarshalError)
continue
}
if got, want := string(data), test.ExpectXML; got != want {
@@ -1268,8 +1790,16 @@ func TestUnmarshal(t *testing.T) {
}
if err != nil {
- t.Errorf("#%d: unexpected error: %#v", i, err)
- } else if got, want := dest, test.Value; !reflect.DeepEqual(got, want) {
+ if test.UnmarshalError == "" {
+ t.Errorf("#%d: unmarshal(%#v): %s", i, test.ExpectXML, err)
+ continue
+ }
+ if !strings.Contains(err.Error(), test.UnmarshalError) {
+ t.Errorf("#%d: unmarshal(%#v): %s, want %q", i, test.ExpectXML, err, test.UnmarshalError)
+ }
+ continue
+ }
+ if got, want := dest, test.Value; !reflect.DeepEqual(got, want) {
t.Errorf("#%d: unmarshal(%q):\nhave %#v\nwant %#v", i, test.ExpectXML, got, want)
}
}
diff --git a/src/go/build/build.go b/src/go/build/build.go
index da12d50..f11bc0c 100644
--- a/src/go/build/build.go
+++ b/src/go/build/build.go
@@ -266,7 +266,7 @@ func defaultGOPATH() string {
}
if home := os.Getenv(env); home != "" {
def := filepath.Join(home, "go")
- if def == runtime.GOROOT() {
+ if filepath.Clean(def) == filepath.Clean(runtime.GOROOT()) {
// Don't set the default GOPATH to GOROOT,
// as that will trigger warnings from the go tool.
return ""
diff --git a/src/reflect/all_test.go b/src/reflect/all_test.go
index 022350b..3eca293 100644
--- a/src/reflect/all_test.go
+++ b/src/reflect/all_test.go
@@ -2478,17 +2478,24 @@ func TestNumMethodOnDDD(t *testing.T) {
}
func TestPtrTo(t *testing.T) {
+ // This block of code means that the ptrToThis field of the
+ // reflect data for *unsafe.Pointer is non zero, see
+ // https://golang.org/issue/19003
+ var x unsafe.Pointer
+ var y = &x
+ var z = &y
+
var i int
- typ := TypeOf(i)
+ typ := TypeOf(z)
for i = 0; i < 100; i++ {
typ = PtrTo(typ)
}
for i = 0; i < 100; i++ {
typ = typ.Elem()
}
- if typ != TypeOf(i) {
- t.Errorf("after 100 PtrTo and Elem, have %s, want %s", typ, TypeOf(i))
+ if typ != TypeOf(z) {
+ t.Errorf("after 100 PtrTo and Elem, have %s, want %s", typ, TypeOf(z))
}
}
diff --git a/src/reflect/type.go b/src/reflect/type.go
index 9d6e7a6..5d3c5c6 100644
--- a/src/reflect/type.go
+++ b/src/reflect/type.go
@@ -1469,6 +1469,7 @@ func (t *rtype) ptrTo() *rtype {
pp := *prototype
pp.str = resolveReflectName(newName(s, "", "", false))
+ pp.ptrToThis = 0
// For the type structures linked into the binary, the
// compiler provides a good hash of the string.
diff --git a/src/runtime/mgc.go b/src/runtime/mgc.go
index 0b996d8..cd57720 100644
--- a/src/runtime/mgc.go
+++ b/src/runtime/mgc.go
@@ -628,10 +628,12 @@ func (c *gcControllerState) endCycle() {
//go:nowritebarrier
func (c *gcControllerState) enlistWorker() {
// If there are idle Ps, wake one so it will run an idle worker.
- if atomic.Load(&sched.npidle) != 0 && atomic.Load(&sched.nmspinning) == 0 {
- wakep()
- return
- }
+ // NOTE: This is suspected of causing deadlocks. See golang.org/issue/19112.
+ //
+ // if atomic.Load(&sched.npidle) != 0 && atomic.Load(&sched.nmspinning) == 0 {
+ // wakep()
+ // return
+ // }
// There are no idle Ps. If we need more dedicated workers,
// try to preempt a running P so it will switch to a worker.
diff --git a/src/runtime/testdata/testprogcgo/threadpprof.go b/src/runtime/testdata/testprogcgo/threadpprof.go
index 44afb91..3da8296 100644
--- a/src/runtime/testdata/testprogcgo/threadpprof.go
+++ b/src/runtime/testdata/testprogcgo/threadpprof.go
@@ -61,7 +61,7 @@ static void* cpuHogDriver(void* arg __attribute__ ((unused))) {
return 0;
}
-void runCPUHogThread() {
+void runCPUHogThread(void) {
pthread_t tid;
pthread_create(&tid, 0, cpuHogDriver, 0);
}
diff --git a/src/runtime/testdata/testprogcgo/traceback.go b/src/runtime/testdata/testprogcgo/traceback.go
index e8b0a04..2a023f6 100644
--- a/src/runtime/testdata/testprogcgo/traceback.go
+++ b/src/runtime/testdata/testprogcgo/traceback.go
@@ -15,16 +15,16 @@ package main
char *p;
-static int f3() {
+static int f3(void) {
*p = 0;
return 0;
}
-static int f2() {
+static int f2(void) {
return f3();
}
-static int f1() {
+static int f1(void) {
return f2();
}
diff --git a/src/testing/testing.go b/src/testing/testing.go
index ddbdc25..bd19a31 100644
--- a/src/testing/testing.go
+++ b/src/testing/testing.go
@@ -821,6 +821,7 @@ func (m *M) Run() int {
haveExamples = len(m.examples) > 0
testRan, testOk := runTests(m.deps.MatchString, m.tests)
exampleRan, exampleOk := runExamples(m.deps.MatchString, m.examples)
+ stopAlarm()
if !testRan && !exampleRan && *matchBenchmarks == "" {
fmt.Fprintln(os.Stderr, "testing: warning: no tests to run")
}
diff --git a/src/vendor/golang_org/x/crypto/curve25519/const_amd64.h b/src/vendor/golang_org/x/crypto/curve25519/const_amd64.h
new file mode 100644
index 0000000..80ad222
--- /dev/null
+++ b/src/vendor/golang_org/x/crypto/curve25519/const_amd64.h
@@ -0,0 +1,8 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This code was translated into a form compatible with 6a from the public
+// domain sources in SUPERCOP: http://bench.cr.yp.to/supercop.html
+
+#define REDMASK51 0x0007FFFFFFFFFFFF
diff --git a/src/vendor/golang_org/x/crypto/curve25519/const_amd64.s b/src/vendor/golang_org/x/crypto/curve25519/const_amd64.s
index 797f9b0..0ad5398 100644
--- a/src/vendor/golang_org/x/crypto/curve25519/const_amd64.s
+++ b/src/vendor/golang_org/x/crypto/curve25519/const_amd64.s
@@ -7,8 +7,8 @@
// +build amd64,!gccgo,!appengine
-DATA ·REDMASK51(SB)/8, $0x0007FFFFFFFFFFFF
-GLOBL ·REDMASK51(SB), 8, $8
+// These constants cannot be encoded in non-MOVQ immediates.
+// We access them directly from memory instead.
DATA ·_121666_213(SB)/8, $996687872
GLOBL ·_121666_213(SB), 8, $8
diff --git a/src/vendor/golang_org/x/crypto/curve25519/freeze_amd64.s b/src/vendor/golang_org/x/crypto/curve25519/freeze_amd64.s
index 932800b..536479b 100644
--- a/src/vendor/golang_org/x/crypto/curve25519/freeze_amd64.s
+++ b/src/vendor/golang_org/x/crypto/curve25519/freeze_amd64.s
@@ -7,6 +7,8 @@
// +build amd64,!gccgo,!appengine
+#include "const_amd64.h"
+
// func freeze(inout *[5]uint64)
TEXT ·freeze(SB),7,$0-8
MOVQ inout+0(FP), DI
@@ -16,7 +18,7 @@ TEXT ·freeze(SB),7,$0-8
MOVQ 16(DI),CX
MOVQ 24(DI),R8
MOVQ 32(DI),R9
- MOVQ ·REDMASK51(SB),AX
+ MOVQ $REDMASK51,AX
MOVQ AX,R10
SUBQ $18,R10
MOVQ $3,R11
diff --git a/src/vendor/golang_org/x/crypto/curve25519/ladderstep_amd64.s b/src/vendor/golang_org/x/crypto/curve25519/ladderstep_amd64.s
index ee7b36c..7074e5c 100644
--- a/src/vendor/golang_org/x/crypto/curve25519/ladderstep_amd64.s
+++ b/src/vendor/golang_org/x/crypto/curve25519/ladderstep_amd64.s
@@ -7,6 +7,8 @@
// +build amd64,!gccgo,!appengine
+#include "const_amd64.h"
+
// func ladderstep(inout *[5][5]uint64)
TEXT ·ladderstep(SB),0,$296-8
MOVQ inout+0(FP),DI
@@ -118,7 +120,7 @@ TEXT ·ladderstep(SB),0,$296-8
MULQ 72(SP)
ADDQ AX,R12
ADCQ DX,R13
- MOVQ ·REDMASK51(SB),DX
+ MOVQ $REDMASK51,DX
SHLQ $13,CX:SI
ANDQ DX,SI
SHLQ $13,R9:R8
@@ -233,7 +235,7 @@ TEXT ·ladderstep(SB),0,$296-8
MULQ 32(SP)
ADDQ AX,R12
ADCQ DX,R13
- MOVQ ·REDMASK51(SB),DX
+ MOVQ $REDMASK51,DX
SHLQ $13,CX:SI
ANDQ DX,SI
SHLQ $13,R9:R8
@@ -438,7 +440,7 @@ TEXT ·ladderstep(SB),0,$296-8
MULQ 72(SP)
ADDQ AX,R12
ADCQ DX,R13
- MOVQ ·REDMASK51(SB),DX
+ MOVQ $REDMASK51,DX
SHLQ $13,CX:SI
ANDQ DX,SI
SHLQ $13,R9:R8
@@ -588,7 +590,7 @@ TEXT ·ladderstep(SB),0,$296-8
MULQ 32(SP)
ADDQ AX,R12
ADCQ DX,R13
- MOVQ ·REDMASK51(SB),DX
+ MOVQ $REDMASK51,DX
SHLQ $13,CX:SI
ANDQ DX,SI
SHLQ $13,R9:R8
@@ -728,7 +730,7 @@ TEXT ·ladderstep(SB),0,$296-8
MULQ 152(DI)
ADDQ AX,R12
ADCQ DX,R13
- MOVQ ·REDMASK51(SB),DX
+ MOVQ $REDMASK51,DX
SHLQ $13,CX:SI
ANDQ DX,SI
SHLQ $13,R9:R8
@@ -843,7 +845,7 @@ TEXT ·ladderstep(SB),0,$296-8
MULQ 192(DI)
ADDQ AX,R12
ADCQ DX,R13
- MOVQ ·REDMASK51(SB),DX
+ MOVQ $REDMASK51,DX
SHLQ $13,CX:SI
ANDQ DX,SI
SHLQ $13,R9:R8
@@ -993,7 +995,7 @@ TEXT ·ladderstep(SB),0,$296-8
MULQ 32(DI)
ADDQ AX,R12
ADCQ DX,R13
- MOVQ ·REDMASK51(SB),DX
+ MOVQ $REDMASK51,DX
SHLQ $13,CX:SI
ANDQ DX,SI
SHLQ $13,R9:R8
@@ -1143,7 +1145,7 @@ TEXT ·ladderstep(SB),0,$296-8
MULQ 112(SP)
ADDQ AX,R12
ADCQ DX,R13
- MOVQ ·REDMASK51(SB),DX
+ MOVQ $REDMASK51,DX
SHLQ $13,CX:SI
ANDQ DX,SI
SHLQ $13,R9:R8
@@ -1329,7 +1331,7 @@ TEXT ·ladderstep(SB),0,$296-8
MULQ 192(SP)
ADDQ AX,R12
ADCQ DX,R13
- MOVQ ·REDMASK51(SB),DX
+ MOVQ $REDMASK51,DX
SHLQ $13,CX:SI
ANDQ DX,SI
SHLQ $13,R9:R8
diff --git a/src/vendor/golang_org/x/crypto/curve25519/mul_amd64.s b/src/vendor/golang_org/x/crypto/curve25519/mul_amd64.s
index 33ce57d..b162e65 100644
--- a/src/vendor/golang_org/x/crypto/curve25519/mul_amd64.s
+++ b/src/vendor/golang_org/x/crypto/curve25519/mul_amd64.s
@@ -7,6 +7,8 @@
// +build amd64,!gccgo,!appengine
+#include "const_amd64.h"
+
// func mul(dest, a, b *[5]uint64)
TEXT ·mul(SB),0,$16-24
MOVQ dest+0(FP), DI
@@ -121,7 +123,7 @@ TEXT ·mul(SB),0,$16-24
MULQ 32(CX)
ADDQ AX,R14
ADCQ DX,R15
- MOVQ ·REDMASK51(SB),SI
+ MOVQ $REDMASK51,SI
SHLQ $13,R9:R8
ANDQ SI,R8
SHLQ $13,R11:R10
diff --git a/src/vendor/golang_org/x/crypto/curve25519/square_amd64.s b/src/vendor/golang_org/x/crypto/curve25519/square_amd64.s
index 3a92804..4e864a8 100644
--- a/src/vendor/golang_org/x/crypto/curve25519/square_amd64.s
+++ b/src/vendor/golang_org/x/crypto/curve25519/square_amd64.s
@@ -7,6 +7,8 @@
// +build amd64,!gccgo,!appengine
+#include "const_amd64.h"
+
// func square(out, in *[5]uint64)
TEXT ·square(SB),7,$0-16
MOVQ out+0(FP), DI
@@ -84,7 +86,7 @@ TEXT ·square(SB),7,$0-16
MULQ 32(SI)
ADDQ AX,R13
ADCQ DX,R14
- MOVQ ·REDMASK51(SB),SI
+ MOVQ $REDMASK51,SI
SHLQ $13,R8:CX
ANDQ SI,CX
SHLQ $13,R10:R9
diff --git a/test/fixedbugs/issue18808.go b/test/fixedbugs/issue18808.go
new file mode 100644
index 0000000..c98386e
--- /dev/null
+++ b/test/fixedbugs/issue18808.go
@@ -0,0 +1,63 @@
+// run
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+const lim = 0x80000000
+
+//go:noinline
+func eq(x uint32) {
+ if x == lim {
+ return
+ }
+ panic("x == lim returned false")
+}
+
+//go:noinline
+func neq(x uint32) {
+ if x != lim {
+ panic("x != lim returned true")
+ }
+}
+
+//go:noinline
+func gt(x uint32) {
+ if x > lim {
+ return
+ }
+ panic("x > lim returned false")
+}
+
+//go:noinline
+func gte(x uint32) {
+ if x >= lim {
+ return
+ }
+ panic("x >= lim returned false")
+}
+
+//go:noinline
+func lt(x uint32) {
+ if x < lim {
+ panic("x < lim returned true")
+ }
+}
+
+//go:noinline
+func lte(x uint32) {
+ if x <= lim {
+ panic("x <= lim returned true")
+ }
+}
+
+func main() {
+ eq(lim)
+ neq(lim)
+ gt(lim+1)
+ gte(lim+1)
+ lt(lim+1)
+ lte(lim+1)
+}
diff --git a/test/fixedbugs/issue18906.go b/test/fixedbugs/issue18906.go
new file mode 100644
index 0000000..544400b
--- /dev/null
+++ b/test/fixedbugs/issue18906.go
@@ -0,0 +1,36 @@
+// run
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+//go:noinline
+func f(x int) {
+}
+
+//go:noinline
+func val() int8 {
+ return -1
+}
+
+var (
+ array = [257]int{}
+ slice = array[1:]
+)
+
+func init() {
+ for i := range array {
+ array[i] = i - 1
+ }
+}
+
+func main() {
+ x := val()
+ y := int(uint8(x))
+ f(y) // try and force y to be calculated and spilled
+ if slice[y] != 255 {
+ panic("incorrect value")
+ }
+}
diff --git a/test/fixedbugs/issue18915.go b/test/fixedbugs/issue18915.go
new file mode 100644
index 0000000..a432bbc
--- /dev/null
+++ b/test/fixedbugs/issue18915.go
@@ -0,0 +1,21 @@
+// errorcheck
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Make sure error message for invalid conditions
+// or tags are consistent with earlier Go versions.
+
+package p
+
+func _() {
+ if a := 10 { // ERROR "a := 10 used as value"
+ }
+
+ for b := 10 { // ERROR "b := 10 used as value"
+ }
+
+ switch c := 10 { // ERROR "c := 10 used as value"
+ }
+}
diff --git a/test/fixedbugs/issue6036.go b/test/fixedbugs/issue6036.go
index 795b223..8ebef5a 100644
--- a/test/fixedbugs/issue6036.go
+++ b/test/fixedbugs/issue6036.go
@@ -1,4 +1,4 @@
-// +build amd64
+// +build !386,!arm,!mips,!mipsle,!amd64p32
// compile
// Copyright 2013 The Go Authors. All rights reserved.
diff --git a/test/writebarrier.go b/test/writebarrier.go
index 6460a6f..13f7b54 100644
--- a/test/writebarrier.go
+++ b/test/writebarrier.go
@@ -220,3 +220,19 @@ func f22(x *int) (y *int) {
*p = x // no barrier
return
}
+
+type T23 struct {
+ p *int
+ a int
+}
+
+var t23 T23
+var i23 int
+
+func f23() {
+ // zeroing global needs write barrier for the hybrid barrier.
+ t23 = T23{} // ERROR "write barrier"
+ // also test partial assignments
+ t23 = T23{a: 1} // ERROR "write barrier"
+ t23 = T23{p: &i23} // ERROR "write barrier"
+}
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-golang/golang.git
More information about the pkg-golang-commits
mailing list