From c87d4f351f08e8a9c65a6076bc632b0161cae3f9 Mon Sep 17 00:00:00 2001 From: Mark Koch <48097969+mark-koch@users.noreply.github.com> Date: Wed, 27 Nov 2024 15:21:50 +0000 Subject: [PATCH] feat: Lower collections extension (#1720) Closes #1701 and fixes #1645. Note that destructors and ref-counting hooks are still missing. These will follow in a future PR once they are available in hugr-llvm. --- hugr-core/src/std_extensions/collections.rs | 10 + hugr-llvm/src/emit/func.rs | 36 +- hugr-llvm/src/emit/test.rs | 3 +- hugr-llvm/src/extension.rs | 1 + hugr-llvm/src/extension/collections.rs | 445 ++++++++++++++++++ ...sion__collections__test__const@llvm14.snap | 31 ++ ...tions__test__const@pre-mem2reg@llvm14.snap | 37 ++ ...ension__collections__test__get@llvm14.snap | 24 + ...ections__test__get@pre-mem2reg@llvm14.snap | 36 ++ ...ion__collections__test__insert@llvm14.snap | 25 + ...ions__test__insert@pre-mem2reg@llvm14.snap | 46 ++ ...ion__collections__test__length@llvm14.snap | 19 + ...ions__test__length@pre-mem2reg@llvm14.snap | 34 ++ ...ension__collections__test__pop@llvm14.snap | 26 + ...ections__test__pop@pre-mem2reg@llvm14.snap | 41 ++ ...nsion__collections__test__push@llvm14.snap | 20 + ...ctions__test__push@pre-mem2reg@llvm14.snap | 32 ++ ...ension__collections__test__set@llvm14.snap | 29 ++ ...ections__test__set@pre-mem2reg@llvm14.snap | 50 ++ 19 files changed, 943 insertions(+), 2 deletions(-) create mode 100644 hugr-llvm/src/extension/collections.rs create mode 100644 hugr-llvm/src/extension/snapshots/hugr_llvm__extension__collections__test__const@llvm14.snap create mode 100644 hugr-llvm/src/extension/snapshots/hugr_llvm__extension__collections__test__const@pre-mem2reg@llvm14.snap create mode 100644 hugr-llvm/src/extension/snapshots/hugr_llvm__extension__collections__test__get@llvm14.snap create mode 100644 hugr-llvm/src/extension/snapshots/hugr_llvm__extension__collections__test__get@pre-mem2reg@llvm14.snap create mode 100644 hugr-llvm/src/extension/snapshots/hugr_llvm__extension__collections__test__insert@llvm14.snap create mode 100644 hugr-llvm/src/extension/snapshots/hugr_llvm__extension__collections__test__insert@pre-mem2reg@llvm14.snap create mode 100644 hugr-llvm/src/extension/snapshots/hugr_llvm__extension__collections__test__length@llvm14.snap create mode 100644 hugr-llvm/src/extension/snapshots/hugr_llvm__extension__collections__test__length@pre-mem2reg@llvm14.snap create mode 100644 hugr-llvm/src/extension/snapshots/hugr_llvm__extension__collections__test__pop@llvm14.snap create mode 100644 hugr-llvm/src/extension/snapshots/hugr_llvm__extension__collections__test__pop@pre-mem2reg@llvm14.snap create mode 100644 hugr-llvm/src/extension/snapshots/hugr_llvm__extension__collections__test__push@llvm14.snap create mode 100644 hugr-llvm/src/extension/snapshots/hugr_llvm__extension__collections__test__push@pre-mem2reg@llvm14.snap create mode 100644 hugr-llvm/src/extension/snapshots/hugr_llvm__extension__collections__test__set@llvm14.snap create mode 100644 hugr-llvm/src/extension/snapshots/hugr_llvm__extension__collections__test__set@pre-mem2reg@llvm14.snap diff --git a/hugr-core/src/std_extensions/collections.rs b/hugr-core/src/std_extensions/collections.rs index 2f416c92b..6a82da334 100644 --- a/hugr-core/src/std_extensions/collections.rs +++ b/hugr-core/src/std_extensions/collections.rs @@ -59,6 +59,16 @@ impl ListValue { pub fn custom_type(&self) -> CustomType { list_custom_type(self.1.clone()) } + + /// Returns the type of values inside the `[ListValue]`. + pub fn get_element_type(&self) -> &Type { + &self.1 + } + + /// Returns the values contained inside the `[ListValue]`. + pub fn get_contents(&self) -> &[Value] { + &self.0 + } } impl TryHash for ListValue { diff --git a/hugr-llvm/src/emit/func.rs b/hugr-llvm/src/emit/func.rs index e9d861337..0a09dc9b3 100644 --- a/hugr-llvm/src/emit/func.rs +++ b/hugr-llvm/src/emit/func.rs @@ -2,6 +2,7 @@ use std::{collections::HashMap, rc::Rc}; use anyhow::{anyhow, Result}; use hugr_core::{ + extension::prelude::{either_type, option_type}, ops::{constant::CustomConst, ExtensionOp, FuncDecl, FuncDefn}, types::Type, HugrView, NodeIndex, PortIndex, Wire, @@ -12,7 +13,7 @@ use inkwell::{ context::Context, module::Module, types::{BasicType, BasicTypeEnum, FunctionType}, - values::{BasicValueEnum, FunctionValue, GlobalValue}, + values::{BasicValueEnum, FunctionValue, GlobalValue, IntValue}, }; use itertools::zip_eq; @@ -314,3 +315,36 @@ impl<'c, 'a, H: HugrView> EmitFuncContext<'c, 'a, H> { Ok((self.emit_context, self.todo)) } } + +/// Builds an optional value wrapping `some_value` conditioned on the provided `is_some` flag. +pub fn build_option<'c, H: HugrView>( + ctx: &mut EmitFuncContext<'c, '_, H>, + is_some: IntValue<'c>, + some_value: BasicValueEnum<'c>, + hugr_ty: HugrType, +) -> Result> { + let option_ty = ctx.llvm_sum_type(option_type(hugr_ty))?; + let builder = ctx.builder(); + let some = option_ty.build_tag(builder, 1, vec![some_value])?; + let none = option_ty.build_tag(builder, 0, vec![])?; + let option = builder.build_select(is_some, some, none, "")?; + Ok(option) +} + +/// Builds a result value wrapping either `ok_value` or `else_value` depending on the provided +/// `is_ok` flag. +pub fn build_ok_or_else<'c, H: HugrView>( + ctx: &mut EmitFuncContext<'c, '_, H>, + is_ok: IntValue<'c>, + ok_value: BasicValueEnum<'c>, + ok_hugr_ty: HugrType, + else_value: BasicValueEnum<'c>, + else_hugr_ty: HugrType, +) -> Result> { + let either_ty = ctx.llvm_sum_type(either_type(else_hugr_ty, ok_hugr_ty))?; + let builder = ctx.builder(); + let left = either_ty.build_tag(builder, 0, vec![else_value])?; + let right = either_ty.build_tag(builder, 1, vec![ok_value])?; + let either = builder.build_select(is_ok, right, left, "")?; + Ok(either) +} diff --git a/hugr-llvm/src/emit/test.rs b/hugr-llvm/src/emit/test.rs index 647636c95..632224946 100644 --- a/hugr-llvm/src/emit/test.rs +++ b/hugr-llvm/src/emit/test.rs @@ -10,7 +10,7 @@ use hugr_core::ops::handle::FuncID; use hugr_core::std_extensions::arithmetic::{ conversions, float_ops, float_types, int_ops, int_types, }; -use hugr_core::std_extensions::logic; +use hugr_core::std_extensions::{collections, logic}; use hugr_core::types::TypeRow; use hugr_core::{Hugr, HugrView}; use inkwell::module::Module; @@ -153,6 +153,7 @@ impl SimpleHugrConfig { float_ops::EXTENSION_ID, conversions::EXTENSION_ID, logic::EXTENSION_ID, + collections::EXTENSION_ID, ]), ), ) diff --git a/hugr-llvm/src/extension.rs b/hugr-llvm/src/extension.rs index fe6db7ed5..4757926b3 100644 --- a/hugr-llvm/src/extension.rs +++ b/hugr-llvm/src/extension.rs @@ -1,3 +1,4 @@ +pub mod collections; pub mod conversions; pub mod float; pub mod int; diff --git a/hugr-llvm/src/extension/collections.rs b/hugr-llvm/src/extension/collections.rs new file mode 100644 index 000000000..2b8e9011a --- /dev/null +++ b/hugr-llvm/src/extension/collections.rs @@ -0,0 +1,445 @@ +use anyhow::{bail, Ok, Result}; +use hugr_core::{ + ops::{ExtensionOp, NamedOp}, + std_extensions::collections::{self, ListOp, ListValue}, + types::{SumType, Type, TypeArg}, + HugrView, +}; +use inkwell::values::FunctionValue; +use inkwell::{ + types::{BasicType, BasicTypeEnum, FunctionType}, + values::{BasicValueEnum, PointerValue}, + AddressSpace, +}; + +use crate::emit::func::{build_ok_or_else, build_option}; +use crate::{ + custom::{CodegenExtension, CodegenExtsBuilder}, + emit::{emit_value, func::EmitFuncContext, EmitOpArgs}, + types::TypingSession, +}; + +/// Runtime functions that implement operations on lists. +#[derive(Clone, Copy, Debug, PartialEq, Hash)] +#[non_exhaustive] +pub enum CollectionsRtFunc { + New, + Push, + Pop, + Get, + Set, + Insert, + Length, +} + +impl CollectionsRtFunc { + /// The signature of a given [CollectionsRtFunc]. + /// + /// Requires a [CollectionsCodegen] to determine the type of lists. + pub fn signature<'c>( + self, + ts: TypingSession<'c, '_>, + ccg: &(impl CollectionsCodegen + 'c), + ) -> FunctionType<'c> { + let iwc = ts.iw_context(); + match self { + CollectionsRtFunc::New => ccg.list_type(ts).fn_type( + &[ + iwc.i64_type().into(), // Capacity + iwc.i64_type().into(), // Single element size in bytes + iwc.i64_type().into(), // Element alignment + // Pointer to element destructor + iwc.i8_type().ptr_type(AddressSpace::default()).into(), + ], + false, + ), + CollectionsRtFunc::Push => iwc.void_type().fn_type( + &[ + ccg.list_type(ts).into(), + iwc.i8_type().ptr_type(AddressSpace::default()).into(), + ], + false, + ), + CollectionsRtFunc::Pop => iwc.bool_type().fn_type( + &[ + ccg.list_type(ts).into(), + iwc.i8_type().ptr_type(AddressSpace::default()).into(), + ], + false, + ), + CollectionsRtFunc::Get | CollectionsRtFunc::Set | CollectionsRtFunc::Insert => { + iwc.bool_type().fn_type( + &[ + ccg.list_type(ts).into(), + iwc.i64_type().into(), + iwc.i8_type().ptr_type(AddressSpace::default()).into(), + ], + false, + ) + } + CollectionsRtFunc::Length => iwc.i64_type().fn_type(&[ccg.list_type(ts).into()], false), + } + } + + /// Returns the extern function corresponding to this [CollectionsRtFunc]. + /// + /// Requires a [CollectionsCodegen] to determine the function signature. + pub fn get_extern<'c, H: HugrView>( + self, + ctx: &EmitFuncContext<'c, '_, H>, + ccg: &(impl CollectionsCodegen + 'c), + ) -> Result> { + ctx.get_extern_func( + ccg.rt_func_name(self), + self.signature(ctx.typing_session(), ccg), + ) + } +} + +impl From for CollectionsRtFunc { + fn from(op: ListOp) -> Self { + match op { + ListOp::get => CollectionsRtFunc::Get, + ListOp::set => CollectionsRtFunc::Set, + ListOp::push => CollectionsRtFunc::Push, + ListOp::pop => CollectionsRtFunc::Pop, + ListOp::insert => CollectionsRtFunc::Insert, + ListOp::length => CollectionsRtFunc::Length, + _ => todo!(), + } + } +} + +/// A helper trait for customising the lowering of [hugr_core::std_extensions::collections] +/// types, [hugr_core::ops::constant::CustomConst]s, and ops. +pub trait CollectionsCodegen: Clone { + /// Return the llvm type of [hugr_core::std_extensions::collections::LIST_TYPENAME]. + fn list_type<'c>(&self, session: TypingSession<'c, '_>) -> BasicTypeEnum<'c> { + session + .iw_context() + .i8_type() + .ptr_type(AddressSpace::default()) + .into() + } + + /// Return the name of a given [CollectionsRtFunc]. + fn rt_func_name(&self, func: CollectionsRtFunc) -> String { + match func { + CollectionsRtFunc::New => "__rt__list__new", + CollectionsRtFunc::Push => "__rt__list__push", + CollectionsRtFunc::Pop => "__rt__list__pop", + CollectionsRtFunc::Get => "__rt__list__get", + CollectionsRtFunc::Set => "__rt__list__set", + CollectionsRtFunc::Insert => "__rt__list__insert", + CollectionsRtFunc::Length => "__rt__list__length", + } + .into() + } +} + +/// A trivial implementation of [CollectionsCodegen] which passes all methods +/// through to their default implementations. +#[derive(Default, Clone)] +pub struct DefaultCollectionsCodegen; + +impl CollectionsCodegen for DefaultCollectionsCodegen {} + +#[derive(Clone, Debug, Default)] +pub struct CollectionsCodegenExtension(CCG); + +impl CollectionsCodegenExtension { + pub fn new(ccg: CCG) -> Self { + Self(ccg) + } +} + +impl From for CollectionsCodegenExtension { + fn from(ccg: CCG) -> Self { + Self::new(ccg) + } +} + +impl CodegenExtension for CollectionsCodegenExtension { + fn add_extension<'a, H: HugrView + 'a>( + self, + builder: CodegenExtsBuilder<'a, H>, + ) -> CodegenExtsBuilder<'a, H> + where + Self: 'a, + { + builder + .custom_type((collections::EXTENSION_ID, collections::LIST_TYPENAME), { + let ccg = self.0.clone(); + move |ts, _hugr_type| Ok(ccg.list_type(ts).as_basic_type_enum()) + }) + .custom_const::({ + let ccg = self.0.clone(); + move |ctx, k| emit_list_value(ctx, &ccg, k) + }) + .simple_extension_op::(move |ctx, args, op| { + emit_list_op(ctx, &self.0, args, op) + }) + } +} + +impl<'a, H: HugrView + 'a> CodegenExtsBuilder<'a, H> { + /// Add a [CollectionsCodegenExtension] to the given [CodegenExtsBuilder] using `ccg` + /// as the implementation. + pub fn add_default_collections_extensions(self) -> Self { + self.add_collections_extensions(DefaultCollectionsCodegen) + } + + /// Add a [CollectionsCodegenExtension] to the given [CodegenExtsBuilder] using + /// [DefaultCollectionsCodegen] as the implementation. + pub fn add_collections_extensions(self, ccg: impl CollectionsCodegen + 'a) -> Self { + self.add_extension(CollectionsCodegenExtension::from(ccg)) + } +} + +fn emit_list_op<'c, H: HugrView>( + ctx: &mut EmitFuncContext<'c, '_, H>, + ccg: &(impl CollectionsCodegen + 'c), + args: EmitOpArgs<'c, '_, ExtensionOp, H>, + op: ListOp, +) -> Result<()> { + let hugr_elem_ty = match args.node().args() { + [TypeArg::Type { ty }] => ty.clone(), + _ => { + bail!("Collections: invalid type args for list op"); + } + }; + let elem_ty = ctx.llvm_type(&hugr_elem_ty)?; + let func = CollectionsRtFunc::get_extern(op.into(), ctx, ccg)?; + match op { + ListOp::push => { + let [list, elem] = args.inputs.try_into().unwrap(); + let elem_ptr = build_alloca_i8_ptr(ctx, elem_ty, Some(elem))?; + ctx.builder() + .build_call(func, &[list.into(), elem_ptr.into()], "")?; + args.outputs.finish(ctx.builder(), vec![list])?; + } + ListOp::pop => { + let [list] = args.inputs.try_into().unwrap(); + let out_ptr = build_alloca_i8_ptr(ctx, elem_ty, None)?; + let ok = ctx + .builder() + .build_call(func, &[list.into(), out_ptr.into()], "")? + .try_as_basic_value() + .unwrap_left() + .into_int_value(); + let elem = build_load_i8_ptr(ctx, out_ptr, elem_ty)?; + let elem_opt = build_option(ctx, ok, elem, hugr_elem_ty)?; + args.outputs.finish(ctx.builder(), vec![list, elem_opt])?; + } + ListOp::get => { + let [list, idx] = args.inputs.try_into().unwrap(); + let out_ptr = build_alloca_i8_ptr(ctx, elem_ty, None)?; + let ok = ctx + .builder() + .build_call(func, &[list.into(), idx.into(), out_ptr.into()], "")? + .try_as_basic_value() + .unwrap_left() + .into_int_value(); + let elem = build_load_i8_ptr(ctx, out_ptr, elem_ty)?; + let elem_opt = build_option(ctx, ok, elem, hugr_elem_ty)?; + args.outputs.finish(ctx.builder(), vec![elem_opt])?; + } + ListOp::set => { + let [list, idx, elem] = args.inputs.try_into().unwrap(); + let elem_ptr = build_alloca_i8_ptr(ctx, elem_ty, Some(elem))?; + let ok = ctx + .builder() + .build_call(func, &[list.into(), idx.into(), elem_ptr.into()], "")? + .try_as_basic_value() + .unwrap_left() + .into_int_value(); + let old_elem = build_load_i8_ptr(ctx, elem_ptr, elem.get_type())?; + let ok_or = + build_ok_or_else(ctx, ok, elem, hugr_elem_ty.clone(), old_elem, hugr_elem_ty)?; + args.outputs.finish(ctx.builder(), vec![list, ok_or])?; + } + ListOp::insert => { + let [list, idx, elem] = args.inputs.try_into().unwrap(); + let elem_ptr = build_alloca_i8_ptr(ctx, elem_ty, Some(elem))?; + let ok = ctx + .builder() + .build_call(func, &[list.into(), idx.into(), elem_ptr.into()], "")? + .try_as_basic_value() + .unwrap_left() + .into_int_value(); + let unit = + ctx.llvm_sum_type(SumType::new_unary(1))? + .build_tag(ctx.builder(), 0, vec![])?; + let ok_or = build_ok_or_else(ctx, ok, unit, Type::UNIT, elem, hugr_elem_ty)?; + args.outputs.finish(ctx.builder(), vec![list, ok_or])?; + } + ListOp::length => { + let [list] = args.inputs.try_into().unwrap(); + let length = ctx + .builder() + .build_call(func, &[list.into()], "")? + .try_as_basic_value() + .unwrap_left() + .into_int_value(); + args.outputs + .finish(ctx.builder(), vec![list, length.into()])?; + } + _ => bail!("Collections: unimplemented op: {}", op.name()), + } + Ok(()) +} + +fn emit_list_value<'c, H: HugrView>( + ctx: &mut EmitFuncContext<'c, '_, H>, + ccg: &(impl CollectionsCodegen + 'c), + val: &ListValue, +) -> Result> { + let elem_ty = ctx.llvm_type(val.get_element_type())?; + let iwc = ctx.typing_session().iw_context(); + let capacity = iwc + .i64_type() + .const_int(val.get_contents().len() as u64, false); + let elem_size = elem_ty.size_of().unwrap(); + let alignment = iwc.i64_type().const_int(8, false); + // TODO: Lookup destructor for elem_ty + let destructor = iwc.i8_type().ptr_type(AddressSpace::default()).const_null(); + let list = ctx + .builder() + .build_call( + CollectionsRtFunc::New.get_extern(ctx, ccg)?, + &[ + capacity.into(), + elem_size.into(), + alignment.into(), + destructor.into(), + ], + "", + )? + .try_as_basic_value() + .unwrap_left(); + // Push elements onto the list + let rt_push = CollectionsRtFunc::Push.get_extern(ctx, ccg)?; + for v in val.get_contents() { + let elem = emit_value(ctx, v)?; + let elem_ptr = build_alloca_i8_ptr(ctx, elem_ty, Some(elem))?; + ctx.builder() + .build_call(rt_push, &[list.into(), elem_ptr.into()], "")?; + } + Ok(list) +} + +/// Helper function to allocate space on the stack for a given type. +/// +/// Optionally also stores a value at that location. +/// +/// Returns an i8 pointer to the allocated memory. +fn build_alloca_i8_ptr<'c, H: HugrView>( + ctx: &mut EmitFuncContext<'c, '_, H>, + ty: BasicTypeEnum<'c>, + value: Option>, +) -> Result> { + let builder = ctx.builder(); + let ptr = builder.build_alloca(ty, "")?; + if let Some(val) = value { + builder.build_store(ptr, val)?; + } + let i8_ptr = builder.build_pointer_cast( + ptr, + ctx.iw_context().i8_type().ptr_type(AddressSpace::default()), + "", + )?; + Ok(i8_ptr) +} + +/// Helper function to load a value from an i8 pointer. +fn build_load_i8_ptr<'c, H: HugrView>( + ctx: &mut EmitFuncContext<'c, '_, H>, + i8_ptr: PointerValue<'c>, + ty: BasicTypeEnum<'c>, +) -> Result> { + let builder = ctx.builder(); + let ptr = builder.build_pointer_cast(i8_ptr, ty.ptr_type(AddressSpace::default()), "")?; + let val = builder.build_load(ptr, "")?; + Ok(val) +} + +#[cfg(test)] +mod test { + use hugr_core::{ + builder::{Dataflow, DataflowSubContainer}, + extension::{ + prelude::{self, ConstUsize, QB_T, USIZE_T}, + ExtensionRegistry, + }, + ops::{DataflowOpTrait, NamedOp, Value}, + std_extensions::collections::{self, list_type, ListOp, ListValue}, + }; + use rstest::rstest; + + use crate::{ + check_emission, + custom::CodegenExtsBuilder, + emit::test::SimpleHugrConfig, + test::{llvm_ctx, TestContext}, + }; + + #[rstest] + #[case::push(ListOp::push)] + #[case::pop(ListOp::pop)] + #[case::get(ListOp::get)] + #[case::set(ListOp::set)] + #[case::insert(ListOp::insert)] + #[case::length(ListOp::length)] + fn test_collections_emission(mut llvm_ctx: TestContext, #[case] op: ListOp) { + let ext_op = collections::EXTENSION + .instantiate_extension_op( + op.name().as_ref(), + [QB_T.into()], + &collections::COLLECTIONS_REGISTRY, + ) + .unwrap(); + let es = ExtensionRegistry::try_new([ + collections::EXTENSION.to_owned(), + prelude::PRELUDE.to_owned(), + ]) + .unwrap(); + let hugr = SimpleHugrConfig::new() + .with_ins(ext_op.signature().input().clone()) + .with_outs(ext_op.signature().output().clone()) + .with_extensions(es) + .finish(|mut hugr_builder| { + let outputs = hugr_builder + .add_dataflow_op(ext_op, hugr_builder.input_wires()) + .unwrap() + .outputs(); + hugr_builder.finish_with_outputs(outputs).unwrap() + }); + llvm_ctx.add_extensions(CodegenExtsBuilder::add_default_prelude_extensions); + llvm_ctx.add_extensions(CodegenExtsBuilder::add_default_collections_extensions); + check_emission!(op.name().as_str(), hugr, llvm_ctx); + } + + #[rstest] + fn test_const_list_emmission(mut llvm_ctx: TestContext) { + let elem_ty = USIZE_T; + let contents = (1..4).map(|i| Value::extension(ConstUsize::new(i))); + let es = ExtensionRegistry::try_new([ + collections::EXTENSION.to_owned(), + prelude::PRELUDE.to_owned(), + ]) + .unwrap(); + + let hugr = SimpleHugrConfig::new() + .with_ins(vec![]) + .with_outs(vec![list_type(elem_ty.clone())]) + .with_extensions(es) + .finish(|mut hugr_builder| { + let list = hugr_builder.add_load_value(ListValue::new(elem_ty, contents)); + hugr_builder.finish_with_outputs(vec![list]).unwrap() + }); + + llvm_ctx.add_extensions(CodegenExtsBuilder::add_default_prelude_extensions); + llvm_ctx.add_extensions(CodegenExtsBuilder::add_default_collections_extensions); + check_emission!("const", hugr, llvm_ctx); + } +} diff --git a/hugr-llvm/src/extension/snapshots/hugr_llvm__extension__collections__test__const@llvm14.snap b/hugr-llvm/src/extension/snapshots/hugr_llvm__extension__collections__test__const@llvm14.snap new file mode 100644 index 000000000..8ad058cf3 --- /dev/null +++ b/hugr-llvm/src/extension/snapshots/hugr_llvm__extension__collections__test__const@llvm14.snap @@ -0,0 +1,31 @@ +--- +source: hugr-llvm/src/extension/collections.rs +expression: mod_str +--- +; ModuleID = 'test_context' +source_filename = "test_context" + +define i8* @_hl.main.1() { +alloca_block: + br label %entry_block + +entry_block: ; preds = %alloca_block + %0 = call i8* @__rt__list__new(i64 3, i64 ptrtoint (i64* getelementptr (i64, i64* null, i32 1) to i64), i64 8, i8* null) + %1 = alloca i64, align 8 + store i64 1, i64* %1, align 4 + %2 = bitcast i64* %1 to i8* + call void @__rt__list__push(i8* %0, i8* %2) + %3 = alloca i64, align 8 + store i64 2, i64* %3, align 4 + %4 = bitcast i64* %3 to i8* + call void @__rt__list__push(i8* %0, i8* %4) + %5 = alloca i64, align 8 + store i64 3, i64* %5, align 4 + %6 = bitcast i64* %5 to i8* + call void @__rt__list__push(i8* %0, i8* %6) + ret i8* %0 +} + +declare i8* @__rt__list__new(i64, i64, i64, i8*) + +declare void @__rt__list__push(i8*, i8*) diff --git a/hugr-llvm/src/extension/snapshots/hugr_llvm__extension__collections__test__const@pre-mem2reg@llvm14.snap b/hugr-llvm/src/extension/snapshots/hugr_llvm__extension__collections__test__const@pre-mem2reg@llvm14.snap new file mode 100644 index 000000000..5522be9ad --- /dev/null +++ b/hugr-llvm/src/extension/snapshots/hugr_llvm__extension__collections__test__const@pre-mem2reg@llvm14.snap @@ -0,0 +1,37 @@ +--- +source: hugr-llvm/src/extension/collections.rs +expression: mod_str +--- +; ModuleID = 'test_context' +source_filename = "test_context" + +define i8* @_hl.main.1() { +alloca_block: + %"0" = alloca i8*, align 8 + %"5_0" = alloca i8*, align 8 + br label %entry_block + +entry_block: ; preds = %alloca_block + %0 = call i8* @__rt__list__new(i64 3, i64 ptrtoint (i64* getelementptr (i64, i64* null, i32 1) to i64), i64 8, i8* null) + %1 = alloca i64, align 8 + store i64 1, i64* %1, align 4 + %2 = bitcast i64* %1 to i8* + call void @__rt__list__push(i8* %0, i8* %2) + %3 = alloca i64, align 8 + store i64 2, i64* %3, align 4 + %4 = bitcast i64* %3 to i8* + call void @__rt__list__push(i8* %0, i8* %4) + %5 = alloca i64, align 8 + store i64 3, i64* %5, align 4 + %6 = bitcast i64* %5 to i8* + call void @__rt__list__push(i8* %0, i8* %6) + store i8* %0, i8** %"5_0", align 8 + %"5_01" = load i8*, i8** %"5_0", align 8 + store i8* %"5_01", i8** %"0", align 8 + %"02" = load i8*, i8** %"0", align 8 + ret i8* %"02" +} + +declare i8* @__rt__list__new(i64, i64, i64, i8*) + +declare void @__rt__list__push(i8*, i8*) diff --git a/hugr-llvm/src/extension/snapshots/hugr_llvm__extension__collections__test__get@llvm14.snap b/hugr-llvm/src/extension/snapshots/hugr_llvm__extension__collections__test__get@llvm14.snap new file mode 100644 index 000000000..5d7d0d381 --- /dev/null +++ b/hugr-llvm/src/extension/snapshots/hugr_llvm__extension__collections__test__get@llvm14.snap @@ -0,0 +1,24 @@ +--- +source: hugr-llvm/src/extension/collections.rs +expression: mod_str +--- +; ModuleID = 'test_context' +source_filename = "test_context" + +define { i32, {}, { i16 } } @_hl.main.1(i8* %0, i64 %1) { +alloca_block: + br label %entry_block + +entry_block: ; preds = %alloca_block + %2 = alloca i16, align 2 + %3 = bitcast i16* %2 to i8* + %4 = call i1 @__rt__list__get(i8* %0, i64 %1, i8* %3) + %5 = bitcast i8* %3 to i16* + %6 = load i16, i16* %5, align 2 + %7 = insertvalue { i16 } undef, i16 %6, 0 + %8 = insertvalue { i32, {}, { i16 } } { i32 1, {} poison, { i16 } poison }, { i16 } %7, 2 + %9 = select i1 %4, { i32, {}, { i16 } } %8, { i32, {}, { i16 } } { i32 0, {} undef, { i16 } poison } + ret { i32, {}, { i16 } } %9 +} + +declare i1 @__rt__list__get(i8*, i64, i8*) diff --git a/hugr-llvm/src/extension/snapshots/hugr_llvm__extension__collections__test__get@pre-mem2reg@llvm14.snap b/hugr-llvm/src/extension/snapshots/hugr_llvm__extension__collections__test__get@pre-mem2reg@llvm14.snap new file mode 100644 index 000000000..a7eee4d03 --- /dev/null +++ b/hugr-llvm/src/extension/snapshots/hugr_llvm__extension__collections__test__get@pre-mem2reg@llvm14.snap @@ -0,0 +1,36 @@ +--- +source: hugr-llvm/src/extension/collections.rs +expression: mod_str +--- +; ModuleID = 'test_context' +source_filename = "test_context" + +define { i32, {}, { i16 } } @_hl.main.1(i8* %0, i64 %1) { +alloca_block: + %"0" = alloca { i32, {}, { i16 } }, align 8 + %"2_0" = alloca i8*, align 8 + %"2_1" = alloca i64, align 8 + %"4_0" = alloca { i32, {}, { i16 } }, align 8 + br label %entry_block + +entry_block: ; preds = %alloca_block + store i8* %0, i8** %"2_0", align 8 + store i64 %1, i64* %"2_1", align 4 + %"2_01" = load i8*, i8** %"2_0", align 8 + %"2_12" = load i64, i64* %"2_1", align 4 + %2 = alloca i16, align 2 + %3 = bitcast i16* %2 to i8* + %4 = call i1 @__rt__list__get(i8* %"2_01", i64 %"2_12", i8* %3) + %5 = bitcast i8* %3 to i16* + %6 = load i16, i16* %5, align 2 + %7 = insertvalue { i16 } undef, i16 %6, 0 + %8 = insertvalue { i32, {}, { i16 } } { i32 1, {} poison, { i16 } poison }, { i16 } %7, 2 + %9 = select i1 %4, { i32, {}, { i16 } } %8, { i32, {}, { i16 } } { i32 0, {} undef, { i16 } poison } + store { i32, {}, { i16 } } %9, { i32, {}, { i16 } }* %"4_0", align 4 + %"4_03" = load { i32, {}, { i16 } }, { i32, {}, { i16 } }* %"4_0", align 4 + store { i32, {}, { i16 } } %"4_03", { i32, {}, { i16 } }* %"0", align 4 + %"04" = load { i32, {}, { i16 } }, { i32, {}, { i16 } }* %"0", align 4 + ret { i32, {}, { i16 } } %"04" +} + +declare i1 @__rt__list__get(i8*, i64, i8*) diff --git a/hugr-llvm/src/extension/snapshots/hugr_llvm__extension__collections__test__insert@llvm14.snap b/hugr-llvm/src/extension/snapshots/hugr_llvm__extension__collections__test__insert@llvm14.snap new file mode 100644 index 000000000..deb84f1b5 --- /dev/null +++ b/hugr-llvm/src/extension/snapshots/hugr_llvm__extension__collections__test__insert@llvm14.snap @@ -0,0 +1,25 @@ +--- +source: hugr-llvm/src/extension/collections.rs +expression: mod_str +--- +; ModuleID = 'test_context' +source_filename = "test_context" + +define { i8*, { i32, { i16 }, { { {} } } } } @_hl.main.1(i8* %0, i64 %1, i16 %2) { +alloca_block: + br label %entry_block + +entry_block: ; preds = %alloca_block + %3 = alloca i16, align 2 + store i16 %2, i16* %3, align 2 + %4 = bitcast i16* %3 to i8* + %5 = call i1 @__rt__list__insert(i8* %0, i64 %1, i8* %4) + %6 = insertvalue { i16 } undef, i16 %2, 0 + %7 = insertvalue { i32, { i16 }, { { {} } } } { i32 0, { i16 } poison, { { {} } } poison }, { i16 } %6, 1 + %8 = select i1 %5, { i32, { i16 }, { { {} } } } { i32 1, { i16 } poison, { { {} } } undef }, { i32, { i16 }, { { {} } } } %7 + %mrv = insertvalue { i8*, { i32, { i16 }, { { {} } } } } undef, i8* %0, 0 + %mrv8 = insertvalue { i8*, { i32, { i16 }, { { {} } } } } %mrv, { i32, { i16 }, { { {} } } } %8, 1 + ret { i8*, { i32, { i16 }, { { {} } } } } %mrv8 +} + +declare i1 @__rt__list__insert(i8*, i64, i8*) diff --git a/hugr-llvm/src/extension/snapshots/hugr_llvm__extension__collections__test__insert@pre-mem2reg@llvm14.snap b/hugr-llvm/src/extension/snapshots/hugr_llvm__extension__collections__test__insert@pre-mem2reg@llvm14.snap new file mode 100644 index 000000000..9f92cf9a6 --- /dev/null +++ b/hugr-llvm/src/extension/snapshots/hugr_llvm__extension__collections__test__insert@pre-mem2reg@llvm14.snap @@ -0,0 +1,46 @@ +--- +source: hugr-llvm/src/extension/collections.rs +expression: mod_str +--- +; ModuleID = 'test_context' +source_filename = "test_context" + +define { i8*, { i32, { i16 }, { { {} } } } } @_hl.main.1(i8* %0, i64 %1, i16 %2) { +alloca_block: + %"0" = alloca i8*, align 8 + %"1" = alloca { i32, { i16 }, { { {} } } }, align 8 + %"2_0" = alloca i8*, align 8 + %"2_1" = alloca i64, align 8 + %"2_2" = alloca i16, align 2 + %"4_0" = alloca i8*, align 8 + %"4_1" = alloca { i32, { i16 }, { { {} } } }, align 8 + br label %entry_block + +entry_block: ; preds = %alloca_block + store i8* %0, i8** %"2_0", align 8 + store i64 %1, i64* %"2_1", align 4 + store i16 %2, i16* %"2_2", align 2 + %"2_01" = load i8*, i8** %"2_0", align 8 + %"2_12" = load i64, i64* %"2_1", align 4 + %"2_23" = load i16, i16* %"2_2", align 2 + %3 = alloca i16, align 2 + store i16 %"2_23", i16* %3, align 2 + %4 = bitcast i16* %3 to i8* + %5 = call i1 @__rt__list__insert(i8* %"2_01", i64 %"2_12", i8* %4) + %6 = insertvalue { i16 } undef, i16 %"2_23", 0 + %7 = insertvalue { i32, { i16 }, { { {} } } } { i32 0, { i16 } poison, { { {} } } poison }, { i16 } %6, 1 + %8 = select i1 %5, { i32, { i16 }, { { {} } } } { i32 1, { i16 } poison, { { {} } } undef }, { i32, { i16 }, { { {} } } } %7 + store i8* %"2_01", i8** %"4_0", align 8 + store { i32, { i16 }, { { {} } } } %8, { i32, { i16 }, { { {} } } }* %"4_1", align 4 + %"4_04" = load i8*, i8** %"4_0", align 8 + %"4_15" = load { i32, { i16 }, { { {} } } }, { i32, { i16 }, { { {} } } }* %"4_1", align 4 + store i8* %"4_04", i8** %"0", align 8 + store { i32, { i16 }, { { {} } } } %"4_15", { i32, { i16 }, { { {} } } }* %"1", align 4 + %"06" = load i8*, i8** %"0", align 8 + %"17" = load { i32, { i16 }, { { {} } } }, { i32, { i16 }, { { {} } } }* %"1", align 4 + %mrv = insertvalue { i8*, { i32, { i16 }, { { {} } } } } undef, i8* %"06", 0 + %mrv8 = insertvalue { i8*, { i32, { i16 }, { { {} } } } } %mrv, { i32, { i16 }, { { {} } } } %"17", 1 + ret { i8*, { i32, { i16 }, { { {} } } } } %mrv8 +} + +declare i1 @__rt__list__insert(i8*, i64, i8*) diff --git a/hugr-llvm/src/extension/snapshots/hugr_llvm__extension__collections__test__length@llvm14.snap b/hugr-llvm/src/extension/snapshots/hugr_llvm__extension__collections__test__length@llvm14.snap new file mode 100644 index 000000000..61ddae3a3 --- /dev/null +++ b/hugr-llvm/src/extension/snapshots/hugr_llvm__extension__collections__test__length@llvm14.snap @@ -0,0 +1,19 @@ +--- +source: hugr-llvm/src/extension/collections.rs +expression: mod_str +--- +; ModuleID = 'test_context' +source_filename = "test_context" + +define { i8*, i64 } @_hl.main.1(i8* %0) { +alloca_block: + br label %entry_block + +entry_block: ; preds = %alloca_block + %1 = call i64 @__rt__list__length(i8* %0) + %mrv = insertvalue { i8*, i64 } undef, i8* %0, 0 + %mrv6 = insertvalue { i8*, i64 } %mrv, i64 %1, 1 + ret { i8*, i64 } %mrv6 +} + +declare i64 @__rt__list__length(i8*) diff --git a/hugr-llvm/src/extension/snapshots/hugr_llvm__extension__collections__test__length@pre-mem2reg@llvm14.snap b/hugr-llvm/src/extension/snapshots/hugr_llvm__extension__collections__test__length@pre-mem2reg@llvm14.snap new file mode 100644 index 000000000..e993956bb --- /dev/null +++ b/hugr-llvm/src/extension/snapshots/hugr_llvm__extension__collections__test__length@pre-mem2reg@llvm14.snap @@ -0,0 +1,34 @@ +--- +source: hugr-llvm/src/extension/collections.rs +expression: mod_str +--- +; ModuleID = 'test_context' +source_filename = "test_context" + +define { i8*, i64 } @_hl.main.1(i8* %0) { +alloca_block: + %"0" = alloca i8*, align 8 + %"1" = alloca i64, align 8 + %"2_0" = alloca i8*, align 8 + %"4_0" = alloca i8*, align 8 + %"4_1" = alloca i64, align 8 + br label %entry_block + +entry_block: ; preds = %alloca_block + store i8* %0, i8** %"2_0", align 8 + %"2_01" = load i8*, i8** %"2_0", align 8 + %1 = call i64 @__rt__list__length(i8* %"2_01") + store i8* %"2_01", i8** %"4_0", align 8 + store i64 %1, i64* %"4_1", align 4 + %"4_02" = load i8*, i8** %"4_0", align 8 + %"4_13" = load i64, i64* %"4_1", align 4 + store i8* %"4_02", i8** %"0", align 8 + store i64 %"4_13", i64* %"1", align 4 + %"04" = load i8*, i8** %"0", align 8 + %"15" = load i64, i64* %"1", align 4 + %mrv = insertvalue { i8*, i64 } undef, i8* %"04", 0 + %mrv6 = insertvalue { i8*, i64 } %mrv, i64 %"15", 1 + ret { i8*, i64 } %mrv6 +} + +declare i64 @__rt__list__length(i8*) diff --git a/hugr-llvm/src/extension/snapshots/hugr_llvm__extension__collections__test__pop@llvm14.snap b/hugr-llvm/src/extension/snapshots/hugr_llvm__extension__collections__test__pop@llvm14.snap new file mode 100644 index 000000000..e011b3dfe --- /dev/null +++ b/hugr-llvm/src/extension/snapshots/hugr_llvm__extension__collections__test__pop@llvm14.snap @@ -0,0 +1,26 @@ +--- +source: hugr-llvm/src/extension/collections.rs +expression: mod_str +--- +; ModuleID = 'test_context' +source_filename = "test_context" + +define { i8*, { i32, {}, { i16 } } } @_hl.main.1(i8* %0) { +alloca_block: + br label %entry_block + +entry_block: ; preds = %alloca_block + %1 = alloca i16, align 2 + %2 = bitcast i16* %1 to i8* + %3 = call i1 @__rt__list__pop(i8* %0, i8* %2) + %4 = bitcast i8* %2 to i16* + %5 = load i16, i16* %4, align 2 + %6 = insertvalue { i16 } undef, i16 %5, 0 + %7 = insertvalue { i32, {}, { i16 } } { i32 1, {} poison, { i16 } poison }, { i16 } %6, 2 + %8 = select i1 %3, { i32, {}, { i16 } } %7, { i32, {}, { i16 } } { i32 0, {} undef, { i16 } poison } + %mrv = insertvalue { i8*, { i32, {}, { i16 } } } undef, i8* %0, 0 + %mrv6 = insertvalue { i8*, { i32, {}, { i16 } } } %mrv, { i32, {}, { i16 } } %8, 1 + ret { i8*, { i32, {}, { i16 } } } %mrv6 +} + +declare i1 @__rt__list__pop(i8*, i8*) diff --git a/hugr-llvm/src/extension/snapshots/hugr_llvm__extension__collections__test__pop@pre-mem2reg@llvm14.snap b/hugr-llvm/src/extension/snapshots/hugr_llvm__extension__collections__test__pop@pre-mem2reg@llvm14.snap new file mode 100644 index 000000000..4b677b1a8 --- /dev/null +++ b/hugr-llvm/src/extension/snapshots/hugr_llvm__extension__collections__test__pop@pre-mem2reg@llvm14.snap @@ -0,0 +1,41 @@ +--- +source: hugr-llvm/src/extension/collections.rs +expression: mod_str +--- +; ModuleID = 'test_context' +source_filename = "test_context" + +define { i8*, { i32, {}, { i16 } } } @_hl.main.1(i8* %0) { +alloca_block: + %"0" = alloca i8*, align 8 + %"1" = alloca { i32, {}, { i16 } }, align 8 + %"2_0" = alloca i8*, align 8 + %"4_0" = alloca i8*, align 8 + %"4_1" = alloca { i32, {}, { i16 } }, align 8 + br label %entry_block + +entry_block: ; preds = %alloca_block + store i8* %0, i8** %"2_0", align 8 + %"2_01" = load i8*, i8** %"2_0", align 8 + %1 = alloca i16, align 2 + %2 = bitcast i16* %1 to i8* + %3 = call i1 @__rt__list__pop(i8* %"2_01", i8* %2) + %4 = bitcast i8* %2 to i16* + %5 = load i16, i16* %4, align 2 + %6 = insertvalue { i16 } undef, i16 %5, 0 + %7 = insertvalue { i32, {}, { i16 } } { i32 1, {} poison, { i16 } poison }, { i16 } %6, 2 + %8 = select i1 %3, { i32, {}, { i16 } } %7, { i32, {}, { i16 } } { i32 0, {} undef, { i16 } poison } + store i8* %"2_01", i8** %"4_0", align 8 + store { i32, {}, { i16 } } %8, { i32, {}, { i16 } }* %"4_1", align 4 + %"4_02" = load i8*, i8** %"4_0", align 8 + %"4_13" = load { i32, {}, { i16 } }, { i32, {}, { i16 } }* %"4_1", align 4 + store i8* %"4_02", i8** %"0", align 8 + store { i32, {}, { i16 } } %"4_13", { i32, {}, { i16 } }* %"1", align 4 + %"04" = load i8*, i8** %"0", align 8 + %"15" = load { i32, {}, { i16 } }, { i32, {}, { i16 } }* %"1", align 4 + %mrv = insertvalue { i8*, { i32, {}, { i16 } } } undef, i8* %"04", 0 + %mrv6 = insertvalue { i8*, { i32, {}, { i16 } } } %mrv, { i32, {}, { i16 } } %"15", 1 + ret { i8*, { i32, {}, { i16 } } } %mrv6 +} + +declare i1 @__rt__list__pop(i8*, i8*) diff --git a/hugr-llvm/src/extension/snapshots/hugr_llvm__extension__collections__test__push@llvm14.snap b/hugr-llvm/src/extension/snapshots/hugr_llvm__extension__collections__test__push@llvm14.snap new file mode 100644 index 000000000..6e9be48bc --- /dev/null +++ b/hugr-llvm/src/extension/snapshots/hugr_llvm__extension__collections__test__push@llvm14.snap @@ -0,0 +1,20 @@ +--- +source: hugr-llvm/src/extension/collections.rs +expression: mod_str +--- +; ModuleID = 'test_context' +source_filename = "test_context" + +define i8* @_hl.main.1(i8* %0, i16 %1) { +alloca_block: + br label %entry_block + +entry_block: ; preds = %alloca_block + %2 = alloca i16, align 2 + store i16 %1, i16* %2, align 2 + %3 = bitcast i16* %2 to i8* + call void @__rt__list__push(i8* %0, i8* %3) + ret i8* %0 +} + +declare void @__rt__list__push(i8*, i8*) diff --git a/hugr-llvm/src/extension/snapshots/hugr_llvm__extension__collections__test__push@pre-mem2reg@llvm14.snap b/hugr-llvm/src/extension/snapshots/hugr_llvm__extension__collections__test__push@pre-mem2reg@llvm14.snap new file mode 100644 index 000000000..5e88ddf5a --- /dev/null +++ b/hugr-llvm/src/extension/snapshots/hugr_llvm__extension__collections__test__push@pre-mem2reg@llvm14.snap @@ -0,0 +1,32 @@ +--- +source: hugr-llvm/src/extension/collections.rs +expression: mod_str +--- +; ModuleID = 'test_context' +source_filename = "test_context" + +define i8* @_hl.main.1(i8* %0, i16 %1) { +alloca_block: + %"0" = alloca i8*, align 8 + %"2_0" = alloca i8*, align 8 + %"2_1" = alloca i16, align 2 + %"4_0" = alloca i8*, align 8 + br label %entry_block + +entry_block: ; preds = %alloca_block + store i8* %0, i8** %"2_0", align 8 + store i16 %1, i16* %"2_1", align 2 + %"2_01" = load i8*, i8** %"2_0", align 8 + %"2_12" = load i16, i16* %"2_1", align 2 + %2 = alloca i16, align 2 + store i16 %"2_12", i16* %2, align 2 + %3 = bitcast i16* %2 to i8* + call void @__rt__list__push(i8* %"2_01", i8* %3) + store i8* %"2_01", i8** %"4_0", align 8 + %"4_03" = load i8*, i8** %"4_0", align 8 + store i8* %"4_03", i8** %"0", align 8 + %"04" = load i8*, i8** %"0", align 8 + ret i8* %"04" +} + +declare void @__rt__list__push(i8*, i8*) diff --git a/hugr-llvm/src/extension/snapshots/hugr_llvm__extension__collections__test__set@llvm14.snap b/hugr-llvm/src/extension/snapshots/hugr_llvm__extension__collections__test__set@llvm14.snap new file mode 100644 index 000000000..f2b0ac21a --- /dev/null +++ b/hugr-llvm/src/extension/snapshots/hugr_llvm__extension__collections__test__set@llvm14.snap @@ -0,0 +1,29 @@ +--- +source: hugr-llvm/src/extension/collections.rs +expression: mod_str +--- +; ModuleID = 'test_context' +source_filename = "test_context" + +define { i8*, { i32, { i16 }, { i16 } } } @_hl.main.1(i8* %0, i64 %1, i16 %2) { +alloca_block: + br label %entry_block + +entry_block: ; preds = %alloca_block + %3 = alloca i16, align 2 + store i16 %2, i16* %3, align 2 + %4 = bitcast i16* %3 to i8* + %5 = call i1 @__rt__list__set(i8* %0, i64 %1, i8* %4) + %6 = bitcast i8* %4 to i16* + %7 = load i16, i16* %6, align 2 + %8 = insertvalue { i16 } undef, i16 %7, 0 + %9 = insertvalue { i32, { i16 }, { i16 } } { i32 0, { i16 } poison, { i16 } poison }, { i16 } %8, 1 + %10 = insertvalue { i16 } undef, i16 %2, 0 + %11 = insertvalue { i32, { i16 }, { i16 } } { i32 1, { i16 } poison, { i16 } poison }, { i16 } %10, 2 + %12 = select i1 %5, { i32, { i16 }, { i16 } } %11, { i32, { i16 }, { i16 } } %9 + %mrv = insertvalue { i8*, { i32, { i16 }, { i16 } } } undef, i8* %0, 0 + %mrv8 = insertvalue { i8*, { i32, { i16 }, { i16 } } } %mrv, { i32, { i16 }, { i16 } } %12, 1 + ret { i8*, { i32, { i16 }, { i16 } } } %mrv8 +} + +declare i1 @__rt__list__set(i8*, i64, i8*) diff --git a/hugr-llvm/src/extension/snapshots/hugr_llvm__extension__collections__test__set@pre-mem2reg@llvm14.snap b/hugr-llvm/src/extension/snapshots/hugr_llvm__extension__collections__test__set@pre-mem2reg@llvm14.snap new file mode 100644 index 000000000..ba89dc6cc --- /dev/null +++ b/hugr-llvm/src/extension/snapshots/hugr_llvm__extension__collections__test__set@pre-mem2reg@llvm14.snap @@ -0,0 +1,50 @@ +--- +source: hugr-llvm/src/extension/collections.rs +expression: mod_str +--- +; ModuleID = 'test_context' +source_filename = "test_context" + +define { i8*, { i32, { i16 }, { i16 } } } @_hl.main.1(i8* %0, i64 %1, i16 %2) { +alloca_block: + %"0" = alloca i8*, align 8 + %"1" = alloca { i32, { i16 }, { i16 } }, align 8 + %"2_0" = alloca i8*, align 8 + %"2_1" = alloca i64, align 8 + %"2_2" = alloca i16, align 2 + %"4_0" = alloca i8*, align 8 + %"4_1" = alloca { i32, { i16 }, { i16 } }, align 8 + br label %entry_block + +entry_block: ; preds = %alloca_block + store i8* %0, i8** %"2_0", align 8 + store i64 %1, i64* %"2_1", align 4 + store i16 %2, i16* %"2_2", align 2 + %"2_01" = load i8*, i8** %"2_0", align 8 + %"2_12" = load i64, i64* %"2_1", align 4 + %"2_23" = load i16, i16* %"2_2", align 2 + %3 = alloca i16, align 2 + store i16 %"2_23", i16* %3, align 2 + %4 = bitcast i16* %3 to i8* + %5 = call i1 @__rt__list__set(i8* %"2_01", i64 %"2_12", i8* %4) + %6 = bitcast i8* %4 to i16* + %7 = load i16, i16* %6, align 2 + %8 = insertvalue { i16 } undef, i16 %7, 0 + %9 = insertvalue { i32, { i16 }, { i16 } } { i32 0, { i16 } poison, { i16 } poison }, { i16 } %8, 1 + %10 = insertvalue { i16 } undef, i16 %"2_23", 0 + %11 = insertvalue { i32, { i16 }, { i16 } } { i32 1, { i16 } poison, { i16 } poison }, { i16 } %10, 2 + %12 = select i1 %5, { i32, { i16 }, { i16 } } %11, { i32, { i16 }, { i16 } } %9 + store i8* %"2_01", i8** %"4_0", align 8 + store { i32, { i16 }, { i16 } } %12, { i32, { i16 }, { i16 } }* %"4_1", align 4 + %"4_04" = load i8*, i8** %"4_0", align 8 + %"4_15" = load { i32, { i16 }, { i16 } }, { i32, { i16 }, { i16 } }* %"4_1", align 4 + store i8* %"4_04", i8** %"0", align 8 + store { i32, { i16 }, { i16 } } %"4_15", { i32, { i16 }, { i16 } }* %"1", align 4 + %"06" = load i8*, i8** %"0", align 8 + %"17" = load { i32, { i16 }, { i16 } }, { i32, { i16 }, { i16 } }* %"1", align 4 + %mrv = insertvalue { i8*, { i32, { i16 }, { i16 } } } undef, i8* %"06", 0 + %mrv8 = insertvalue { i8*, { i32, { i16 }, { i16 } } } %mrv, { i32, { i16 }, { i16 } } %"17", 1 + ret { i8*, { i32, { i16 }, { i16 } } } %mrv8 +} + +declare i1 @__rt__list__set(i8*, i64, i8*)