mirror of
https://github.com/golang/go
synced 2024-10-05 20:31:20 -06:00
[dev.ssa] cmd/compile: fix phi floats
The code previously always used AX causing errors. For now, just switch off the type in order to at least generate valid code. Change-Id: Iaf13120a24b62456b9b33c04ab31f2d5104b381b Reviewed-on: https://go-review.googlesource.com/13943 Reviewed-by: David Chase <drchase@google.com>
This commit is contained in:
parent
752fe4dcb5
commit
7cadf23afb
46
src/cmd/compile/internal/gc/testdata/fp_ssa.go
vendored
46
src/cmd/compile/internal/gc/testdata/fp_ssa.go
vendored
@ -35,6 +35,52 @@ func manysub_ssa(a, b, c, d float64) (aa, ab, ac, ad, ba, bb, bc, bd, ca, cb, cc
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// fpspill_ssa attempts to trigger a bug where phis with floating point values
|
||||||
|
// were stored in non-fp registers causing an error in doasm.
|
||||||
|
func fpspill_ssa(a int) float64 {
|
||||||
|
switch {
|
||||||
|
}
|
||||||
|
|
||||||
|
ret := -1.0
|
||||||
|
switch a {
|
||||||
|
case 0:
|
||||||
|
ret = 1.0
|
||||||
|
case 1:
|
||||||
|
ret = 1.1
|
||||||
|
case 2:
|
||||||
|
ret = 1.2
|
||||||
|
case 3:
|
||||||
|
ret = 1.3
|
||||||
|
case 4:
|
||||||
|
ret = 1.4
|
||||||
|
case 5:
|
||||||
|
ret = 1.5
|
||||||
|
case 6:
|
||||||
|
ret = 1.6
|
||||||
|
case 7:
|
||||||
|
ret = 1.7
|
||||||
|
case 8:
|
||||||
|
ret = 1.8
|
||||||
|
case 9:
|
||||||
|
ret = 1.9
|
||||||
|
case 10:
|
||||||
|
ret = 1.10
|
||||||
|
case 11:
|
||||||
|
ret = 1.11
|
||||||
|
case 12:
|
||||||
|
ret = 1.12
|
||||||
|
case 13:
|
||||||
|
ret = 1.13
|
||||||
|
case 14:
|
||||||
|
ret = 1.14
|
||||||
|
case 15:
|
||||||
|
ret = 1.15
|
||||||
|
case 16:
|
||||||
|
ret = 1.16
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
func add64_ssa(a, b float64) float64 {
|
func add64_ssa(a, b float64) float64 {
|
||||||
switch {
|
switch {
|
||||||
}
|
}
|
||||||
|
@ -550,6 +550,16 @@ func (s *regAllocState) setState(state []regState) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// compatReg returns a register compatible with the a value and is used when
|
||||||
|
// spilling/loading.
|
||||||
|
// TODO: choose a better default register (set of reg by type?).
|
||||||
|
func compatReg(v *Value) regMask {
|
||||||
|
if v.Type.IsFloat() {
|
||||||
|
return 1 << 16 // X0
|
||||||
|
}
|
||||||
|
return 1 << 0 // AX
|
||||||
|
}
|
||||||
|
|
||||||
func (s *regAllocState) regalloc(f *Func) {
|
func (s *regAllocState) regalloc(f *Func) {
|
||||||
liveset := newSparseSet(f.NumValues())
|
liveset := newSparseSet(f.NumValues())
|
||||||
argset := newSparseSet(f.NumValues())
|
argset := newSparseSet(f.NumValues())
|
||||||
@ -836,10 +846,11 @@ func (s *regAllocState) regalloc(f *Func) {
|
|||||||
if !argset.contains(v.ID) {
|
if !argset.contains(v.ID) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// This stack-based phi is the argument of some other
|
// This stack-based phi is the argument of some other
|
||||||
// phi in this block. We must make a copy of its
|
// phi in this block. We must make a copy of its
|
||||||
// value so that we don't clobber it prematurely.
|
// value so that we don't clobber it prematurely.
|
||||||
c := s.allocValToReg(v, s.values[v.ID].regs|1<<0, false)
|
c := s.allocValToReg(v, s.values[v.ID].regs|compatReg(v), false)
|
||||||
d := p.NewValue1(v.Line, OpStoreReg, v.Type, c)
|
d := p.NewValue1(v.Line, OpStoreReg, v.Type, c)
|
||||||
s.values[v.ID].spill2 = d
|
s.values[v.ID].spill2 = d
|
||||||
}
|
}
|
||||||
@ -848,9 +859,10 @@ func (s *regAllocState) regalloc(f *Func) {
|
|||||||
// we might need a register to do the assignment.
|
// we might need a register to do the assignment.
|
||||||
for _, v := range stackPhis {
|
for _, v := range stackPhis {
|
||||||
// Load phi arg into a register, then store it with a StoreReg.
|
// Load phi arg into a register, then store it with a StoreReg.
|
||||||
// If already in a register, use that. If not, use register 0.
|
// If already in a register, use that. If not, pick a compatible
|
||||||
// TODO: choose a better default register (set of reg by type?).
|
// register.
|
||||||
c := s.allocValToReg(v.Args[i], s.values[v.Args[i].ID].regs|1<<0, false)
|
w := v.Args[i]
|
||||||
|
c := s.allocValToReg(w, s.values[w.ID].regs|compatReg(w), false)
|
||||||
v.Args[i] = p.NewValue1(v.Line, OpStoreReg, v.Type, c)
|
v.Args[i] = p.NewValue1(v.Line, OpStoreReg, v.Type, c)
|
||||||
}
|
}
|
||||||
// Figure out what value goes in each register.
|
// Figure out what value goes in each register.
|
||||||
|
Loading…
Reference in New Issue
Block a user