Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

interpreter,compiler(amd64): complete SIMD instructions #624

Merged
merged 9 commits into from
Jun 15, 2022
Merged

Conversation

mathetake
Copy link
Member

@mathetake mathetake commented Jun 6, 2022

This completes the implementation of SIMD proposal for both
the interpreter and compiler(amd64).
This also fixes #210 by adding the complete documentation
over all the wazeroir operations.

arm64 compiler will follow in subsequent PRs.

part of #484

@mathetake
Copy link
Member Author

ok passed simd_**_arith.wast, simd_**_arith2.wast, simd_f32.wast, simd_f64.wast spectests with both engines... will implement more!

@mathetake
Copy link
Member Author

ok simd_i16x8_q15mulr_sat_s, simd_int_to_int_extend, simd_i64x2_extmul_i32x4, simd_i32x4_extmul_i16x8 and simd_i16x8_extmul_i8x16 passed...

@mathetake mathetake changed the title SIMD: misc instructions interpreter,compiler(amd64): complete SIMD instructions Jun 9, 2022
@mathetake
Copy link
Member Author

ok passed all spec test with the interpreter, meaning that it is fully compatible with WebAssembly 2.0 draft!

@mathetake
Copy link
Member Author

ok passed all tests for both engines... backfilling comments and unit tests...

@mathetake mathetake force-pushed the simdarith branch 2 times, most recently from 8cd5b5f to 79bd254 Compare June 14, 2022 04:16
@mathetake mathetake marked this pull request as ready for review June 14, 2022 04:16
@mathetake mathetake force-pushed the simdarith branch 2 times, most recently from 02438ad to 3cbfac9 Compare June 14, 2022 04:22
@mathetake
Copy link
Member Author

ok finished the tests for spectest.go... marked this for ready!

Signed-off-by: Takeshi Yoneda <[email protected]>
Signed-off-by: Takeshi Yoneda <[email protected]>
Makefile Show resolved Hide resolved
Copy link
Contributor

@codefromthecrypt codefromthecrypt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unleashing a few

internal/asm/amd64/impl.go Show resolved Hide resolved
internal/asm/amd64/impl.go Show resolved Hide resolved
// https://www.felixcloutier.com/x86/pmulhrsw
PMULHRSW: {mandatoryPrefix: 0x66, opcode: []byte{0x0f, 0x38, 0x0b}, requireSrcFloat: true, requireDstFloat: true},
// https://www.felixcloutier.com/x86/pmovsx
PMOVSXBW: {mandatoryPrefix: 0x66, opcode: []byte{0x0f, 0x38, 0x20}, requireSrcFloat: true, requireDstFloat: true},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add something like this to registerToRegisterOpcode to help next person figure out when an instruction is missing ;) I don't know the correct words, so gave it a shot.

ex.

// The index of felixcloutier.com does not include all instruction variations.
// For example, removing the suffix `BW` from `PMOVSXBW` allows you to find it in https://www.felixcloutier.com/x86/index.html.
//
// Here are the known instruction conventions used in felixcloutier.com
//	* BW - 16-bit integer
//	* BD - 32-bit integer
//	* BQ - 64-bit integer

Copy link
Contributor

@codefromthecrypt codefromthecrypt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I notice we are getting to tens of thousands of tests due to matrix t.Run

While this is a good default, I think that in the case of instruction boundary testing, especially later with fuzzing, we can do it differently to keep things like IDEs from crashing, and also keep the runtime lower.

Basically substitute dimensional explosions with a format string on input instead of t.Run
ex. require.False(t, x, "input %d", y)

Then in RATIONALE.md, say...

Test matrices

Typically, we advice boundary tests to use go test tables, where t.Run is run repeatedly with different inputs, using pinned variables. An exception to this are compiler instruction tests, where there are too many inputs, resulting in tens of thousands of tests.

Instead, we run a normal loop substituting dimensional explosions with a format string on input instead of t.Run
ex. require.False(t, x, "input %d", y)

This keeps the test cardinality low which reduces runtime. On the rare failure, the input is visible in the failure output. While re-running this input is less ideal than a separate test, it is possible manually by temporarily removing the loop.

internal/asm/amd64/impl.go Outdated Show resolved Hide resolved
name: "pmullw xmm13, xmm1",
n: &NodeImpl{
Instruction: PMULLW,
SrcReg: RegX1,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think in this file, maybe order dest first so that it doesn't break the brain that the name is the other way ;)

internal/asm/assembler.go Outdated Show resolved Hide resolved
Copy link
Contributor

@codefromthecrypt codefromthecrypt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is great, especially as I'm sure arm64 is gonna be easier!

main thing to do now or later is pay down some techdebt accruing in interpreter.go. I feel this part of the codebase may see some contributions by external folks, so it could be a bit more inviting.

@@ -330,7 +330,7 @@ const (
nativeCallStatusIntegerDivisionByZero
)

// causePanic causes a panic with the corresponding error to the status code.
// causePanic causes a panic with the corresponding error to the nativeCallStatusCode.
func (s nativeCallStatusCode) causePanic() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed in go Panic() functions.. this avoids clash on panic food for thought.

internal/engine/compiler/engine.go Show resolved Hide resolved
internal/engine/compiler/impl_vec_amd64.go Show resolved Hide resolved
internal/engine/compiler/impl_vec_amd64.go Outdated Show resolved Hide resolved
internal/engine/interpreter/interpreter.go Outdated Show resolved Hide resolved
internal/engine/interpreter/interpreter.go Show resolved Hide resolved
internal/engine/interpreter/interpreter.go Outdated Show resolved Hide resolved
internal/engine/interpreter/interpreter.go Outdated Show resolved Hide resolved
internal/engine/interpreter/interpreter.go Outdated Show resolved Hide resolved
mathetake and others added 5 commits June 15, 2022 10:45
Signed-off-by: Takeshi Yoneda <[email protected]>
Signed-off-by: Takeshi Yoneda <[email protected]>
Signed-off-by: Takeshi Yoneda <[email protected]>
Signed-off-by: Takeshi Yoneda <[email protected]>
Signed-off-by: Takeshi Yoneda <[email protected]>
@mathetake mathetake merged commit 3068d17 into main Jun 15, 2022
@mathetake mathetake deleted the simdarith branch June 15, 2022 02:52
mathetake added a commit that referenced this pull request Jun 21, 2022
This completes the implementation of arm64 backend for SIMD instructions.
Notably, now the arm64 compiler passes 100% of WebAssemby 2.0 draft
specification tests.

Combined with the completion of the interpreter and amd64 backend (#624),
this finally resolves #484. Therefore, this also documents that wazero is
100% compatible with WebAssembly 1.0 and 2.0.

Signed-off-by: Takeshi Yoneda <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Document all wazeroir instructions with ref to the spec
2 participants