From 9089c63444bea77a49f3c186be35d233b05b9814 Mon Sep 17 00:00:00 2001 From: SChernykh <15806605+SChernykh@users.noreply.github.com> Date: Fri, 8 May 2026 21:29:19 +0200 Subject: [PATCH 1/4] Added ISUB_R edge case test --- .github/workflows/c-cpp.yml | 29 +++++++++++++---------------- src/tests/tests.cpp | 14 ++++++++++++++ 2 files changed, 27 insertions(+), 16 deletions(-) diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index 47ade398..b711d27c 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -20,7 +20,7 @@ jobs: - {arch: armhf, branch: latest-stable} - {arch: armv7, branch: latest-stable} - {arch: ppc64le, branch: latest-stable} - - {arch: riscv64, branch: edge} + - {arch: riscv64, branch: latest-stable} - {arch: s390x, branch: latest-stable} steps: @@ -45,7 +45,7 @@ jobs: run: | mkdir build cd build - cmake .. + cmake .. -DCMAKE_BUILD_TYPE=Release -DARCH=native make -j$(nproc) - name: Run tests @@ -61,8 +61,8 @@ jobs: strategy: matrix: config: - - {os: ubuntu-20.04, c: gcc-11, cpp: g++-11} - - {os: ubuntu-22.04, c: gcc-12, cpp: g++-12} + - {os: ubuntu-24.04, c: gcc-14, cpp: g++-14} + - {os: ubuntu-24.04-arm, c: gcc-14, cpp: g++-14} steps: - name: Install dependencies @@ -133,9 +133,7 @@ jobs: strategy: matrix: config: - - {arch: x64, os: 2019, vs: Visual Studio 16 2019, msbuild: "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Enterprise\\MSBuild\\Current\\Bin\\amd64\\"} - {arch: x64, os: 2022, vs: Visual Studio 17 2022, msbuild: "C:\\Program Files\\Microsoft Visual Studio\\2022\\Enterprise\\Msbuild\\Current\\Bin\\amd64\\"} - - {arch: Win32, os: 2019, vs: Visual Studio 16 2019, msbuild: "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Enterprise\\MSBuild\\Current\\Bin\\"} - {arch: Win32, os: 2022, vs: Visual Studio 17 2022, msbuild: "C:\\Program Files\\Microsoft Visual Studio\\2022\\Enterprise\\Msbuild\\Current\\Bin\\"} steps: @@ -165,7 +163,7 @@ jobs: strategy: matrix: - os: [macos-11, macos-12, macos-13] + os: [macos-15, macos-15-intel] steps: - name: Checkout repository @@ -173,15 +171,12 @@ jobs: with: submodules: recursive - - name: Install dependencies - run: HOMEBREW_NO_AUTO_UPDATE=1 brew install cmake - - name: Build RandomX run: | mkdir build cd build cmake .. - make -j3 + make -j4 - name: Run tests run: | @@ -197,13 +192,13 @@ jobs: os: - name: freebsd architecture: x86-64 - version: '13.2' - host: ubuntu-22.04 + version: '13.3' + host: ubuntu-latest - name: freebsd architecture: arm64 - version: '13.2' - host: ubuntu-22.04 + version: '13.3' + host: ubuntu-latest steps: - name: Checkout repository @@ -212,11 +207,13 @@ jobs: submodules: recursive - name: Build RandomX - uses: cross-platform-actions/action@v0.19.0 + uses: cross-platform-actions/action@v0.24.0 with: operating_system: ${{ matrix.os.name }} architecture: ${{ matrix.os.architecture }} version: ${{ matrix.os.version }} + memory: 12G + cpu_count: 4 shell: bash run: | sudo pkg install -y cmake diff --git a/src/tests/tests.cpp b/src/tests/tests.cpp index 5e1b41a3..579ce624 100644 --- a/src/tests/tests.cpp +++ b/src/tests/tests.cpp @@ -1001,6 +1001,16 @@ int main() { assert(equalsHex(hash, "c56414121acda1713c2f2a819d8ae38aed7c80c35c2a769298d34f03833cd5f1")); }; + auto test_f = [&] { + char key[RANDOMX_HASH_SIZE] = { + 0x77, 0x97, 0x37, 0x3e, 0xa4, 0x63, 0x31, 0x94, 0x64, 0x0b, 0xf8, 0xd8, 0xc3, 0xb6, 0x67, 0x24, 0xd6, 0xaa, 0x7b, 0xd2, 0xdc, 0x20, 0xe0, 0x09, 0xdf, 0x2f, 0x8f, 0x17, 0x10, 0xab, 0xe8, 0x24 + }; + + char hash[RANDOMX_HASH_SIZE]; + calcHexHash(key, "1010e1eaf8cf067b37b5f0ee031ab23ed1755e090a3af4415830145853e2be3e1f6821fed84dae58d00e00da5214d6c1f2d0622e0abd51f9373d04e0b0f8e6d6514d90689721c4aac5a9bb0d", &hash); + assert(equalsHex(hash, "78af2a1864c42abce36d2e8983e13df99b2af0ce1362999af09fab004d4435a8")); + }; + runTest("Hash test 1a (interpreter)", stringsEqual(RANDOMX_ARGON_SALT, "RandomX\x03"), test_a); runTest("Hash test 1b (interpreter)", stringsEqual(RANDOMX_ARGON_SALT, "RandomX\x03"), test_b); @@ -1011,6 +1021,8 @@ int main() { runTest("Hash test 1e (interpreter)", stringsEqual(RANDOMX_ARGON_SALT, "RandomX\x03"), test_e); + runTest("Hash test 1f (ISUB_R edge case, interpreter)", stringsEqual(RANDOMX_ARGON_SALT, "RandomX\x03"), test_f); + if (RANDOMX_HAVE_COMPILER) { randomx_release_cache(cache); randomx_destroy_vm(vm); @@ -1034,6 +1046,8 @@ int main() { runTest("Hash test 2e (compiler)", RANDOMX_HAVE_COMPILER && stringsEqual(RANDOMX_ARGON_SALT, "RandomX\x03"), test_e); + runTest("Hash test 2f (ISUB_R edge case, compiler)", stringsEqual(RANDOMX_ARGON_SALT, "RandomX\x03"), test_f); + auto flags = randomx_get_flags(); randomx_release_cache(cache); From d71dadb735f737472f4ddf7b52861efa3dd215da Mon Sep 17 00:00:00 2001 From: SChernykh <15806605+SChernykh@users.noreply.github.com> Date: Fri, 8 May 2026 21:39:12 +0200 Subject: [PATCH 2/4] Fixed ISUB_R edge case (ARM, RISC-V JIT) --- src/jit_compiler_a64.cpp | 11 ++++++++++- src/jit_compiler_rv64.cpp | 13 ++++++++++--- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/jit_compiler_a64.cpp b/src/jit_compiler_a64.cpp index 5be8f6e4..f11db860 100644 --- a/src/jit_compiler_a64.cpp +++ b/src/jit_compiler_a64.cpp @@ -561,7 +561,16 @@ void JitCompilerA64::h_ISUB_R(Instruction& instr, uint32_t& codePos) } else { - emitAddImmediate(dst, dst, -instr.getImm32(), code, k); + const uint32_t imm = instr.getImm32(); + + if (imm == 0x80000000ul) { + constexpr uint32_t tmp_reg = 20; + emit32(ARMV8A::MOVZ | tmp_reg | (1u << 21) | (0x8000u << 5), code, k); + emit32(ARMV8A::ADD | dst | (dst << 5) | (tmp_reg << 16), code, k); + } + else { + emitAddImmediate(dst, dst, -instr.getImm32(), code, k); + } } reg_changed_offset[instr.dst] = k; diff --git a/src/jit_compiler_rv64.cpp b/src/jit_compiler_rv64.cpp index 6f0842e5..91f42f09 100644 --- a/src/jit_compiler_rv64.cpp +++ b/src/jit_compiler_rv64.cpp @@ -714,9 +714,16 @@ namespace randomx { state.emit(rvi(rv64::SUB, regR(isn.dst), regR(isn.dst), regR(isn.src))); } else { - int32_t imm = unsigned32ToSigned2sCompl(-isn.getImm32()); //convert to add - //x{dst} = x{dst} + {-imm} - emitImm32(state, imm, regR(isn.dst), regR(isn.dst), Tmp1Reg); + const uint32_t uimm = isn.getImm32(); + if (uimm == 0x80000000ul) { + state.emit(rv64::LUI | (0x80000 << 12) | rvrd(Tmp1Reg)); + state.emit(rvi(rv64::SUB, regR(isn.dst), regR(isn.dst), Tmp1Reg)); + } + else { + int32_t imm = unsigned32ToSigned2sCompl(-uimm); //convert to add + //x{dst} = x{dst} + {-imm} + emitImm32(state, imm, regR(isn.dst), regR(isn.dst), Tmp1Reg); + } } } From e511bad7f3d87c2ed02279adbe9da9adb8451467 Mon Sep 17 00:00:00 2001 From: SChernykh <15806605+SChernykh@users.noreply.github.com> Date: Fri, 8 May 2026 21:45:07 +0200 Subject: [PATCH 3/4] Fixed tests compilation on gcc/clang --- src/tests/tests.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/tests/tests.cpp b/src/tests/tests.cpp index 579ce624..970a4025 100644 --- a/src/tests/tests.cpp +++ b/src/tests/tests.cpp @@ -1002,9 +1002,13 @@ int main() { }; auto test_f = [&] { - char key[RANDOMX_HASH_SIZE] = { + uint8_t key_u[RANDOMX_HASH_SIZE] = { 0x77, 0x97, 0x37, 0x3e, 0xa4, 0x63, 0x31, 0x94, 0x64, 0x0b, 0xf8, 0xd8, 0xc3, 0xb6, 0x67, 0x24, 0xd6, 0xaa, 0x7b, 0xd2, 0xdc, 0x20, 0xe0, 0x09, 0xdf, 0x2f, 0x8f, 0x17, 0x10, 0xab, 0xe8, 0x24 }; + char key[RANDOMX_HASH_SIZE]; + + // workaround for picky compilers + memcpy(key, key_u, sizeof(key_u)); char hash[RANDOMX_HASH_SIZE]; calcHexHash(key, "1010e1eaf8cf067b37b5f0ee031ab23ed1755e090a3af4415830145853e2be3e1f6821fed84dae58d00e00da5214d6c1f2d0622e0abd51f9373d04e0b0f8e6d6514d90689721c4aac5a9bb0d", &hash); From 5f3807fd81ace5bc43e032c569d420410958836e Mon Sep 17 00:00:00 2001 From: SChernykh <15806605+SChernykh@users.noreply.github.com> Date: Sat, 9 May 2026 05:10:28 +0200 Subject: [PATCH 4/4] Fixed tests visuals --- src/tests/tests.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/tests.cpp b/src/tests/tests.cpp index 970a4025..2e344130 100644 --- a/src/tests/tests.cpp +++ b/src/tests/tests.cpp @@ -59,7 +59,7 @@ void runTest(const char* name, bool condition, FUNC f) { std::cout << "["; std::cout.width(2); std::cout << std::right << ++testNo << "] "; - std::cout.width(40); + std::cout.width(44); std::cout << std::left << name << " ... "; std::cout.flush(); if (condition) {