We try to preserve type correctness of generic ops.
phiopt modified a bool to be an int without a conversion.
Add a conversion. There are a few random fluctations in the
generated code as a result, but nothing noteworthy or systematic.
no binary size changes
file before after Δ %
math.s 35966 35961 -5 -0.014%
debug/dwarf.s 108141 108147 +6 +0.006%
crypto/dsa.s 6047 6044 -3 -0.050%
image/png.s 42882 42885 +3 +0.007%
go/parser.s 80281 80278 -3 -0.004%
cmd/internal/obj.s 115116 115113 -3 -0.003%
go/types.s 322130 322118 -12 -0.004%
cmd/internal/obj/arm64.s 151679 151685 +6 +0.004%
go/internal/gccgoimporter.s 56487 56493 +6 +0.011%
cmd/test2json.s 1650 1647 -3 -0.182%
cmd/link/internal/loadelf.s 35442 35443 +1 +0.003%
cmd/go/internal/work.s 305039 305035 -4 -0.001%
cmd/link/internal/ld.s 544835 544834 -1 -0.000%
net/http.s 558777 558774 -3 -0.001%
cmd/compile/internal/ssa.s
3926551 3926994 +443 +0.011%
cmd/compile/internal/gc.s
1552320 1552321 +1 +0.000%
total
18862241 18862670 +429 +0.002%
Change-Id: I4289e773be6be534ea3f907d68f614441b8f9b46
Reviewed-on: https://go-review.googlesource.com/c/go/+/221607
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
Reviewed-by: Keith Randall <khr@golang.org>
(Round32F ...) -> (Copy ...)
(Round64F ...) -> (Copy ...)
+(CvtBoolToUint8 ...) -> (Copy ...)
+
// Lowering shifts
// Unsigned shifts need to return 0 if shift amount is >= width of shifted value.
// result = (arg << shift) & (shift >= argbits ? 0 : 0xffffffffffffffff)
(Round(32|64)F ...) -> (Copy ...)
+(CvtBoolToUint8 ...) -> (Copy ...)
+
// Lowering shifts
// Unsigned shifts need to return 0 if shift amount is >= width of shifted value.
// result = (arg << shift) & (shift >= argbits ? 0 : 0xffffffffffffffff)
(Round(32|64)F ...) -> (Copy ...)
+(CvtBoolToUint8 ...) -> (Copy ...)
+
// fused-multiply-add
(FMA x y z) -> (FMULAD z x y)
(Cvt32Fto64F ...) -> (FCVTSD ...)
(Cvt64Fto32F ...) -> (FCVTDS ...)
+(CvtBoolToUint8 ...) -> (Copy ...)
+
(Round32F ...) -> (LoweredRound32F ...)
(Round64F ...) -> (LoweredRound64F ...)
(Cvt32Fto64F ...) -> (MOVFD ...)
(Cvt64Fto32F ...) -> (MOVDF ...)
+(CvtBoolToUint8 ...) -> (Copy ...)
+
(Round(32|64)F ...) -> (Copy ...)
// comparisons
(Cvt32Fto64F ...) -> (MOVFD ...)
(Cvt64Fto32F ...) -> (MOVDF ...)
+(CvtBoolToUint8 ...) -> (Copy ...)
+
(Round(32|64)F ...) -> (Copy ...)
// comparisons
(Cvt32Fto64F ...) -> (Copy ...) // Note v will have the wrong type for patterns dependent on Float32/Float64
(Cvt64Fto32F ...) -> (FRSP ...)
+(CvtBoolToUint8 ...) -> (Copy ...)
+
(Round(32|64)F ...) -> (LoweredRound(32|64)F ...)
(Sqrt ...) -> (FSQRT ...)
(Cvt32Fto64F ...) -> (FCVTDS ...)
(Cvt64Fto32F ...) -> (FCVTSD ...)
+(CvtBoolToUint8 ...) -> (Copy ...)
+
(Round32F ...) -> (Copy ...)
(Round64F ...) -> (Copy ...)
(Cvt32Fto64F ...) -> (LDEBR ...)
(Cvt64Fto32F ...) -> (LEDBR ...)
+(CvtBoolToUint8 ...) -> (Copy ...)
+
(Round(32|64)F ...) -> (LoweredRound(32|64)F ...)
// Lowering shifts
(Cvt32Fto64F ...) -> (F64PromoteF32 ...)
(Cvt64Fto32F ...) -> (F32DemoteF64 ...)
+(CvtBoolToUint8 ...) -> (Copy ...)
+
(Round32F ...) -> (Copy ...)
(Round64F ...) -> (Copy ...)
{name: "Cvt64Fto64", argLength: 1},
{name: "Cvt32Fto64F", argLength: 1},
{name: "Cvt64Fto32F", argLength: 1},
+ {name: "CvtBoolToUint8", argLength: 1},
// Force rounding to precision of type.
{name: "Round32F", argLength: 1},
OpCvt64Fto64
OpCvt32Fto64F
OpCvt64Fto32F
+ OpCvtBoolToUint8
OpRound32F
OpRound64F
OpIsNonNil
argLen: 1,
generic: true,
},
+ {
+ name: "CvtBoolToUint8",
+ argLen: 1,
+ generic: true,
+ },
{
name: "Round32F",
argLen: 1,
negate = !negate
}
+ a := b0.Controls[0]
+ if negate {
+ a = v.Block.NewValue1(v.Pos, OpNot, a.Type, a)
+ }
+ v.AddArg(a)
+
+ cvt := v.Block.NewValue1(v.Pos, OpCvtBoolToUint8, a.Type, a)
switch v.Type.Size() {
case 1:
v.reset(OpCopy)
default:
v.Fatalf("bad int size %d", v.Type.Size())
}
-
- a := b0.Controls[0]
- if negate {
- a = v.Block.NewValue1(v.Pos, OpNot, a.Type, a)
- }
- v.AddArg(a)
+ v.AddArg(cvt)
f := b0.Func
if f.pass.debug > 0 {
case OpCvt64Fto32F:
v.Op = Op386CVTSD2SS
return true
+ case OpCvtBoolToUint8:
+ v.Op = OpCopy
+ return true
case OpDiv16:
v.Op = Op386DIVW
return true
case OpCvt64to64F:
v.Op = OpAMD64CVTSQ2SD
return true
+ case OpCvtBoolToUint8:
+ v.Op = OpCopy
+ return true
case OpDiv128u:
v.Op = OpAMD64DIVQU2
return true
case OpCvt64Fto32U:
v.Op = OpARMMOVDWU
return true
+ case OpCvtBoolToUint8:
+ v.Op = OpCopy
+ return true
case OpDiv16:
return rewriteValueARM_OpDiv16(v)
case OpDiv16u:
case OpCvt64to64F:
v.Op = OpARM64SCVTFD
return true
+ case OpCvtBoolToUint8:
+ v.Op = OpCopy
+ return true
case OpDiv16:
return rewriteValueARM64_OpDiv16(v)
case OpDiv16u:
case OpCvt64Fto32F:
v.Op = OpMIPSMOVDF
return true
+ case OpCvtBoolToUint8:
+ v.Op = OpCopy
+ return true
case OpDiv16:
return rewriteValueMIPS_OpDiv16(v)
case OpDiv16u:
case OpCvt64to64F:
v.Op = OpMIPS64MOVVD
return true
+ case OpCvtBoolToUint8:
+ v.Op = OpCopy
+ return true
case OpDiv16:
return rewriteValueMIPS64_OpDiv16(v)
case OpDiv16u:
return rewriteValuePPC64_OpCvt64to32F(v)
case OpCvt64to64F:
return rewriteValuePPC64_OpCvt64to64F(v)
+ case OpCvtBoolToUint8:
+ v.Op = OpCopy
+ return true
case OpDiv16:
return rewriteValuePPC64_OpDiv16(v)
case OpDiv16u:
case OpCvt64to64F:
v.Op = OpRISCV64FCVTDL
return true
+ case OpCvtBoolToUint8:
+ v.Op = OpCopy
+ return true
case OpDiv16:
return rewriteValueRISCV64_OpDiv16(v)
case OpDiv16u:
case OpCvt64to64F:
v.Op = OpS390XCDGBRA
return true
+ case OpCvtBoolToUint8:
+ v.Op = OpCopy
+ return true
case OpDiv16:
return rewriteValueS390X_OpDiv16(v)
case OpDiv16u:
case OpCvt64to64F:
v.Op = OpWasmF64ConvertI64S
return true
+ case OpCvtBoolToUint8:
+ v.Op = OpCopy
+ return true
case OpDiv16:
return rewriteValueWasm_OpDiv16(v)
case OpDiv16u: