Skip to content

Fix i64x2 shift on big-endian#8748

Merged
kripken merged 1 commit into
WebAssembly:mainfrom
sertonix:i64x2-shift-be
May 21, 2026
Merged

Fix i64x2 shift on big-endian#8748
kripken merged 1 commit into
WebAssembly:mainfrom
sertonix:i64x2-shift-be

Conversation

@sertonix
Copy link
Copy Markdown
Contributor

@sertonix sertonix commented May 21, 2026

Since the i64x2.sh* functions use i32 as shift argument the access to other.i64 may not use the correct union member. On big-endian systems this causes tests in test/spec/testsuite/simd_bit_shift.wast and a few other places to fail.

Ref #2983

@sertonix sertonix requested a review from a team as a code owner May 21, 2026 12:14
@sertonix sertonix requested review from tlively and removed request for a team May 21, 2026 12:14
The i64x2 shift functions use i32 for the second argument. This makes
the other.i64 not always match other.type. On big-endian systems this
causes tests in test/spec/testsuite/simd_bit_shift.wast and a few
other places to fail.

Ref WebAssembly#2983
Comment thread src/wasm/literal.cpp
return Literal(uint64_t(i64)
<< Bits::getEffectiveShifts(other.i64, Type::i64));
return Literal(uint64_t(i64) << Bits::getEffectiveShifts(
other.getInteger(), Type::i64));
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Hmm, by the wasm validation rules, the type of other must be identical. Are you seeing a situation where it is not?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Not with the indirect usage of Literal::shl through Literal::shlI64x2:

binaryen/src/wasm/literal.cpp

Lines 2264 to 2266 in 2f63efb

Literal Literal::shlI64x2(const Literal& other) const {
return shift<2, &Literal::getLanesI64x2, &Literal::shl>(*this, other);
}

void FunctionValidator::visitSIMDShift(SIMDShift* curr) {
shouldBeTrue(getModule()->features.hasSIMD(),
curr,
"SIMD operations require SIMD [--enable-simd]");
shouldBeEqualOrFirstIsUnreachable(
curr->type, Type(Type::v128), curr, "vector shift must have type v128");
shouldBeEqualOrFirstIsUnreachable(
curr->vec->type, Type(Type::v128), curr, "expected operand of type v128");
shouldBeEqualOrFirstIsUnreachable(curr->shift->type,
Type(Type::i32),
curr,
"expected shift amount to have type i32");
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I see, thanks. I guess this makes sense - wasm semantics are more strict than our Literal APIs should allow. I was confused before.

@kripken kripken merged commit cfc3d50 into WebAssembly:main May 21, 2026
15 of 16 checks passed
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.

2 participants