]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/internal/obj/x86: move MOV->XOR rewriting into compiler
authorMatthew Dempsky <mdempsky@google.com>
Tue, 24 Oct 2017 20:24:14 +0000 (13:24 -0700)
committerMatthew Dempsky <mdempsky@google.com>
Tue, 24 Oct 2017 21:32:17 +0000 (21:32 +0000)
Fixes #20986.

Change-Id: Ic3cf5c0ab260f259ecff7b92cfdf5f4ae432aef3
Reviewed-on: https://go-review.googlesource.com/73072
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Austin Clements <austin@google.com>
src/cmd/compile/internal/amd64/ssa.go
src/cmd/compile/internal/x86/ssa.go
src/cmd/internal/obj/x86/a.out.go
src/cmd/internal/obj/x86/asm6.go
src/math/big/arith_amd64.s

index 2d3034b64b043b64a7c6e553ea462bee6ed0d852..97b01d20fa53160a2d5a6168876f60eca08b9193 100644 (file)
@@ -494,6 +494,18 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                p.To.Reg = v.Args[0].Reg()
        case ssa.OpAMD64MOVLconst, ssa.OpAMD64MOVQconst:
                x := v.Reg()
+
+               // If flags aren't live (indicated by v.Aux == nil),
+               // then we can rewrite MOV $0, AX into XOR AX, AX.
+               if v.AuxInt == 0 && v.Aux == nil {
+                       p := s.Prog(x86.AXORL)
+                       p.From.Type = obj.TYPE_REG
+                       p.From.Reg = x
+                       p.To.Type = obj.TYPE_REG
+                       p.To.Reg = x
+                       break
+               }
+
                asm := v.Op.Asm()
                // Use MOVL to move a small constant into a register
                // when the constant is positive and fits into 32 bits.
@@ -506,11 +518,6 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                p.From.Offset = v.AuxInt
                p.To.Type = obj.TYPE_REG
                p.To.Reg = x
-               // If flags are live at this instruction, suppress the
-               // MOV $0,AX -> XOR AX,AX optimization.
-               if v.Aux != nil {
-                       p.Mark |= x86.PRESERVEFLAGS
-               }
        case ssa.OpAMD64MOVSSconst, ssa.OpAMD64MOVSDconst:
                x := v.Reg()
                p := s.Prog(v.Op.Asm())
index 6ac0022d8f2d9c21341cd53005cafbcab4b2c5a7..69217f29159c942457433f0915ca071eb7ae47fd 100644 (file)
@@ -426,16 +426,23 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                p.To.Reg = v.Args[0].Reg()
        case ssa.Op386MOVLconst:
                x := v.Reg()
+
+               // If flags aren't live (indicated by v.Aux == nil),
+               // then we can rewrite MOV $0, AX into XOR AX, AX.
+               if v.AuxInt == 0 && v.Aux == nil {
+                       p := s.Prog(x86.AXORL)
+                       p.From.Type = obj.TYPE_REG
+                       p.From.Reg = x
+                       p.To.Type = obj.TYPE_REG
+                       p.To.Reg = x
+                       break
+               }
+
                p := s.Prog(v.Op.Asm())
                p.From.Type = obj.TYPE_CONST
                p.From.Offset = v.AuxInt
                p.To.Type = obj.TYPE_REG
                p.To.Reg = x
-               // If flags are live at this instruction, suppress the
-               // MOV $0,AX -> XOR AX,AX optimization.
-               if v.Aux != nil {
-                       p.Mark |= x86.PRESERVEFLAGS
-               }
        case ssa.Op386MOVSSconst, ssa.Op386MOVSDconst:
                x := v.Reg()
                p := s.Prog(v.Op.Asm())
index 5cf13e193c6a4ae4f33d31b2119489c971b0726d..5babeea36c0e8bc5e89b2949e1f18ef450e4983d 100644 (file)
@@ -36,8 +36,7 @@ import "cmd/internal/obj"
 
 const (
        /* mark flags */
-       DONE          = 1 << iota
-       PRESERVEFLAGS // not allowed to clobber flags
+       DONE = 1 << iota
 )
 
 /*
index 6044a9d24d81e65793a1bc222073eb296ff31016..56106955d2a5fa083661ba6c3fa0488f81006116 100644 (file)
@@ -202,7 +202,6 @@ const (
        Zm_ilo
        Zib_rr
        Zil_rr
-       Zclr
        Zbyte
        Zvex_rm_v_r
        Zvex_r_v_rm
@@ -412,7 +411,6 @@ var ybtl = []ytab{
 var ymovw = []ytab{
        {Zr_m, 1, argList{Yrl, Yml}},
        {Zm_r, 1, argList{Yml, Yrl}},
-       {Zclr, 1, argList{Yi0, Yrl}},
        {Zil_rp, 1, argList{Yi32, Yrl}},
        {Zilo_m, 2, argList{Yi32, Yml}},
        {Zaut_r, 2, argList{Yiauto, Yrl}},
@@ -421,7 +419,6 @@ var ymovw = []ytab{
 var ymovl = []ytab{
        {Zr_m, 1, argList{Yrl, Yml}},
        {Zm_r, 1, argList{Yml, Yrl}},
-       {Zclr, 1, argList{Yi0, Yrl}},
        {Zil_rp, 1, argList{Yi32, Yrl}},
        {Zilo_m, 2, argList{Yi32, Yml}},
        {Zm_r_xm, 1, argList{Yml, Ymr}}, // MMX MOVD
@@ -447,7 +444,6 @@ var ymovq = []ytab{
        // valid only in 64-bit mode, usually with 64-bit prefix
        {Zr_m, 1, argList{Yrl, Yml}},      // 0x89
        {Zm_r, 1, argList{Yml, Yrl}},      // 0x8b
-       {Zclr, 1, argList{Yi0, Yrl}},      // 0x31
        {Zilo_m, 2, argList{Ys32, Yrl}},   // 32 bit signed 0xc7,(0)
        {Ziq_rp, 1, argList{Yi64, Yrl}},   // 0xb8 -- 32/64 bit immediate
        {Zilo_m, 2, argList{Yi32, Yml}},   // 0xc7,(0)
@@ -1217,7 +1213,7 @@ var optab =
        {AMOVHLPS, yxr, Pm, [23]uint8{0x12}},
        {AMOVHPD, yxmov, Pe, [23]uint8{0x16, 0x17}},
        {AMOVHPS, yxmov, Pm, [23]uint8{0x16, 0x17}},
-       {AMOVL, ymovl, Px, [23]uint8{0x89, 0x8b, 0x31, 0xb8, 0xc7, 00, 0x6e, 0x7e, Pe, 0x6e, Pe, 0x7e, 0}},
+       {AMOVL, ymovl, Px, [23]uint8{0x89, 0x8b, 0xb8, 0xc7, 00, 0x6e, 0x7e, Pe, 0x6e, Pe, 0x7e, 0}},
        {AMOVLHPS, yxr, Pm, [23]uint8{0x16}},
        {AMOVLPD, yxmov, Pe, [23]uint8{0x12, 0x13}},
        {AMOVLPS, yxmov, Pm, [23]uint8{0x12, 0x13}},
@@ -1230,7 +1226,7 @@ var optab =
        {AMOVNTPD, yxr_ml, Pe, [23]uint8{0x2b}},
        {AMOVNTPS, yxr_ml, Pm, [23]uint8{0x2b}},
        {AMOVNTQ, ymr_ml, Pm, [23]uint8{0xe7}},
-       {AMOVQ, ymovq, Pw8, [23]uint8{0x6f, 0x7f, Pf2, 0xd6, Pf3, 0x7e, Pe, 0xd6, 0x89, 0x8b, 0x31, 0xc7, 00, 0xb8, 0xc7, 00, 0x6e, 0x7e, Pe, 0x6e, Pe, 0x7e, 0}},
+       {AMOVQ, ymovq, Pw8, [23]uint8{0x6f, 0x7f, Pf2, 0xd6, Pf3, 0x7e, Pe, 0xd6, 0x89, 0x8b, 0xc7, 00, 0xb8, 0xc7, 00, 0x6e, 0x7e, Pe, 0x6e, Pe, 0x7e, 0}},
        {AMOVQOZX, ymrxr, Pf3, [23]uint8{0xd6, 0x7e}},
        {AMOVSB, ynone, Pb, [23]uint8{0xa4}},
        {AMOVSD, yxmov, Pf2, [23]uint8{0x10, 0x11}},
@@ -1240,7 +1236,7 @@ var optab =
        {AMOVSW, ynone, Pe, [23]uint8{0xa5}},
        {AMOVUPD, yxmov, Pe, [23]uint8{0x10, 0x11}},
        {AMOVUPS, yxmov, Pm, [23]uint8{0x10, 0x11}},
-       {AMOVW, ymovw, Pe, [23]uint8{0x89, 0x8b, 0x31, 0xb8, 0xc7, 00, 0}},
+       {AMOVW, ymovw, Pe, [23]uint8{0x89, 0x8b, 0xb8, 0xc7, 00, 0}},
        {AMOVWLSX, yml_rl, Pm, [23]uint8{0xbf}},
        {AMOVWLZX, yml_rl, Pm, [23]uint8{0xb7}},
        {AMOVWQSX, yml_rl, Pw, [23]uint8{0x0f, 0xbf}},
@@ -2405,10 +2401,6 @@ func oclass(ctxt *obj.Link, p *obj.Prog, a *obj.Addr) int {
                        v = int64(int32(v))
                }
                if v == 0 {
-                       if p.Mark&PRESERVEFLAGS != 0 {
-                               // If PRESERVEFLAGS is set, avoid MOV $0, AX turning into XOR AX, AX.
-                               return Yu7
-                       }
                        return Yi0
                }
                if v == 1 {
@@ -3857,11 +3849,6 @@ func (asmbuf *AsmBuf) doasm(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog) {
                                asmbuf.rexflag |= regrex[p.From.Reg] & (Rxb | 0x40)
                                asmbuf.Put1(byte(op + reg[p.From.Reg]))
 
-                       case Zclr:
-                               asmbuf.rexflag &^= Pw
-                               asmbuf.Put1(byte(op))
-                               asmbuf.asmand(ctxt, cursym, p, &p.To, &p.To)
-
                        case Zcallcon, Zjmpcon:
                                if yt.zcase == Zcallcon {
                                        asmbuf.Put1(byte(op))
index 7e502246c89e58005c6261fe4004cc2d9349f9cb..9a2405ee1c24d20bf5a5e190f959e13fc3cd2e2d 100644 (file)
@@ -30,8 +30,6 @@ TEXT ·divWW(SB),NOSPLIT,$0
 // The carry bit is saved with SBBQ Rx, Rx: if the carry was set, Rx is -1, otherwise it is 0.
 // It is restored with ADDQ Rx, Rx: if Rx was -1 the carry is set, otherwise it is cleared.
 // This is faster than using rotate instructions.
-//
-// CAUTION: Note that MOVQ $0, Rx is translated to XORQ Rx, Rx which clears the carry bit!
 
 // func addVV(z, x, y []Word) (c Word)
 TEXT ·addVV(SB),NOSPLIT,$0