]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.ssa] cmd/compile: fix rare issue caused by liblink rewrite
authorTodd Neal <todd@tneal.org>
Sat, 29 Aug 2015 20:41:57 +0000 (15:41 -0500)
committerTodd Neal <todd@tneal.org>
Tue, 1 Sep 2015 22:19:49 +0000 (22:19 +0000)
liblink rewrites MOV $0, reg into XOR reg, reg. Make MOVxconst clobber
flags so we don't generate invalid code in the unlikely case that it
matters.  In testing, this change leads to no additional regenerated
flags due to a scheduling fix in CL14042.

Change-Id: I7bc1cfee94ef83beb2f97c31ec6a97e19872fb89
Reviewed-on: https://go-review.googlesource.com/14043
Reviewed-by: Keith Randall <khr@golang.org>
src/cmd/compile/internal/gc/testdata/ctl_ssa.go
src/cmd/compile/internal/ssa/gen/AMD64Ops.go
src/cmd/compile/internal/ssa/opGen.go

index cc55134b9664f53ab0393596ad84396f6eb1023a..09880ef94fed9b2c8c3fdcecdd2696b5473ab612 100644 (file)
@@ -115,6 +115,35 @@ func testSwitch() {
        }
 }
 
+type junk struct {
+       step int
+}
+
+// flagOverwrite_ssa is intended to reproduce an issue seen where a XOR
+// was scheduled between a compare and branch, clearing flags.
+func flagOverwrite_ssa(s *junk, c int) int {
+       switch {
+       }
+       if '0' <= c && c <= '9' {
+               s.step = 0
+               return 1
+       }
+       if c == 'e' || c == 'E' {
+               s.step = 0
+               return 2
+       }
+       s.step = 0
+       return 3
+}
+
+func testFlagOverwrite() {
+       j := junk{}
+       if got := flagOverwrite_ssa(&j, ' '); got != 3 {
+               println("flagOverwrite_ssa =", got, "wanted 3")
+               failed = true
+       }
+}
+
 var failed = false
 
 func main() {
@@ -124,6 +153,8 @@ func main() {
        testSwitch()
        testFallthrough()
 
+       testFlagOverwrite()
+
        if failed {
                panic("failed")
        }
index 555a5149a782781ea12cd76a08e551c2a9deadf6..09ffd4526f0cbe868454447ceda89f14ebf46127 100644 (file)
@@ -93,6 +93,7 @@ func init() {
        // Common regInfo
        var (
                gp01      = regInfo{inputs: []regMask{}, outputs: gponly}
+               gp01flags = regInfo{inputs: []regMask{}, outputs: gponly, clobbers: flags}
                gp11      = regInfo{inputs: []regMask{gpsp}, outputs: gponly, clobbers: flags}
                gp11nf    = regInfo{inputs: []regMask{gpsp}, outputs: gponly} // nf: no flags clobbered
                gp11sb    = regInfo{inputs: []regMask{gpspsb}, outputs: gponly}
@@ -338,10 +339,12 @@ func init() {
                {name: "MOVLQSX", reg: gp11nf, asm: "MOVLQSX"}, // sign extend arg0 from int32 to int64
                {name: "MOVLQZX", reg: gp11nf, asm: "MOVLQZX"}, // zero extend arg0 from int32 to int64
 
-               {name: "MOVBconst", reg: gp01, asm: "MOVB"}, // 8 low bits of auxint
-               {name: "MOVWconst", reg: gp01, asm: "MOVW"}, // 16 low bits of auxint
-               {name: "MOVLconst", reg: gp01, asm: "MOVL"}, // 32 low bits of auxint
-               {name: "MOVQconst", reg: gp01, asm: "MOVQ"}, // auxint
+               // clobbers flags as liblink will rewrite these to XOR reg, reg if the constant is zero
+               // TODO: revisit when issue 12405 is fixed
+               {name: "MOVBconst", reg: gp01flags, asm: "MOVB"}, // 8 low bits of auxint
+               {name: "MOVWconst", reg: gp01flags, asm: "MOVW"}, // 16 low bits of auxint
+               {name: "MOVLconst", reg: gp01flags, asm: "MOVL"}, // 32 low bits of auxint
+               {name: "MOVQconst", reg: gp01flags, asm: "MOVQ"}, // auxint
 
                {name: "CVTSD2SL", reg: fpgp, asm: "CVTSD2SL"}, // convert float64 to int32
                {name: "CVTSD2SQ", reg: fpgp, asm: "CVTSD2SQ"}, // convert float64 to int64
index a41b04b29fafbca4c596ffa8acfffcf9ca156cb7..8263268019cc45aae920a728b57ef88ee7490166 100644 (file)
@@ -2645,6 +2645,7 @@ var opcodeTable = [...]opInfo{
                name: "MOVBconst",
                asm:  x86.AMOVB,
                reg: regInfo{
+                       clobbers: 8589934592, // .FLAGS
                        outputs: []regMask{
                                65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
                        },
@@ -2654,6 +2655,7 @@ var opcodeTable = [...]opInfo{
                name: "MOVWconst",
                asm:  x86.AMOVW,
                reg: regInfo{
+                       clobbers: 8589934592, // .FLAGS
                        outputs: []regMask{
                                65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
                        },
@@ -2663,6 +2665,7 @@ var opcodeTable = [...]opInfo{
                name: "MOVLconst",
                asm:  x86.AMOVL,
                reg: regInfo{
+                       clobbers: 8589934592, // .FLAGS
                        outputs: []regMask{
                                65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
                        },
@@ -2672,6 +2675,7 @@ var opcodeTable = [...]opInfo{
                name: "MOVQconst",
                asm:  x86.AMOVQ,
                reg: regInfo{
+                       clobbers: 8589934592, // .FLAGS
                        outputs: []regMask{
                                65519, // .AX .CX .DX .BX .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15
                        },