diff --git a/src/cmd/compile/internal/ssa/cse.go b/src/cmd/compile/internal/ssa/cse.go index 25f424fbee..58c52f23e6 100644 --- a/src/cmd/compile/internal/ssa/cse.go +++ b/src/cmd/compile/internal/ssa/cse.go @@ -153,7 +153,6 @@ func cse(f *Func) { i++ } } - // TODO(khr): if value is a control value, do we need to keep it block-local? } } @@ -166,6 +165,16 @@ func cse(f *Func) { } } } + if v := b.Control; v != nil { + if x := rewrite[v.ID]; x != nil { + if v.Op == OpNilCheck { + // nilcheck pass will remove the nil checks and log + // them appropriately, so don't mess with them here. + continue + } + b.Control = x + } + } } } diff --git a/src/cmd/compile/internal/ssa/flagalloc.go b/src/cmd/compile/internal/ssa/flagalloc.go index c088158057..714ac016a2 100644 --- a/src/cmd/compile/internal/ssa/flagalloc.go +++ b/src/cmd/compile/internal/ssa/flagalloc.go @@ -21,6 +21,15 @@ func flagalloc(f *Func) { // Walk blocks backwards. Poor-man's postorder traversal. for i := len(f.Blocks) - 1; i >= 0; i-- { b := f.Blocks[i] + if len(b.Preds) > 1 { + // Don't use any flags register at the start + // of a merge block. This causes problems + // in regalloc because some of the rematerialization + // instructions used on incoming merge edges clobber + // the flags register. + // TODO: only for architectures where this matters? + continue + } // Walk values backwards to figure out what flag // value we want in the flag register at the start // of the block. diff --git a/src/cmd/compile/internal/ssa/gen/AMD64.rules b/src/cmd/compile/internal/ssa/gen/AMD64.rules index 7d0aa4b2d3..0edbfdaa1a 100644 --- a/src/cmd/compile/internal/ssa/gen/AMD64.rules +++ b/src/cmd/compile/internal/ssa/gen/AMD64.rules @@ -370,7 +370,7 @@ (If (SETGF cmp) yes no) -> (UGT cmp yes no) (If (SETGEF cmp) yes no) -> (UGE cmp yes no) (If (SETEQF cmp) yes no) -> (EQF cmp yes no) -(If (SETNEF cmp) yes no) -> (EQF cmp yes no) +(If (SETNEF cmp) yes no) -> (NEF cmp yes no) (If cond yes no) -> (NE (TESTB cond cond) yes no) diff --git a/src/cmd/compile/internal/ssa/gen/AMD64Ops.go b/src/cmd/compile/internal/ssa/gen/AMD64Ops.go index ba53e81ddd..461026bd7b 100644 --- a/src/cmd/compile/internal/ssa/gen/AMD64Ops.go +++ b/src/cmd/compile/internal/ssa/gen/AMD64Ops.go @@ -433,7 +433,7 @@ func init() { name: "DUFFCOPY", reg: regInfo{ inputs: []regMask{buildReg("DI"), buildReg("SI")}, - clobbers: buildReg("DI SI X0"), // uses X0 as a temporary + clobbers: buildReg("DI SI X0 FLAGS"), // uses X0 as a temporary }, }, diff --git a/src/cmd/compile/internal/ssa/opGen.go b/src/cmd/compile/internal/ssa/opGen.go index 132ca83f95..bbedf2fb64 100644 --- a/src/cmd/compile/internal/ssa/opGen.go +++ b/src/cmd/compile/internal/ssa/opGen.go @@ -3177,7 +3177,7 @@ var opcodeTable = [...]opInfo{ {0, 128}, // .DI {1, 64}, // .SI }, - clobbers: 65728, // .SI .DI .X0 + clobbers: 8590000320, // .SI .DI .X0 .FLAGS }, }, { diff --git a/src/cmd/compile/internal/ssa/rewriteAMD64.go b/src/cmd/compile/internal/ssa/rewriteAMD64.go index 3be94e37e7..5c2f3db4b2 100644 --- a/src/cmd/compile/internal/ssa/rewriteAMD64.go +++ b/src/cmd/compile/internal/ssa/rewriteAMD64.go @@ -14213,23 +14213,23 @@ func rewriteBlockAMD64(b *Block) bool { ; // match: (If (SETNEF cmp) yes no) // cond: - // result: (EQF cmp yes no) + // result: (NEF cmp yes no) { v := b.Control if v.Op != OpAMD64SETNEF { - goto endfe25939ca97349543bc2d2ce4f97ba41 + goto endaa989df10b5bbc5fdf8f7f0b81767e86 } cmp := v.Args[0] yes := b.Succs[0] no := b.Succs[1] - b.Kind = BlockAMD64EQF + b.Kind = BlockAMD64NEF b.Control = cmp b.Succs[0] = yes b.Succs[1] = no return true } - goto endfe25939ca97349543bc2d2ce4f97ba41 - endfe25939ca97349543bc2d2ce4f97ba41: + goto endaa989df10b5bbc5fdf8f7f0b81767e86 + endaa989df10b5bbc5fdf8f7f0b81767e86: ; // match: (If cond yes no) // cond: