mirror of
https://github.com/golang/go.git
synced 2026-01-29 23:22:06 +03:00
cmd/compile/internal/ssa: simplify riscv64 FCLASSD rewrite rules
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>
This commit is contained in:
committed by
Gopher Robot
parent
856238615d
commit
a7d174ccaa
@@ -823,16 +823,16 @@
|
||||
(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.
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user