mirror of
https://github.com/pezkuwichain/revive.git
synced 2026-10-25 05:05:06 +00:00
Apply LLVM patches for deterministic operand order and correct peephole optimization for minsize (#500)
## Description Applies LLVM patches that have not been backported to the major version used in our submodule: * [LLVM PR #163679](https://github.com/llvm/llvm-project/pull/163679) * *"[RISCV] Allow large div peephole optimization for minsize"* * Fixes peephole optimization of large integers when `minsize` function attribute is set. * (Our revive codebase used a workaround that can be removed once this 500 PR is merged and we publish a new LLVM release.) * [LLVM PR #190219](https://github.com/llvm/llvm-project/pull/190219) * *"[TargetLowering] Speculative fix for a non-determinism issue between different compilers"* * Operand ordering of `mul i256` were different depending on the target ABI when building LLVM, producing different RISC-V and PVM bytecode for our Windows vs macOS/linux builds. * The bytecode divergence (yet functionally equivalent) affected Solidity contracts containing a value [multiplied by itself](https://github.com/llvm/llvm-project/issues/190148) (e.g. via explicit squaring or exponentiation), manifesting primarily when using optimization level `-O0`.
This commit is contained in:
9 files changed
+99
-11
No files matched your search
@@ -82,6 +82,8 @@ pub fn build(
|
||||
)
|
||||
}
|
||||
|
||||
utils::apply_patches()?;
|
||||
|
||||
std::fs::create_dir_all(llvm_path::DIRECTORY_LLVM_TARGET.get().unwrap())?;
|
||||
|
||||
if cfg!(target_arch = "x86_64") {
|
||||
|
||||
@@ -20,6 +20,9 @@ impl LLVMPath {
|
||||
/// The Emscripten SDK source directory.
|
||||
pub const DIRECTORY_EMSDK_SOURCE: &'static str = "./emsdk/";
|
||||
|
||||
/// The directory containing patches to apply to the LLVM source.
|
||||
pub const DIRECTORY_PATCHES: &'static str = "./patches/llvm/";
|
||||
|
||||
/// Returns the path to the `llvm` stage 1 host LLVM source module directory.
|
||||
pub fn llvm_host_module_llvm() -> anyhow::Result<PathBuf> {
|
||||
let mut path = PathBuf::from(Self::DIRECTORY_LLVM_HOST_SOURCE);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//! The LLVM builder utilities.
|
||||
|
||||
use std::fs::File;
|
||||
use std::fs::{read_dir, File};
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
use std::process::Command;
|
||||
@@ -10,12 +10,6 @@ use std::time::Duration;
|
||||
use anyhow::Context;
|
||||
use path_slash::PathBufExt;
|
||||
|
||||
/// The LLVM host repository URL.
|
||||
pub const LLVM_HOST_SOURCE_URL: &str = "https://github.com/llvm/llvm-project";
|
||||
|
||||
/// The LLVM host repository tag.
|
||||
pub const LLVM_HOST_SOURCE_TAG: &str = "llvmorg-18.1.8";
|
||||
|
||||
/// The minimum required XCode version.
|
||||
pub const XCODE_MIN_VERSION: u32 = 11;
|
||||
|
||||
@@ -220,6 +214,57 @@ pub fn install_emsdk() -> anyhow::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Applies all LLVM `.patch` files to the LLVM source.
|
||||
///
|
||||
/// Patches that have already been applied are skipped.
|
||||
pub fn apply_patches() -> anyhow::Result<()> {
|
||||
let patches_directory = PathBuf::from(crate::LLVMPath::DIRECTORY_PATCHES);
|
||||
if !patches_directory.exists() {
|
||||
log::debug!("no patches directory found, skipping");
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let llvm_source = PathBuf::from(crate::LLVMPath::DIRECTORY_LLVM_SOURCE);
|
||||
let mut patches: Vec<_> = read_dir(&patches_directory)?
|
||||
.filter_map(|entry| entry.ok())
|
||||
.map(|entry| entry.path())
|
||||
.filter(|path| {
|
||||
path.extension()
|
||||
.is_some_and(|extension| extension == "patch")
|
||||
})
|
||||
.collect();
|
||||
patches.sort();
|
||||
|
||||
for patch in patches {
|
||||
let patch = absolute_path(&patch)?;
|
||||
let already_applied = Command::new("git")
|
||||
.args(["apply", "--reverse", "--check"])
|
||||
.arg(&patch)
|
||||
.current_dir(&llvm_source)
|
||||
.stdout(Stdio::null())
|
||||
.stderr(Stdio::null())
|
||||
.status()
|
||||
.map(|status| status.success())
|
||||
.unwrap_or(false);
|
||||
|
||||
if already_applied {
|
||||
log::info!("patch already applied, skipping: {}", patch.display());
|
||||
continue;
|
||||
}
|
||||
|
||||
log::info!("applying patch: {}", patch.display());
|
||||
command(
|
||||
Command::new("git")
|
||||
.args(["apply"])
|
||||
.arg(&patch)
|
||||
.current_dir(&llvm_source),
|
||||
&format!("applying patch {}", patch.display()),
|
||||
)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// The LLVM target directory default path.
|
||||
pub fn directory_target_llvm(target_env: crate::target_env::TargetEnv) -> PathBuf {
|
||||
crate::llvm_path::DIRECTORY_LLVM_TARGET
|
||||
|
||||
Reference in new issue
Block a user