Support solc v0.8.31 (#430)

- Support for solc v0.8.31.
- Support for the `clz` Yul builtin.

---------

Signed-off-by: xermicus <cyrill@parity.io>
This commit is contained in:
xermicus
2025-12-05 15:25:13 +01:00
committed by GitHub
parent d0c10e6d5c
commit 11f82c8488
16 changed files with 142 additions and 11 deletions
@@ -14,6 +14,8 @@ pub struct Intrinsics<'ctx> {
pub byte_swap_word: FunctionDeclaration<'ctx>,
/// Performs endianness swaps on i160 values
pub byte_swap_eth_address: FunctionDeclaration<'ctx>,
/// Counts leading zeroes.
pub count_leading_zeros: FunctionDeclaration<'ctx>,
}
impl<'ctx> Intrinsics<'ctx> {
@@ -26,6 +28,9 @@ impl<'ctx> Intrinsics<'ctx> {
/// The corresponding intrinsic function name.
pub const FUNCTION_BYTE_SWAP_ETH_ADDRESS: &'static str = "llvm.bswap.i160";
/// The corresponding intrinsic function name.
pub const FUNCTION_COUNT_LEADING_ZEROS: &'static str = "llvm.ctlz.i256";
/// A shortcut constructor.
pub fn new(
llvm: &'ctx inkwell::context::Context,
@@ -53,11 +58,18 @@ impl<'ctx> Intrinsics<'ctx> {
Self::FUNCTION_BYTE_SWAP_ETH_ADDRESS,
address_type.fn_type(&[address_type.as_basic_type_enum().into()], false),
);
let count_leading_zeros = Self::declare(
llvm,
module,
Self::FUNCTION_COUNT_LEADING_ZEROS,
word_type.fn_type(&[word_type.into(), llvm.bool_type().into()], false),
);
Self {
trap,
byte_swap_word,
byte_swap_eth_address,
count_leading_zeros,
}
}
@@ -85,12 +97,15 @@ impl<'ctx> Intrinsics<'ctx> {
let word_type = llvm.custom_width_int_type(revive_common::BIT_LENGTH_WORD as u32);
match name {
name if name == Self::FUNCTION_BYTE_SWAP_WORD => vec![word_type.as_basic_type_enum()],
name if name == Self::FUNCTION_BYTE_SWAP_ETH_ADDRESS => {
_ if name == Self::FUNCTION_BYTE_SWAP_WORD => vec![word_type.as_basic_type_enum()],
_ if name == Self::FUNCTION_BYTE_SWAP_ETH_ADDRESS => {
vec![llvm
.custom_width_int_type(revive_common::BIT_LENGTH_ETH_ADDRESS as u32)
.as_basic_type_enum()]
}
_ if name == Self::FUNCTION_COUNT_LEADING_ZEROS => {
vec![word_type.as_basic_type_enum()]
}
_ => vec![],
}
}
@@ -261,3 +261,20 @@ pub fn byte<'ctx>(
Ok(byte.as_basic_value_enum())
}
/// Translates the CLZ instruction.
pub fn count_leading_zeros<'ctx>(
context: &mut Context<'ctx>,
value: inkwell::values::IntValue<'ctx>,
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>> {
Ok(context
.builder()
.build_call(
context.intrinsics().count_leading_zeros.function_value(),
&[value.into(), context.bool_const(false).into()],
"clz",
)?
.try_as_basic_value()
.left()
.expect("the llvm.ctlz should return a value"))
}