diff --git a/src/cmd/compile/internal/arm64/ssa.go b/src/cmd/compile/internal/arm64/ssa.go index 0bc8f3a5ab..0ea3c191ac 100644 --- a/src/cmd/compile/internal/arm64/ssa.go +++ b/src/cmd/compile/internal/arm64/ssa.go @@ -301,6 +301,12 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) { p.From.Val = math.Float64frombits(uint64(v.AuxInt)) p.To.Type = obj.TYPE_REG p.To.Reg = v.Reg() + case ssa.OpARM64FCMPS0, + ssa.OpARM64FCMPD0: + p := s.Prog(v.Op.Asm()) + p.From.Type = obj.TYPE_FCONST + p.From.Val = math.Float64frombits(0) + p.Reg = v.Args[0].Reg() case ssa.OpARM64CMP, ssa.OpARM64CMPW, ssa.OpARM64CMN, diff --git a/src/cmd/compile/internal/ssa/gen/ARM64.rules b/src/cmd/compile/internal/ssa/gen/ARM64.rules index 8b263a092f..3adb7895a2 100644 --- a/src/cmd/compile/internal/ssa/gen/ARM64.rules +++ b/src/cmd/compile/internal/ssa/gen/ARM64.rules @@ -348,6 +348,12 @@ (Geq32U x y) -> (GreaterEqualU (CMPW x y)) (Geq64U x y) -> (GreaterEqualU (CMP x y)) +// Optimize comparision between a floating-point value and 0.0 with "FCMP $(0.0), Fn" +(FCMPS x (FMOVSconst [0])) -> (FCMPS0 x) +(FCMPS (FMOVSconst [0]) x) -> (InvertFlags (FCMPS0 x)) +(FCMPD x (FMOVDconst [0])) -> (FCMPD0 x) +(FCMPD (FMOVDconst [0]) x) -> (InvertFlags (FCMPD0 x)) + // CSEL needs a flag-generating argument. Synthesize a CMPW if necessary. (CondSelect x y bool) && flagArg(bool) != nil -> (CSEL {bool.Op} x y flagArg(bool)) (CondSelect x y bool) && flagArg(bool) == nil -> (CSEL {OpARM64NotEqual} x y (CMPWconst [0] bool)) @@ -1615,6 +1621,10 @@ (LessEqualU (InvertFlags x)) -> (GreaterEqualU x) (GreaterEqual (InvertFlags x)) -> (LessEqual x) (GreaterEqualU (InvertFlags x)) -> (LessEqualU x) +(LessThanF (InvertFlags x)) -> (GreaterThanF x) +(LessEqualF (InvertFlags x)) -> (GreaterEqualF x) +(GreaterThanF (InvertFlags x)) -> (LessThanF x) +(GreaterEqualF (InvertFlags x)) -> (LessEqualF x) // Boolean-generating instructions always // zero upper bit of the register; no need to zero-extend diff --git a/src/cmd/compile/internal/ssa/gen/ARM64Ops.go b/src/cmd/compile/internal/ssa/gen/ARM64Ops.go index 2a65d547bd..b6bf10315e 100644 --- a/src/cmd/compile/internal/ssa/gen/ARM64Ops.go +++ b/src/cmd/compile/internal/ssa/gen/ARM64Ops.go @@ -158,6 +158,7 @@ func init() { fp21 = regInfo{inputs: []regMask{fp, fp}, outputs: []regMask{fp}} fp31 = regInfo{inputs: []regMask{fp, fp, fp}, outputs: []regMask{fp}} fp2flags = regInfo{inputs: []regMask{fp, fp}} + fp1flags = regInfo{inputs: []regMask{fp}} fpload = regInfo{inputs: []regMask{gpspsbg}, outputs: []regMask{fp}} fp2load = regInfo{inputs: []regMask{gpspsbg, gpg}, outputs: []regMask{fp}} fpstore = regInfo{inputs: []regMask{gpspsbg, fp}} @@ -271,6 +272,8 @@ func init() { {name: "TSTWconst", argLength: 1, reg: gp1flags, asm: "TSTW", aux: "Int32", typ: "Flags"}, // arg0 & auxInt compare to 0, 32 bit {name: "FCMPS", argLength: 2, reg: fp2flags, asm: "FCMPS", typ: "Flags"}, // arg0 compare to arg1, float32 {name: "FCMPD", argLength: 2, reg: fp2flags, asm: "FCMPD", typ: "Flags"}, // arg0 compare to arg1, float64 + {name: "FCMPS0", argLength: 1, reg: fp1flags, asm: "FCMPS", typ: "Flags"}, // arg0 compare to 0, float32 + {name: "FCMPD0", argLength: 1, reg: fp1flags, asm: "FCMPD", typ: "Flags"}, // arg0 compare to 0, float64 // shifted ops {name: "MVNshiftLL", argLength: 1, reg: gp11, asm: "MVN", aux: "Int64"}, // ^(arg0<