]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: allow 128-bit values to be spilled
authorKeith Randall <khr@golang.org>
Tue, 21 Jun 2022 00:06:09 +0000 (17:06 -0700)
committerKeith Randall <khr@google.com>
Tue, 21 Jun 2022 17:23:40 +0000 (17:23 +0000)
We sometimes use 16-byte load+store to move values around in memory.
In rare circumstances, the loaded value must be spilled because the
store can't happen yet.

In that case, we need to be able to spill the 16-byte value.

Fixes #53454

Change-Id: I09fd08e11a63c6ba3ef781d3f5ede237e9b0132e
Reviewed-on: https://go-review.googlesource.com/c/go/+/413294
Reviewed-by: Keith Randall <khr@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
Run-TryBot: Keith Randall <khr@golang.org>
Reviewed-by: Keith Randall <khr@google.com>
src/cmd/compile/internal/amd64/ssa.go
src/cmd/compile/internal/dwarfgen/dwarf.go
src/cmd/compile/internal/types/size.go
src/cmd/compile/internal/types/type.go
test/fixedbugs/issue53454.go [new file with mode: 0644]

index c9667bd04ae7c8d4a9d3ebbb589daeaa122b8c8c..0a95aaabd77c95f3a68451217ed0ea9e260dea0c 100644 (file)
@@ -78,6 +78,8 @@ func storeByType(t *types.Type) obj.As {
                        return x86.AMOVL
                case 8:
                        return x86.AMOVQ
+               case 16:
+                       return x86.AMOVUPS
                }
        }
        panic(fmt.Sprintf("bad store type %v", t))
index f84368ece3421154914806b1aa3484687e3602ed..4bbc04826a8dc0414629a3dfcb5f817a3efb3828 100644 (file)
@@ -91,6 +91,11 @@ func Info(fnsym *obj.LSym, infosym *obj.LSym, curfn interface{}) ([]dwarf.Scope,
                                continue
                        }
                        apdecls = append(apdecls, n)
+                       if n.Type().Kind() == types.TSSA {
+                               // Can happen for TypeInt128 types. This only happens for
+                               // spill locations, so not a huge deal.
+                               continue
+                       }
                        fnsym.Func().RecordAutoType(reflectdata.TypeLinksym(n.Type()))
                }
        }
index a5a5c0b5b1442e3c35c1d89f2e9c5d0947da9391..68b9ac3ff3ff7f3c1fff8898e6d36d247a63e33d 100644 (file)
@@ -590,6 +590,12 @@ func PtrDataSize(t *Type) int64 {
                }
                return 0
 
+       case TSSA:
+               if t != TypeInt128 {
+                       base.Fatalf("PtrDataSize: unexpected ssa type %v", t)
+               }
+               return 0
+
        default:
                base.Fatalf("PtrDataSize: unexpected type, %v", t)
                return 0
index 1ea239ea328aa13dc7ba132c47da9f442d764821..9e229a59c63026561b6c8349379376724efef191 100644 (file)
@@ -1705,6 +1705,11 @@ var (
        TypeResultMem = newResults([]*Type{TypeMem})
 )
 
+func init() {
+       TypeInt128.width = 16
+       TypeInt128.align = 8
+}
+
 // NewNamed returns a new named type for the given type name. obj should be an
 // ir.Name. The new type is incomplete (marked as TFORW kind), and the underlying
 // type should be set later via SetUnderlying(). References to the type are
diff --git a/test/fixedbugs/issue53454.go b/test/fixedbugs/issue53454.go
new file mode 100644 (file)
index 0000000..8b16d81
--- /dev/null
@@ -0,0 +1,89 @@
+// compile
+
+// Copyright 2022 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
+
+type T1 struct {
+       A T5
+       B T2
+       C T7
+       D T4
+}
+
+type T2 struct {
+       T3
+       A float64
+       E float64
+       C float64
+}
+
+type T3 struct {
+       F float64
+       G float64
+       H float64
+       I float64
+       J float64
+       K float64
+       L float64
+}
+
+type T4 struct {
+       M float64
+       N float64
+       O float64
+       P float64
+}
+
+type T5 struct {
+       Q float64
+       R float64
+       S float64
+       T float64
+       U float64
+       V float64
+}
+
+type T6 struct {
+       T9
+       C T10
+}
+
+type T7 struct {
+       T10
+       T11
+}
+
+type T8 struct {
+       T9
+       C T7
+}
+
+type T9 struct {
+       A T5
+       B T3
+       D T4
+}
+
+type T10 struct {
+       W float64
+}
+
+type T11 struct {
+       X float64
+       Y float64
+}
+
+func MainTest(x T1, y T8, z T6) float64 {
+       return Test(x.B, x.A, x.D, x.C, y.B, y.A, y.D, y.C, z.B, z.A, z.D,
+               T7{
+                       T10: T10{
+                               W: z.C.W,
+                       },
+                       T11: T11{},
+               },
+       )
+}
+func Test(a T2, b T5, c T4, d T7, e T3, f T5, g T4, h T7, i T3, j T5, k T4, l T7) float64