diff options
| author | Keith Randall <khr@golang.org> | 2026-03-27 15:12:23 -0700 |
|---|---|---|
| committer | Gopher Robot <gobot@golang.org> | 2026-03-31 11:01:09 -0700 |
| commit | 1673075d4bd324e69cb4e6e58760316e2c84e604 (patch) | |
| tree | 0241cf5ff198bb149dec6843dfaef57dafb57c43 | |
| parent | 9387929d09490ae30a8da75c64d9c64e2c16936d (diff) | |
| download | go-1673075d4bd324e69cb4e6e58760316e2c84e604.tar.xz | |
test/codegen: fix broken syntax
A bunch of tests had broken yet undetected syntax errors
in their assembly output regexps. Things like mismatched quotes,
using ^ instead of - for negation, etc.
In addition, since CL 716060 using commas as separators between
regexps doesn't work, and ends up just silently dropping every
regexp after the comma.
Fix all these things, and add a test to make sure that we're not
silently dropping regexps on the floor.
After this CL I will do some cleanup to align with CL 716060, like
replacing commas and \s with spaces (which was the point of that CL,
but wasn't consistently rewritten everywhere).
Change-Id: I54f226120a311ead0c6c62eaf5d152ceed106034
Reviewed-on: https://go-review.googlesource.com/c/go/+/760521
Reviewed-by: Junyang Shao <shaojunyang@google.com>
Reviewed-by: Keith Randall <khr@google.com>
Reviewed-by: Paul Murphy <paumurph@redhat.com>
Auto-Submit: Keith Randall <khr@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
| -rw-r--r-- | src/cmd/internal/testdir/testdir_test.go | 33 | ||||
| -rw-r--r-- | test/codegen/README | 19 | ||||
| -rw-r--r-- | test/codegen/arithmetic.go | 6 | ||||
| -rw-r--r-- | test/codegen/bitfield.go | 8 | ||||
| -rw-r--r-- | test/codegen/bits.go | 2 | ||||
| -rw-r--r-- | test/codegen/bool.go | 22 | ||||
| -rw-r--r-- | test/codegen/comparisons.go | 32 | ||||
| -rw-r--r-- | test/codegen/divmod.go | 6 | ||||
| -rw-r--r-- | test/codegen/memcombine.go | 10 | ||||
| -rw-r--r-- | test/codegen/slices.go | 6 | ||||
| -rw-r--r-- | test/codegen/writebarrier.go | 4 |
11 files changed, 82 insertions, 66 deletions
diff --git a/src/cmd/internal/testdir/testdir_test.go b/src/cmd/internal/testdir/testdir_test.go index c706089877..e4d5b5d70b 100644 --- a/src/cmd/internal/testdir/testdir_test.go +++ b/src/cmd/internal/testdir/testdir_test.go @@ -1394,10 +1394,11 @@ type wantedError struct { } var ( - errRx = regexp.MustCompile(`// (?:GC_)?ERROR (.*)`) - errAutoRx = regexp.MustCompile(`// (?:GC_)?ERRORAUTO (.*)`) - errQuotesRx = regexp.MustCompile(`"([^"]*)"`) - lineRx = regexp.MustCompile(`LINE(([+-])(\d+))?`) + errRx = regexp.MustCompile(`// (?:GC_)?ERROR (.*)`) + errAutoRx = regexp.MustCompile(`// (?:GC_)?ERRORAUTO (.*)`) + errQuotesRx = regexp.MustCompile(`"([^"]*)"`) + lineRx = regexp.MustCompile(`LINE(([+-])(\d+))?`) + possibleOpcodeRx = regexp.MustCompile(`([A-Z][A-Z]|[IF](32|64))`) // two caps, or a wasm prefix ) func (t test) wantedErrors(file, short string) (errs []wantedError) { @@ -1477,7 +1478,7 @@ var ( // followed by semi-colon, followed by a comma-separated list of opcode checks. // Extraneous spaces are ignored. // - // An example: arm64/v8.1 : -`ADD` , `SUB` + // An example: arm64/v8.1 : -`ADD` `SUB` // "(\w+)" matches "arm64" (architecture name) // "(/[\w.]+)?" matches "v8.1" (architecture version) // "(/\w*)?" doesn't match anything here (it's an optional part of the triplet) @@ -1485,10 +1486,11 @@ var ( // "(" starts a capturing group // first reMatchCheck matches "-`ADD`" // `(?:" starts a non-capturing group - // "\s*,\s*` matches " , " + // "[\s,]+" matches " " // second reMatchCheck matches "`SUB`" - // ")*)" closes started groups; "*" means that there might be other elements in the comma-separated list - rxAsmPlatform = regexp.MustCompile(`(\w+)(/[\w.]+)?(/\w*)?\s*:\s*(` + reMatchCheck + `(?:\s+` + reMatchCheck + `)*)`) + // ")*)" closes started groups; "*" means that there might be other elements in the space-separated list + // (TODO: remove allowance for comma-separation once the repo is all fixed.) + rxAsmPlatform = regexp.MustCompile(`(\w+)(/[\w.]+)?(/\w*)?\s*:\s*(` + reMatchCheck + `(?:[\s,]+` + reMatchCheck + `)*)`) // Regexp to extract a single opcoded check rxAsmCheck = regexp.MustCompile(reMatchCheck) @@ -1582,9 +1584,10 @@ func (t test) wantedAsmOpcodes(fn string) asmChecks { // Parse and extract any architecture check from comments, // made by one architecture name and multiple checks. lnum := fn + ":" + strconv.Itoa(i+1) + lastUsed := 0 for _, ac := range rxAsmPlatform.FindAllStringSubmatch(comment, -1) { archspec, allchecks := ac[1:4], ac[4] - + lastUsed = strings.LastIndex(comment, allchecks) + len(allchecks) var arch, subarch, os string switch { case archspec[2] != "": // 3 components: "linux/386/sse2" @@ -1670,6 +1673,18 @@ func (t test) wantedAsmOpcodes(fn string) asmChecks { } } } + if lastUsed > 0 { + // There was an asm spec in this comment. Check for possible syntax + // errors, which would leave some asm patterns unused. We want + // to allow some tail, for example for English comments. The + // hueristic we use here is we look for two consecutive capital + // letters (or a wasm prefix). Those are probably assembly mnemonics + // that weren't used. + tail := comment[lastUsed:] + if possibleOpcodeRx.MatchString(tail) { + t.Errorf("%s:%d: possible unused assembly pattern: %v", t.goFileName(), i+1, tail) + } + } comment = "" } diff --git a/test/codegen/README b/test/codegen/README index 33b9fbc49c..9345c67f5a 100644 --- a/test/codegen/README +++ b/test/codegen/README @@ -63,25 +63,26 @@ regexp will be matched against the code found on the same line: return math.Sqrt(x) // arm:"SQRTD" } -It's possible to specify a comma-separated list of regexps to be +It's possible to specify a space-separated list of regexps to be matched. For example, the following test: func TZ8(n uint8) int { - // amd64:"BSFQ","ORQ\t\\$256" + // amd64:"BSFL" "ORL [$]256" return bits.TrailingZeros8(n) } verifies that the code generated for a bits.TrailingZeros8 call on -amd64 contains both a "BSFQ" instruction and an "ORQ $256". +amd64 contains both a "BSFL" instruction and an "ORL $256". -Note how the ORQ regex includes a tab char (\t). In the Go assembly -syntax, operands are separated from opcodes by a tabulation. +Note that spaces are special - they will match any sequence of +whitespace (including tabs) in the printed assembly. Regexps can be quoted using either " or `. Special characters must be -escaped accordingly. Both of these are accepted, and equivalent: +escaped accordingly. All of these are accepted, and equivalent: - // amd64:"ADDQ\t\\$3" - // amd64:`ADDQ\t\$3` + // amd64:"ADDQ \\$3" + // amd64:`ADDQ \$3` + // amd64:"ADDQ [$]3" and they'll match this assembly line: @@ -102,7 +103,7 @@ The expected number of matches for the regexp can be specified using a positive number: func fb(a [4]int) (r [4]int) { - // amd64:2`MOVUPS[^,]+, X0$`,2`MOVUPS\sX0,[^\n]+$` + // amd64:2`MOVUPS[^,]+, X0$` 2`MOVUPS X0,[^\n]+$` return a } diff --git a/test/codegen/arithmetic.go b/test/codegen/arithmetic.go index 93e4aaed03..867b08a55e 100644 --- a/test/codegen/arithmetic.go +++ b/test/codegen/arithmetic.go @@ -37,11 +37,11 @@ func AddLargeConst(a uint64, out []uint64) { // ppc64x/power9:"ADDIS [$]-32768,", "ADD [$]1," // ppc64x/power8:"ADDIS [$]-32768,", "ADD [$]1," out[5] = a - 2147483647 - // ppc64x:"ADDIS [$]-32768,", ^"ADD " + // ppc64x:"ADDIS [$]-32768,", -"ADD " out[6] = a - 2147483648 - // ppc64x:"ADD [$]2147450880,", ^"ADDIS " + // ppc64x:"ADD [$]2147450880,", -"ADDIS " out[7] = a + 0x7FFF8000 - // ppc64x:"ADD [$]-32768,", ^"ADDIS " + // ppc64x:"ADD [$]-32768,", -"ADDIS " out[8] = a - 32768 // ppc64x/power10:"ADD [$]-32769," // ppc64x/power9:"ADDIS [$]-1,", "ADD [$]32767," diff --git a/test/codegen/bitfield.go b/test/codegen/bitfield.go index 2539362750..a26a21c18d 100644 --- a/test/codegen/bitfield.go +++ b/test/codegen/bitfield.go @@ -188,15 +188,15 @@ func ubfiz5(x uint8) uint64 { } func ubfiz6(x uint32) uint64 { - return uint64(x << 30) // arm64:"UBFIZ [$]30, R[0-9]+, [$]2", + return uint64(x << 30) // arm64:"UBFIZ [$]30, R[0-9]+, [$]2" } func ubfiz7(x uint16) uint64 { - return uint64(x << 10) // arm64:"UBFIZ [$]10, R[0-9]+, [$]6", + return uint64(x << 10) // arm64:"UBFIZ [$]10, R[0-9]+, [$]6" } func ubfiz8(x uint8) uint64 { - return uint64(x << 7) // arm64:"UBFIZ [$]7, R[0-9]+, [$]1", + return uint64(x << 7) // arm64:"UBFIZ [$]7, R[0-9]+, [$]1" } // merge ANDconst into ubfiz. @@ -366,7 +366,7 @@ func shift(x uint32, y uint16, z uint8) uint64 { // arm64:-`MOVWU`,-`LSR [$]32` // loong64:-`MOVWU`,-`SRLV [$]32` a := uint64(x) >> 32 - // arm64:-`MOVHU + // arm64:-`MOVHU` // loong64:-`MOVHU`,-`SRLV [$]16` b := uint64(y) >> 16 // arm64:-`MOVBU` diff --git a/test/codegen/bits.go b/test/codegen/bits.go index 7bedaff712..c5bce3d318 100644 --- a/test/codegen/bits.go +++ b/test/codegen/bits.go @@ -616,7 +616,7 @@ func bitsRotateAndMask(io64 [8]uint64, io32 [4]uint32, io16 [4]uint16, io8 [4]ui io32[0] = io32[0] & 0x0FFFF000 // ppc64x: "RLWNM [$]0, R[0-9]*, [$]20, [$]3, R" io32[1] = io32[1] & 0xF0000FFF - // ppc64x: -"RLWNM", MOVD, AND + // ppc64x: -"RLWNM", "MOVD", "AND" io32[2] = io32[2] & 0xFFFF0002 var bigc uint32 = 0x12345678 diff --git a/test/codegen/bool.go b/test/codegen/bool.go index 8fe7a94687..453b4c6652 100644 --- a/test/codegen/bool.go +++ b/test/codegen/bool.go @@ -242,52 +242,52 @@ func TestSetInvGeFp64(x float64, y float64) bool { return b } func TestLogicalCompareZero(x *[64]uint64) { - // ppc64x:"ANDCC",^"AND" + // ppc64x:"ANDCC",-"AND\\s" b := x[0] & 3 if b != 0 { x[0] = b } - // ppc64x:"ANDCC",^"AND" + // ppc64x:"ANDCC",-"AND\\s" b = x[1] & x[2] if b != 0 { x[1] = b } - // ppc64x:"ANDNCC",^"ANDN" + // ppc64x:"ANDNCC",-"ANDN\\s" b = x[1] &^ x[2] if b != 0 { x[1] = b } - // ppc64x:"ORCC",^"OR" + // ppc64x:"ORCC",-"OR\\s" b = x[3] | x[4] if b != 0 { x[3] = b } - // ppc64x:"SUBCC",^"SUB" + // ppc64x:"SUBCC",-"SUB\\s" b = x[5] - x[6] if b != 0 { x[5] = b } - // ppc64x:"NORCC",^"NOR" + // ppc64x:"NORCC",-"NOR\\s" b = ^(x[5] | x[6]) if b != 0 { x[5] = b } - // ppc64x:"XORCC",^"XOR" + // ppc64x:"XORCC",-"XOR\\s" b = x[7] ^ x[8] if b != 0 { x[7] = b } - // ppc64x:"ADDCC",^"ADD" + // ppc64x:"ADDCC",-"ADD\\s" b = x[9] + x[10] if b != 0 { x[9] = b } - // ppc64x:"NEGCC",^"NEG" + // ppc64x:"NEGCC",-"NEG\\s" b = -x[11] if b != 0 { x[11] = b } - // ppc64x:"CNTLZDCC",^"CNTLZD" + // ppc64x:"CNTLZDCC",-"CNTLZD\\s" b = uint64(bits.LeadingZeros64(x[12])) if b != 0 { x[12] = b @@ -299,7 +299,7 @@ func TestLogicalCompareZero(x *[64]uint64) { x[12] = uint64(c) } - // ppc64x:"MULHDUCC",^"MULHDU" + // ppc64x:"MULHDUCC",-"MULHDU\\s" hi, _ := bits.Mul64(x[13], x[14]) if hi != 0 { x[14] = hi diff --git a/test/codegen/comparisons.go b/test/codegen/comparisons.go index 43b95646eb..e05877ea46 100644 --- a/test/codegen/comparisons.go +++ b/test/codegen/comparisons.go @@ -543,19 +543,19 @@ func ConditionalCompareInt64(a, b int64) int { } func CmpToZeroU_ex1(a uint8, b uint16, c uint32, d uint64) int { - // wasm:"I64Eqz"-"I64LtU" + // wasm:"I64Eqz" -"I64LtU" if 0 < a { return 1 } - // wasm:"I64Eqz"-"I64LtU" + // wasm:"I64Eqz" -"I64LtU" if 0 < b { return 1 } - // wasm:"I64Eqz"-"I64LtU" + // wasm:"I64Eqz" -"I64LtU" if 0 < c { return 1 } - // wasm:"I64Eqz"-"I64LtU" + // wasm:"I64Eqz" -"I64LtU" if 0 < d { return 1 } @@ -563,19 +563,19 @@ func CmpToZeroU_ex1(a uint8, b uint16, c uint32, d uint64) int { } func CmpToZeroU_ex2(a uint8, b uint16, c uint32, d uint64) int { - // wasm:"I64Eqz"-"I64LeU" + // wasm:"I64Eqz" -"I64LeU" if a <= 0 { return 1 } - // wasm:"I64Eqz"-"I64LeU" + // wasm:"I64Eqz" -"I64LeU" if b <= 0 { return 1 } - // wasm:"I64Eqz"-"I64LeU" + // wasm:"I64Eqz" -"I64LeU" if c <= 0 { return 1 } - // wasm:"I64Eqz"-"I64LeU" + // wasm:"I64Eqz" -"I64LeU" if d <= 0 { return 1 } @@ -583,19 +583,19 @@ func CmpToZeroU_ex2(a uint8, b uint16, c uint32, d uint64) int { } func CmpToOneU_ex1(a uint8, b uint16, c uint32, d uint64) int { - // wasm:"I64Eqz"-"I64LtU" + // wasm:"I64Eqz" -"I64LtU" if a < 1 { return 1 } - // wasm:"I64Eqz"-"I64LtU" + // wasm:"I64Eqz" -"I64LtU" if b < 1 { return 1 } - // wasm:"I64Eqz"-"I64LtU" + // wasm:"I64Eqz" -"I64LtU" if c < 1 { return 1 } - // wasm:"I64Eqz"-"I64LtU" + // wasm:"I64Eqz" -"I64LtU" if d < 1 { return 1 } @@ -603,19 +603,19 @@ func CmpToOneU_ex1(a uint8, b uint16, c uint32, d uint64) int { } func CmpToOneU_ex2(a uint8, b uint16, c uint32, d uint64) int { - // wasm:"I64Eqz"-"I64LeU" + // wasm:"I64Eqz" -"I64LeU" if 1 <= a { return 1 } - // wasm:"I64Eqz"-"I64LeU" + // wasm:"I64Eqz" -"I64LeU" if 1 <= b { return 1 } - // wasm:"I64Eqz"-"I64LeU" + // wasm:"I64Eqz" -"I64LeU" if 1 <= c { return 1 } - // wasm:"I64Eqz"-"I64LeU" + // wasm:"I64Eqz" -"I64LeU" if 1 <= d { return 1 } diff --git a/test/codegen/divmod.go b/test/codegen/divmod.go index 9de091af7a..a8f8227364 100644 --- a/test/codegen/divmod.go +++ b/test/codegen/divmod.go @@ -221,7 +221,7 @@ func div7_int16u(i int16) int16 { // arm64: "UBFX [$]18, R[0-9]+, [$]14," // arm64: -"SUB" // wasm: "I64Const [$]37450" - // wasm -"I64Sub" + // wasm: -"I64Sub" return i / 7 } @@ -238,7 +238,7 @@ func div7_int32u(i int32) int32 { // arm64: "LSR [$]34," // arm64: -"SUB" // wasm: "I64Const [$]2454267027" - // wasm -"I64Sub" + // wasm: -"I64Sub" return i / 7 } @@ -253,7 +253,7 @@ func div7_int64u(i int64) int64 { // arm64: -"SUB" // wasm: "I64Const [$]1227133514" // wasm: "I64Const [$]2454267026" - // wasm -"I64Sub" + // wasm: -"I64Sub" return i / 7 } diff --git a/test/codegen/memcombine.go b/test/codegen/memcombine.go index 6feef26ce8..48ecd4fd01 100644 --- a/test/codegen/memcombine.go +++ b/test/codegen/memcombine.go @@ -53,7 +53,7 @@ func load_le32_idx(b []byte, idx int) uint32 { // arm64:`MOVWU\s\(R[0-9]+\)\(R[0-9]+\),`,-`MOV[BH]` // loong64:`MOVWU\s\(R[0-9]+\)\(R[0-9]+\),` // ppc64le:`MOVWZ\s`,-`MOV[BH]Z\s` - // ppc64:`MOVWBR\s`,-`MOV[BH]Z\s' + // ppc64:`MOVWBR\s`,-`MOV[BH]Z\s` return binary.LittleEndian.Uint32(b[idx:]) } @@ -103,7 +103,7 @@ func load_be32(b []byte) uint32 { // s390x:`MOVWZ\s\(.*\),` // arm64:`REVW`,`MOVWU\s\(R[0-9]+\),`,-`MOV[BH]`,-`REV16W` // ppc64le:`MOVWBR`,-`MOV[BH]Z` - // ppc64:`MOVWZ`,-MOV[BH]Z` + // ppc64:`MOVWZ`,-`MOV[BH]Z` return binary.BigEndian.Uint32(b) } @@ -113,7 +113,7 @@ func load_be32_idx(b []byte, idx int) uint32 { // s390x:`MOVWZ\s\(.*\)\(.*\*1\),` // arm64:`REVW`,`MOVWU\s\(R[0-9]+\)\(R[0-9]+\),`,-`MOV[HB]`,-`REV16W` // ppc64le:`MOVWBR`,-`MOV[BH]Z` - // ppc64:`MOVWZ`,-MOV[BH]Z` + // ppc64:`MOVWZ`,-`MOV[BH]Z` return binary.BigEndian.Uint32(b[idx:]) } @@ -158,7 +158,7 @@ func load_le_byte4_uint32(s []byte) uint32 { // 386:`MOVL\s\([A-Z]+\)`,-`MOV[BW]`,-`OR` // amd64:`MOVL\s\([A-Z]+\)`,-`MOV[BW]`,-`OR` // ppc64le:`MOVWZ \(R[0-9]+\)`,-`MOV[BH]Z` - // ppc64:`MOVWBR`,-MOV[BH]Z` + // ppc64:`MOVWBR`,-`MOV[BH]Z` return uint32(s[0]) | uint32(s[1])<<8 | uint32(s[2])<<16 | uint32(s[3])<<24 } @@ -486,7 +486,7 @@ func store_le32_idx(b []byte, x uint32, idx int) { func store_le32_idx_const(b []byte, idx int) { // amd64:`MOVL\s\$123, \(.*\)\(.*\*1\)$` - // ppc64x:`MOVW\s`,-MOV[HB]` + // ppc64x:`MOVW\s`,-`MOV[HB]` binary.LittleEndian.PutUint32(b[idx:], 123) } diff --git a/test/codegen/slices.go b/test/codegen/slices.go index 32561b2235..64191ab09a 100644 --- a/test/codegen/slices.go +++ b/test/codegen/slices.go @@ -163,10 +163,10 @@ func SliceMakeCopyLen(s []int) []int { func SliceMakeCopyLenPtr(s []*int) []*int { // amd64:`.*runtime\.makeslicecopy` // amd64:-`.*runtime\.makeslice\(` - // amd64:-`.*runtime\.typedslicecopy + // amd64:-`.*runtime\.typedslicecopy` // ppc64x:`.*runtime\.makeslicecopy` // ppc64x:-`.*runtime\.makeslice\(` - // ppc64x:-`.*runtime\.typedslicecopy + // ppc64x:-`.*runtime\.typedslicecopy` a := make([]*int, len(s)) copy(a, s) return a @@ -184,7 +184,7 @@ func SliceMakeCopyConst(s []int) []int { func SliceMakeCopyConstPtr(s []*int) []*int { // amd64:`.*runtime\.makeslicecopy` // amd64:-`.*runtime\.makeslice\(` - // amd64:-`.*runtime\.typedslicecopy + // amd64:-`.*runtime\.typedslicecopy` a := make([]*int, 4) copy(a, s) return a diff --git a/test/codegen/writebarrier.go b/test/codegen/writebarrier.go index c3c39c58f7..271d8d25d3 100644 --- a/test/codegen/writebarrier.go +++ b/test/codegen/writebarrier.go @@ -90,9 +90,9 @@ func issue71228(dst *S, ptr *int) { } func writeDouble(p *[2]*int, x, y *int) { - // arm64: `LDP\s`, `STP\s\(R[0-9]+, R[0-9]+\), \(`, + // arm64: `LDP\s`, `STP\s\(R[0-9]+, R[0-9]+\), \(` p[0] = x - // arm64: `STP\s\(R[0-9]+, R[0-9]+\), 16\(`, + // arm64: `STP\s\(R[0-9]+, R[0-9]+\), 16\(` p[1] = y } |
