diff --git a/src/cmd/compile/internal/amd64/ssa.go b/src/cmd/compile/internal/amd64/ssa.go index 4ce81592f47..2314db520c8 100644 --- a/src/cmd/compile/internal/amd64/ssa.go +++ b/src/cmd/compile/internal/amd64/ssa.go @@ -903,7 +903,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) { p.From.Reg = v.Args[0].Reg() gc.AddrAuto(&p.To, v) case ssa.OpAMD64LoweredHasCPUFeature: - p := s.Prog(x86.AMOVB) + p := s.Prog(x86.AMOVBQZX) p.From.Type = obj.TYPE_MEM gc.AddAux(&p.From, v) p.To.Type = obj.TYPE_REG diff --git a/src/cmd/compile/internal/ssa/gen/AMD64.rules b/src/cmd/compile/internal/ssa/gen/AMD64.rules index 7a2c148699b..f21e1d8bf74 100644 --- a/src/cmd/compile/internal/ssa/gen/AMD64.rules +++ b/src/cmd/compile/internal/ssa/gen/AMD64.rules @@ -478,7 +478,8 @@ (GetClosurePtr ...) -> (LoweredGetClosurePtr ...) (GetCallerPC ...) -> (LoweredGetCallerPC ...) (GetCallerSP ...) -> (LoweredGetCallerSP ...) -(HasCPUFeature ...) -> (LoweredHasCPUFeature ...) + +(HasCPUFeature {s}) -> (SETNE (CMPQconst [0] (LoweredHasCPUFeature {s}))) (Addr ...) -> (LEAQ ...) (LocalAddr {sym} base _) -> (LEAQ {sym} base) diff --git a/src/cmd/compile/internal/ssa/gen/AMD64Ops.go b/src/cmd/compile/internal/ssa/gen/AMD64Ops.go index b32f1234180..be4a0bf805d 100644 --- a/src/cmd/compile/internal/ssa/gen/AMD64Ops.go +++ b/src/cmd/compile/internal/ssa/gen/AMD64Ops.go @@ -738,7 +738,7 @@ func init() { // It saves all GP registers if necessary, but may clobber others. {name: "LoweredWB", argLength: 3, reg: regInfo{inputs: []regMask{buildReg("DI"), buildReg("AX CX DX BX BP SI R8 R9")}, clobbers: callerSave &^ gp}, clobberFlags: true, aux: "Sym", symEffect: "None"}, - {name: "LoweredHasCPUFeature", argLength: 0, reg: gp01, rematerializeable: true, typ: "bool", aux: "Sym", symEffect: "None"}, + {name: "LoweredHasCPUFeature", argLength: 0, reg: gp01, rematerializeable: true, typ: "UInt64", aux: "Sym", symEffect: "None"}, // There are three of these functions so that they can have three different register inputs. // When we check 0 <= c <= cap (A), then 0 <= b <= c (B), then 0 <= a <= b (C), we want the diff --git a/src/cmd/compile/internal/ssa/rewriteAMD64.go b/src/cmd/compile/internal/ssa/rewriteAMD64.go index 1f147c9eb5c..ce802a97c58 100644 --- a/src/cmd/compile/internal/ssa/rewriteAMD64.go +++ b/src/cmd/compile/internal/ssa/rewriteAMD64.go @@ -787,8 +787,7 @@ func rewriteValueAMD64(v *Value) bool { case OpGreater64F: return rewriteValueAMD64_OpGreater64F(v) case OpHasCPUFeature: - v.Op = OpAMD64LoweredHasCPUFeature - return true + return rewriteValueAMD64_OpHasCPUFeature(v) case OpHmul32: v.Op = OpAMD64HMULL return true @@ -29924,6 +29923,23 @@ func rewriteValueAMD64_OpGreater64F(v *Value) bool { return true } } +func rewriteValueAMD64_OpHasCPUFeature(v *Value) bool { + b := v.Block + typ := &b.Func.Config.Types + // match: (HasCPUFeature {s}) + // result: (SETNE (CMPQconst [0] (LoweredHasCPUFeature {s}))) + for { + s := v.Aux + v.reset(OpAMD64SETNE) + v0 := b.NewValue0(v.Pos, OpAMD64CMPQconst, types.TypeFlags) + v0.AuxInt = 0 + v1 := b.NewValue0(v.Pos, OpAMD64LoweredHasCPUFeature, typ.UInt64) + v1.Aux = s + v0.AddArg(v1) + v.AddArg(v0) + return true + } +} func rewriteValueAMD64_OpIsInBounds(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0]