]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile/internal/ssa: simplify riscv64 FCLASSD rewrite rules
authorMichael Munday <mndygolang+git@gmail.com>
Mon, 3 Nov 2025 23:05:25 +0000 (23:05 +0000)
committerGopher Robot <gobot@golang.org>
Tue, 4 Nov 2025 20:47:42 +0000 (12:47 -0800)
We don't need to check that the bit patterns of the constants
match, it is sufficient to just check the constant is equal to the
given value.

While we're here also change the FCLASSD rules to use a bit pattern
for the mask. I think this improves readability, particularly as
more uses of FCLASSD get added (e.g. CL 717560).

These changes should not affect codegen.

Change-Id: I92a6338dc71e6a71e04306f67d7d86016c6e9c47
Reviewed-on: https://go-review.googlesource.com/c/go/+/717580
Reviewed-by: Michael Pratt <mpratt@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Keith Randall <khr@golang.org>
Reviewed-by: Keith Randall <khr@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
src/cmd/compile/internal/ssa/_gen/RISCV64.rules
src/cmd/compile/internal/ssa/rewrite.go
src/cmd/compile/internal/ssa/rewriteRISCV64.go

index 49bdbc875fc3cdbdef4a91e17c6daa1430d26ab1..31829a5eed7d0f91cdaae7f09943efcf52f2eaeb 100644 (file)
 (F(MADD|NMADD|MSUB|NMSUB)D x y neg:(FNEGD z)) && neg.Uses == 1 => (F(MSUB|NMSUB|MADD|NMADD)D x y z)
 
 // Test for -∞ (bit 0) using 64 bit classify instruction.
-(FLTD x (FMOVDconst [c])) && float64ExactBits(c, -math.MaxFloat64) => (ANDI [1] (FCLASSD x))
-(FLED (FMOVDconst [c]) x) && float64ExactBits(c, -math.MaxFloat64) => (SNEZ (ANDI <typ.Int64> [0xff &^ 1] (FCLASSD x)))
-(FEQD x (FMOVDconst [c])) && float64ExactBits(c, math.Inf(-1)) => (ANDI [1] (FCLASSD x))
-(FNED x (FMOVDconst [c])) && float64ExactBits(c, math.Inf(-1)) => (SEQZ (ANDI <typ.Int64> [1] (FCLASSD x)))
+(FLTD x (FMOVDconst [-math.MaxFloat64])) => (ANDI [0b00_0000_0001] (FCLASSD x))
+(FLED (FMOVDconst [-math.MaxFloat64]) x) => (SNEZ (ANDI <typ.Int64> [0b00_1111_1110] (FCLASSD x)))
+(FEQD x (FMOVDconst [math.Inf(-1)])) => (ANDI [0b00_0000_0001] (FCLASSD x))
+(FNED x (FMOVDconst [math.Inf(-1)])) => (SEQZ (ANDI <typ.Int64> [0b00_0000_0001] (FCLASSD x)))
 
 // Test for +∞ (bit 7) using 64 bit classify instruction.
-(FLTD (FMOVDconst [c]) x) && float64ExactBits(c, math.MaxFloat64) => (SNEZ (ANDI <typ.Int64> [1<<7] (FCLASSD x)))
-(FLED x (FMOVDconst [c])) && float64ExactBits(c, math.MaxFloat64) => (SNEZ (ANDI <typ.Int64> [0xff &^ (1<<7)] (FCLASSD x)))
-(FEQD x (FMOVDconst [c])) && float64ExactBits(c, math.Inf(1)) => (SNEZ (ANDI <typ.Int64> [1<<7] (FCLASSD x)))
-(FNED x (FMOVDconst [c])) && float64ExactBits(c, math.Inf(1)) => (SEQZ (ANDI <typ.Int64> [1<<7] (FCLASSD x)))
+(FLTD (FMOVDconst [math.MaxFloat64]) x) => (SNEZ (ANDI <typ.Int64> [0b00_1000_0000] (FCLASSD x)))
+(FLED x (FMOVDconst [math.MaxFloat64])) => (SNEZ (ANDI <typ.Int64> [0b00_0111_1111] (FCLASSD x)))
+(FEQD x (FMOVDconst [math.Inf(1)])) => (SNEZ (ANDI <typ.Int64> [0b00_1000_0000] (FCLASSD x)))
+(FNED x (FMOVDconst [math.Inf(1)])) => (SEQZ (ANDI <typ.Int64> [0b00_1000_0000] (FCLASSD x)))
 
 //
 // Optimisations for rva22u64 and above.
index a822ebcbbd112ece69f7633f3e8559b3414ff314..07308973b15ec10ad34ac3f85f86df34ad487943 100644 (file)
@@ -765,10 +765,6 @@ func arm64ConditionalParamsToAuxInt(v arm64ConditionalParams) int64 {
        return i
 }
 
-func float64ExactBits(f float64, c float64) bool {
-       return math.Float64bits(f) == math.Float64bits(c)
-}
-
 func flagConstantToAuxInt(x flagConstant) int64 {
        return int64(x)
 }
index 8a390eb85c8870901346fd6585ee46ca999148a9..52870fe19921ce2e37562a52663210ab98cfe233 100644 (file)
@@ -3582,21 +3582,16 @@ func rewriteValueRISCV64_OpRISCV64FEQD(v *Value) bool {
        v_0 := v.Args[0]
        b := v.Block
        typ := &b.Func.Config.Types
-       // match: (FEQD x (FMOVDconst [c]))
-       // cond: float64ExactBits(c, math.Inf(-1))
-       // result: (ANDI [1] (FCLASSD x))
+       // match: (FEQD x (FMOVDconst [math.Inf(-1)]))
+       // result: (ANDI [0b00_0000_0001] (FCLASSD x))
        for {
                for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
                        x := v_0
-                       if v_1.Op != OpRISCV64FMOVDconst {
-                               continue
-                       }
-                       c := auxIntToFloat64(v_1.AuxInt)
-                       if !(float64ExactBits(c, math.Inf(-1))) {
+                       if v_1.Op != OpRISCV64FMOVDconst || auxIntToFloat64(v_1.AuxInt) != math.Inf(-1) {
                                continue
                        }
                        v.reset(OpRISCV64ANDI)
-                       v.AuxInt = int64ToAuxInt(1)
+                       v.AuxInt = int64ToAuxInt(0b00_0000_0001)
                        v0 := b.NewValue0(v.Pos, OpRISCV64FCLASSD, typ.Int64)
                        v0.AddArg(x)
                        v.AddArg(v0)
@@ -3604,22 +3599,17 @@ func rewriteValueRISCV64_OpRISCV64FEQD(v *Value) bool {
                }
                break
        }
-       // match: (FEQD x (FMOVDconst [c]))
-       // cond: float64ExactBits(c, math.Inf(1))
-       // result: (SNEZ (ANDI <typ.Int64> [1<<7] (FCLASSD x)))
+       // match: (FEQD x (FMOVDconst [math.Inf(1)]))
+       // result: (SNEZ (ANDI <typ.Int64> [0b00_1000_0000] (FCLASSD x)))
        for {
                for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
                        x := v_0
-                       if v_1.Op != OpRISCV64FMOVDconst {
-                               continue
-                       }
-                       c := auxIntToFloat64(v_1.AuxInt)
-                       if !(float64ExactBits(c, math.Inf(1))) {
+                       if v_1.Op != OpRISCV64FMOVDconst || auxIntToFloat64(v_1.AuxInt) != math.Inf(1) {
                                continue
                        }
                        v.reset(OpRISCV64SNEZ)
                        v0 := b.NewValue0(v.Pos, OpRISCV64ANDI, typ.Int64)
-                       v0.AuxInt = int64ToAuxInt(1 << 7)
+                       v0.AuxInt = int64ToAuxInt(0b00_1000_0000)
                        v1 := b.NewValue0(v.Pos, OpRISCV64FCLASSD, typ.Int64)
                        v1.AddArg(x)
                        v0.AddArg(v1)
@@ -3635,42 +3625,32 @@ func rewriteValueRISCV64_OpRISCV64FLED(v *Value) bool {
        v_0 := v.Args[0]
        b := v.Block
        typ := &b.Func.Config.Types
-       // match: (FLED (FMOVDconst [c]) x)
-       // cond: float64ExactBits(c, -math.MaxFloat64)
-       // result: (SNEZ (ANDI <typ.Int64> [0xff &^ 1] (FCLASSD x)))
+       // match: (FLED (FMOVDconst [-math.MaxFloat64]) x)
+       // result: (SNEZ (ANDI <typ.Int64> [0b00_1111_1110] (FCLASSD x)))
        for {
-               if v_0.Op != OpRISCV64FMOVDconst {
+               if v_0.Op != OpRISCV64FMOVDconst || auxIntToFloat64(v_0.AuxInt) != -math.MaxFloat64 {
                        break
                }
-               c := auxIntToFloat64(v_0.AuxInt)
                x := v_1
-               if !(float64ExactBits(c, -math.MaxFloat64)) {
-                       break
-               }
                v.reset(OpRISCV64SNEZ)
                v0 := b.NewValue0(v.Pos, OpRISCV64ANDI, typ.Int64)
-               v0.AuxInt = int64ToAuxInt(0xff &^ 1)
+               v0.AuxInt = int64ToAuxInt(0b00_1111_1110)
                v1 := b.NewValue0(v.Pos, OpRISCV64FCLASSD, typ.Int64)
                v1.AddArg(x)
                v0.AddArg(v1)
                v.AddArg(v0)
                return true
        }
-       // match: (FLED x (FMOVDconst [c]))
-       // cond: float64ExactBits(c, math.MaxFloat64)
-       // result: (SNEZ (ANDI <typ.Int64> [0xff &^ (1<<7)] (FCLASSD x)))
+       // match: (FLED x (FMOVDconst [math.MaxFloat64]))
+       // result: (SNEZ (ANDI <typ.Int64> [0b00_0111_1111] (FCLASSD x)))
        for {
                x := v_0
-               if v_1.Op != OpRISCV64FMOVDconst {
-                       break
-               }
-               c := auxIntToFloat64(v_1.AuxInt)
-               if !(float64ExactBits(c, math.MaxFloat64)) {
+               if v_1.Op != OpRISCV64FMOVDconst || auxIntToFloat64(v_1.AuxInt) != math.MaxFloat64 {
                        break
                }
                v.reset(OpRISCV64SNEZ)
                v0 := b.NewValue0(v.Pos, OpRISCV64ANDI, typ.Int64)
-               v0.AuxInt = int64ToAuxInt(0xff &^ (1 << 7))
+               v0.AuxInt = int64ToAuxInt(0b00_0111_1111)
                v1 := b.NewValue0(v.Pos, OpRISCV64FCLASSD, typ.Int64)
                v1.AddArg(x)
                v0.AddArg(v1)
@@ -3684,40 +3664,30 @@ func rewriteValueRISCV64_OpRISCV64FLTD(v *Value) bool {
        v_0 := v.Args[0]
        b := v.Block
        typ := &b.Func.Config.Types
-       // match: (FLTD x (FMOVDconst [c]))
-       // cond: float64ExactBits(c, -math.MaxFloat64)
-       // result: (ANDI [1] (FCLASSD x))
+       // match: (FLTD x (FMOVDconst [-math.MaxFloat64]))
+       // result: (ANDI [0b00_0000_0001] (FCLASSD x))
        for {
                x := v_0
-               if v_1.Op != OpRISCV64FMOVDconst {
-                       break
-               }
-               c := auxIntToFloat64(v_1.AuxInt)
-               if !(float64ExactBits(c, -math.MaxFloat64)) {
+               if v_1.Op != OpRISCV64FMOVDconst || auxIntToFloat64(v_1.AuxInt) != -math.MaxFloat64 {
                        break
                }
                v.reset(OpRISCV64ANDI)
-               v.AuxInt = int64ToAuxInt(1)
+               v.AuxInt = int64ToAuxInt(0b00_0000_0001)
                v0 := b.NewValue0(v.Pos, OpRISCV64FCLASSD, typ.Int64)
                v0.AddArg(x)
                v.AddArg(v0)
                return true
        }
-       // match: (FLTD (FMOVDconst [c]) x)
-       // cond: float64ExactBits(c, math.MaxFloat64)
-       // result: (SNEZ (ANDI <typ.Int64> [1<<7] (FCLASSD x)))
+       // match: (FLTD (FMOVDconst [math.MaxFloat64]) x)
+       // result: (SNEZ (ANDI <typ.Int64> [0b00_1000_0000] (FCLASSD x)))
        for {
-               if v_0.Op != OpRISCV64FMOVDconst {
+               if v_0.Op != OpRISCV64FMOVDconst || auxIntToFloat64(v_0.AuxInt) != math.MaxFloat64 {
                        break
                }
-               c := auxIntToFloat64(v_0.AuxInt)
                x := v_1
-               if !(float64ExactBits(c, math.MaxFloat64)) {
-                       break
-               }
                v.reset(OpRISCV64SNEZ)
                v0 := b.NewValue0(v.Pos, OpRISCV64ANDI, typ.Int64)
-               v0.AuxInt = int64ToAuxInt(1 << 7)
+               v0.AuxInt = int64ToAuxInt(0b00_1000_0000)
                v1 := b.NewValue0(v.Pos, OpRISCV64FCLASSD, typ.Int64)
                v1.AddArg(x)
                v0.AddArg(v1)
@@ -4155,22 +4125,17 @@ func rewriteValueRISCV64_OpRISCV64FNED(v *Value) bool {
        v_0 := v.Args[0]
        b := v.Block
        typ := &b.Func.Config.Types
-       // match: (FNED x (FMOVDconst [c]))
-       // cond: float64ExactBits(c, math.Inf(-1))
-       // result: (SEQZ (ANDI <typ.Int64> [1] (FCLASSD x)))
+       // match: (FNED x (FMOVDconst [math.Inf(-1)]))
+       // result: (SEQZ (ANDI <typ.Int64> [0b00_0000_0001] (FCLASSD x)))
        for {
                for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
                        x := v_0
-                       if v_1.Op != OpRISCV64FMOVDconst {
-                               continue
-                       }
-                       c := auxIntToFloat64(v_1.AuxInt)
-                       if !(float64ExactBits(c, math.Inf(-1))) {
+                       if v_1.Op != OpRISCV64FMOVDconst || auxIntToFloat64(v_1.AuxInt) != math.Inf(-1) {
                                continue
                        }
                        v.reset(OpRISCV64SEQZ)
                        v0 := b.NewValue0(v.Pos, OpRISCV64ANDI, typ.Int64)
-                       v0.AuxInt = int64ToAuxInt(1)
+                       v0.AuxInt = int64ToAuxInt(0b00_0000_0001)
                        v1 := b.NewValue0(v.Pos, OpRISCV64FCLASSD, typ.Int64)
                        v1.AddArg(x)
                        v0.AddArg(v1)
@@ -4179,22 +4144,17 @@ func rewriteValueRISCV64_OpRISCV64FNED(v *Value) bool {
                }
                break
        }
-       // match: (FNED x (FMOVDconst [c]))
-       // cond: float64ExactBits(c, math.Inf(1))
-       // result: (SEQZ (ANDI <typ.Int64> [1<<7] (FCLASSD x)))
+       // match: (FNED x (FMOVDconst [math.Inf(1)]))
+       // result: (SEQZ (ANDI <typ.Int64> [0b00_1000_0000] (FCLASSD x)))
        for {
                for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
                        x := v_0
-                       if v_1.Op != OpRISCV64FMOVDconst {
-                               continue
-                       }
-                       c := auxIntToFloat64(v_1.AuxInt)
-                       if !(float64ExactBits(c, math.Inf(1))) {
+                       if v_1.Op != OpRISCV64FMOVDconst || auxIntToFloat64(v_1.AuxInt) != math.Inf(1) {
                                continue
                        }
                        v.reset(OpRISCV64SEQZ)
                        v0 := b.NewValue0(v.Pos, OpRISCV64ANDI, typ.Int64)
-                       v0.AuxInt = int64ToAuxInt(1 << 7)
+                       v0.AuxInt = int64ToAuxInt(0b00_1000_0000)
                        v1 := b.NewValue0(v.Pos, OpRISCV64FCLASSD, typ.Int64)
                        v1.AddArg(x)
                        v0.AddArg(v1)