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)
|
(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.
|
// Test for -∞ (bit 0) using 64 bit classify instruction.
|
||||||
(FLTD x (FMOVDconst [c])) && float64ExactBits(c, -math.MaxFloat64) => (ANDI [1] (FCLASSD x))
|
(FLTD x (FMOVDconst [-math.MaxFloat64])) => (ANDI [0b00_0000_0001] (FCLASSD x))
|
||||||
(FLED (FMOVDconst [c]) x) && float64ExactBits(c, -math.MaxFloat64) => (SNEZ (ANDI <typ.Int64> [0xff &^ 1] (FCLASSD x)))
|
(FLED (FMOVDconst [-math.MaxFloat64]) x) => (SNEZ (ANDI <typ.Int64> [0b00_1111_1110] (FCLASSD x)))
|
||||||
(FEQD x (FMOVDconst [c])) && float64ExactBits(c, math.Inf(-1)) => (ANDI [1] (FCLASSD x))
|
(FEQD x (FMOVDconst [math.Inf(-1)])) => (ANDI [0b00_0000_0001] (FCLASSD x))
|
||||||
(FNED x (FMOVDconst [c])) && float64ExactBits(c, math.Inf(-1)) => (SEQZ (ANDI <typ.Int64> [1] (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.
|
// 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)))
|
(FLTD (FMOVDconst [math.MaxFloat64]) x) => (SNEZ (ANDI <typ.Int64> [0b00_1000_0000] (FCLASSD x)))
|
||||||
(FLED x (FMOVDconst [c])) && float64ExactBits(c, math.MaxFloat64) => (SNEZ (ANDI <typ.Int64> [0xff &^ (1<<7)] (FCLASSD x)))
|
(FLED x (FMOVDconst [math.MaxFloat64])) => (SNEZ (ANDI <typ.Int64> [0b00_0111_1111] (FCLASSD x)))
|
||||||
(FEQD x (FMOVDconst [c])) && float64ExactBits(c, math.Inf(1)) => (SNEZ (ANDI <typ.Int64> [1<<7] (FCLASSD x)))
|
(FEQD x (FMOVDconst [math.Inf(1)])) => (SNEZ (ANDI <typ.Int64> [0b00_1000_0000] (FCLASSD x)))
|
||||||
(FNED x (FMOVDconst [c])) && float64ExactBits(c, math.Inf(1)) => (SEQZ (ANDI <typ.Int64> [1<<7] (FCLASSD x)))
|
(FNED x (FMOVDconst [math.Inf(1)])) => (SEQZ (ANDI <typ.Int64> [0b00_1000_0000] (FCLASSD x)))
|
||||||
|
|
||||||
//
|
//
|
||||||
// Optimisations for rva22u64 and above.
|
// Optimisations for rva22u64 and above.
|
||||||
|
|
|
||||||
|
|
@ -765,10 +765,6 @@ func arm64ConditionalParamsToAuxInt(v arm64ConditionalParams) int64 {
|
||||||
return i
|
return i
|
||||||
}
|
}
|
||||||
|
|
||||||
func float64ExactBits(f float64, c float64) bool {
|
|
||||||
return math.Float64bits(f) == math.Float64bits(c)
|
|
||||||
}
|
|
||||||
|
|
||||||
func flagConstantToAuxInt(x flagConstant) int64 {
|
func flagConstantToAuxInt(x flagConstant) int64 {
|
||||||
return int64(x)
|
return int64(x)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3582,21 +3582,16 @@ func rewriteValueRISCV64_OpRISCV64FEQD(v *Value) bool {
|
||||||
v_0 := v.Args[0]
|
v_0 := v.Args[0]
|
||||||
b := v.Block
|
b := v.Block
|
||||||
typ := &b.Func.Config.Types
|
typ := &b.Func.Config.Types
|
||||||
// match: (FEQD x (FMOVDconst [c]))
|
// match: (FEQD x (FMOVDconst [math.Inf(-1)]))
|
||||||
// cond: float64ExactBits(c, math.Inf(-1))
|
// result: (ANDI [0b00_0000_0001] (FCLASSD x))
|
||||||
// result: (ANDI [1] (FCLASSD x))
|
|
||||||
for {
|
for {
|
||||||
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
|
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
|
||||||
x := v_0
|
x := v_0
|
||||||
if v_1.Op != OpRISCV64FMOVDconst {
|
if v_1.Op != OpRISCV64FMOVDconst || auxIntToFloat64(v_1.AuxInt) != math.Inf(-1) {
|
||||||
continue
|
|
||||||
}
|
|
||||||
c := auxIntToFloat64(v_1.AuxInt)
|
|
||||||
if !(float64ExactBits(c, math.Inf(-1))) {
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
v.reset(OpRISCV64ANDI)
|
v.reset(OpRISCV64ANDI)
|
||||||
v.AuxInt = int64ToAuxInt(1)
|
v.AuxInt = int64ToAuxInt(0b00_0000_0001)
|
||||||
v0 := b.NewValue0(v.Pos, OpRISCV64FCLASSD, typ.Int64)
|
v0 := b.NewValue0(v.Pos, OpRISCV64FCLASSD, typ.Int64)
|
||||||
v0.AddArg(x)
|
v0.AddArg(x)
|
||||||
v.AddArg(v0)
|
v.AddArg(v0)
|
||||||
|
|
@ -3604,22 +3599,17 @@ func rewriteValueRISCV64_OpRISCV64FEQD(v *Value) bool {
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
// match: (FEQD x (FMOVDconst [c]))
|
// match: (FEQD x (FMOVDconst [math.Inf(1)]))
|
||||||
// cond: float64ExactBits(c, math.Inf(1))
|
// result: (SNEZ (ANDI <typ.Int64> [0b00_1000_0000] (FCLASSD x)))
|
||||||
// result: (SNEZ (ANDI <typ.Int64> [1<<7] (FCLASSD x)))
|
|
||||||
for {
|
for {
|
||||||
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
|
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
|
||||||
x := v_0
|
x := v_0
|
||||||
if v_1.Op != OpRISCV64FMOVDconst {
|
if v_1.Op != OpRISCV64FMOVDconst || auxIntToFloat64(v_1.AuxInt) != math.Inf(1) {
|
||||||
continue
|
|
||||||
}
|
|
||||||
c := auxIntToFloat64(v_1.AuxInt)
|
|
||||||
if !(float64ExactBits(c, math.Inf(1))) {
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
v.reset(OpRISCV64SNEZ)
|
v.reset(OpRISCV64SNEZ)
|
||||||
v0 := b.NewValue0(v.Pos, OpRISCV64ANDI, typ.Int64)
|
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 := b.NewValue0(v.Pos, OpRISCV64FCLASSD, typ.Int64)
|
||||||
v1.AddArg(x)
|
v1.AddArg(x)
|
||||||
v0.AddArg(v1)
|
v0.AddArg(v1)
|
||||||
|
|
@ -3635,42 +3625,32 @@ func rewriteValueRISCV64_OpRISCV64FLED(v *Value) bool {
|
||||||
v_0 := v.Args[0]
|
v_0 := v.Args[0]
|
||||||
b := v.Block
|
b := v.Block
|
||||||
typ := &b.Func.Config.Types
|
typ := &b.Func.Config.Types
|
||||||
// match: (FLED (FMOVDconst [c]) x)
|
// match: (FLED (FMOVDconst [-math.MaxFloat64]) x)
|
||||||
// cond: float64ExactBits(c, -math.MaxFloat64)
|
// result: (SNEZ (ANDI <typ.Int64> [0b00_1111_1110] (FCLASSD x)))
|
||||||
// result: (SNEZ (ANDI <typ.Int64> [0xff &^ 1] (FCLASSD x)))
|
|
||||||
for {
|
for {
|
||||||
if v_0.Op != OpRISCV64FMOVDconst {
|
if v_0.Op != OpRISCV64FMOVDconst || auxIntToFloat64(v_0.AuxInt) != -math.MaxFloat64 {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
c := auxIntToFloat64(v_0.AuxInt)
|
|
||||||
x := v_1
|
x := v_1
|
||||||
if !(float64ExactBits(c, -math.MaxFloat64)) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
v.reset(OpRISCV64SNEZ)
|
v.reset(OpRISCV64SNEZ)
|
||||||
v0 := b.NewValue0(v.Pos, OpRISCV64ANDI, typ.Int64)
|
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 := b.NewValue0(v.Pos, OpRISCV64FCLASSD, typ.Int64)
|
||||||
v1.AddArg(x)
|
v1.AddArg(x)
|
||||||
v0.AddArg(v1)
|
v0.AddArg(v1)
|
||||||
v.AddArg(v0)
|
v.AddArg(v0)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
// match: (FLED x (FMOVDconst [c]))
|
// match: (FLED x (FMOVDconst [math.MaxFloat64]))
|
||||||
// cond: float64ExactBits(c, math.MaxFloat64)
|
// result: (SNEZ (ANDI <typ.Int64> [0b00_0111_1111] (FCLASSD x)))
|
||||||
// result: (SNEZ (ANDI <typ.Int64> [0xff &^ (1<<7)] (FCLASSD x)))
|
|
||||||
for {
|
for {
|
||||||
x := v_0
|
x := v_0
|
||||||
if v_1.Op != OpRISCV64FMOVDconst {
|
if v_1.Op != OpRISCV64FMOVDconst || auxIntToFloat64(v_1.AuxInt) != math.MaxFloat64 {
|
||||||
break
|
|
||||||
}
|
|
||||||
c := auxIntToFloat64(v_1.AuxInt)
|
|
||||||
if !(float64ExactBits(c, math.MaxFloat64)) {
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
v.reset(OpRISCV64SNEZ)
|
v.reset(OpRISCV64SNEZ)
|
||||||
v0 := b.NewValue0(v.Pos, OpRISCV64ANDI, typ.Int64)
|
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 := b.NewValue0(v.Pos, OpRISCV64FCLASSD, typ.Int64)
|
||||||
v1.AddArg(x)
|
v1.AddArg(x)
|
||||||
v0.AddArg(v1)
|
v0.AddArg(v1)
|
||||||
|
|
@ -3684,40 +3664,30 @@ func rewriteValueRISCV64_OpRISCV64FLTD(v *Value) bool {
|
||||||
v_0 := v.Args[0]
|
v_0 := v.Args[0]
|
||||||
b := v.Block
|
b := v.Block
|
||||||
typ := &b.Func.Config.Types
|
typ := &b.Func.Config.Types
|
||||||
// match: (FLTD x (FMOVDconst [c]))
|
// match: (FLTD x (FMOVDconst [-math.MaxFloat64]))
|
||||||
// cond: float64ExactBits(c, -math.MaxFloat64)
|
// result: (ANDI [0b00_0000_0001] (FCLASSD x))
|
||||||
// result: (ANDI [1] (FCLASSD x))
|
|
||||||
for {
|
for {
|
||||||
x := v_0
|
x := v_0
|
||||||
if v_1.Op != OpRISCV64FMOVDconst {
|
if v_1.Op != OpRISCV64FMOVDconst || auxIntToFloat64(v_1.AuxInt) != -math.MaxFloat64 {
|
||||||
break
|
|
||||||
}
|
|
||||||
c := auxIntToFloat64(v_1.AuxInt)
|
|
||||||
if !(float64ExactBits(c, -math.MaxFloat64)) {
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
v.reset(OpRISCV64ANDI)
|
v.reset(OpRISCV64ANDI)
|
||||||
v.AuxInt = int64ToAuxInt(1)
|
v.AuxInt = int64ToAuxInt(0b00_0000_0001)
|
||||||
v0 := b.NewValue0(v.Pos, OpRISCV64FCLASSD, typ.Int64)
|
v0 := b.NewValue0(v.Pos, OpRISCV64FCLASSD, typ.Int64)
|
||||||
v0.AddArg(x)
|
v0.AddArg(x)
|
||||||
v.AddArg(v0)
|
v.AddArg(v0)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
// match: (FLTD (FMOVDconst [c]) x)
|
// match: (FLTD (FMOVDconst [math.MaxFloat64]) x)
|
||||||
// cond: float64ExactBits(c, math.MaxFloat64)
|
// result: (SNEZ (ANDI <typ.Int64> [0b00_1000_0000] (FCLASSD x)))
|
||||||
// result: (SNEZ (ANDI <typ.Int64> [1<<7] (FCLASSD x)))
|
|
||||||
for {
|
for {
|
||||||
if v_0.Op != OpRISCV64FMOVDconst {
|
if v_0.Op != OpRISCV64FMOVDconst || auxIntToFloat64(v_0.AuxInt) != math.MaxFloat64 {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
c := auxIntToFloat64(v_0.AuxInt)
|
|
||||||
x := v_1
|
x := v_1
|
||||||
if !(float64ExactBits(c, math.MaxFloat64)) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
v.reset(OpRISCV64SNEZ)
|
v.reset(OpRISCV64SNEZ)
|
||||||
v0 := b.NewValue0(v.Pos, OpRISCV64ANDI, typ.Int64)
|
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 := b.NewValue0(v.Pos, OpRISCV64FCLASSD, typ.Int64)
|
||||||
v1.AddArg(x)
|
v1.AddArg(x)
|
||||||
v0.AddArg(v1)
|
v0.AddArg(v1)
|
||||||
|
|
@ -4155,22 +4125,17 @@ func rewriteValueRISCV64_OpRISCV64FNED(v *Value) bool {
|
||||||
v_0 := v.Args[0]
|
v_0 := v.Args[0]
|
||||||
b := v.Block
|
b := v.Block
|
||||||
typ := &b.Func.Config.Types
|
typ := &b.Func.Config.Types
|
||||||
// match: (FNED x (FMOVDconst [c]))
|
// match: (FNED x (FMOVDconst [math.Inf(-1)]))
|
||||||
// cond: float64ExactBits(c, math.Inf(-1))
|
// result: (SEQZ (ANDI <typ.Int64> [0b00_0000_0001] (FCLASSD x)))
|
||||||
// result: (SEQZ (ANDI <typ.Int64> [1] (FCLASSD x)))
|
|
||||||
for {
|
for {
|
||||||
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
|
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
|
||||||
x := v_0
|
x := v_0
|
||||||
if v_1.Op != OpRISCV64FMOVDconst {
|
if v_1.Op != OpRISCV64FMOVDconst || auxIntToFloat64(v_1.AuxInt) != math.Inf(-1) {
|
||||||
continue
|
|
||||||
}
|
|
||||||
c := auxIntToFloat64(v_1.AuxInt)
|
|
||||||
if !(float64ExactBits(c, math.Inf(-1))) {
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
v.reset(OpRISCV64SEQZ)
|
v.reset(OpRISCV64SEQZ)
|
||||||
v0 := b.NewValue0(v.Pos, OpRISCV64ANDI, typ.Int64)
|
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 := b.NewValue0(v.Pos, OpRISCV64FCLASSD, typ.Int64)
|
||||||
v1.AddArg(x)
|
v1.AddArg(x)
|
||||||
v0.AddArg(v1)
|
v0.AddArg(v1)
|
||||||
|
|
@ -4179,22 +4144,17 @@ func rewriteValueRISCV64_OpRISCV64FNED(v *Value) bool {
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
// match: (FNED x (FMOVDconst [c]))
|
// match: (FNED x (FMOVDconst [math.Inf(1)]))
|
||||||
// cond: float64ExactBits(c, math.Inf(1))
|
// result: (SEQZ (ANDI <typ.Int64> [0b00_1000_0000] (FCLASSD x)))
|
||||||
// result: (SEQZ (ANDI <typ.Int64> [1<<7] (FCLASSD x)))
|
|
||||||
for {
|
for {
|
||||||
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
|
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
|
||||||
x := v_0
|
x := v_0
|
||||||
if v_1.Op != OpRISCV64FMOVDconst {
|
if v_1.Op != OpRISCV64FMOVDconst || auxIntToFloat64(v_1.AuxInt) != math.Inf(1) {
|
||||||
continue
|
|
||||||
}
|
|
||||||
c := auxIntToFloat64(v_1.AuxInt)
|
|
||||||
if !(float64ExactBits(c, math.Inf(1))) {
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
v.reset(OpRISCV64SEQZ)
|
v.reset(OpRISCV64SEQZ)
|
||||||
v0 := b.NewValue0(v.Pos, OpRISCV64ANDI, typ.Int64)
|
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 := b.NewValue0(v.Pos, OpRISCV64FCLASSD, typ.Int64)
|
||||||
v1.AddArg(x)
|
v1.AddArg(x)
|
||||||
v0.AddArg(v1)
|
v0.AddArg(v1)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue