diff options
| author | Cherry Mui <cherryyz@google.com> | 2025-09-23 10:32:03 -0400 |
|---|---|---|
| committer | Cherry Mui <cherryyz@google.com> | 2025-09-23 10:32:03 -0400 |
| commit | 2d8cb80d7c4af3dbcb507783938ceb0e071f64e3 (patch) | |
| tree | 719d86801da431f6ba11a84a3b66c60b4e5c1f38 /src/cmd/compile/internal | |
| parent | 63a09d6d3d68acedfc9e5fd2daf6febc35aca1d6 (diff) | |
| parent | 9b2d39b75bcc8ced3eaab1c841d7d62e27867931 (diff) | |
| download | go-2d8cb80d7c4af3dbcb507783938ceb0e071f64e3.tar.xz | |
[dev.simd] all: merge master (9b2d39b) into dev.simd
Conflicts:
- src/internal/buildcfg/exp.go
Merge List:
+ 2025-09-22 9b2d39b75b cmd/compile/internal/ssa: match style and formatting
+ 2025-09-22 e23edf5e55 runtime: don't re-read metrics before check in TestReadMetricsSched
+ 2025-09-22 177cd8d763 log/slog: use a pooled json encoder
+ 2025-09-22 2353c15785 cmd/cgo/internal/test: skip TestMultipleAssign when using UCRT on Windows
+ 2025-09-22 32dfd69282 cmd/dist: disable FIPS 140-3 mode when testing maphash with purego
+ 2025-09-19 7f6ff5ec3e cmd/compile: fix doc word
+ 2025-09-19 9693b94be0 runtime: include stderr when objdump fails
+ 2025-09-19 8616981ce6 log/slog: optimize slog Level.String() to avoid fmt.Sprintf
+ 2025-09-19 b8af744360 testing: fix example for unexported identifier
+ 2025-09-19 51dc5bfe6c Revert "cmd/go: disable cgo by default if CC unset and DefaultCC doesn't exist"
+ 2025-09-19 ee7bf06cb3 time: improve ParseDuration performance for invalid input
+ 2025-09-19 f9e61a9a32 cmd/compile: duplicate nil check to two branches of write barrier
+ 2025-09-18 3cf1aaf8b9 runtime: use futexes with 64-bit time on Linux
+ 2025-09-18 0ab038af62 cmd/compile/internal/abi: use clear built-in
+ 2025-09-18 00bf24fdca bytes: use clear in test
+ 2025-09-18 f9701d21d2 crypto: use clear built-in
+ 2025-09-18 a58afe44fa net: fix testHookCanceledDial race
+ 2025-09-18 3203a5da29 net/http: avoid connCount underflow race
+ 2025-09-18 8ca209ec39 context: don't return a non-nil from Err before Done is closed
+ 2025-09-18 3032894e04 runtime: make explicit nil check in heapSetTypeSmallHeader
+ 2025-09-17 ef05b66d61 cmd/internal/obj/riscv: add support for Zicond instructions
+ 2025-09-17 78ef487a6f cmd/compile: fix the issue of shift amount exceeding the valid range
+ 2025-09-17 77aac7bb75 runtime: don't enable heap randomization if MSAN or ASAN is enabled
+ 2025-09-17 465b85eb76 runtime: fix CheckScavengedBitsCleared with randomized heap base
+ 2025-09-17 909704b85e encoding/json/v2: fix typo in comment
+ 2025-09-17 3db5979e8c testing: use reflect.TypeAssert and reflect.TypeFor
+ 2025-09-17 6a8dbbecbf path/filepath: fix EvalSymlinks to return ENOTDIR on plan9
+ 2025-09-17 bffe7ad9f1 go/parser: Add TestBothLineAndLeadComment
+ 2025-09-17 02a888e820 go/ast: document that (*ast.File).Comments is sorted by position
+ 2025-09-16 594deca981 cmd/link: simplify PE relocations mapping
+ 2025-09-16 9df1a289ac go/parser: simplify expectSemi
+ 2025-09-16 72ba117bda internal/buildcfg: enable randomizedHeapBase64 by default
+ 2025-09-16 796ea3bc2e os/user: align test file name and build tags
+ 2025-09-16 a69395eab2 runtime/_mkmalloc: add a copy of cloneNode
+ 2025-09-16 cbdad4fc3c cmd/go: check pattern for utf8 validity before call regexp.MustCompile
+ 2025-09-16 c2d85eb999 cmd/go: disable cgo by default if CC unset and DefaultCC doesn't exist
+ 2025-09-16 ac82fe68aa bytes,strings: remove reference to non-existent SplitFunc
+ 2025-09-16 0b26678db2 cmd/compile: fix mips zerorange implementation
+ 2025-09-16 e2cfc1eb3a cmd/internal/obj/riscv: improve handling of float point moves
+ 2025-09-16 281c632e6e crypto/x509/internal/macos: standardize package name
+ 2025-09-16 61dc7fe30d iter: document that calling yield after terminated range loop causes runtime panic
Change-Id: Ic06019efc855913632003f41eb10c746b3410b0a
Diffstat (limited to 'src/cmd/compile/internal')
| -rw-r--r-- | src/cmd/compile/internal/abi/abiutils.go | 4 | ||||
| -rw-r--r-- | src/cmd/compile/internal/mips/ggen.go | 3 | ||||
| -rw-r--r-- | src/cmd/compile/internal/mips64/ggen.go | 2 | ||||
| -rw-r--r-- | src/cmd/compile/internal/ssa/README.md | 3 | ||||
| -rw-r--r-- | src/cmd/compile/internal/ssa/_gen/LOONG64.rules | 3 | ||||
| -rw-r--r-- | src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go | 2 | ||||
| -rw-r--r-- | src/cmd/compile/internal/ssa/rewriteLOONG64.go | 46 | ||||
| -rw-r--r-- | src/cmd/compile/internal/ssa/writebarrier.go | 43 |
8 files changed, 84 insertions, 22 deletions
diff --git a/src/cmd/compile/internal/abi/abiutils.go b/src/cmd/compile/internal/abi/abiutils.go index cef7885815..7acab36e8d 100644 --- a/src/cmd/compile/internal/abi/abiutils.go +++ b/src/cmd/compile/internal/abi/abiutils.go @@ -664,9 +664,7 @@ func (state *assignState) tryAllocRegs(typ *types.Type) []RegIndex { func (pa *ABIParamAssignment) ComputePadding(storage []uint64) []uint64 { nr := len(pa.Registers) padding := storage[:nr] - for i := 0; i < nr; i++ { - padding[i] = 0 - } + clear(padding) if pa.Type.Kind() != types.TSTRUCT || nr == 0 { return padding } diff --git a/src/cmd/compile/internal/mips/ggen.go b/src/cmd/compile/internal/mips/ggen.go index 023f4d958e..394f015589 100644 --- a/src/cmd/compile/internal/mips/ggen.go +++ b/src/cmd/compile/internal/mips/ggen.go @@ -5,6 +5,7 @@ package mips import ( + "cmd/compile/internal/base" "cmd/compile/internal/objw" "cmd/compile/internal/types" "cmd/internal/obj" @@ -17,7 +18,7 @@ func zerorange(pp *objw.Progs, p *obj.Prog, off, cnt int64, _ *uint32) *obj.Prog } for cnt != 0 { - p = pp.Append(p, mips.AMOVW, obj.TYPE_REG, mips.REGZERO, 0, obj.TYPE_MEM, mips.REGSP, off) + p = pp.Append(p, mips.AMOVW, obj.TYPE_REG, mips.REGZERO, 0, obj.TYPE_MEM, mips.REGSP, base.Ctxt.Arch.FixedFrameSize+off) cnt -= int64(types.PtrSize) off += int64(types.PtrSize) } diff --git a/src/cmd/compile/internal/mips64/ggen.go b/src/cmd/compile/internal/mips64/ggen.go index 0740d9abe8..740d68e335 100644 --- a/src/cmd/compile/internal/mips64/ggen.go +++ b/src/cmd/compile/internal/mips64/ggen.go @@ -17,7 +17,7 @@ func zerorange(pp *objw.Progs, p *obj.Prog, off, cnt int64, _ *uint32) *obj.Prog } for cnt != 0 { - p = pp.Append(p, mips.AMOVV, obj.TYPE_REG, mips.REGZERO, 0, obj.TYPE_MEM, mips.REGSP, off) + p = pp.Append(p, mips.AMOVV, obj.TYPE_REG, mips.REGZERO, 0, obj.TYPE_MEM, mips.REGSP, off+8) cnt -= int64(types.PtrSize) off += int64(types.PtrSize) } diff --git a/src/cmd/compile/internal/ssa/README.md b/src/cmd/compile/internal/ssa/README.md index 8184f9c002..3626f5bb7b 100644 --- a/src/cmd/compile/internal/ssa/README.md +++ b/src/cmd/compile/internal/ssa/README.md @@ -48,8 +48,7 @@ However, certain types don't come from Go and are special; below we will cover Some operators contain an auxiliary field. The aux fields are usually printed as enclosed in `[]` or `{}`, and could be the constant op argument, argument type, -etc. -for example: +etc. For example: v13 (?) = Const64 <int> [1] diff --git a/src/cmd/compile/internal/ssa/_gen/LOONG64.rules b/src/cmd/compile/internal/ssa/_gen/LOONG64.rules index d0a64364d6..0d2384143c 100644 --- a/src/cmd/compile/internal/ssa/_gen/LOONG64.rules +++ b/src/cmd/compile/internal/ssa/_gen/LOONG64.rules @@ -717,7 +717,8 @@ (SRLVconst [rc] (MOVBUreg x)) && rc >= 8 => (MOVVconst [0]) // (x + x) << c -> x << c+1 -((SLLV|SLL)const [c] (ADDV x x)) => ((SLLV|SLL)const [c+1] x) +((SLLV|SLL)const <t> [c] (ADDV x x)) && c < t.Size() * 8 - 1 => ((SLLV|SLL)const [c+1] x) +((SLLV|SLL)const <t> [c] (ADDV x x)) && c >= t.Size() * 8 - 1 => (MOVVconst [0]) // mul by constant (MULV _ (MOVVconst [0])) => (MOVVconst [0]) diff --git a/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go b/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go index 0d5e0eb76f..a3db4def56 100644 --- a/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go +++ b/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go @@ -247,7 +247,7 @@ func init() { {name: "SLL", argLength: 2, reg: gp21, asm: "SLL"}, // arg0 << arg1, shift amount is mod 32 {name: "SLLV", argLength: 2, reg: gp21, asm: "SLLV"}, // arg0 << arg1, shift amount is mod 64 {name: "SLLconst", argLength: 1, reg: gp11, asm: "SLL", aux: "Int64"}, // arg0 << auxInt, auxInt should be in the range 0 to 31. - {name: "SLLVconst", argLength: 1, reg: gp11, asm: "SLLV", aux: "Int64"}, // arg0 << auxInt + {name: "SLLVconst", argLength: 1, reg: gp11, asm: "SLLV", aux: "Int64"}, // arg0 << auxInt, auxInt should be in the range 0 to 63. {name: "SRL", argLength: 2, reg: gp21, asm: "SRL"}, // arg0 >> arg1, shift amount is mod 32 {name: "SRLV", argLength: 2, reg: gp21, asm: "SRLV"}, // arg0 >> arg1, unsigned, shift amount is mod 64 {name: "SRLconst", argLength: 1, reg: gp11, asm: "SRL", aux: "Int64"}, // arg0 >> auxInt, auxInt should be in the range 0 to 31. diff --git a/src/cmd/compile/internal/ssa/rewriteLOONG64.go b/src/cmd/compile/internal/ssa/rewriteLOONG64.go index 6a9b723c8c..3990b2833b 100644 --- a/src/cmd/compile/internal/ssa/rewriteLOONG64.go +++ b/src/cmd/compile/internal/ssa/rewriteLOONG64.go @@ -6561,15 +6561,17 @@ func rewriteValueLOONG64_OpLOONG64SLLV(v *Value) bool { } func rewriteValueLOONG64_OpLOONG64SLLVconst(v *Value) bool { v_0 := v.Args[0] - // match: (SLLVconst [c] (ADDV x x)) + // match: (SLLVconst <t> [c] (ADDV x x)) + // cond: c < t.Size() * 8 - 1 // result: (SLLVconst [c+1] x) for { + t := v.Type c := auxIntToInt64(v.AuxInt) if v_0.Op != OpLOONG64ADDV { break } x := v_0.Args[1] - if x != v_0.Args[0] { + if x != v_0.Args[0] || !(c < t.Size()*8-1) { break } v.reset(OpLOONG64SLLVconst) @@ -6577,6 +6579,23 @@ func rewriteValueLOONG64_OpLOONG64SLLVconst(v *Value) bool { v.AddArg(x) return true } + // match: (SLLVconst <t> [c] (ADDV x x)) + // cond: c >= t.Size() * 8 - 1 + // result: (MOVVconst [0]) + for { + t := v.Type + c := auxIntToInt64(v.AuxInt) + if v_0.Op != OpLOONG64ADDV { + break + } + x := v_0.Args[1] + if x != v_0.Args[0] || !(c >= t.Size()*8-1) { + break + } + v.reset(OpLOONG64MOVVconst) + v.AuxInt = int64ToAuxInt(0) + return true + } // match: (SLLVconst [c] (MOVVconst [d])) // result: (MOVVconst [d<<uint64(c)]) for { @@ -6593,15 +6612,17 @@ func rewriteValueLOONG64_OpLOONG64SLLVconst(v *Value) bool { } func rewriteValueLOONG64_OpLOONG64SLLconst(v *Value) bool { v_0 := v.Args[0] - // match: (SLLconst [c] (ADDV x x)) + // match: (SLLconst <t> [c] (ADDV x x)) + // cond: c < t.Size() * 8 - 1 // result: (SLLconst [c+1] x) for { + t := v.Type c := auxIntToInt64(v.AuxInt) if v_0.Op != OpLOONG64ADDV { break } x := v_0.Args[1] - if x != v_0.Args[0] { + if x != v_0.Args[0] || !(c < t.Size()*8-1) { break } v.reset(OpLOONG64SLLconst) @@ -6609,6 +6630,23 @@ func rewriteValueLOONG64_OpLOONG64SLLconst(v *Value) bool { v.AddArg(x) return true } + // match: (SLLconst <t> [c] (ADDV x x)) + // cond: c >= t.Size() * 8 - 1 + // result: (MOVVconst [0]) + for { + t := v.Type + c := auxIntToInt64(v.AuxInt) + if v_0.Op != OpLOONG64ADDV { + break + } + x := v_0.Args[1] + if x != v_0.Args[0] || !(c >= t.Size()*8-1) { + break + } + v.reset(OpLOONG64MOVVconst) + v.AuxInt = int64ToAuxInt(0) + return true + } return false } func rewriteValueLOONG64_OpLOONG64SRA(v *Value) bool { diff --git a/src/cmd/compile/internal/ssa/writebarrier.go b/src/cmd/compile/internal/ssa/writebarrier.go index 9ef3667d51..ec6901f13e 100644 --- a/src/cmd/compile/internal/ssa/writebarrier.go +++ b/src/cmd/compile/internal/ssa/writebarrier.go @@ -303,6 +303,15 @@ func writebarrier(f *Func) { mem := stores[0].MemoryArg() pos := stores[0].Pos + // If there is a nil check before the WB store, duplicate it to + // the two branches, where the store and the WB load occur. So + // they are more likely be removed by late nilcheck removal (which + // is block-local). + var nilcheck, nilcheckThen, nilcheckEnd *Value + if a := stores[0].Args[0]; a.Op == OpNilCheck && a.Args[1] == mem { + nilcheck = a + } + // If the source of a MoveWB is volatile (will be clobbered by a // function call), we need to copy it to a temporary location, as // marshaling the args of wbMove might clobber the value we're @@ -377,6 +386,10 @@ func writebarrier(f *Func) { // For each write barrier store, append write barrier code to bThen. memThen := mem + if nilcheck != nil { + nilcheckThen = bThen.NewValue2(nilcheck.Pos, OpNilCheck, nilcheck.Type, nilcheck.Args[0], memThen) + } + // Note: we can issue the write barrier code in any order. In particular, // it doesn't matter if they are in a different order *even if* they end // up referring to overlapping memory regions. For instance if an OpStore @@ -447,6 +460,9 @@ func writebarrier(f *Func) { // take care of the vast majority of these. We could // patch this up in the signal handler, or use XCHG to // combine the read and the write. + if ptr == nilcheck { + ptr = nilcheckThen + } oldVal := bThen.NewValue2(pos, OpLoad, types.Types[types.TUINTPTR], ptr, memThen) // Save old value to write buffer. addEntry(pos, oldVal) @@ -459,9 +475,12 @@ func writebarrier(f *Func) { // Now do the rare cases, Zeros and Moves. for _, w := range stores { pos := w.Pos + dst := w.Args[0] + if dst == nilcheck { + dst = nilcheckThen + } switch w.Op { case OpZeroWB: - dst := w.Args[0] typ := reflectdata.TypeLinksym(w.Aux.(*types.Type)) // zeroWB(&typ, dst) taddr := b.NewValue1A(pos, OpAddr, b.Func.Config.Types.Uintptr, typ, sb) @@ -469,7 +488,6 @@ func writebarrier(f *Func) { f.fe.Func().SetWBPos(pos) nWBops-- case OpMoveWB: - dst := w.Args[0] src := w.Args[1] if isVolatile(src) { for _, c := range volatiles { @@ -491,24 +509,29 @@ func writebarrier(f *Func) { // merge memory mem = bEnd.NewValue2(pos, OpPhi, types.TypeMem, mem, memThen) + if nilcheck != nil { + nilcheckEnd = bEnd.NewValue2(nilcheck.Pos, OpNilCheck, nilcheck.Type, nilcheck.Args[0], mem) + } + // Do raw stores after merge point. for _, w := range stores { pos := w.Pos + dst := w.Args[0] + if dst == nilcheck { + dst = nilcheckEnd + } switch w.Op { case OpStoreWB: - ptr := w.Args[0] val := w.Args[1] if buildcfg.Experiment.CgoCheck2 { // Issue cgo checking code. - mem = wbcall(pos, bEnd, cgoCheckPtrWrite, sp, mem, ptr, val) + mem = wbcall(pos, bEnd, cgoCheckPtrWrite, sp, mem, dst, val) } - mem = bEnd.NewValue3A(pos, OpStore, types.TypeMem, w.Aux, ptr, val, mem) + mem = bEnd.NewValue3A(pos, OpStore, types.TypeMem, w.Aux, dst, val, mem) case OpZeroWB: - dst := w.Args[0] mem = bEnd.NewValue2I(pos, OpZero, types.TypeMem, w.AuxInt, dst, mem) mem.Aux = w.Aux case OpMoveWB: - dst := w.Args[0] src := w.Args[1] if isVolatile(src) { for _, c := range volatiles { @@ -529,9 +552,8 @@ func writebarrier(f *Func) { case OpVarDef, OpVarLive: mem = bEnd.NewValue1A(pos, w.Op, types.TypeMem, w.Aux, mem) case OpStore: - ptr := w.Args[0] val := w.Args[1] - mem = bEnd.NewValue3A(pos, OpStore, types.TypeMem, w.Aux, ptr, val, mem) + mem = bEnd.NewValue3A(pos, OpStore, types.TypeMem, w.Aux, dst, val, mem) } } @@ -557,6 +579,9 @@ func writebarrier(f *Func) { f.freeValue(w) } } + if nilcheck != nil && nilcheck.Uses == 0 { + nilcheck.reset(OpInvalid) + } // put values after the store sequence into the end block bEnd.Values = append(bEnd.Values, after...) |
