]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.ssa] cmd/compile: fix phi floats
authorTodd Neal <todd@tneal.org>
Wed, 26 Aug 2015 03:49:59 +0000 (22:49 -0500)
committerDavid Chase <drchase@google.com>
Wed, 26 Aug 2015 14:40:34 +0000 (14:40 +0000)
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>
src/cmd/compile/internal/gc/testdata/fp_ssa.go
src/cmd/compile/internal/ssa/regalloc.go

index 95e3cf9196ad9e3eeec5fd43ce823cd66125b8c2..5eb65035d4954185bcc4a335795356ef41fdc8c3 100644 (file)
@@ -35,6 +35,52 @@ func manysub_ssa(a, b, c, d float64) (aa, ab, ac, ad, ba, bb, bc, bd, ca, cb, cc
        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 {
        switch {
        }
index b62f9042b6f6220df7edf84415415ec03bc67be0..b098ea1a19393e79fa8c074931a5b659aa7ff63a 100644 (file)
@@ -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) {
        liveset := newSparseSet(f.NumValues())
        argset := newSparseSet(f.NumValues())
@@ -836,10 +846,11 @@ func (s *regAllocState) regalloc(f *Func) {
                                if !argset.contains(v.ID) {
                                        continue
                                }
+
                                // This stack-based phi is the argument of some other
                                // phi in this block.  We must make a copy of its
                                // 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)
                                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.
                        for _, v := range stackPhis {
                                // Load phi arg into a register, then store it with a StoreReg.
-                               // If already in a register, use that.  If not, use register 0.
-                               // TODO: choose a better default register (set of reg by type?).
-                               c := s.allocValToReg(v.Args[i], s.values[v.Args[i].ID].regs|1<<0, false)
+                               // If already in a register, use that.  If not, pick a compatible
+                               // register.
+                               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)
                        }
                        // Figure out what value goes in each register.