]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/internal/obj/riscv: prevent duplicate error reports
authorMark Ryan <markdryan@rivosinc.com>
Tue, 10 Dec 2024 16:02:26 +0000 (17:02 +0100)
committerMeng Zhuo <mengzhuo1203@gmail.com>
Wed, 19 Mar 2025 01:36:01 +0000 (18:36 -0700)
The riscv64 Go assembler can output certain errors, ones produced by
instructionsForProg, multiple times.  These errors are guaranteed to
be output at least twice and can appear three or more times if a
rescan is needed to recompute branch addresses.  For example, the
syntactically incorrect instruction

MOV (X10), $1

will generate at least two identical errors

asm: 86076 (asm.s:21524) MOV (X10), $1: unsupported MOV
asm: 86076 (asm.s:21524) MOV (X10), $1: unsupported MOV
asm: assembly failed

In addition to confusing the user, these duplicate errors make it
difficult to write negative tests for certain types of instructions,
e.g., branches, whose duplicate errors are not always identical,
and so not ignored by endtoend_test.go.

We fix the issue by returning from preprocess if any errors have been
generated by the time we reach the end of the rescan loop. One
implication of this change is that validation errors will no longer
be reported if an error is generated earlier in the preprocess stage.
Negative test cases for validation errors are therefore moved to
their own file as the existing riscv64error.s file contains errors
generated by instructionsForProg that will now suppress the
validation errors.

Change-Id: Iffacdbefce28f44970dd5dda44990b822b8a23d4
Reviewed-on: https://go-review.googlesource.com/c/go/+/637315
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Joel Sing <joel@sing.id.au>
Reviewed-by: David Chase <drchase@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
src/cmd/asm/internal/asm/endtoend_test.go
src/cmd/asm/internal/asm/testdata/riscv64error.s
src/cmd/asm/internal/asm/testdata/riscv64validation.s [new file with mode: 0644]
src/cmd/internal/obj/riscv/obj.go

index 3760b77625d102101e66cb23b21c4e584b877e1f..f33b1e75bf6c0627bdb3096226e6d2c812fc68c5 100644 (file)
@@ -489,6 +489,10 @@ func TestRISCVErrors(t *testing.T) {
        testErrors(t, "riscv64", "riscv64error")
 }
 
+func TestRISCVValidation(t *testing.T) {
+       testErrors(t, "riscv64", "riscv64validation")
+}
+
 func TestS390XEndToEnd(t *testing.T) {
        testEndToEnd(t, "s390x", "s390x")
 }
index 82a23488946a368e64f6bde8e12c3e345975b655..e8855f6cd5f8aaa2c5bbe84568952b1c2dd5631b 100644 (file)
@@ -43,50 +43,16 @@ TEXT errors(SB),$0
        SRLIW   $-1, X5, X6                     // ERROR "immediate out of range 0 to 31"
        SRAIW   $-1, X5, X6                     // ERROR "immediate out of range 0 to 31"
        SD      X5, 4294967296(X6)              // ERROR "constant 4294967296 too large"
-       SRLI    $1, X5, F1                      // ERROR "expected integer register in rd position but got non-integer register F1"
-       SRLI    $1, F1, X5                      // ERROR "expected integer register in rs1 position but got non-integer register F1"
        FNES    F1, (X5)                        // ERROR "needs an integer register output"
-       VSETVLI $32, E16, M1, TU, MU, X12       // ERROR "must be in range [0, 31] (5 bits)"
-       VSETVLI $-1, E32, M2, TA, MA, X12       // ERROR "must be in range [0, 31] (5 bits)"
        VSETIVLI X10, E32, M2, TA, MA, X12      // ERROR "expected immediate value"
-       VSETVL  X10, X11                        // ERROR "expected integer register in rs1 position"
-       VLE8V   (X10), X10                      // ERROR "expected vector register in rd position"
-       VLE8V   (V1), V3                        // ERROR "expected integer register in rs1 position"
        VLE8V   (X10), V1, V3                   // ERROR "invalid vector mask register"
-       VSE8V   X10, (X10)                      // ERROR "expected vector register in rs1 position"
-       VSE8V   V3, (V1)                        // ERROR "expected integer register in rd position"
        VSE8V   V3, V1, (X10)                   // ERROR "invalid vector mask register"
-       VLSE8V  (X10), V3                       // ERROR "expected integer register in rs2 position"
-       VLSE8V  (X10), X10, X11                 // ERROR "expected vector register in rd position"
-       VLSE8V  (V1), X10, V3                   // ERROR "expected integer register in rs1 position"
-       VLSE8V  (X10), V1, V0, V3               // ERROR "expected integer register in rs2 position"
        VLSE8V  (X10), X10, V1, V3              // ERROR "invalid vector mask register"
-       VSSE8V  V3, (X10)                       // ERROR "expected integer register in rs2 position"
-       VSSE8V  X10, X11, (X10)                 // ERROR "expected vector register in rd position"
-       VSSE8V  V3, X11, (V1)                   // ERROR "expected integer register in rs1 position"
-       VSSE8V  V3, V1, V0, (X10)               // ERROR "expected integer register in rs2 position"
        VSSE8V  V3, X11, V1, (X10)              // ERROR "invalid vector mask register"
-       VLUXEI8V (X10), V2, X11                 // ERROR "expected vector register in rd position"
-       VLUXEI8V (X10), V2, X11                 // ERROR "expected vector register in rd position"
-       VLUXEI8V (V1), V2, V3                   // ERROR "expected integer register in rs1 position"
-       VLUXEI8V (X10), X11, V0, V3             // ERROR "expected vector register in rs2 position"
        VLUXEI8V (X10), V2, V1, V3              // ERROR "invalid vector mask register"
-       VSUXEI8V X10, V2, (X10)                 // ERROR "expected vector register in rd position"
-       VSUXEI8V V3, V2, (V1)                   // ERROR "expected integer register in rs1 position"
-       VSUXEI8V V3, X11, V0, (X10)             // ERROR "expected vector register in rs2 position"
        VSUXEI8V V3, V2, V1, (X10)              // ERROR "invalid vector mask register"
-       VLOXEI8V (X10), V2, X11                 // ERROR "expected vector register in rd position"
-       VLOXEI8V (V1), V2, V3                   // ERROR "expected integer register in rs1 position"
-       VLOXEI8V (X10), X11, V0, V3             // ERROR "expected vector register in rs2 position"
        VLOXEI8V (X10), V2, V1, V3              // ERROR "invalid vector mask register"
-       VSOXEI8V X10, V2, (X10)                 // ERROR "expected vector register in rd position"
-       VSOXEI8V V3, V2, (V1)                   // ERROR "expected integer register in rs1 position"
-       VSOXEI8V V3, X11, V0, (X10)             // ERROR "expected vector register in rs2 position"
        VSOXEI8V V3, V2, V1, (X10)              // ERROR "invalid vector mask register"
        VL1RV   (X10), V0, V3                   // ERROR "too many operands for instruction"
-       VL1RV   (X10), X10                      // ERROR "expected vector register in rd position"
-       VL1RV   (V1), V3                        // ERROR "expected integer register in rs1 position"
        VS1RV   V3, V0, (X11)                   // ERROR "too many operands for instruction"
-       VS1RV   X11, (X11)                      // ERROR "expected vector register in rs1 position"
-       VS1RV   V3, (V1)                        // ERROR "expected integer register in rd position"
        RET
diff --git a/src/cmd/asm/internal/asm/testdata/riscv64validation.s b/src/cmd/asm/internal/asm/testdata/riscv64validation.s
new file mode 100644 (file)
index 0000000..773f275
--- /dev/null
@@ -0,0 +1,46 @@
+// Copyright 2024 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 file is for validation errors only, i.e., errors reported by the validate function.
+// Negative test cases for errors generated earlier in the assembler's preprocess stage
+// should be added to riscv64error.s.  If they are added to this file, they will prevent
+// the validate function from being run and TestRISCVValidation will report missing
+// errors.
+
+TEXT validation(SB),$0
+       SRLI    $1, X5, F1                      // ERROR "expected integer register in rd position but got non-integer register F1"
+       SRLI    $1, F1, X5                      // ERROR "expected integer register in rs1 position but got non-integer register F1"
+       VSETVLI $32, E16, M1, TU, MU, X12       // ERROR "must be in range [0, 31] (5 bits)"
+       VSETVLI $-1, E32, M2, TA, MA, X12       // ERROR "must be in range [0, 31] (5 bits)"
+       VSETVL  X10, X11                        // ERROR "expected integer register in rs1 position"
+       VLE8V   (X10), X10                      // ERROR "expected vector register in rd position"
+       VLE8V   (V1), V3                        // ERROR "expected integer register in rs1 position"
+       VSE8V   X10, (X10)                      // ERROR "expected vector register in rs1 position"
+       VSE8V   V3, (V1)                        // ERROR "expected integer register in rd position"
+       VLSE8V  (X10), V3                       // ERROR "expected integer register in rs2 position"
+       VLSE8V  (X10), X10, X11                 // ERROR "expected vector register in rd position"
+       VLSE8V  (V1), X10, V3                   // ERROR "expected integer register in rs1 position"
+       VLSE8V  (X10), V1, V0, V3               // ERROR "expected integer register in rs2 position"
+       VSSE8V  V3, (X10)                       // ERROR "expected integer register in rs2 position"
+       VSSE8V  X10, X11, (X10)                 // ERROR "expected vector register in rd position"
+       VSSE8V  V3, X11, (V1)                   // ERROR "expected integer register in rs1 position"
+       VSSE8V  V3, V1, V0, (X10)               // ERROR "expected integer register in rs2 position"
+       VLUXEI8V (X10), V2, X11                 // ERROR "expected vector register in rd position"
+       VLUXEI8V (X10), V2, X11                 // ERROR "expected vector register in rd position"
+       VLUXEI8V (V1), V2, V3                   // ERROR "expected integer register in rs1 position"
+       VLUXEI8V (X10), X11, V0, V3             // ERROR "expected vector register in rs2 position"
+       VSUXEI8V X10, V2, (X10)                 // ERROR "expected vector register in rd position"
+       VSUXEI8V V3, V2, (V1)                   // ERROR "expected integer register in rs1 position"
+       VSUXEI8V V3, X11, V0, (X10)             // ERROR "expected vector register in rs2 position"
+       VLOXEI8V (X10), V2, X11                 // ERROR "expected vector register in rd position"
+       VLOXEI8V (V1), V2, V3                   // ERROR "expected integer register in rs1 position"
+       VLOXEI8V (X10), X11, V0, V3             // ERROR "expected vector register in rs2 position"
+       VSOXEI8V X10, V2, (X10)                 // ERROR "expected vector register in rd position"
+       VSOXEI8V V3, V2, (V1)                   // ERROR "expected integer register in rs1 position"
+       VSOXEI8V V3, X11, V0, (X10)             // ERROR "expected vector register in rs2 position"
+       VL1RV   (X10), X10                      // ERROR "expected vector register in rd position"
+       VL1RV   (V1), V3                        // ERROR "expected integer register in rs1 position"
+       VS1RV   X11, (X11)                      // ERROR "expected vector register in rs1 position"
+       VS1RV   V3, (V1)                        // ERROR "expected integer register in rd position"
+       RET
index 16bd1310c1ac853ee1d971007174e56229b3a5c3..de9851519acca975fb9cc13b8e58cc069918c468 100644 (file)
@@ -833,6 +833,11 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
                        }
                }
 
+               // Return if errors have been detected up to this point. Continuing
+               // may lead to duplicate errors being output.
+               if ctxt.Errors > 0 {
+                       return
+               }
                if !rescan {
                        break
                }