Repository: matter-labs/era-compiler-llvm
Pull request #814: [EVM] Add a C-API to retrieve linker symbol offsets from an ELF file
Author: login: PavelKopyl
Created: 2025-05-18T23:35:20Z | Merged: 2025-05-24T09:15:57Z

These are linker symbol offsets in a generated bytecode.

# Code Review Checklist



## Purpose


## Ticket Number


## Requirements
- [x] Have the requirements been met?
- [ ] Have stakeholder(s) approved the change?

## Implementation
- [ ] Does this code change accomplish what it is supposed to do?
- [ ] Can this solution be simplified?
- [ ] Does this change add unwanted compile-time or run-time dependencies?
- [ ] Could an additional framework, API, library, or service improve the solution?
- [ ] Could we reuse part of LLVM instead of implementing the patch or a part of it?
- [ ] Is the code at the right abstraction level?
- [ ] Is the code modular enough?
- [ ] Can a better solution be found in terms of maintainability, readability, performance, or security?
- [ ] Does similar functionality already exist in the codebase? If yes, why isn’t it reused?
- [ ] Are there any best practices, design patterns or language-specific patterns that could substantially improve this code? 

## Logic Errors and Bugs
- [ ] Can you think of any use case in which the
code does not behave as intended?
- [ ] Can you think of any inputs or external events
that could break the code?

## Error Handling and Logging
- [ ] Is error handling done the correct way?
- [ ] Should any logging or debugging information
be added or removed?
- [ ] Are error messages user-friendly?
- [ ] Are there enough log events and are they
written in a way that allows for easy
debugging?

## Maintainability
- [ ] Is the code easy to read?
- [ ] Is the code not repeated (DRY Principle)?
- [ ] Is the code method/class not too long?

## Dependencies
- [ ] Were updates to documentation, configuration, or readme files made as required by this change?
- [ ] Are there any potential impacts on other parts of the system or backward compatibility?

## Security
- [ ] Does the code introduce any security vulnerabilities?

## Performance
- [ ] Do you think this code change decreases
system performance?
- [ ] Do you see any potential to improve the
performance of the code significantly?

## Testing and Testability
- [ ] Is the code testable?
- [ ] Have automated tests been added, or have related ones been updated to cover the change?
	- [ ] For changes to mutable state
- [ ] Do tests reasonably cover the code change (unit/integration/system tests)? 
	- [ ] Line Coverage
	- [ ] Region Coverage
	- [ ] Branch Coverage
- [ ] Are there some test cases, input or edge cases
that should be tested in addition?

## Readability
- [ ] Is the code easy to understand?
- [ ] Which parts were confusing to you and why?
- [ ] Can the readability of the code be improved by
smaller methods?
- [ ] Can the readability of the code be improved by
different function, method or variable names?
- [ ] Is the code located in the right
file/folder/package?
- [ ] Do you think certain methods should be
restructured to have a more intuitive control
flow?
- [ ] Is the data flow understandable?
- [ ] Are there redundant or outdated comments?
- [ ] Could some comments convey the message
better?
- [ ] Would more comments make the code more
understandable?
- [ ] Could some comments be removed by making the code itself more readable?
- [ ] Is there any commented-out code?
- [ ] Have you run a spelling and grammar checker?

## Documentation
- [ ] Is there sufficient documentation?
- [ ] Is the ReadMe.md file up to date?

## Best Practices
- [ ] Follow Single Responsibility principle?
- [ ] Are different errors handled correctly?
- [ ] Are errors and warnings logged?
- [ ] Magic values avoided?
- [ ] No unnecessary comments?
- [ ] Minimal nesting used?

## Experts' Opinion
- [ ] Do you think a specific expert, like a security
expert or a usability expert, should look over
the code before it can be accepted?
- [ ] Will this code change impact different teams, and should they review the change as well?

<!-- 
MIT License

Copyright (c) 2020 Michaela Greiler
from https://github.com/mgreiler/code-review-checklist/
Modified 2023– by Matter Labs,
some extracts from https://www.codereviewchecklist.com added,
Copyright (c) 2020 Lee Englestone
also MIT License.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
 -->



Diff:
diff --git a/lld/include/lld-c/LLDAsLibraryC.h b/lld/include/lld-c/LLDAsLibraryC.h
index 58d8eaae6961..bc05eb36a05d 100644
--- a/lld/include/lld-c/LLDAsLibraryC.h
+++ b/lld/include/lld-c/LLDAsLibraryC.h
@@ -181,10 +181,20 @@ uint64_t LLVMGetImmutablesEVM(LLVMMemoryBufferRef inBuffer,
                               char ***immutableIDs,
                               uint64_t **immutableOffsets);
 
+/** Returns an array of offsets of the linker symbol relocations form the
+ *  ELF object file provided in \p inBuffer. */
+uint64_t LLVMGetSymbolOffsetsEVM(LLVMMemoryBufferRef inBuffer,
+                                 const char *symbolName,
+                                 uint64_t **symbolOffsets);
+
 /** Disposes of the immutable names and their offsets returned by
  *  'LLVMGetImmutablesEVM'. */
 void LLVMDisposeImmutablesEVM(char **immutableIDs, uint64_t *immutableOffsets,
                               uint64_t numOfImmutables);
+
+/** Releases the array of linker symbol offsets. */
+void LLVMDisposeSymbolOffsetsEVM(uint64_t *offsets);
+
 LLVM_C_EXTERN_C_END
 
 #endif // LLD_C_LLDASLIBRARYC_H
diff --git a/lld/lld-c/LLDAsLibraryC.cpp b/lld/lld-c/LLDAsLibraryC.cpp
index 0ea3645e5616..002715c84200 100644
--- a/lld/lld-c/LLDAsLibraryC.cpp
+++ b/lld/lld-c/LLDAsLibraryC.cpp
@@ -942,6 +942,49 @@ static void getUndefinedNonRefSymbols(LLVMMemoryBufferRef inBuffer,
   }
 }
 
+/// Returns an array of offsets for the linker symbol relocations.
+/// These are the symbol offsets in the generated bytecode.
+uint64_t LLVMGetSymbolOffsetsEVM(LLVMMemoryBufferRef inBuffer,
+                                 const char *symbolName,
+                                 uint64_t **symbolOffsets) {
+  std::unique_ptr<Binary> inBinary =
+      cantFail(createBinary(unwrap(inBuffer)->getMemBufferRef()));
+  auto *elfFile = static_cast<ELFObjectFileBase *>(inBinary.get());
+
+  SmallVector<uint64_t> Offsets;
+  // The relocation of a linker symbol is expressed as a sequence of
+  // five consecutive 32-bit relocations. We need only the first one.
+  std::string subSymName = getLinkerSubSymbolName(symbolName, 0);
+  for (const ELFSectionRef relocsSec : elfFile->sections()) {
+    // Find the relocation section. It should be .rela.text.
+    if (relocsSec.relocations().empty() ||
+        !cantFail(relocsSec.getRelocatedSection())->isText())
+      continue;
+
+    // Check relocations of the specified type.
+    for (const ELFRelocationRef rel : relocsSec.relocations()) {
+      if (rel.getType() != ELF::R_EVM_DATA)
+        continue;
+
+      elf_symbol_iterator sym = rel.getSymbol();
+      uint32_t symFlags = cantFail(sym->getFlags());
+      StringRef symName = cantFail(sym->getName());
+      if ((sym->getOther() == llvm::ELF::STO_ERAVM_REFERENCE_SYMBOL) &&
+          (symFlags & object::SymbolRef::SF_Undefined) &&
+          (symName == subSymName))
+        Offsets.push_back(rel.getOffset());
+    }
+  }
+
+  *symbolOffsets = reinterpret_cast<uint64_t *>(
+      std::malloc(Offsets.size() * sizeof(uint64_t)));
+
+  sort(Offsets);
+  copy(Offsets, *symbolOffsets);
+
+  return Offsets.size();
+}
+
 /// Performs the following steps, which are based on Ethereum's
 /// Assembly::assemble() logic:
 ///  - Concatenates the .text sections of input ELF files referenced
@@ -1158,3 +1201,5 @@ void LLVMDisposeImmutablesEVM(char **immutableIDs, uint64_t *immutableOffsets,
   std::free(immutableIDs);
   std::free(immutableOffsets);
 }
+
+void LLVMDisposeSymbolOffsetsEVM(uint64_t *offsets) { std::free(offsets); }
diff --git a/lld/unittests/EVM/LLDTest.cpp b/lld/unittests/EVM/LLDTest.cpp
index 933fb3d5529d..78d71e2969db 100644
--- a/lld/unittests/EVM/LLDTest.cpp
+++ b/lld/unittests/EVM/LLDTest.cpp
@@ -23,7 +23,6 @@
 
 using namespace llvm;
 
-#include <iostream>
 static std::string expand(const char *Path) {
   llvm::SmallString<256> ThisPath;
   ThisPath.append(getenv("LLD_SRC_DIR"));
@@ -291,6 +290,13 @@ TEST_F(LLDCTest, Assembly) {
       {R_deploy_obj, R_deployed_assemble, A_assembly, A_assembly_deployed},
       {"R_107", "R_107_deployed", "A_38", "A_38.A_38_deployed"});
 
+  // Get linker symbols offsets
+  uint64_t *SymOffsets = nullptr;
+  uint64_t NumOffsets =
+      LLVMGetSymbolOffsetsEVM(R_assembly, LinkerSymbol[1], &SymOffsets);
+  EXPECT_TRUE(NumOffsets == 3);
+  LLVMDisposeSymbolOffsetsEVM(SymOffsets);
+
   // Linking with no linker symbols.
   LLVMMemoryBufferRef TmpAssembly = link(R_assembly, "R", nullptr, nullptr, 0);
   EXPECT_TRUE(LLVMIsELFEVM(TmpAssembly));


Reviews:
user: login: hedgar2017
state: CHANGES_REQUESTED
author_association: COLLABORATOR
submitted_at: 2025-05-19T00:38:53Z
user: login: PavelKopyl
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-19T00:55:54Z
user: login: PavelKopyl
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-19T00:56:13Z
user: login: hedgar2017
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-05-19T01:12:57Z
user: login: PavelKopyl
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-19T21:10:29Z
user: login: hedgar2017
state: APPROVED
author_association: COLLABORATOR
submitted_at: 2025-05-22T10:34:35Z
user: login: akiramenai
state: APPROVED
author_association: COLLABORATOR
submitted_at: 2025-05-24T07:20:40Z

Review comments:
diff_hunk: @@ -291,6 +290,18 @@ TEST_F(LLDCTest, Assembly) {
       {R_deploy_obj, R_deployed_assemble, A_assembly, A_assembly_deployed},
       {"R_107", "R_107_deployed", "A_38", "A_38.A_38_deployed"});
 
+  // Get linker symbols offsets
+  uint64_t *SymOffsets = nullptr;
+  uint64_t NumOffsets =
+      LLVMSymbolOffsetsEVM(R_assembly, LinkerSymbol[1], &SymOffsets);
+  EXPECT_TRUE(NumOffsets == 3);
+  // These offsets depend on the compiler's optimization level. Since the
path: lld/unittests/EVM/LLDTest.cpp
user: login: hedgar2017
body: Do they also depend on any changes in the codegen?
created_at: 2025-05-19T00:38:15Z
author_association: COLLABORATOR
diff_hunk: @@ -181,10 +181,19 @@ uint64_t LLVMGetImmutablesEVM(LLVMMemoryBufferRef inBuffer,
                               char ***immutableIDs,
                               uint64_t **immutableOffsets);
 
+/** Returns an array of offsets of the linker symbol relocations form the
+ *  ELF object file provided in \p inBuffer. */
+uint64_t LLVMSymbolOffsetsEVM(LLVMMemoryBufferRef inBuffer,
path: lld/include/lld-c/LLDAsLibraryC.h
user: login: hedgar2017
body: Please unify the getter function names.
created_at: 2025-05-19T00:38:49Z
author_association: COLLABORATOR
diff_hunk: @@ -291,6 +290,18 @@ TEST_F(LLDCTest, Assembly) {
       {R_deploy_obj, R_deployed_assemble, A_assembly, A_assembly_deployed},
       {"R_107", "R_107_deployed", "A_38", "A_38.A_38_deployed"});
 
+  // Get linker symbols offsets
+  uint64_t *SymOffsets = nullptr;
+  uint64_t NumOffsets =
+      LLVMSymbolOffsetsEVM(R_assembly, LinkerSymbol[1], &SymOffsets);
+  EXPECT_TRUE(NumOffsets == 3);
+  // These offsets depend on the compiler's optimization level. Since the
path: lld/unittests/EVM/LLDTest.cpp
user: login: PavelKopyl
body: Right. But anyway I do not expect we will change them often. On the other hand we can drop them, as the don't have big meaning. 
created_at: 2025-05-19T00:55:54Z
author_association: CONTRIBUTOR
diff_hunk: @@ -181,10 +181,19 @@ uint64_t LLVMGetImmutablesEVM(LLVMMemoryBufferRef inBuffer,
                               char ***immutableIDs,
                               uint64_t **immutableOffsets);
 
+/** Returns an array of offsets of the linker symbol relocations form the
+ *  ELF object file provided in \p inBuffer. */
+uint64_t LLVMSymbolOffsetsEVM(LLVMMemoryBufferRef inBuffer,
path: lld/include/lld-c/LLDAsLibraryC.h
user: login: PavelKopyl
body: Ah, thanks.
created_at: 2025-05-19T00:56:13Z
author_association: CONTRIBUTOR
diff_hunk: @@ -291,6 +290,18 @@ TEST_F(LLDCTest, Assembly) {
       {R_deploy_obj, R_deployed_assemble, A_assembly, A_assembly_deployed},
       {"R_107", "R_107_deployed", "A_38", "A_38.A_38_deployed"});
 
+  // Get linker symbols offsets
+  uint64_t *SymOffsets = nullptr;
+  uint64_t NumOffsets =
+      LLVMSymbolOffsetsEVM(R_assembly, LinkerSymbol[1], &SymOffsets);
+  EXPECT_TRUE(NumOffsets == 3);
+  // These offsets depend on the compiler's optimization level. Since the
path: lld/unittests/EVM/LLDTest.cpp
user: login: hedgar2017
body: OK, I'm just trying to avoid fixing these offsets after every such change. If it's applicable, `EXPECT_TRUE(NumOffsets == 3);` should be enough. I use similar logic on FE.
created_at: 2025-05-19T01:12:57Z
author_association: COLLABORATOR
diff_hunk: @@ -291,6 +290,18 @@ TEST_F(LLDCTest, Assembly) {
       {R_deploy_obj, R_deployed_assemble, A_assembly, A_assembly_deployed},
       {"R_107", "R_107_deployed", "A_38", "A_38.A_38_deployed"});
 
+  // Get linker symbols offsets
+  uint64_t *SymOffsets = nullptr;
+  uint64_t NumOffsets =
+      LLVMSymbolOffsetsEVM(R_assembly, LinkerSymbol[1], &SymOffsets);
+  EXPECT_TRUE(NumOffsets == 3);
+  // These offsets depend on the compiler's optimization level. Since the
path: lld/unittests/EVM/LLDTest.cpp
user: login: PavelKopyl
body: OK, I agree. Removed checking for exact numbers. 
created_at: 2025-05-19T21:10:29Z
author_association: CONTRIBUTOR

PR comments:
user: login: github-actions[bot]
created_at: 2025-05-19T00:13:05Z
body: <!-- add-pr-comment:evm-ir-llvm-EVMInterpreter -->

```
Results for: evm ir-llvm EVMInterpreter
╔═╡ Size (-%) ╞═══════════════════════╡ All E +M3B3 ╞═╗
║ Best                                          0.000 ║
║ Worst                                         0.000 ║
║ Total                                         0.000 ║
╠═╡ Cycles (-%) ╞═════════════════════╡ All E +M3B3 ╞═╣
║ Best                                          0.000 ║
║ Worst                                         0.000 ║
║ Total                                         0.000 ║
╠═╡ Ergs (-%) ╞═══════════════════════╡ All E +M3B3 ╞═╣
║ Best                                          0.000 ║
║ Worst                                         0.000 ║
║ Total                                         0.000 ║
╠══╡ Gas (-%) ╞═══════════════════════╡ All E +M3B3 ╞═╣
║ Best                                          0.000 ║
║ Worst                                         0.000 ║
║ Total                                         0.000 ║
╚═════════════════════════════════════════════════════╝

╔═╡ Size (-%) ╞═══════════════════════╡ All E +MzB3 ╞═╗
║ Best                                          0.000 ║
║ Worst                                         0.000 ║
║ Total                                         0.000 ║
╠═╡ Cycles (-%) ╞═════════════════════╡ All E +MzB3 ╞═╣
║ Best                                          0.000 ║
║ Worst                                         0.000 ║
║ Total                                         0.000 ║
╠═╡ Ergs (-%) ╞═══════════════════════╡ All E +MzB3 ╞═╣
║ Best                                          0.000 ║
║ Worst                                         0.000 ║
║ Total                                         0.000 ║
╠══╡ Gas (-%) ╞═══════════════════════╡ All E +MzB3 ╞═╣
║ Best                                          0.000 ║
║ Worst                                         0.000 ║
║ Total                                         0.000 ║
╚═════════════════════════════════════════════════════╝

╔═╡ Size (-%) ╞═══════════════════════╡ All Y +M3B3 ╞═╗
║ Best                                          0.000 ║
║ Worst                                         0.000 ║
║ Total                                         0.000 ║
╠═╡ Cycles (-%) ╞═════════════════════╡ All Y +M3B3 ╞═╣
║ Best                                          0.000 ║
║ Worst                                         0.000 ║
║ Total                                         0.000 ║
╠═╡ Ergs (-%) ╞═══════════════════════╡ All Y +M3B3 ╞═╣
║ Best                                          0.000 ║
║ Worst                                         0.000 ║
║ Total                                         0.000 ║
╠══╡ Gas (-%) ╞═══════════════════════╡ All Y +M3B3 ╞═╣
║ Best                                          0.000 ║
║ Worst                                         0.000 ║
║ Total                                         0.000 ║
╚═════════════════════════════════════════════════════╝

╔═╡ Size (-%) ╞═══════════════════════╡ All Y +MzB3 ╞═╗
║ Best                                          0.000 ║
║ Worst                                         0.000 ║
║ Total                                         0.000 ║
╠═╡ Cycles (-%) ╞═════════════════════╡ All Y +MzB3 ╞═╣
║ Best                                          0.000 ║
║ Worst                                         0.000 ║
║ Total                                         0.000 ║
╠═╡ Ergs (-%) ╞═══════════════════════╡ All Y +MzB3 ╞═╣
║ Best                                          0.000 ║
║ Worst                                         0.000 ║
║ Total                                         0.000 ║
╠══╡ Gas (-%) ╞═══════════════════════╡ All Y +MzB3 ╞═╣
║ Best                                          0.000 ║
║ Worst                                         0.000 ║
║ Total                                         0.000 ║
╚═════════════════════════════════════════════════════╝

╔═╡ Size (-%) ╞═════════════════╡ Real life E +M3B3 ╞═╗
║ Best                                          0.000 ║
║ Worst                                         0.000 ║
║ Total                                         0.000 ║
╠═╡ Cycles (-%) ╞═══════════════╡ Real life E +M3B3 ╞═╣
║ Best                                          0.000 ║
║ Worst                                         0.000 ║
║ Total                                         0.000 ║
╠═╡ Ergs (-%) ╞═════════════════╡ Real life E +M3B3 ╞═╣
║ Best                                          0.000 ║
║ Worst                                         0.000 ║
║ Total                                         0.000 ║
╠══╡ Gas (-%) ╞═════════════════╡ Real life E +M3B3 ╞═╣
║ Best                                          0.000 ║
║ Worst                                         0.000 ║
║ Total                                         0.000 ║
╚═════════════════════════════════════════════════════╝

╔═╡ Size (-%) ╞═════════════════╡ Real life E +MzB3 ╞═╗
║ Best                                          0.000 ║
║ Worst                                         0.000 ║
║ Total                                         0.000 ║
╠═╡ Cycles (-%) ╞═══════════════╡ Real life E +MzB3 ╞═╣
║ Best                                          0.000 ║
║ Worst                                         0.000 ║
║ Total                                         0.000 ║
╠═╡ Ergs (-%) ╞═════════════════╡ Real life E +MzB3 ╞═╣
║ Best                                          0.000 ║
║ Worst                                         0.000 ║
║ Total                                         0.000 ║
╠══╡ Gas (-%) ╞═════════════════╡ Real life E +MzB3 ╞═╣
║ Best                                          0.000 ║
║ Worst                                         0.000 ║
║ Total                                         0.000 ║
╚═════════════════════════════════════════════════════╝

╔═╡ Size (-%) ╞═════════════════╡ Real life Y +M3B3 ╞═╗
║ Best                                          0.000 ║
║ Worst                                         0.000 ║
║ Total                                         0.000 ║
╠═╡ Cycles (-%) ╞═══════════════╡ Real life Y +M3B3 ╞═╣
║ Best                                          0.000 ║
║ Worst                                         0.000 ║
║ Total                                         0.000 ║
╠═╡ Ergs (-%) ╞═════════════════╡ Real life Y +M3B3 ╞═╣
║ Best                                          0.000 ║
║ Worst                                         0.000 ║
║ Total                                         0.000 ║
╠══╡ Gas (-%) ╞═════════════════╡ Real life Y +M3B3 ╞═╣
║ Best                                          0.000 ║
║ Worst                                         0.000 ║
║ Total                                         0.000 ║
╚═════════════════════════════════════════════════════╝

╔═╡ Size (-%) ╞═════════════════╡ Real life Y +MzB3 ╞═╗
║ Best                                          0.000 ║
║ Worst                                         0.000 ║
║ Total                                         0.000 ║
╠═╡ Cycles (-%) ╞═══════════════╡ Real life Y +MzB3 ╞═╣
║ Best                                          0.000 ║
║ Worst                                         0.000 ║
║ Total                                         0.000 ║
╠═╡ Ergs (-%) ╞═════════════════╡ Real life Y +MzB3 ╞═╣
║ Best                                          0.000 ║
║ Worst                                         0.000 ║
║ Total                                         0.000 ║
╠══╡ Gas (-%) ╞═════════════════╡ Real life Y +MzB3 ╞═╣
║ Best                                          0.000 ║
║ Worst                                         0.000 ║
║ Total                                         0.000 ║
╚═════════════════════════════════════════════════════╝

```

author_association: NONE
user: login: github-actions[bot]
created_at: 2025-05-19T00:53:57Z
body: <!-- add-pr-comment:comparison_links -->

| Target | Mode    | Toolchain | Environment      | Link |
|--------|---------|-----------|------------------|------|
| eravm |  | ir-llvm | zk_evm | [Results](http://llvm-lnt.infra.matterlabs.corp/db_default/v4/zksync/1436?compare_to=808) |
| eravm |  | ir-llvm | zk_evm | [Results](http://llvm-lnt.infra.matterlabs.corp/db_default/v4/zksync/1437?compare_to=1365) |
| eravm |  | ir-llvm | zk_evm | [Results](http://llvm-lnt.infra.matterlabs.corp/db_default/v4/zksync/1438?compare_to=1366) |
| eravm |  | ir-llvm | zk_evm | [Results](http://llvm-lnt.infra.matterlabs.corp/db_default/v4/zksync/1439?compare_to=1367) |
| eravm | E+M3B3_0.8 | ir-llvm | zk_evm | [Results](http://llvm-lnt.infra.matterlabs.corp/db_default/v4/zksync/1440?compare_to=34) |
| eravm |  | ir-llvm | zk_evm | [Results](http://llvm-lnt.infra.matterlabs.corp/db_default/v4/zksync/1441?compare_to=1369) |
| eravm |  | ir-llvm | zk_evm | [Results](http://llvm-lnt.infra.matterlabs.corp/db_default/v4/zksync/1442?compare_to=1370) |
| eravm |  | ir-llvm | zk_evm | [Results](http://llvm-lnt.infra.matterlabs.corp/db_default/v4/zksync/1443?compare_to=1371) |
| eravm |  | ir-llvm | zk_evm | [Results](http://llvm-lnt.infra.matterlabs.corp/db_default/v4/zksync/1444?compare_to=1372) |
| eravm | E+MzB3_0.8 | ir-llvm | zk_evm | [Results](http://llvm-lnt.infra.matterlabs.corp/db_default/v4/zksync/1445?compare_to=35) |
| eravm | Y+M3B3 | ir-llvm | zk_evm | [Results](http://llvm-lnt.infra.matterlabs.corp/db_default/v4/zksync/1446?compare_to=1326) |
| eravm | Y+MzB3 | ir-llvm | zk_evm | [Results](http://llvm-lnt.infra.matterlabs.corp/db_default/v4/zksync/1447?compare_to=1327) |
| evm |  | ir-llvm | EVMInterpreter | [Results](http://llvm-lnt.infra.matterlabs.corp/db_default/v4/zksync/1448?compare_to=1328) |
| evm |  | ir-llvm | REVM | [Results](http://llvm-lnt.infra.matterlabs.corp/db_default/v4/zksync/1449?compare_to=821) |
| evm |  | ir-llvm | EVMInterpreter | [Results](http://llvm-lnt.infra.matterlabs.corp/db_default/v4/zksync/1450?compare_to=822) |
| evm |  | ir-llvm | REVM | [Results](http://llvm-lnt.infra.matterlabs.corp/db_default/v4/zksync/1451?compare_to=823) |
| evm | Y+M3B3 | ir-llvm | EVMInterpreter | [Results](http://llvm-lnt.infra.matterlabs.corp/db_default/v4/zksync/1452?compare_to=38) |
| evm | Y+M3B3 | ir-llvm | REVM | [Results](http://llvm-lnt.infra.matterlabs.corp/db_default/v4/zksync/1453?compare_to=39) |
| evm | Y+MzB3 | ir-llvm | EVMInterpreter | [Results](http://llvm-lnt.infra.matterlabs.corp/db_default/v4/zksync/1454?compare_to=40) |
| evm | Y+MzB3 | ir-llvm | REVM | [Results](http://llvm-lnt.infra.matterlabs.corp/db_default/v4/zksync/1455?compare_to=77) |
| evm | E+_0.8 | solc | EVMInterpreter | [Results](http://llvm-lnt.infra.matterlabs.corp/db_default/v4/zksync/1456?compare_to=204) |
| evm | E+_0.8 | solc | REVM | [Results](http://llvm-lnt.infra.matterlabs.corp/db_default/v4/zksync/1457?compare_to=205) |
| evm | Y+ | solc | EVMInterpreter | [Results](http://llvm-lnt.infra.matterlabs.corp/db_default/v4/zksync/1458?compare_to=42) |
| evm | Y+ | solc | REVM | [Results](http://llvm-lnt.infra.matterlabs.corp/db_default/v4/zksync/1459?compare_to=43) |

author_association: NONE