mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00: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:
parent
856238615d
commit
a7d174ccaa
3 changed files with 40 additions and 84 deletions
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue