aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal
diff options
context:
space:
mode:
authorMatthew Dempsky <mdempsky@google.com>2021-01-22 12:00:45 -0800
committerMatthew Dempsky <mdempsky@google.com>2021-01-22 12:01:13 -0800
commit7e0a81d2806b073c6455f73b10fbf2c811703f46 (patch)
tree4b7bc9664df2a88ba01afcc06b25da026037940f /src/cmd/compile/internal
parentd7e71c01ad1c8edd568380ce9276c265dfd3635b (diff)
parentdab3e5affefb7e0b157ad27fe4797c4c6f3c4ea6 (diff)
downloadgo-7e0a81d2806b073c6455f73b10fbf2c811703f46.tar.gz
go-7e0a81d2806b073c6455f73b10fbf2c811703f46.zip
[dev.regabi] all: merge master (dab3e5a) into dev.regabi
This merge had two conflicts to resolve: 1. The embed code on master had somewhat substantially diverged, so this CL tediously backported the changes to dev.regabi. In particular, I went through all of the embed changes to gc/{embed,noder,syntax}.go and made sure the analogous code on dev.regabi in noder/noder.go and staticdata/embed.go mirrors it. 2. The init-cycle reporting code on master was extended slightly to track already visited declarations to avoid exponential behavior. The same fix is applied on dev.regabi, just using ir.NameSet instead of map[ir.Node]bool. Conflicts: - src/cmd/compile/internal/gc/embed.go - src/cmd/compile/internal/gc/noder.go - src/cmd/compile/internal/gc/syntax.go - src/cmd/compile/internal/pkginit/initorder.go - src/embed/internal/embedtest/embed_test.go - src/go/types/stdlib_test.go Merge List: + 2021-01-22 dab3e5affe runtime: switch runtime to libc for openbsd/amd64 + 2021-01-22 a1b53d85da cmd/go: add documentation for test and xtest fields output by go list + 2021-01-22 b268b60774 runtime: remove pthread_kill/pthread_self for openbsd + 2021-01-22 ec4051763d runtime: fix typo in mgcscavenge.go + 2021-01-22 7ece3a7b17 net/http: fix flaky TestDisableKeepAliveUpgrade + 2021-01-22 50cba0506f time: clarify Timer.Reset behavior on AfterFunc Timers + 2021-01-22 cf10e69f17 doc/go1.16: mention net/http.Transport.GetProxyConnectHeader + 2021-01-22 ec1b945265 doc/go1.16: mention path/filepath.WalkDir + 2021-01-22 11def3d40b doc/go1.16: mention syscall.AllThreadsSyscall + 2021-01-21 07b0235609 doc/go1.16: add notes about package-specific fs.FS changes + 2021-01-21 e2b4f1fea5 doc/go1.16: minor formatting fix + 2021-01-21 9f43a9e07b doc/go1.16: mention new debug/elf constants + 2021-01-21 3c2f11ba5b cmd/go: overwrite program name with full path + 2021-01-21 953d1feca9 all: introduce and use internal/execabs + 2021-01-21 b186e4d70d cmd/go: add test case for cgo CC setting + 2021-01-21 5a8a2265fb cmd/cgo: report exec errors a bit more clearly + 2021-01-21 46e2e2e9d9 cmd/go: pass resolved CC, GCCGO to cgo + 2021-01-21 3d40895e36 runtime: switch openbsd/arm64 to pthreads + 2021-01-21 d95ca91380 crypto/elliptic: fix P-224 field reduction + 2021-01-20 ecf4ebf100 cmd/internal/moddeps: check content of all modules in GOROOT + 2021-01-20 d2d155d1ae runtime: don't adjust timer pp field in timerWaiting status + 2021-01-20 803d18fc6c cmd/go: set Incomplete field on go list output if no files match embed + 2021-01-20 6e243ce71d cmd/go: have go mod vendor copy embedded files in subdirs + 2021-01-20 be28e5abc5 cmd/go: fix mod_get_fallback test + 2021-01-20 928bda4f4a runtime: convert openbsd/amd64 locking to libc + 2021-01-19 824f2d635c cmd/go: allow go fmt to complete when embedded file is missing + 2021-01-19 0575e35e50 cmd/compile: require 'go 1.16' go.mod line for //go:embed + 2021-01-19 ccb2e90688 cmd/link: exit before Asmb2 if error + 2021-01-19 ca5774a5a5 embed: treat uninitialized FS as empty + 2021-01-19 d047c91a6c cmd/link,runtime: switch openbsd/amd64 to pthreads + 2021-01-19 61debffd97 runtime: factor out usesLibcall + 2021-01-19 9fed39d281 runtime: factor out mStackIsSystemAllocated + 2021-01-18 dbab079835 runtime: free Windows event handles after last lock is dropped + 2021-01-18 5a8fbb0d2d os: do not close syscall.Stdin in TestReadStdin + 2021-01-15 682a1d2176 runtime: detect errors in DuplicateHandle + 2021-01-15 9f83418b83 cmd/link: remove GOROOT write in TestBuildForTvOS + 2021-01-15 ec9470162f cmd/compile: allow embed into any string or byte slice type + 2021-01-15 54198b04db cmd/compile: disallow embed of var inside func + 2021-01-15 b386c735e7 cmd/go: fix go generate docs + 2021-01-15 bb5075a525 syscall: remove RtlGenRandom and move it into internal/syscall + 2021-01-15 1deae0b597 os: invoke processKiller synchronously in testKillProcess + 2021-01-15 ff196c3e84 crypto/x509: update iOS bundled roots to version 55188.40.9 + 2021-01-14 e125ccd10e cmd/go: in 'go mod edit', validate versions given to -retract and -exclude + 2021-01-14 eb330020dc cmd/dist, cmd/go: pass -arch for C compilation on Darwin + 2021-01-14 84e8a06f62 cmd/cgo: remove unnecessary space in cgo export header + 2021-01-14 0c86b999c3 cmd/test2json: document passing -test.paniconexit0 + 2021-01-14 9135795891 cmd/go/internal/load: report positions for embed errors + 2021-01-14 d9b79e53bb cmd/compile: fix wrong complement for arm64 floating-point comparisons + 2021-01-14 c73232d08f cmd/go/internal/load: refactor setErrorPos to PackageError.setPos + 2021-01-14 6aa28d3e06 go/build: report positions for go:embed directives + 2021-01-13 7eb31d999c cmd/go: add hints to more missing sum error messages + 2021-01-12 ba76567bc2 cmd/go/internal/modload: delete unused *mvsReqs.next method + 2021-01-12 665def2c11 encoding/asn1: document unmarshaling behavior for IMPLICIT string fields + 2021-01-11 81ea89adf3 cmd/go: fix non-script staleness checks interacting badly with GOFLAGS + 2021-01-11 759309029f doc: update editors.html for Go 1.16 + 2021-01-11 c3b4c7093a cmd/internal/objfile: don't require runtime.symtab symbol for XCOFF + 2021-01-08 59bfc18e34 cmd/go: add hint to read 'go help vcs' to GOVCS errors + 2021-01-08 cd6f3a54e4 cmd/go: revise 'go help' documentation for modules + 2021-01-08 6192b98751 cmd/go: make hints in error messages more consistent + 2021-01-08 25886cf4bd cmd/go: preserve sums for indirect deps fetched by 'go mod download' + 2021-01-08 6250833911 runtime/metrics: mark histogram metrics as cumulative + 2021-01-08 8f6a9acbb3 runtime/metrics: remove unused StopTheWorld Description field + 2021-01-08 6598c65646 cmd/compile: fix exponential-time init-cycle reporting + 2021-01-08 fefad1dc85 test: fix timeout code for invoking compiler + 2021-01-08 6728118e0a cmd/go: pass signals forward during "go tool" + 2021-01-08 e65c543f3c go/build/constraint: add parser for build tag constraint expressions + 2021-01-08 0c5afc4fb7 testing/fstest,os: clarify racy behavior of TestFS + 2021-01-08 32afcc9436 runtime/metrics: change unit on *-by-size metrics to match bucket unit + 2021-01-08 c6513bca5a io/fs: minor corrections to Glob doc + 2021-01-08 304f769ffc cmd/compile: don't short-circuit copies whose source is volatile + 2021-01-08 ae97717133 runtime,runtime/metrics: use explicit histogram boundaries + 2021-01-08 a9ccd2d795 go/build: skip string literal while findEmbed + 2021-01-08 d92f8add32 archive/tar: fix typo in comment + 2021-01-08 cab1202183 cmd/link: accept extra blocks in TestFallocate + 2021-01-08 ee4d32249b io/fs: minor corrections to Glob release date + 2021-01-08 54bd1ccce2 cmd: update to latest golang.org/x/tools + 2021-01-07 9ec21a8f34 Revert "reflect: support multiple keys in struct tags" + 2021-01-07 091414b5b7 io/fs: correct WalkDirFunc documentation + 2021-01-07 9b55088d6b doc/go1.16: add release note for disallowing non-ASCII import paths + 2021-01-07 fa90aaca7d cmd/compile: fix late expand_calls leaf type for OpStructSelect/OpArraySelect + 2021-01-07 7cee66d4cb cmd/go: add documentation for Embed fields in go list output + 2021-01-07 e60cffa4ca html/template: attach functions to namespace + 2021-01-07 6da2d3b7d7 cmd/link: fix typo in asm.go + 2021-01-07 df81a15819 runtime: check mips64 VDSO clock_gettime return code + 2021-01-06 4787e906cf crypto/x509: rollback new CertificateRequest fields + 2021-01-06 c9658bee93 cmd/go: make module suggestion more friendly + 2021-01-06 4c668b25c6 runtime/metrics: fix panic message for Float64Histogram + 2021-01-06 d2131704a6 net/http/httputil: fix deadlock in DumpRequestOut + 2021-01-05 3e1e13ce6d cmd/go: set cfg.BuildMod to "readonly" by default with no module root + 2021-01-05 0b0d004983 cmd/go: pass embedcfg to gccgo if supported + 2021-01-05 1b85e7c057 cmd/go: don't scan gccgo standard library packages for imports + 2021-01-05 6b37b15d95 runtime: don't take allglock in tracebackothers + 2021-01-04 9eef49cfa6 math/rand: fix typo in comment + 2021-01-04 b01fb2af9e testing/fstest: fix typo in error message + 2021-01-01 3dd5867605 doc: 2021 is the Year of the Gopher + 2020-12-31 95ce805d14 io/fs: remove darwin/arm64 special condition + 2020-12-30 20d0991b86 lib/time, time/tzdata: update tzdata to 2020f + 2020-12-30 ed301733bb misc/cgo/testcarchive: remove special flags for Darwin/ARM + 2020-12-30 0ae2e032f2 misc/cgo/test: enable TestCrossPackageTests on darwin/arm64 + 2020-12-29 780b4de16b misc/ios: fix wording for command line instructions + 2020-12-29 b4a71c95d2 doc/go1.16: reference misc/ios/README for how to build iOS programs + 2020-12-29 f83e0f6616 misc/ios: add to README how to build ios executables + 2020-12-28 4fd9455882 io/fs: fix typo in comment Change-Id: I2f257bbc5fbb05f15c2d959f8cfe0ce13b083538
Diffstat (limited to 'src/cmd/compile/internal')
-rw-r--r--src/cmd/compile/internal/arm64/ssa.go20
-rw-r--r--src/cmd/compile/internal/noder/noder.go19
-rw-r--r--src/cmd/compile/internal/pkginit/initorder.go18
-rw-r--r--src/cmd/compile/internal/ssa/expand_calls.go3
-rw-r--r--src/cmd/compile/internal/ssa/gen/ARM64Ops.go32
-rw-r--r--src/cmd/compile/internal/ssa/gen/generic.rules4
-rw-r--r--src/cmd/compile/internal/ssa/html.go2
-rw-r--r--src/cmd/compile/internal/ssa/opGen.go40
-rw-r--r--src/cmd/compile/internal/ssa/rewrite.go31
-rw-r--r--src/cmd/compile/internal/ssa/rewritegeneric.go8
-rw-r--r--src/cmd/compile/internal/staticdata/embed.go58
11 files changed, 146 insertions, 89 deletions
diff --git a/src/cmd/compile/internal/arm64/ssa.go b/src/cmd/compile/internal/arm64/ssa.go
index 8d25fa8592..73e74e1219 100644
--- a/src/cmd/compile/internal/arm64/ssa.go
+++ b/src/cmd/compile/internal/arm64/ssa.go
@@ -1056,7 +1056,11 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
ssa.OpARM64LessThanF,
ssa.OpARM64LessEqualF,
ssa.OpARM64GreaterThanF,
- ssa.OpARM64GreaterEqualF:
+ ssa.OpARM64GreaterEqualF,
+ ssa.OpARM64NotLessThanF,
+ ssa.OpARM64NotLessEqualF,
+ ssa.OpARM64NotGreaterThanF,
+ ssa.OpARM64NotGreaterEqualF:
// generate boolean values using CSET
p := s.Prog(arm64.ACSET)
p.From.Type = obj.TYPE_REG // assembler encodes conditional bits in Reg
@@ -1100,10 +1104,16 @@ var condBits = map[ssa.Op]int16{
ssa.OpARM64GreaterThanU: arm64.COND_HI,
ssa.OpARM64GreaterEqual: arm64.COND_GE,
ssa.OpARM64GreaterEqualU: arm64.COND_HS,
- ssa.OpARM64LessThanF: arm64.COND_MI,
- ssa.OpARM64LessEqualF: arm64.COND_LS,
- ssa.OpARM64GreaterThanF: arm64.COND_GT,
- ssa.OpARM64GreaterEqualF: arm64.COND_GE,
+ ssa.OpARM64LessThanF: arm64.COND_MI, // Less than
+ ssa.OpARM64LessEqualF: arm64.COND_LS, // Less than or equal to
+ ssa.OpARM64GreaterThanF: arm64.COND_GT, // Greater than
+ ssa.OpARM64GreaterEqualF: arm64.COND_GE, // Greater than or equal to
+
+ // The following condition codes have unordered to handle comparisons related to NaN.
+ ssa.OpARM64NotLessThanF: arm64.COND_PL, // Greater than, equal to, or unordered
+ ssa.OpARM64NotLessEqualF: arm64.COND_HI, // Greater than or unordered
+ ssa.OpARM64NotGreaterThanF: arm64.COND_LE, // Less than, equal to or unordered
+ ssa.OpARM64NotGreaterEqualF: arm64.COND_LT, // Less than or unordered
}
var blockJump = map[ssa.BlockKind]struct {
diff --git a/src/cmd/compile/internal/noder/noder.go b/src/cmd/compile/internal/noder/noder.go
index 0ea72a28dc..5bb01895cc 100644
--- a/src/cmd/compile/internal/noder/noder.go
+++ b/src/cmd/compile/internal/noder/noder.go
@@ -475,7 +475,7 @@ func (p *noder) varDecl(decl *syntax.VarDecl) []ir.Node {
p.errorAt(e.Pos, "//go:embed only allowed in Go files that import \"embed\"")
}
} else {
- exprs = varEmbed(p, names, typ, exprs, pragma.Embeds)
+ varEmbed(p, names, typ, exprs, pragma.Embeds)
}
pragma.Embeds = nil
}
@@ -1923,7 +1923,7 @@ func oldname(s *types.Sym) ir.Node {
return n
}
-func varEmbed(p *noder, names []*ir.Name, typ ir.Ntype, exprs []ir.Node, embeds []pragmaEmbed) (newExprs []ir.Node) {
+func varEmbed(p *noder, names []*ir.Name, typ ir.Ntype, exprs []ir.Node, embeds []pragmaEmbed) {
haveEmbed := false
for _, decl := range p.file.DeclList {
imp, ok := decl.(*syntax.ImportDecl)
@@ -1941,28 +1941,24 @@ func varEmbed(p *noder, names []*ir.Name, typ ir.Ntype, exprs []ir.Node, embeds
pos := embeds[0].Pos
if !haveEmbed {
p.errorAt(pos, "invalid go:embed: missing import \"embed\"")
- return exprs
- }
- if base.Flag.Cfg.Embed.Patterns == nil {
- p.errorAt(pos, "invalid go:embed: build system did not supply embed configuration")
- return exprs
+ return
}
if len(names) > 1 {
p.errorAt(pos, "go:embed cannot apply to multiple vars")
- return exprs
+ return
}
if len(exprs) > 0 {
p.errorAt(pos, "go:embed cannot apply to var with initializer")
- return exprs
+ return
}
if typ == nil {
// Should not happen, since len(exprs) == 0 now.
p.errorAt(pos, "go:embed cannot apply to var without type")
- return exprs
+ return
}
if typecheck.DeclContext != ir.PEXTERN {
p.errorAt(pos, "go:embed cannot apply to var inside func")
- return exprs
+ return
}
v := names[0]
@@ -1971,5 +1967,4 @@ func varEmbed(p *noder, names []*ir.Name, typ ir.Ntype, exprs []ir.Node, embeds
for _, e := range embeds {
*v.Embed = append(*v.Embed, ir.Embed{Pos: p.makeXPos(e.Pos), Patterns: e.Patterns})
}
- return exprs
}
diff --git a/src/cmd/compile/internal/pkginit/initorder.go b/src/cmd/compile/internal/pkginit/initorder.go
index bdefd594ff..97d69629fb 100644
--- a/src/cmd/compile/internal/pkginit/initorder.go
+++ b/src/cmd/compile/internal/pkginit/initorder.go
@@ -113,7 +113,7 @@ func initOrder(l []ir.Node) []ir.Node {
// first.
base.ExitIfErrors()
- o.findInitLoopAndExit(firstLHS(n), new([]*ir.Name))
+ o.findInitLoopAndExit(firstLHS(n), new([]*ir.Name), new(ir.NameSet))
base.Fatalf("initialization unfinished, but failed to identify loop")
}
}
@@ -184,10 +184,7 @@ func (o *InitOrder) flushReady(initialize func(ir.Node)) {
// path points to a slice used for tracking the sequence of
// variables/functions visited. Using a pointer to a slice allows the
// slice capacity to grow and limit reallocations.
-func (o *InitOrder) findInitLoopAndExit(n *ir.Name, path *[]*ir.Name) {
- // We implement a simple DFS loop-finding algorithm. This
- // could be faster, but initialization cycles are rare.
-
+func (o *InitOrder) findInitLoopAndExit(n *ir.Name, path *[]*ir.Name, ok *ir.NameSet) {
for i, x := range *path {
if x == n {
reportInitLoopAndExit((*path)[i:])
@@ -204,12 +201,19 @@ func (o *InitOrder) findInitLoopAndExit(n *ir.Name, path *[]*ir.Name) {
*path = append(*path, n)
for _, ref := range refers {
// Short-circuit variables that were initialized.
- if ref.Class == ir.PEXTERN && o.order[ref.Defn] == orderDone {
+ if ref.Class == ir.PEXTERN && o.order[ref.Defn] == orderDone || ok.Has(ref) {
continue
}
- o.findInitLoopAndExit(ref, path)
+ o.findInitLoopAndExit(ref, path, ok)
}
+
+ // n is not involved in a cycle.
+ // Record that fact to avoid checking it again when reached another way,
+ // or else this traversal will take exponential time traversing all paths
+ // through the part of the package's call graph implicated in the cycle.
+ ok.Add(n)
+
*path = (*path)[:len(*path)-1]
}
diff --git a/src/cmd/compile/internal/ssa/expand_calls.go b/src/cmd/compile/internal/ssa/expand_calls.go
index 66ef1b3515..af994d4b5b 100644
--- a/src/cmd/compile/internal/ssa/expand_calls.go
+++ b/src/cmd/compile/internal/ssa/expand_calls.go
@@ -198,7 +198,8 @@ func expandCalls(f *Func) {
}
break
}
- if leaf.Op == OpIData {
+ switch leaf.Op {
+ case OpIData, OpStructSelect, OpArraySelect:
leafType = removeTrivialWrapperTypes(leaf.Type)
}
aux := selector.Aux
diff --git a/src/cmd/compile/internal/ssa/gen/ARM64Ops.go b/src/cmd/compile/internal/ssa/gen/ARM64Ops.go
index 87db2b7c9d..b0bc9c78ff 100644
--- a/src/cmd/compile/internal/ssa/gen/ARM64Ops.go
+++ b/src/cmd/compile/internal/ssa/gen/ARM64Ops.go
@@ -478,20 +478,24 @@ func init() {
// pseudo-ops
{name: "LoweredNilCheck", argLength: 2, reg: regInfo{inputs: []regMask{gpg}}, nilCheck: true, faultOnNilArg0: true}, // panic if arg0 is nil. arg1=mem.
- {name: "Equal", argLength: 1, reg: readflags}, // bool, true flags encode x==y false otherwise.
- {name: "NotEqual", argLength: 1, reg: readflags}, // bool, true flags encode x!=y false otherwise.
- {name: "LessThan", argLength: 1, reg: readflags}, // bool, true flags encode signed x<y false otherwise.
- {name: "LessEqual", argLength: 1, reg: readflags}, // bool, true flags encode signed x<=y false otherwise.
- {name: "GreaterThan", argLength: 1, reg: readflags}, // bool, true flags encode signed x>y false otherwise.
- {name: "GreaterEqual", argLength: 1, reg: readflags}, // bool, true flags encode signed x>=y false otherwise.
- {name: "LessThanU", argLength: 1, reg: readflags}, // bool, true flags encode unsigned x<y false otherwise.
- {name: "LessEqualU", argLength: 1, reg: readflags}, // bool, true flags encode unsigned x<=y false otherwise.
- {name: "GreaterThanU", argLength: 1, reg: readflags}, // bool, true flags encode unsigned x>y false otherwise.
- {name: "GreaterEqualU", argLength: 1, reg: readflags}, // bool, true flags encode unsigned x>=y false otherwise.
- {name: "LessThanF", argLength: 1, reg: readflags}, // bool, true flags encode floating-point x<y false otherwise.
- {name: "LessEqualF", argLength: 1, reg: readflags}, // bool, true flags encode floating-point x<=y false otherwise.
- {name: "GreaterThanF", argLength: 1, reg: readflags}, // bool, true flags encode floating-point x>y false otherwise.
- {name: "GreaterEqualF", argLength: 1, reg: readflags}, // bool, true flags encode floating-point x>=y false otherwise.
+ {name: "Equal", argLength: 1, reg: readflags}, // bool, true flags encode x==y false otherwise.
+ {name: "NotEqual", argLength: 1, reg: readflags}, // bool, true flags encode x!=y false otherwise.
+ {name: "LessThan", argLength: 1, reg: readflags}, // bool, true flags encode signed x<y false otherwise.
+ {name: "LessEqual", argLength: 1, reg: readflags}, // bool, true flags encode signed x<=y false otherwise.
+ {name: "GreaterThan", argLength: 1, reg: readflags}, // bool, true flags encode signed x>y false otherwise.
+ {name: "GreaterEqual", argLength: 1, reg: readflags}, // bool, true flags encode signed x>=y false otherwise.
+ {name: "LessThanU", argLength: 1, reg: readflags}, // bool, true flags encode unsigned x<y false otherwise.
+ {name: "LessEqualU", argLength: 1, reg: readflags}, // bool, true flags encode unsigned x<=y false otherwise.
+ {name: "GreaterThanU", argLength: 1, reg: readflags}, // bool, true flags encode unsigned x>y false otherwise.
+ {name: "GreaterEqualU", argLength: 1, reg: readflags}, // bool, true flags encode unsigned x>=y false otherwise.
+ {name: "LessThanF", argLength: 1, reg: readflags}, // bool, true flags encode floating-point x<y false otherwise.
+ {name: "LessEqualF", argLength: 1, reg: readflags}, // bool, true flags encode floating-point x<=y false otherwise.
+ {name: "GreaterThanF", argLength: 1, reg: readflags}, // bool, true flags encode floating-point x>y false otherwise.
+ {name: "GreaterEqualF", argLength: 1, reg: readflags}, // bool, true flags encode floating-point x>=y false otherwise.
+ {name: "NotLessThanF", argLength: 1, reg: readflags}, // bool, true flags encode floating-point x>=y || x is unordered with y, false otherwise.
+ {name: "NotLessEqualF", argLength: 1, reg: readflags}, // bool, true flags encode floating-point x>y || x is unordered with y, false otherwise.
+ {name: "NotGreaterThanF", argLength: 1, reg: readflags}, // bool, true flags encode floating-point x<=y || x is unordered with y, false otherwise.
+ {name: "NotGreaterEqualF", argLength: 1, reg: readflags}, // bool, true flags encode floating-point x<y || x is unordered with y, false otherwise.
// duffzero
// arg0 = address of memory to zero
// arg1 = mem
diff --git a/src/cmd/compile/internal/ssa/gen/generic.rules b/src/cmd/compile/internal/ssa/gen/generic.rules
index 81568b7b7a..1784923224 100644
--- a/src/cmd/compile/internal/ssa/gen/generic.rules
+++ b/src/cmd/compile/internal/ssa/gen/generic.rules
@@ -2512,7 +2512,7 @@
(Move {t1} [s] dst tmp1 midmem:(Move {t2} [s] tmp2 src _))
&& t1.Compare(t2) == types.CMPeq
&& isSamePtr(tmp1, tmp2)
- && isStackPtr(src)
+ && isStackPtr(src) && !isVolatile(src)
&& disjoint(src, s, tmp2, s)
&& (disjoint(src, s, dst, s) || isInlinableMemmove(dst, src, s, config))
=> (Move {t1} [s] dst src midmem)
@@ -2521,7 +2521,7 @@
(Move {t1} [s] dst tmp1 midmem:(VarDef (Move {t2} [s] tmp2 src _)))
&& t1.Compare(t2) == types.CMPeq
&& isSamePtr(tmp1, tmp2)
- && isStackPtr(src)
+ && isStackPtr(src) && !isVolatile(src)
&& disjoint(src, s, tmp2, s)
&& (disjoint(src, s, dst, s) || isInlinableMemmove(dst, src, s, config))
=> (Move {t1} [s] dst src midmem)
diff --git a/src/cmd/compile/internal/ssa/html.go b/src/cmd/compile/internal/ssa/html.go
index a9d52fa4ee..c06b5808e1 100644
--- a/src/cmd/compile/internal/ssa/html.go
+++ b/src/cmd/compile/internal/ssa/html.go
@@ -9,9 +9,9 @@ import (
"cmd/internal/src"
"fmt"
"html"
+ exec "internal/execabs"
"io"
"os"
- "os/exec"
"path/filepath"
"strconv"
"strings"
diff --git a/src/cmd/compile/internal/ssa/opGen.go b/src/cmd/compile/internal/ssa/opGen.go
index 83d35cf7e1..e590f6ba5d 100644
--- a/src/cmd/compile/internal/ssa/opGen.go
+++ b/src/cmd/compile/internal/ssa/opGen.go
@@ -1564,6 +1564,10 @@ const (
OpARM64LessEqualF
OpARM64GreaterThanF
OpARM64GreaterEqualF
+ OpARM64NotLessThanF
+ OpARM64NotLessEqualF
+ OpARM64NotGreaterThanF
+ OpARM64NotGreaterEqualF
OpARM64DUFFZERO
OpARM64LoweredZero
OpARM64DUFFCOPY
@@ -20799,6 +20803,42 @@ var opcodeTable = [...]opInfo{
},
},
{
+ name: "NotLessThanF",
+ argLen: 1,
+ reg: regInfo{
+ outputs: []outputInfo{
+ {0, 670826495}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 R30
+ },
+ },
+ },
+ {
+ name: "NotLessEqualF",
+ argLen: 1,
+ reg: regInfo{
+ outputs: []outputInfo{
+ {0, 670826495}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 R30
+ },
+ },
+ },
+ {
+ name: "NotGreaterThanF",
+ argLen: 1,
+ reg: regInfo{
+ outputs: []outputInfo{
+ {0, 670826495}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 R30
+ },
+ },
+ },
+ {
+ name: "NotGreaterEqualF",
+ argLen: 1,
+ reg: regInfo{
+ outputs: []outputInfo{
+ {0, 670826495}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 R30
+ },
+ },
+ },
+ {
name: "DUFFZERO",
auxType: auxInt64,
argLen: 2,
diff --git a/src/cmd/compile/internal/ssa/rewrite.go b/src/cmd/compile/internal/ssa/rewrite.go
index e0a20668e2..e82aa84cdf 100644
--- a/src/cmd/compile/internal/ssa/rewrite.go
+++ b/src/cmd/compile/internal/ssa/rewrite.go
@@ -996,9 +996,10 @@ func flagArg(v *Value) *Value {
}
// arm64Negate finds the complement to an ARM64 condition code,
-// for example Equal -> NotEqual or LessThan -> GreaterEqual
+// for example !Equal -> NotEqual or !LessThan -> GreaterEqual
//
-// TODO: add floating-point conditions
+// For floating point, it's more subtle because NaN is unordered. We do
+// !LessThanF -> NotLessThanF, the latter takes care of NaNs.
func arm64Negate(op Op) Op {
switch op {
case OpARM64LessThan:
@@ -1022,13 +1023,21 @@ func arm64Negate(op Op) Op {
case OpARM64NotEqual:
return OpARM64Equal
case OpARM64LessThanF:
- return OpARM64GreaterEqualF
- case OpARM64GreaterThanF:
- return OpARM64LessEqualF
+ return OpARM64NotLessThanF
+ case OpARM64NotLessThanF:
+ return OpARM64LessThanF
case OpARM64LessEqualF:
+ return OpARM64NotLessEqualF
+ case OpARM64NotLessEqualF:
+ return OpARM64LessEqualF
+ case OpARM64GreaterThanF:
+ return OpARM64NotGreaterThanF
+ case OpARM64NotGreaterThanF:
return OpARM64GreaterThanF
case OpARM64GreaterEqualF:
- return OpARM64LessThanF
+ return OpARM64NotGreaterEqualF
+ case OpARM64NotGreaterEqualF:
+ return OpARM64GreaterEqualF
default:
panic("unreachable")
}
@@ -1039,8 +1048,6 @@ func arm64Negate(op Op) Op {
// that the same result would be produced if the arguments
// to the flag-generating instruction were reversed, e.g.
// (InvertFlags (CMP x y)) -> (CMP y x)
-//
-// TODO: add floating-point conditions
func arm64Invert(op Op) Op {
switch op {
case OpARM64LessThan:
@@ -1069,6 +1076,14 @@ func arm64Invert(op Op) Op {
return OpARM64GreaterEqualF
case OpARM64GreaterEqualF:
return OpARM64LessEqualF
+ case OpARM64NotLessThanF:
+ return OpARM64NotGreaterThanF
+ case OpARM64NotGreaterThanF:
+ return OpARM64NotLessThanF
+ case OpARM64NotLessEqualF:
+ return OpARM64NotGreaterEqualF
+ case OpARM64NotGreaterEqualF:
+ return OpARM64NotLessEqualF
default:
panic("unreachable")
}
diff --git a/src/cmd/compile/internal/ssa/rewritegeneric.go b/src/cmd/compile/internal/ssa/rewritegeneric.go
index 4cb9a8f328..958e24d29f 100644
--- a/src/cmd/compile/internal/ssa/rewritegeneric.go
+++ b/src/cmd/compile/internal/ssa/rewritegeneric.go
@@ -13637,7 +13637,7 @@ func rewriteValuegeneric_OpMove(v *Value) bool {
return true
}
// match: (Move {t1} [s] dst tmp1 midmem:(Move {t2} [s] tmp2 src _))
- // cond: t1.Compare(t2) == types.CMPeq && isSamePtr(tmp1, tmp2) && isStackPtr(src) && disjoint(src, s, tmp2, s) && (disjoint(src, s, dst, s) || isInlinableMemmove(dst, src, s, config))
+ // cond: t1.Compare(t2) == types.CMPeq && isSamePtr(tmp1, tmp2) && isStackPtr(src) && !isVolatile(src) && disjoint(src, s, tmp2, s) && (disjoint(src, s, dst, s) || isInlinableMemmove(dst, src, s, config))
// result: (Move {t1} [s] dst src midmem)
for {
s := auxIntToInt64(v.AuxInt)
@@ -13651,7 +13651,7 @@ func rewriteValuegeneric_OpMove(v *Value) bool {
t2 := auxToType(midmem.Aux)
src := midmem.Args[1]
tmp2 := midmem.Args[0]
- if !(t1.Compare(t2) == types.CMPeq && isSamePtr(tmp1, tmp2) && isStackPtr(src) && disjoint(src, s, tmp2, s) && (disjoint(src, s, dst, s) || isInlinableMemmove(dst, src, s, config))) {
+ if !(t1.Compare(t2) == types.CMPeq && isSamePtr(tmp1, tmp2) && isStackPtr(src) && !isVolatile(src) && disjoint(src, s, tmp2, s) && (disjoint(src, s, dst, s) || isInlinableMemmove(dst, src, s, config))) {
break
}
v.reset(OpMove)
@@ -13661,7 +13661,7 @@ func rewriteValuegeneric_OpMove(v *Value) bool {
return true
}
// match: (Move {t1} [s] dst tmp1 midmem:(VarDef (Move {t2} [s] tmp2 src _)))
- // cond: t1.Compare(t2) == types.CMPeq && isSamePtr(tmp1, tmp2) && isStackPtr(src) && disjoint(src, s, tmp2, s) && (disjoint(src, s, dst, s) || isInlinableMemmove(dst, src, s, config))
+ // cond: t1.Compare(t2) == types.CMPeq && isSamePtr(tmp1, tmp2) && isStackPtr(src) && !isVolatile(src) && disjoint(src, s, tmp2, s) && (disjoint(src, s, dst, s) || isInlinableMemmove(dst, src, s, config))
// result: (Move {t1} [s] dst src midmem)
for {
s := auxIntToInt64(v.AuxInt)
@@ -13679,7 +13679,7 @@ func rewriteValuegeneric_OpMove(v *Value) bool {
t2 := auxToType(midmem_0.Aux)
src := midmem_0.Args[1]
tmp2 := midmem_0.Args[0]
- if !(t1.Compare(t2) == types.CMPeq && isSamePtr(tmp1, tmp2) && isStackPtr(src) && disjoint(src, s, tmp2, s) && (disjoint(src, s, dst, s) || isInlinableMemmove(dst, src, s, config))) {
+ if !(t1.Compare(t2) == types.CMPeq && isSamePtr(tmp1, tmp2) && isStackPtr(src) && !isVolatile(src) && disjoint(src, s, tmp2, s) && (disjoint(src, s, dst, s) || isInlinableMemmove(dst, src, s, config))) {
break
}
v.reset(OpMove)
diff --git a/src/cmd/compile/internal/staticdata/embed.go b/src/cmd/compile/internal/staticdata/embed.go
index 2e15841fe2..8936c4f5b4 100644
--- a/src/cmd/compile/internal/staticdata/embed.go
+++ b/src/cmd/compile/internal/staticdata/embed.go
@@ -23,13 +23,7 @@ const (
embedFiles
)
-func embedFileList(v *ir.Name) []string {
- kind := embedKind(v.Type())
- if kind == embedUnknown {
- base.ErrorfAt(v.Pos(), "go:embed cannot apply to var of type %v", v.Type())
- return nil
- }
-
+func embedFileList(v *ir.Name, kind int) []string {
// Build list of files to store.
have := make(map[string]bool)
var list []string
@@ -71,38 +65,15 @@ func embedFileList(v *ir.Name) []string {
return list
}
-// embedKindApprox determines the kind of embedding variable, approximately.
-// The match is approximate because we haven't done scope resolution yet and
-// can't tell whether "string" and "byte" really mean "string" and "byte".
-// The result must be confirmed later, after type checking, using embedKind.
-func embedKindApprox(typ ir.Node) int {
- if typ.Sym() != nil && typ.Sym().Name == "FS" && (typ.Sym().Pkg.Path == "embed" || (typ.Sym().Pkg == types.LocalPkg && base.Ctxt.Pkgpath == "embed")) {
- return embedFiles
- }
- // These are not guaranteed to match only string and []byte -
- // maybe the local package has redefined one of those words.
- // But it's the best we can do now during the noder.
- // The stricter check happens later, in WriteEmbed calling embedKind.
- if typ.Sym() != nil && typ.Sym().Name == "string" && typ.Sym().Pkg == types.LocalPkg {
- return embedString
- }
- if typ, ok := typ.(*ir.SliceType); ok {
- if sym := typ.Elem.Sym(); sym != nil && sym.Name == "byte" && sym.Pkg == types.LocalPkg {
- return embedBytes
- }
- }
- return embedUnknown
-}
-
// embedKind determines the kind of embedding variable.
func embedKind(typ *types.Type) int {
if typ.Sym() != nil && typ.Sym().Name == "FS" && (typ.Sym().Pkg.Path == "embed" || (typ.Sym().Pkg == types.LocalPkg && base.Ctxt.Pkgpath == "embed")) {
return embedFiles
}
- if typ == types.Types[types.TSTRING] {
+ if typ.Kind() == types.TSTRING {
return embedString
}
- if typ.Sym() == nil && typ.IsSlice() && typ.Elem() == types.ByteType {
+ if typ.Sym() == nil && typ.IsSlice() && typ.Elem().Kind() == types.TUINT8 {
return embedBytes
}
return embedUnknown
@@ -134,11 +105,28 @@ func embedFileLess(x, y string) bool {
// WriteEmbed emits the init data for a //go:embed variable,
// which is either a string, a []byte, or an embed.FS.
func WriteEmbed(v *ir.Name) {
- files := embedFileList(v)
- switch kind := embedKind(v.Type()); kind {
- case embedUnknown:
+ // TODO(mdempsky): User errors should be reported by the frontend.
+
+ commentPos := (*v.Embed)[0].Pos
+ if !types.AllowsGoVersion(types.LocalPkg, 1, 16) {
+ prevPos := base.Pos
+ base.Pos = commentPos
+ base.ErrorfVers("go1.16", "go:embed")
+ base.Pos = prevPos
+ return
+ }
+ if base.Flag.Cfg.Embed.Patterns == nil {
+ base.ErrorfAt(commentPos, "invalid go:embed: build system did not supply embed configuration")
+ return
+ }
+ kind := embedKind(v.Type())
+ if kind == embedUnknown {
base.ErrorfAt(v.Pos(), "go:embed cannot apply to var of type %v", v.Type())
+ return
+ }
+ files := embedFileList(v, kind)
+ switch kind {
case embedString, embedBytes:
file := files[0]
fsym, size, err := fileStringSym(v.Pos(), base.Flag.Cfg.Embed.Files[file], kind == embedString, nil)