This CL fixes the merge locals error.
The culprit is that liveness analysis wrongly mark SIMD structs fat,
hence making `StoreReg` of SIMD vectors not a varkill effect, making the
liveness range of SIMD vectors not closed correctly, further making
mergelocals merged 2 concurrently-live SIMD vectors.
Is looks like mergelocals will treat the live range as one instruction
if it's not closed: [st, st+1). Should we make it [st, +inf) instead? So
that we won't have similar errors in the future.
Also, I feel we really need to examine every "case types.TSTRUCT" or "if
t.Kind() == types.TSTRUCT" in the codebase correctly for SIMD types...
Change-Id: I2f4f4f36a890bd317d582cfa73a8f6a789382d91
Reviewed-on: https://go-review.googlesource.com/c/go/+/687775
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: David Chase <drchase@google.com>
}
return true
case types.TSTRUCT:
+ if t.IsSIMD() {
+ return false
+ }
// Struct with 1 field, check if field is fat
if t.NumFields() == 1 {
return isfat(t.Field(0).Type)
// items larger than what CanSSA would allow (approximateky, we disallow things
// marked as open defer slots so as to avoid complicating liveness
// analysis.
-//
-// TODO: make SIMD variables mergible.
-//
-// Right now this check excludes SIMD vars because sometimes two live SIMD
-// vectors will be put into the same partition by mergelocals, we need to figure
-// out why because these vectors are big and should be merged when possible.
-// Details in CL 687375.
func IsMergeCandidate(n *ir.Name) bool {
if base.Debug.MergeLocals == 0 ||
base.Flag.N != 0 ||
n.Type().Size() <= int64(3*types.PtrSize) ||
n.Addrtaken() ||
n.NonMergeable() ||
- n.Type().IsSIMD() ||
n.OpenDeferSlot() {
return false
}