-
Notifications
You must be signed in to change notification settings - Fork 25
fix(compiler): add large-offset 64-bit address path to handleStoreImpl #426
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -935,19 +935,15 @@ class X64OnePassCodeGenImpl | |
| X64Reg::getRegRef<X64::I32>(BaseReg), 0, | ||
| Offset, getWASMTypeSize<SrcType>()); | ||
|
|
||
| #ifdef ZEN_ENABLE_CPU_EXCEPTION | ||
| if (!Base.isImm() && (Offset >= INT32_MAX)) { | ||
| // when offset >= INT32_MAX, then will cause inst like mov edi, dword | ||
| // ptr[r13+edi-1]. | ||
| if (!Base.isImm() && (Offset >= (uint32_t)INT32_MAX)) { | ||
| auto MemAddrReg = Layout.getScopedTemp<AddrType, ScopedTempReg2>(); | ||
| _ mov(X64Reg::getRegRef<X64::I32>(MemAddrReg), Offset); | ||
| _ add(X64Reg::getRegRef<X64::I64>(MemAddrReg), | ||
| X64Reg::getRegRef<X64::I64>(BaseReg)); | ||
| _ add(X64Reg::getRegRef<X64::I64>(MemAddrReg), ABI.getMemoryBaseReg()); | ||
| Addr = asmjit::x86::Mem(X64Reg::getRegRef<X64::I64>(MemAddrReg), 0, | ||
| getWASMTypeSize(SrcType)); | ||
| getWASMTypeSize<SrcType>()); | ||
| } | ||
|
Comment on lines
+938
to
946
|
||
| #endif // ZEN_ENABLE_CPU_EXCEPTION | ||
|
|
||
| LoadOperatorImpl<X64DestType, X64SrcType, Sext>::emit( | ||
| ASM, X64Reg::getRegRef<X64DestType>(ValReg), Addr); | ||
|
|
@@ -1014,15 +1010,23 @@ class X64OnePassCodeGenImpl | |
| ZEN_ABORT(); | ||
| } | ||
|
|
||
| // Addr = memoryBase + (in64) offset, so when offset < 0, | ||
| // the result i32 Addr works like add (2**32 + offset) | ||
| asmjit::x86::Mem Addr = | ||
| Base.isImm() ? asmjit::x86::Mem(ABI.getMemoryBaseReg(), Offset, | ||
| getWASMTypeSize<Type>()) | ||
| : asmjit::x86::Mem(ABI.getMemoryBaseReg(), | ||
| X64Reg::getRegRef<X64::I32>(RegNum), 0, | ||
| Offset, getWASMTypeSize<Type>()); | ||
|
|
||
| if (!Base.isImm() && (Offset >= (uint32_t)INT32_MAX)) { | ||
| auto MemAddrReg = Layout.getScopedTemp<AddrType, ScopedTempReg2>(); | ||
| _ mov(X64Reg::getRegRef<X64::I32>(MemAddrReg), Offset); | ||
| _ add(X64Reg::getRegRef<X64::I64>(MemAddrReg), | ||
| X64Reg::getRegRef<X64::I64>(RegNum)); | ||
|
Comment on lines
+1020
to
+1024
|
||
| _ add(X64Reg::getRegRef<X64::I64>(MemAddrReg), ABI.getMemoryBaseReg()); | ||
| Addr = asmjit::x86::Mem(X64Reg::getRegRef<X64::I64>(MemAddrReg), 0, | ||
| getWASMTypeSize<Type>()); | ||
| } | ||
|
Comment on lines
+1020
to
+1028
|
||
|
|
||
| mov<X64Type, ScopedTempReg0>(Addr, Value); | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,44 @@ | ||||||
| ;; Test: f64.store with offset >= INT32_MAX on large memory should NOT trap. | ||||||
|
||||||
| ;; Test: f64.store with offset >= INT32_MAX on large memory should NOT trap. | |
| ;; Test: f64.store with offset >= 0x80000000 (INT32_MAX + 1) on large memory should NOT trap. |
Copilot
AI
Mar 27, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test exercises large offsets with dynamic bases; to fully cover the disp32 sign-extension regression, consider also adding a case where the base is an immediate constant (e.g., i32.const 0) with an offset>=0x80000000. That hits the Base.isImm() addressing form, which can behave differently in the JIT.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
Offset >= (uint32_t)INT32_MAXthreshold is slightly off for the disp32 sign-extension issue: sign-extension becomes negative starting at0x80000000(i.e.,Offset > INT32_MAX). Using>= INT32_MAXwill unnecessarily take the slower explicit-address path forOffset == 0x7fffffff, which is still representable as a positive disp32.