[go] cmd/compile: make wasm match other platforms for FP->int32/64 conversions

1 view
Skip to first unread message

David Chase (Gerrit)

unread,
11:31 AM (7 hours ago) 11:31 AM
to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

David Chase has uploaded the change for review

Commit message

cmd/compile: make wasm match other platforms for FP->int32/64 conversions

this change is for overflows, so that all the platforms agree.
Change-Id: I9f459353615bf24ef8a5de641063d9ce34986241

Change diff

diff --git a/src/cmd/compile/internal/ssa/_gen/Wasm.rules b/src/cmd/compile/internal/ssa/_gen/Wasm.rules
index f632a01..bb123bc 100644
--- a/src/cmd/compile/internal/ssa/_gen/Wasm.rules
+++ b/src/cmd/compile/internal/ssa/_gen/Wasm.rules
@@ -76,13 +76,14 @@
(Cvt32Uto(64|32)F x) => (F(64|32)ConvertI64U (ZeroExt32to64 x))
(Cvt64Uto(64|32)F ...) => (F(64|32)ConvertI64U ...)

-(Cvt32Fto32 ...) => (I64TruncSatF32S ...)
+(Cvt32Fto32 ...) => (I32TruncSatF32S ...)
(Cvt32Fto64 ...) => (I64TruncSatF32S ...)
-(Cvt64Fto32 ...) => (I64TruncSatF64S ...)
+(Cvt64Fto32 ...) => (I32TruncSatF64S ...)
(Cvt64Fto64 ...) => (I64TruncSatF64S ...)
-(Cvt32Fto32U ...) => (I64TruncSatF32U ...)
+
+(Cvt32Fto32U ...) => (I32TruncSatF32U ...)
(Cvt32Fto64U ...) => (I64TruncSatF32U ...)
-(Cvt64Fto32U ...) => (I64TruncSatF64U ...)
+(Cvt64Fto32U ...) => (I32TruncSatF64U ...)
(Cvt64Fto64U ...) => (I64TruncSatF64U ...)

(Cvt32Fto64F ...) => (F64PromoteF32 ...)
diff --git a/src/cmd/compile/internal/ssa/_gen/WasmOps.go b/src/cmd/compile/internal/ssa/_gen/WasmOps.go
index 45bbed5..b63f28a 100644
--- a/src/cmd/compile/internal/ssa/_gen/WasmOps.go
+++ b/src/cmd/compile/internal/ssa/_gen/WasmOps.go
@@ -222,10 +222,19 @@
{name: "F64Mul", asm: "F64Mul", argLength: 2, reg: fp64_21, typ: "Float64"}, // arg0 * arg1
{name: "F64Div", asm: "F64Div", argLength: 2, reg: fp64_21, typ: "Float64"}, // arg0 / arg1

- {name: "I64TruncSatF64S", asm: "I64TruncSatF64S", argLength: 1, reg: regInfo{inputs: []regMask{fp64}, outputs: []regMask{gp}}, typ: "Int64"}, // truncates the float arg0 to a signed integer (saturating)
- {name: "I64TruncSatF64U", asm: "I64TruncSatF64U", argLength: 1, reg: regInfo{inputs: []regMask{fp64}, outputs: []regMask{gp}}, typ: "Int64"}, // truncates the float arg0 to an unsigned integer (saturating)
- {name: "I64TruncSatF32S", asm: "I64TruncSatF32S", argLength: 1, reg: regInfo{inputs: []regMask{fp32}, outputs: []regMask{gp}}, typ: "Int64"}, // truncates the float arg0 to a signed integer (saturating)
- {name: "I64TruncSatF32U", asm: "I64TruncSatF32U", argLength: 1, reg: regInfo{inputs: []regMask{fp32}, outputs: []regMask{gp}}, typ: "Int64"}, // truncates the float arg0 to an unsigned integer (saturating)
+ {name: "I64TruncSatF64S", asm: "I64TruncSatF64S", argLength: 1, reg: regInfo{inputs: []regMask{fp64}, outputs: []regMask{gp}}, typ: "Int64"}, // truncates the float arg0 to a signed integer (saturating)
+ {name: "I64TruncSatF64U", asm: "I64TruncSatF64U", argLength: 1, reg: regInfo{inputs: []regMask{fp64}, outputs: []regMask{gp}}, typ: "Uint64"}, // truncates the float arg0 to an unsigned integer (saturating)
+ {name: "I64TruncSatF32S", asm: "I64TruncSatF32S", argLength: 1, reg: regInfo{inputs: []regMask{fp32}, outputs: []regMask{gp}}, typ: "Int64"}, // truncates the float arg0 to a signed integer (saturating)
+ {name: "I64TruncSatF32U", asm: "I64TruncSatF32U", argLength: 1, reg: regInfo{inputs: []regMask{fp32}, outputs: []regMask{gp}}, typ: "Uint64"}, // truncates the float arg0 to an unsigned integer (saturating)
+
+ // It appears to be wasm convention that everything lands in a 64-bit register;
+ // the WASM instructions for these operations produce 32-bit width results, but
+ // wasm/ssa.go widens them appropriately to 64-bit results.
+ {name: "I32TruncSatF64S", asm: "I32TruncSatF64S", argLength: 1, reg: regInfo{inputs: []regMask{fp64}, outputs: []regMask{gp}}, typ: "Int64"}, // truncates the float arg0 to a signed integer (saturating)
+ {name: "I32TruncSatF64U", asm: "I32TruncSatF64U", argLength: 1, reg: regInfo{inputs: []regMask{fp64}, outputs: []regMask{gp}}, typ: "Uint64"}, // truncates the float arg0 to an unsigned integer (saturating)
+ {name: "I32TruncSatF32S", asm: "I32TruncSatF32S", argLength: 1, reg: regInfo{inputs: []regMask{fp32}, outputs: []regMask{gp}}, typ: "Int64"}, // truncates the float arg0 to a signed integer (saturating)
+ {name: "I32TruncSatF32U", asm: "I32TruncSatF32U", argLength: 1, reg: regInfo{inputs: []regMask{fp32}, outputs: []regMask{gp}}, typ: "Uint64"}, // truncates the float arg0 to an unsigned integer (saturating)
+
{name: "F32ConvertI64S", asm: "F32ConvertI64S", argLength: 1, reg: regInfo{inputs: []regMask{gp}, outputs: []regMask{fp32}}, typ: "Float32"}, // converts the signed integer arg0 to a float
{name: "F32ConvertI64U", asm: "F32ConvertI64U", argLength: 1, reg: regInfo{inputs: []regMask{gp}, outputs: []regMask{fp32}}, typ: "Float32"}, // converts the unsigned integer arg0 to a float
{name: "F64ConvertI64S", asm: "F64ConvertI64S", argLength: 1, reg: regInfo{inputs: []regMask{gp}, outputs: []regMask{fp64}}, typ: "Float64"}, // converts the signed integer arg0 to a float
diff --git a/src/cmd/compile/internal/ssa/opGen.go b/src/cmd/compile/internal/ssa/opGen.go
index 9cf572b..4fa9aa1 100644
--- a/src/cmd/compile/internal/ssa/opGen.go
+++ b/src/cmd/compile/internal/ssa/opGen.go
@@ -2982,6 +2982,10 @@
OpWasmI64TruncSatF64U
OpWasmI64TruncSatF32S
OpWasmI64TruncSatF32U
+ OpWasmI32TruncSatF64S
+ OpWasmI32TruncSatF64U
+ OpWasmI32TruncSatF32S
+ OpWasmI32TruncSatF32U
OpWasmF32ConvertI64S
OpWasmF32ConvertI64U
OpWasmF64ConvertI64S
@@ -40326,6 +40330,58 @@
},
},
{
+ name: "I32TruncSatF64S",
+ argLen: 1,
+ asm: wasm.AI32TruncSatF64S,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 281470681743360}, // F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
+ },
+ outputs: []outputInfo{
+ {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15
+ },
+ },
+ },
+ {
+ name: "I32TruncSatF64U",
+ argLen: 1,
+ asm: wasm.AI32TruncSatF64U,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 281470681743360}, // F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
+ },
+ outputs: []outputInfo{
+ {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15
+ },
+ },
+ },
+ {
+ name: "I32TruncSatF32S",
+ argLen: 1,
+ asm: wasm.AI32TruncSatF32S,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+ },
+ outputs: []outputInfo{
+ {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15
+ },
+ },
+ },
+ {
+ name: "I32TruncSatF32U",
+ argLen: 1,
+ asm: wasm.AI32TruncSatF32U,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+ },
+ outputs: []outputInfo{
+ {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15
+ },
+ },
+ },
+ {
name: "F32ConvertI64S",
argLen: 1,
asm: wasm.AF32ConvertI64S,
diff --git a/src/cmd/compile/internal/ssa/rewriteWasm.go b/src/cmd/compile/internal/ssa/rewriteWasm.go
index a164a6e..dd73d3a 100644
--- a/src/cmd/compile/internal/ssa/rewriteWasm.go
+++ b/src/cmd/compile/internal/ssa/rewriteWasm.go
@@ -120,10 +120,10 @@
v.Op = OpWasmI64Ctz
return true
case OpCvt32Fto32:
- v.Op = OpWasmI64TruncSatF32S
+ v.Op = OpWasmI32TruncSatF32S
return true
case OpCvt32Fto32U:
- v.Op = OpWasmI64TruncSatF32U
+ v.Op = OpWasmI32TruncSatF32U
return true
case OpCvt32Fto64:
v.Op = OpWasmI64TruncSatF32S
@@ -143,13 +143,13 @@
case OpCvt32to64F:
return rewriteValueWasm_OpCvt32to64F(v)
case OpCvt64Fto32:
- v.Op = OpWasmI64TruncSatF64S
+ v.Op = OpWasmI32TruncSatF64S
return true
case OpCvt64Fto32F:
v.Op = OpWasmF32DemoteF64
return true
case OpCvt64Fto32U:
- v.Op = OpWasmI64TruncSatF64U
+ v.Op = OpWasmI32TruncSatF64U
return true
case OpCvt64Fto64:
v.Op = OpWasmI64TruncSatF64S
diff --git a/src/cmd/compile/internal/wasm/ssa.go b/src/cmd/compile/internal/wasm/ssa.go
index 1e3b318..8ebc902 100644
--- a/src/cmd/compile/internal/wasm/ssa.go
+++ b/src/cmd/compile/internal/wasm/ssa.go
@@ -430,6 +430,17 @@
getValue64(s, v.Args[0])
s.Prog(v.Op.Asm())

+ // 32-bit integer conversion results
+ case ssa.OpWasmI32TruncSatF32S, ssa.OpWasmI32TruncSatF64S:
+ getValue64(s, v.Args[0])
+ s.Prog(v.Op.Asm())
+ s.Prog(wasm.AI64ExtendI32S)
+
+ case ssa.OpWasmI32TruncSatF32U, ssa.OpWasmI32TruncSatF64U:
+ getValue64(s, v.Args[0])
+ s.Prog(v.Op.Asm())
+ s.Prog(wasm.AI64ExtendI32U)
+
case ssa.OpWasmF32DemoteF64:
getValue64(s, v.Args[0])
s.Prog(v.Op.Asm())
diff --git a/test/convert5.go b/test/convert5.go
index 57585ef..5d6a1f9 100644
--- a/test/convert5.go
+++ b/test/convert5.go
@@ -4,11 +4,6 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

-//go:build !wasm
-
-// TODO fix this to work for wasm
-// Doing more than this, however, expands the change.
-
package main

import (

Change information

Files:
  • M src/cmd/compile/internal/ssa/_gen/Wasm.rules
  • M src/cmd/compile/internal/ssa/_gen/WasmOps.go
  • M src/cmd/compile/internal/ssa/opGen.go
  • M src/cmd/compile/internal/ssa/rewriteWasm.go
  • M src/cmd/compile/internal/wasm/ssa.go
  • M test/convert5.go
Change size: M
Delta: 6 files changed, 89 insertions(+), 17 deletions(-)
Open in Gerrit

Related details

Attention set is empty
Submit Requirements:
  • requirement is not satisfiedCode-Review
  • requirement satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
  • requirement is not satisfiedTryBots-Pass
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: newchange
Gerrit-Project: go
Gerrit-Branch: master
Gerrit-Change-Id: I9f459353615bf24ef8a5de641063d9ce34986241
Gerrit-Change-Number: 708358
Gerrit-PatchSet: 1
Gerrit-Owner: David Chase <drc...@google.com>
unsatisfied_requirement
satisfied_requirement
open
diffy

David Chase (Gerrit)

unread,
11:31 AM (7 hours ago) 11:31 AM
to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

David Chase voted Commit-Queue+1

Commit-Queue+1
Open in Gerrit

Related details

Attention set is empty
Submit Requirements:
  • requirement is not satisfiedCode-Review
  • requirement satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
  • requirement is not satisfiedTryBots-Pass
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: go
Gerrit-Branch: master
Gerrit-Change-Id: I9f459353615bf24ef8a5de641063d9ce34986241
Gerrit-Change-Number: 708358
Gerrit-PatchSet: 1
Gerrit-Owner: David Chase <drc...@google.com>
Gerrit-Reviewer: David Chase <drc...@google.com>
Gerrit-Comment-Date: Wed, 01 Oct 2025 15:31:27 +0000
Gerrit-HasComments: No
Gerrit-Has-Labels: Yes
unsatisfied_requirement
satisfied_requirement
open
diffy
Reply all
Reply to author
Forward
0 new messages