├── xdsl ├── py.typed ├── tools │ ├── __init__.py │ └── xdsl_opt.py ├── utils │ ├── __init__.py │ ├── test_value.py │ ├── hasher.py │ ├── str_enum.py │ ├── colors.py │ ├── runtime_final.py │ └── hashable_module.py ├── analysis │ └── __init__.py ├── backend │ ├── __init__.py │ ├── x86 │ │ ├── __init__.py │ │ ├── lowering │ │ │ └── __init__.py │ │ └── register_stack.py │ ├── riscv │ │ ├── __init__.py │ │ ├── lowering │ │ │ ├── __init__.py │ │ │ └── convert_print_format_to_riscv_debug.py │ │ ├── traits.py │ │ └── register_stack.py │ ├── wgsl │ │ └── __init__.py │ ├── csl │ │ └── __init__.py │ └── utils.py ├── frontend │ ├── __init__.py │ ├── pyast │ │ ├── __init__.py │ │ └── utils │ │ │ ├── __init__.py │ │ │ └── block.py │ ├── listlang │ │ ├── __init__.py │ │ └── marimo.py │ └── pypdl │ │ └── __init__.py ├── interactive │ ├── __init__.py │ ├── _pasteboard.py │ ├── load_file_screen.tcss │ ├── pass_list_item.py │ └── add_arguments_screen.tcss ├── rewriting │ ├── __init__.py │ └── composable_rewriting │ │ ├── __init__.py │ │ └── immutable_ir │ │ └── __init__.py ├── dialects │ ├── experimental │ │ └── __init__.py │ ├── irdl │ │ └── __init__.py │ ├── csl │ │ └── __init__.py │ ├── wasm │ │ ├── __init__.py │ │ ├── encoding.py │ │ └── wat.py │ ├── utils │ │ ├── __init__.py │ │ └── fast_math.py │ ├── stim │ │ └── __init__.py │ ├── x86 │ │ └── attributes.py │ ├── cmath.irdl │ └── arm │ │ └── __init__.py ├── interpreters │ ├── utils │ │ └── __init__.py │ ├── printf.py │ ├── riscv_debug.py │ └── cf.py ├── transforms │ ├── experimental │ │ ├── __init__.py │ │ └── dmp │ │ │ └── __init__.py │ ├── canonicalization_patterns │ │ ├── __init__.py │ │ └── utils.py │ ├── shape_inference_patterns │ │ └── __init__.py │ ├── convert_pdl_to_pdl_interp │ │ └── __init__.py │ ├── x86_allocate_registers.py │ └── test_transform_dialect_erase_schedule.py ├── ir │ ├── __init__.py │ └── affine │ │ └── __init__.py ├── irdl │ └── __init__.py ├── parser │ └── __init__.py ├── syntax_printer.py ├── dialect_interfaces │ └── __init__.py └── __init__.py ├── docs ├── Toy │ ├── toy │ │ ├── __init__.py │ │ ├── dialects │ │ │ └── __init__.py │ │ ├── emulator │ │ │ ├── __init__.py │ │ │ └── toy_accelerator_instruction_functions.py │ │ ├── frontend │ │ │ ├── __init__.py │ │ │ └── location.py │ │ └── rewrites │ │ │ └── __init__.py │ └── examples │ │ ├── lit.cfg │ │ ├── scalar.toy │ │ ├── tests │ │ └── infer_shapes.mlir │ │ └── interpret.toy ├── assets │ └── img │ │ └── logos │ │ ├── Logo.png │ │ ├── xdsl.png │ │ ├── xdsl-transparent.png │ │ └── xdsl-transparent-single.png ├── .nav.yml └── marimo │ └── source.mlir ├── tests ├── interpreters │ └── __init__.py ├── my_plugin │ ├── src │ │ └── my_plugin │ │ │ ├── py.typed │ │ │ └── __init__.py │ └── pyproject.toml ├── xdsl_opt │ ├── incomplete_program.mlir │ ├── not_module.mlir │ ├── empty_program.mlir │ ├── empty_program.wrong │ ├── simple_program.mlir │ ├── incomplete_program_residual.mlir │ ├── not_module_with_module.mlir │ ├── unverified_program.mlir │ └── split_input_file.mlir ├── filecheck │ ├── dialects │ │ ├── wasm │ │ │ ├── wat.mlir │ │ │ └── ops.mlir │ │ ├── bigint │ │ │ └── attrs.mlir │ │ ├── llvm │ │ │ ├── attrs-invalid.mlir │ │ │ ├── array.mlir │ │ │ ├── attrs.mlir │ │ │ ├── invalid.mlir │ │ │ └── global.mlir │ │ ├── arm │ │ │ └── test_registers.mlir │ │ ├── scf │ │ │ ├── execute_region_empty.mlir │ │ │ ├── for_args_number.mlir │ │ │ ├── for_iv.mlir │ │ │ ├── parallel_iv.mlir │ │ │ ├── parallel_blocks_args_types.mlir │ │ │ ├── for_body_args_types.mlir │ │ │ ├── for_body_args_number.mlir │ │ │ ├── yield_implicit.mlir │ │ │ ├── for_body_args_number_much.mlir │ │ │ ├── for_yield.mlir │ │ │ ├── parallel_blocks_not_enough_reduce.mlir │ │ │ ├── for_yield_types.mlir │ │ │ ├── for_yield_number.mlir │ │ │ ├── parallel_multiple_blocks.mlir │ │ │ ├── parallel_bounds.mlir │ │ │ ├── unregistered.mlir │ │ │ ├── reduce_arg_type_missmatch.mlir │ │ │ └── reduce_return_type_missmatch.mlir │ │ ├── arm_neon │ │ │ ├── test_registers.mlir │ │ │ └── test_attrs.mlir │ │ ├── accfg │ │ │ └── invalid.mlir │ │ ├── x86 │ │ │ ├── x86_registers_valid.mlir │ │ │ ├── x86_ops_invalid.mlir │ │ │ └── x86_registers_invalid.mlir │ │ ├── ltl │ │ │ ├── ltl_invalid.mlir │ │ │ └── ltl_op.mlir │ │ ├── vector │ │ │ ├── vector_broadcast_type_matching.mlir │ │ │ ├── vector_createmask_indexing.mlir │ │ │ ├── vector_load_indexing.mlir │ │ │ ├── vector_store_indexing.mlir │ │ │ ├── vector_load_type_matching.mlir │ │ │ ├── vector_store_type_matching.mlir │ │ │ ├── vector_maskedstore_indexing.mlir │ │ │ ├── vector_maskedload_indexing.mlir │ │ │ ├── vector_maskedstore_memref_storevec_type_matching.mlir │ │ │ ├── vector_maskedload_memref_res_type_matching.mlir │ │ │ ├── vector_maskedload_memref_passthrough_type_matching.mlir │ │ │ ├── vector_pure_ops.mlir │ │ │ └── vector_extractelement_verify.mlir │ │ ├── builtin │ │ │ ├── packed.mlir │ │ │ ├── parse_with_location.mlir │ │ │ └── module.mlir │ │ ├── mod_arith │ │ │ └── mod_arith.mlir │ │ ├── stim │ │ │ └── attrs.mlir │ │ ├── emitc │ │ │ └── emitc_attrs.mlir │ │ ├── mesh │ │ │ ├── ops_invalid.mlir │ │ │ └── attrs.mlir │ │ ├── riscv_func │ │ │ └── lower_riscv_func_main.mlir │ │ ├── arith │ │ │ ├── arith_constant_fold_interp.mlir │ │ │ ├── arith_cfg.mlir │ │ │ └── arith_invalid.mlir │ │ ├── memref │ │ │ └── canonicalize.mlir │ │ ├── printf │ │ │ ├── invalid.mlir │ │ │ └── printf_basics.mlir │ │ ├── varith │ │ │ └── invalid.mlir │ │ ├── snitch_runtime │ │ │ └── snitch_runtime_invalid.mlir │ │ ├── complex │ │ │ ├── complex_attr.mlir │ │ │ └── invalid.mlir │ │ ├── x86_func │ │ │ ├── x86_func_ops.mlir │ │ │ └── x86_func_asm.mlir │ │ ├── arm_func │ │ │ └── arm_func_ops.mlir │ │ ├── pdl │ │ │ ├── pdl_native_rewrite.mlir │ │ │ ├── pdl_replace.mlir │ │ │ ├── pdl_result.mlir │ │ │ ├── pdl_native_constraint.mlir │ │ │ └── pdl_attribute.mlir │ │ ├── symref │ │ │ └── ops.mlir │ │ ├── transform │ │ │ ├── transform_interpreter.mlir │ │ │ └── transform_named_sequence.mlir │ │ ├── eqsat │ │ │ └── eqsat_invalid.mlir │ │ ├── ptr │ │ │ └── ops.mlir │ │ ├── irdl │ │ │ ├── pyrdl-to-irdl │ │ │ │ └── cmath-conversion.py │ │ │ └── test-type.irdl.mlir │ │ └── comb │ │ │ └── comb_ops_err.mlir │ ├── with-riscemu │ │ ├── lit.local.cfg │ │ └── rvscf_lowering_emu.mlir │ ├── version.mlir │ ├── transforms │ │ ├── eqsat-add-costs │ │ │ ├── costs.json │ │ │ └── eqsat-add-costs-with-default.mlir │ │ ├── apply-pdl │ │ │ ├── apply_pdl_erase.mlir │ │ │ ├── apply_pdl_extra_file.mlir │ │ │ ├── extra_file.mlir │ │ │ ├── apply_pdl_property_rewrite.mlir │ │ │ ├── apply_pdl_attribute_rewrite.mlir │ │ │ ├── apply_pdl_insert_operation.mlir │ │ │ ├── apply_pdl_add_zero.mlir │ │ │ ├── apply_pdl_polymorphic.mlir │ │ │ ├── apply_pdl_match_type.mlir │ │ │ ├── apply_pdl_build_type.mlir │ │ │ └── apply_pdl_simple.mlir │ │ ├── x86-infer-broadcast.mlir │ │ ├── empty-tensor-to-alloc-tensor.mlir │ │ ├── convert_ptr_type_offsets.mlir │ │ ├── arith-add-immediate-zero.mlir │ │ ├── apply-pdl-interp │ │ │ └── apply_pdl_interp_extra_file.mlir │ │ ├── eqsat-serialize-egraph-cycle.mlir │ │ ├── convert_ml_program_to_memref.mlir │ │ ├── eqsat-create-eclasses.mlir │ │ ├── memref_stream_infer_fill.mlir │ │ ├── individual_rewrite │ │ │ └── riscv.mlir │ │ ├── apply-eqsat-pdl-interp │ │ │ └── apply_eqsat_pdl_interp_extra_file.mlir │ │ ├── memref_stream_generalize_fill.mlir │ │ ├── lift-arith-to-linalg.mlir │ │ ├── test_transform_dialect_erase_schedule.mlir │ │ ├── eqsat-serialize-egraph.mlir │ │ └── x86-legalize-for-regalloc.mlir │ ├── parser-printer │ │ ├── attribute_names.mlir │ │ ├── color.mlir │ │ ├── value_tuple_wrong_number.mlir │ │ ├── value_tuple.mlir │ │ ├── value_tuple_access_oob.mlir │ │ ├── duplicate_attribute_keys.mlir │ │ ├── invalid_dense_attr.mlir │ │ ├── verifier_error.mlir │ │ ├── scope.mlir │ │ ├── parse_error.mlir │ │ ├── operation_with_properties.mlir │ │ ├── aliases.mlir │ │ └── float_parsing.mlir │ ├── mlir-conversion │ │ └── with-mlir │ │ │ ├── dialects │ │ │ ├── cf │ │ │ │ └── assert.mlir │ │ │ ├── builtin │ │ │ │ ├── location.mlir │ │ │ │ ├── builtin_tuple_types.mlir │ │ │ │ ├── vector_type.mlir │ │ │ │ └── dense_elements.mlir │ │ │ ├── vector │ │ │ │ ├── ops.mlir │ │ │ │ ├── fma.mlir │ │ │ │ ├── reduction.mlir │ │ │ │ └── insert_extract_ops.mlir │ │ │ ├── complex │ │ │ │ └── attribute.mlir │ │ │ ├── scf │ │ │ │ ├── if.mlir │ │ │ │ ├── while_custom.mlir │ │ │ │ └── for_custom.mlir │ │ │ ├── emitc │ │ │ │ └── emitc_attrs.mlir │ │ │ ├── arith │ │ │ │ ├── arith_fp_ops.mlir │ │ │ │ ├── arith_bcast.mlir │ │ │ │ └── arith_fp_conv.mlir │ │ │ ├── ml_program │ │ │ │ └── ops.mlir │ │ │ ├── pdl │ │ │ │ ├── pdl_native_rewrite.mlir │ │ │ │ ├── pdl_replace.mlir │ │ │ │ ├── pdl_result.mlir │ │ │ │ └── pdl_native_constraint.mlir │ │ │ ├── print │ │ │ │ └── printf_to_llvm.mlir │ │ │ ├── llvm │ │ │ │ ├── attrs.mlir │ │ │ │ └── llvm_types.mlir │ │ │ ├── transform │ │ │ │ └── transform_generic.mlir │ │ │ └── func │ │ │ │ └── func_ops_generic.mlir │ │ │ ├── scope.mlir │ │ │ ├── symbol_tests.mlir │ │ │ ├── lit.local.cfg │ │ │ ├── mlir_opt_fail.mlir │ │ │ ├── apply-eqsat-pdl │ │ │ ├── apply_eqsat_pdl_extra_file.mlir │ │ │ └── extra_file.mlir │ │ │ └── affine_map.mlir │ ├── runner │ │ ├── example.mlir │ │ ├── riscv.mlir │ │ ├── riscv_scf.mlir │ │ ├── runner_args.mlir │ │ └── factorial.mlir │ ├── backend │ │ └── riscv │ │ │ ├── verify.mlir │ │ │ ├── memref_to_riscv_invalid.mlir │ │ │ ├── print_format_to_riscv_debug.mlir │ │ │ └── func_and_arith_to_riscv_asm_flow.mlir │ ├── projects │ │ ├── libxsmm │ │ │ ├── README.md │ │ │ ├── Makefile │ │ │ └── isclose.h │ │ └── eqsat │ │ │ └── identity.mlir │ ├── xdsl_opt │ │ └── split_input.mlir │ └── frontend │ │ └── dialects │ │ └── cf.py ├── dialects │ ├── wasm │ │ ├── test_wat_encoding.py │ │ └── test_wasm_encoding.py │ ├── arm │ │ └── test_assembly_arg_str.py │ ├── test_dialects.py │ ├── test_arm_func.py │ ├── test_emitc.py │ ├── test_riscv_func.py │ ├── test_accfg.py │ ├── test_eqsat.py │ └── test_seq.py ├── utils │ ├── test_hasher.py │ ├── test_final.py │ └── test_bitwise_casts.py ├── test_cli.py ├── xdsl_tblgen │ └── test_tblgen.py ├── transforms │ └── test_transform_interpreter.py ├── ir │ ├── test_attribute.py │ └── test_op_selector.py ├── backend │ ├── x86 │ │ └── test_assembly_printing.py │ ├── test_assembly_printer.py │ └── test_asm_reporter.py └── test_printing_hints.py ├── benchmarks ├── .gitignore └── __init__.py ├── .gitattributes ├── .markdownlint.json ├── .git-blame-ignored-commits ├── .github ├── pull_request_template.md ├── workflows │ ├── release-notes.yml │ ├── markdown-formatting.yml │ ├── pythonpublish.yml │ ├── ci-nix.yml │ ├── code-formatting.yml │ └── ci-docs.yml └── ISSUE_TEMPLATE │ └── bug_report.md ├── scripts └── hooks.py ├── codecov.yml ├── renovate.json ├── .pre-commit-config.yaml ├── .readthedocs.yaml └── flake.nix /xdsl/py.typed: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /xdsl/tools/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /xdsl/utils/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/Toy/toy/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /xdsl/analysis/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /xdsl/backend/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /xdsl/backend/x86/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /xdsl/frontend/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /xdsl/interactive/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /xdsl/rewriting/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/Toy/toy/dialects/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/Toy/toy/emulator/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/Toy/toy/frontend/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/Toy/toy/frontend/location.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/Toy/toy/rewrites/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/interpreters/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /xdsl/backend/riscv/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /xdsl/backend/wgsl/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /xdsl/frontend/pyast/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /benchmarks/.gitignore: -------------------------------------------------------------------------------- 1 | profiles 2 | -------------------------------------------------------------------------------- /tests/my_plugin/src/my_plugin/py.typed: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /xdsl/backend/x86/lowering/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /xdsl/dialects/experimental/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /xdsl/frontend/listlang/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /xdsl/frontend/pyast/utils/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /xdsl/interpreters/utils/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /xdsl/backend/riscv/lowering/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /xdsl/transforms/experimental/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | xdsl/_version.py export-subst 2 | -------------------------------------------------------------------------------- /tests/xdsl_opt/incomplete_program.mlir: -------------------------------------------------------------------------------- 1 | 42 2 | -------------------------------------------------------------------------------- /xdsl/rewriting/composable_rewriting/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /xdsl/transforms/experimental/dmp/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /xdsl/transforms/canonicalization_patterns/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /xdsl/transforms/shape_inference_patterns/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/xdsl_opt/not_module.mlir: -------------------------------------------------------------------------------- 1 | "test.op"() : () -> () 2 | -------------------------------------------------------------------------------- /xdsl/dialects/irdl/__init__.py: -------------------------------------------------------------------------------- 1 | from .irdl import * 2 | -------------------------------------------------------------------------------- /tests/xdsl_opt/empty_program.mlir: -------------------------------------------------------------------------------- 1 | builtin.module { 2 | } 3 | -------------------------------------------------------------------------------- /tests/xdsl_opt/empty_program.wrong: -------------------------------------------------------------------------------- 1 | builtin.module { 2 | } 3 | -------------------------------------------------------------------------------- /xdsl/rewriting/composable_rewriting/immutable_ir/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /benchmarks/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | """Benchmarks for xDSL.""" 3 | -------------------------------------------------------------------------------- /tests/xdsl_opt/simple_program.mlir: -------------------------------------------------------------------------------- 1 | builtin.module { 2 | "test.op"() : () -> () 3 | } 4 | -------------------------------------------------------------------------------- /tests/xdsl_opt/incomplete_program_residual.mlir: -------------------------------------------------------------------------------- 1 | builtin.module {} 2 | builtin.module {} 3 | 42 4 | -------------------------------------------------------------------------------- /docs/assets/img/logos/Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xdslproject/xdsl/HEAD/docs/assets/img/logos/Logo.png -------------------------------------------------------------------------------- /docs/assets/img/logos/xdsl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xdslproject/xdsl/HEAD/docs/assets/img/logos/xdsl.png -------------------------------------------------------------------------------- /.markdownlint.json: -------------------------------------------------------------------------------- 1 | { 2 | "MD013": { 3 | "line_length": 88, 4 | "code_blocks": false 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/wasm/wat.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s -t wat | filecheck %s 2 | 3 | wasm.module 4 | 5 | // CHECK: (module) 6 | -------------------------------------------------------------------------------- /docs/assets/img/logos/xdsl-transparent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xdslproject/xdsl/HEAD/docs/assets/img/logos/xdsl-transparent.png -------------------------------------------------------------------------------- /tests/filecheck/with-riscemu/lit.local.cfg: -------------------------------------------------------------------------------- 1 | 2 | try: 3 | import riscemu 4 | except ImportError: 5 | config.unsupported = True 6 | -------------------------------------------------------------------------------- /tests/filecheck/version.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt --version | filecheck %s 2 | 3 | //CHECK: xdsl-opt built from xdsl version {{[a-z0-9.+-]+}} 4 | -------------------------------------------------------------------------------- /docs/assets/img/logos/xdsl-transparent-single.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xdslproject/xdsl/HEAD/docs/assets/img/logos/xdsl-transparent-single.png -------------------------------------------------------------------------------- /tests/filecheck/transforms/eqsat-add-costs/costs.json: -------------------------------------------------------------------------------- 1 | { 2 | "arith.constant" : 1, 3 | "arith.addi" : 3, 4 | "arith.shli" : 2, 5 | "arith.muli" : 5 6 | } 7 | -------------------------------------------------------------------------------- /xdsl/ir/__init__.py: -------------------------------------------------------------------------------- 1 | # TID 251 enforces to not import from core 2 | # We need to skip it here to allow importing from here instead. 3 | from .core import * # noqa: TID251 4 | -------------------------------------------------------------------------------- /tests/xdsl_opt/not_module_with_module.mlir: -------------------------------------------------------------------------------- 1 | %0 = "test.op"() : () -> i32 2 | %1 = "test.op"(%0, %0) : (i32, i32) -> i32 3 | builtin.module { 4 | %2 = "test.op"() : () -> i32 5 | } 6 | -------------------------------------------------------------------------------- /xdsl/dialects/csl/__init__.py: -------------------------------------------------------------------------------- 1 | # TID 251 enforces to not import from those 2 | # We need to skip it here to allow importing from here instead. 3 | from .csl import * # noqa: TID251 4 | -------------------------------------------------------------------------------- /xdsl/tools/xdsl_opt.py: -------------------------------------------------------------------------------- 1 | from xdsl.xdsl_opt_main import xDSLOptMain 2 | 3 | 4 | def main(): 5 | xDSLOptMain().run() 6 | 7 | 8 | if "__main__" == __name__: 9 | main() 10 | -------------------------------------------------------------------------------- /tests/dialects/wasm/test_wat_encoding.py: -------------------------------------------------------------------------------- 1 | from xdsl.dialects import wasm 2 | 3 | 4 | def test_empty_module(): 5 | module = wasm.WasmModuleOp() 6 | 7 | assert module.wat() == "(module)" 8 | -------------------------------------------------------------------------------- /tests/dialects/wasm/test_wasm_encoding.py: -------------------------------------------------------------------------------- 1 | from xdsl.dialects import wasm 2 | 3 | 4 | def test_empty_module(): 5 | module = wasm.WasmModuleOp() 6 | 7 | assert module.wasm() == b"\x00asm\x01\x00\x00\x00" 8 | -------------------------------------------------------------------------------- /.git-blame-ignored-commits: -------------------------------------------------------------------------------- 1 | #This commit just switched the whole codebase to black format 2 | c1d91c7c7e3dfa5f6c698c8591b2900d27203ab5 3 | #This commit switched to ruff format 4 | 6d27775d1689c4f1c1289373055e5b26cbcc53bc 5 | -------------------------------------------------------------------------------- /xdsl/backend/csl/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | CSL is the language used to program for the Cerebras Wafer Scale Engine (WSE) a wafer-parallel compute accelerator. 3 | 4 | See external [documentation](https://sdk.cerebras.net/). 5 | """ 6 | -------------------------------------------------------------------------------- /tests/xdsl_opt/unverified_program.mlir: -------------------------------------------------------------------------------- 1 | builtin.module { 2 | %a = "arith.constant"() {value = 1 : i32} : () -> i32 3 | %b = "arith.constant"() {value = 1.0 : f32} : () -> f32 4 | %c = "arith.addf"(%a, %b) : (i32, f32) -> f32 5 | } 6 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/bigint/attrs.mlir: -------------------------------------------------------------------------------- 1 | // RUN: XDSL_ROUNDTRIP 2 | 3 | %bigint = "test.op"() : () -> !bigint.bigint 4 | 5 | // CHECK: builtin.module { 6 | // CHECK-NEXT: %bigint = "test.op"() : () -> !bigint.bigint 7 | // CHECK-NEXT: } 8 | -------------------------------------------------------------------------------- /tests/filecheck/parser-printer/attribute_names.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s | xdsl-opt --print-op-generic | filecheck %s 2 | 3 | builtin.module attributes {a = i32, _e = i32, "foo" = i32, _ = i32} { 4 | } 5 | 6 | // CHECK: a = i32, _e = i32, foo = i32, _ = i32 7 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | # PR Template 2 | 3 | Please add a short description of your changes, and the motivation behind them. 4 | 5 | Make sure your PR title follows the [guidelines](https://github.com/xdslproject/xdsl/wiki#commit-and-pr-message-formatting) 6 | -------------------------------------------------------------------------------- /xdsl/dialects/wasm/__init__.py: -------------------------------------------------------------------------------- 1 | from xdsl.ir import Dialect 2 | 3 | from .ops import ( 4 | WasmModuleOp, 5 | ) 6 | 7 | Wasm = Dialect( 8 | "wasm", 9 | [ 10 | WasmModuleOp, 11 | ], 12 | ) 13 | """ 14 | The WebAssembly dialect. 15 | """ 16 | -------------------------------------------------------------------------------- /tests/filecheck/parser-printer/color.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s --syntax-highlight | filecheck %s 2 | 3 | // CHECK: %0 = "test.op"() : () -> i32 4 | %0 = "test.op"() : () -> i32 5 | 6 | // CHECK: "test.op"(%0) : (i32) -> () 7 | "test.op"(%0) : (i32) -> () 8 | -------------------------------------------------------------------------------- /xdsl/ir/affine/__init__.py: -------------------------------------------------------------------------------- 1 | # TID 251 enforces to not import from those 2 | # We need to skip it here to allow importing from here instead. 3 | from .affine_expr import * # noqa: TID251 4 | from .affine_map import * # noqa: TID251 5 | from .affine_set import * # noqa: TID251 6 | -------------------------------------------------------------------------------- /xdsl/irdl/__init__.py: -------------------------------------------------------------------------------- 1 | # TID 251 enforces to not import from nested irdl 2 | # We need to skip it here to allow importing from here instead. 3 | from .attributes import * # noqa: TID251 4 | from .constraints import * # noqa: TID251 5 | from .operations import * # noqa: TID251 6 | -------------------------------------------------------------------------------- /tests/filecheck/parser-printer/value_tuple_wrong_number.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s --parsing-diagnostics | filecheck %s 2 | 3 | "builtin.module"() ({ 4 | 5 | %0:1 = "test.op"() : () -> (i32, i64, i32) 6 | // CHECK: Operation has 3 results, but was given 1 to bind. 7 | 8 | }) : () -> () 9 | -------------------------------------------------------------------------------- /xdsl/utils/test_value.py: -------------------------------------------------------------------------------- 1 | from xdsl.dialects.test import TestOp 2 | from xdsl.ir import AttributeCovT, OpResult 3 | 4 | 5 | def create_ssa_value(t: AttributeCovT) -> OpResult[AttributeCovT]: 6 | op = TestOp(result_types=(t,)) 7 | return op.results[0] # pyright: ignore[reportReturnType] 8 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/llvm/attrs-invalid.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt --verify-diagnostics --split-input-file %s | filecheck %s 2 | 3 | // CHECK: target features must start with '+' or '-' 4 | "test.op"() { 5 | target_features = #llvm.target_features<["-one", "+two", "no-dashes-or-plus"]>, 6 | } : () -> () 7 | -------------------------------------------------------------------------------- /tests/xdsl_opt/split_input_file.mlir: -------------------------------------------------------------------------------- 1 | builtin.module { 2 | } 3 | 4 | // ----- 5 | builtin.module { 6 | "test.op"() : () -> () 7 | } 8 | 9 | // ----- 10 | builtin.module { 11 | %x = "test.op"() : () -> i1 12 | } 13 | 14 | // ----- 15 | builtin.module { 16 | %x = "test.op"() : () -> i2 17 | } 18 | -------------------------------------------------------------------------------- /tests/filecheck/transforms/apply-pdl/apply_pdl_erase.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s -p apply-pdl | filecheck %s 2 | 3 | // CHECK-NOT: "test.op"() 4 | "test.op"() : () -> () 5 | 6 | pdl.pattern : benefit(42) { 7 | %0 = pdl.operation "test.op" 8 | pdl.rewrite %0 { 9 | pdl.erase %0 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/arm/test_registers.mlir: -------------------------------------------------------------------------------- 1 | // RUN: XDSL_ROUNDTRIP 2 | 3 | 4 | // CHECK: "test.op"() {unallocated = !arm.reg} : () -> () 5 | "test.op"() {unallocated = !arm.reg} : () -> () 6 | 7 | // CHECK: "test.op"() {allocated = !arm.reg} : () -> () 8 | "test.op"() {allocated = !arm.reg} : () -> () 9 | -------------------------------------------------------------------------------- /tests/filecheck/transforms/apply-pdl/apply_pdl_extra_file.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s -p 'apply-pdl{pdl_file="%p/extra_file.mlir"}' | filecheck %s 2 | 3 | "test.op"() {attr = 0} : () -> () 4 | 5 | //CHECK: builtin.module { 6 | // CHECK-NEXT: "test.op"() {attr = 1 : i64} : () -> () 7 | // CHECK-NEXT: } 8 | -------------------------------------------------------------------------------- /xdsl/dialects/utils/__init__.py: -------------------------------------------------------------------------------- 1 | # TID 251 enforces to not import from those 2 | # We need to skip it here to allow importing from here instead. 3 | from .dimension_list import * # noqa: TID251 4 | from .dynamic_index_list import * # noqa: TID251 5 | from .fast_math import * # noqa: TID251 6 | from .format import * # noqa: TID251 7 | -------------------------------------------------------------------------------- /docs/.nav.yml: -------------------------------------------------------------------------------- 1 | nav: 2 | - xDSL: "https://xdsl.dev/" 3 | - Getting Started: index.md 4 | - Tutorial Notebooks: marimo 5 | - API Reference: reference 6 | - User Guide: guides 7 | - News: "https://xdsl.dev/news/" 8 | - Events: "https://xdsl.dev/events/2025-HiPEAC/" 9 | - About: "https://xdsl.dev/about/challenge/" 10 | -------------------------------------------------------------------------------- /docs/marimo/source.mlir: -------------------------------------------------------------------------------- 1 | "builtin.module"() ({ 2 | %0 = "arith.constant"() {value = 1 : i32} : () -> i32 3 | %1 = "arith.constant"() {value = 2 : i32} : () -> i32 4 | %2 = "arith.addi"(%0, %1) : (i32, i32) -> i32 5 | %3 = "arith.addi"(%0, %1) : (i32, i32) -> i32 6 | %4 = "arith.addi"(%2, %3) : (i32, i32) -> i32 7 | }) : () -> () 8 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/scf/execute_region_empty.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s --verify-diagnostics | filecheck %s 2 | 3 | // CHECK: Operation does not verify: scf.execute_region op region needs to have at least one block 4 | func.func @execute_region_empty_region() { 5 | scf.execute_region { 6 | } 7 | func.return 8 | } 9 | -------------------------------------------------------------------------------- /tests/utils/test_hasher.py: -------------------------------------------------------------------------------- 1 | from xdsl.utils.hasher import Hasher 2 | 3 | 4 | def test_hasher(): 5 | h = Hasher() 6 | h.combine(1) 7 | hash1 = h.hash 8 | h.combine(2) 9 | 10 | j = Hasher(seed=hash1) 11 | 12 | assert h.hash != j.hash 13 | 14 | j.combine(2) 15 | 16 | assert h.hash == j.hash 17 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/arm_neon/test_registers.mlir: -------------------------------------------------------------------------------- 1 | // RUN: XDSL_ROUNDTRIP 2 | 3 | 4 | // CHECK: "test.op"() {unallocated = !arm_neon.reg} : () -> () 5 | "test.op"() {unallocated = !arm_neon.reg} : () -> () 6 | 7 | // CHECK: "test.op"() {allocated = !arm_neon.reg} : () -> () 8 | "test.op"() {allocated = !arm_neon.reg} : () -> () 9 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/accfg/invalid.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt --split-input-file --parsing-diagnostics %s | filecheck %s 2 | 3 | %one = "test.op"() : () -> i32 4 | %zero = arith.constant 0 : i32 5 | %state = accfg.setup "acc1" to ("A" = %one : i32) : !accfg.state<"acc2"> 6 | 7 | // CHECK: expected !accfg.state<"acc1">, but got !accfg.state<"acc2"> 8 | -------------------------------------------------------------------------------- /xdsl/dialects/stim/__init__.py: -------------------------------------------------------------------------------- 1 | from xdsl.ir import Dialect 2 | 3 | from .ops import QubitAttr, QubitCoordsOp, QubitMappingAttr, StimCircuitOp 4 | 5 | Stim = Dialect( 6 | "stim", 7 | [ 8 | QubitCoordsOp, 9 | StimCircuitOp, 10 | ], 11 | [ 12 | QubitAttr, 13 | QubitMappingAttr, 14 | ], 15 | ) 16 | -------------------------------------------------------------------------------- /tests/filecheck/mlir-conversion/with-mlir/dialects/cf/assert.mlir: -------------------------------------------------------------------------------- 1 | // RUN: MLIR_ROUNDTRIP 2 | // RUN: MLIR_GENERIC_ROUNDTRIP 3 | 4 | module{ 5 | %0 = arith.constant true 6 | cf.assert %0, "some message" 7 | } 8 | 9 | // CHECK: cf.assert %{{.*}}, "some message" 10 | // CHECK-GENERIC: "cf.assert"(%{{.*}}) <{msg = "some message"}> : (i1) -> () 11 | -------------------------------------------------------------------------------- /xdsl/transforms/convert_pdl_to_pdl_interp/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | The pdl-to-pdl-interp conversion works by translating declarative [pdl patterns][xdsl.dialects.pdl] into a set of 3 | [predicates][xdsl.transforms.convert_pdl_to_pdl_interp.predicate] that are then converted to imperative code in 4 | the [pdl_interp dialect][xdsl.dialects.pdl_interp]. 5 | """ 6 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/x86/x86_registers_valid.mlir: -------------------------------------------------------------------------------- 1 | // RUN: XDSL_ROUNDTRIP 2 | 3 | 4 | // CHECK: "test.op"() {unallocated = !x86.avx512maskreg} : () -> () 5 | "test.op"() {unallocated = !x86.avx512maskreg} : () -> () 6 | 7 | // CHECK: "test.op"() {allocated = !x86.avx512maskreg} : () -> () 8 | "test.op"() {allocated = !x86.avx512maskreg} : () -> () 9 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/ltl/ltl_invalid.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s --verify-diagnostics 2 | 3 | 4 | builtin.module { 5 | %seq, %seq2 = "test.op"() : () -> (!ltl.sequence, !ltl.property) 6 | "ltl.and"(%seq, %seq2) : (!ltl.sequence,!ltl.property)->(!ltl.property) 7 | // CHECK: attribute !ltl.sequence expected from variable 'T', but got !ltl.property 8 | } 9 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/vector/vector_broadcast_type_matching.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s --verify-diagnostics | filecheck %s 2 | 3 | "builtin.module"() ({ 4 | 5 | %0 = "test.op"() : () -> index 6 | %1 = "vector.broadcast"(%0) : (index) -> vector<2xi32> 7 | // CHECK: Source operand and result vector must have the same element type. 8 | 9 | }) : () -> () 10 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/vector/vector_createmask_indexing.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s --verify-diagnostics | filecheck %s 2 | 3 | "builtin.module"() ({ 4 | 5 | %0 = "test.op"() : () -> index 6 | 7 | %1 = "vector.create_mask"(%0) : (index) -> vector<2x2xi1> 8 | // CHECK: Expected an operand value for each dimension of resultant mask. 9 | 10 | }) : () -> () 11 | -------------------------------------------------------------------------------- /tests/filecheck/mlir-conversion/with-mlir/scope.mlir: -------------------------------------------------------------------------------- 1 | // RUN: MLIR_GENERIC_ROUNDTRIP 2 | // RUN: MLIR_ROUNDTRIP 3 | 4 | module { 5 | func.func public @my_func() { 6 | return 7 | } 8 | } 9 | 10 | // CHECK: builtin.module { 11 | // CHECK-NEXT: func.func public @my_func() { 12 | // CHECK-NEXT: func.return 13 | // CHECK-NEXT: } 14 | // CHECK-NEXT: } 15 | -------------------------------------------------------------------------------- /tests/dialects/arm/test_assembly_arg_str.py: -------------------------------------------------------------------------------- 1 | from xdsl.backend.assembly_printer import reg 2 | from xdsl.dialects.arm.registers import IntRegisterType 3 | from xdsl.utils.test_value import create_ssa_value 4 | 5 | 6 | def test_assembly_arg_str_ARMRegister(): 7 | x0 = IntRegisterType.from_name("x0") 8 | x0_val = create_ssa_value(x0) 9 | assert reg(x0_val) == "x0" 10 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/vector/vector_load_indexing.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s --verify-diagnostics | filecheck %s 2 | 3 | "builtin.module"() ({ 4 | 5 | %0, %1 = "test.op"() : () -> (memref<4x4xindex>, index) 6 | 7 | %2 = "vector.load"(%0, %1) : (memref<4x4xindex>, index) -> vector<2xindex> 8 | // CHECK: Expected an index for each dimension. 9 | 10 | }) : () -> () 11 | -------------------------------------------------------------------------------- /tests/filecheck/transforms/x86-infer-broadcast.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt -p x86-infer-broadcast %s | filecheck %s 2 | 3 | %ptr = "test.op"() : () -> !x86.reg 4 | %s = x86.dm.mov %ptr, 0 : (!x86.reg) -> !x86.reg 5 | // CHECK: %r = x86.dm.vbroadcastsd %ptr, 0 : (!x86.reg) -> !x86.avx2reg 6 | %r = x86.ds.vpbroadcastq %s : (!x86.reg) -> !x86.avx2reg 7 | "test.op"(%r) : (!x86.avx2reg) -> () 8 | -------------------------------------------------------------------------------- /tests/filecheck/parser-printer/value_tuple.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s | xdsl-opt | filecheck %s 2 | 3 | "builtin.module"() ({ 4 | 5 | %0:3 = "test.op"() : () -> (i32, i64, i32) 6 | "test.op"(%0#1, %0#0) : (i64, i32) -> () 7 | 8 | // CHECK: %0, %1, %2 = "test.op"() : () -> (i32, i64, i32) 9 | // CHECK: "test.op"(%1, %0) : (i64, i32) -> () 10 | 11 | 12 | }) : () -> () 13 | -------------------------------------------------------------------------------- /tests/filecheck/runner/example.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-run %s | filecheck %s 2 | 3 | builtin.module { 4 | func.func @main() { 5 | %6 = arith.constant 6 : index 6 | %7 = arith.constant 7 : index 7 | %42 = arith.muli %6, %7 : index 8 | printf.print_format "The magic number is {}\n", %42 : index 9 | func.return 10 | } 11 | } 12 | 13 | // CHECK: The magic number is 42 14 | -------------------------------------------------------------------------------- /xdsl/utils/hasher.py: -------------------------------------------------------------------------------- 1 | from collections.abc import Hashable 2 | 3 | 4 | class Hasher: 5 | """ 6 | A helper class that accumulates hash values over time. 7 | """ 8 | 9 | hash: int 10 | 11 | def __init__(self, *, seed: int = 0): 12 | self.hash = seed 13 | 14 | def combine(self, other: Hashable) -> None: 15 | self.hash = hash((self.hash, other)) 16 | -------------------------------------------------------------------------------- /scripts/hooks.py: -------------------------------------------------------------------------------- 1 | import os # noqa 2 | 3 | 4 | def build_xdsl_wheel(config: dict[str, str], **kwargs: object): 5 | if os.environ.get("SKIP_BUILD_WHEEL") == "1": 6 | return 7 | 8 | site_dir = config["site_dir"] 9 | 10 | os.system( 11 | f"SETUPTOOLS_SCM_PRETEND_VERSION='0.0.0' uv build --package xdsl --no-build-logs --no-verify-hashes -o {site_dir}" 12 | ) 13 | -------------------------------------------------------------------------------- /tests/filecheck/mlir-conversion/with-mlir/dialects/builtin/location.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt --print-op-generic %s --print-debuginfo | mlir-opt --mlir-print-op-generic --allow-unregistered-dialect --mlir-print-debuginfo --mlir-print-local-scope | xdsl-opt --print-op-generic --print-debuginfo | filecheck %s 2 | 3 | "test.op"() : () -> () loc(unknown) 4 | 5 | // CHECK: "test.op"() : () -> () loc(unknown) 6 | -------------------------------------------------------------------------------- /tests/filecheck/parser-printer/value_tuple_access_oob.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s --allow-unregistered-dialect --parsing-diagnostics | filecheck %s 2 | 3 | "builtin.module"() ({ 4 | 5 | %0:3 = "test.op"() : () -> (i32, i64, i32) 6 | "test.op"(%0#3) : (i32) -> () 7 | // CHECK: SSA value tuple index out of bounds. Tuple is of size 3 but tried to access element 3. 8 | 9 | }) : () -> () 10 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/llvm/array.mlir: -------------------------------------------------------------------------------- 1 | // RUN: XDSL_ROUNDTRIP 2 | builtin.module { 3 | %0 = "llvm.mlir.undef"() : () -> !llvm.array<2 x i64> 4 | %1 = "llvm.mlir.undef"() : () -> !llvm.array<1 x i64> 5 | } 6 | 7 | // CHECK: builtin.module { 8 | // CHECK-NEXT: %0 = "llvm.mlir.undef"() : () -> !llvm.array<2 x i64> 9 | // CHECK-NEXT: %1 = "llvm.mlir.undef"() : () -> !llvm.array<1 x i64> 10 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/vector/vector_store_indexing.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s --verify-diagnostics | filecheck %s 2 | 3 | "builtin.module"() ({ 4 | 5 | %0, %1, %2 = "test.op"() : () -> (vector<2xindex>, memref<4x4xindex>, index) 6 | 7 | "vector.store"(%0, %1, %2) : (vector<2xindex>, memref<4x4xindex>, index) -> () 8 | // CHECK: Expected an index for each dimension. 9 | 10 | }) : () -> () 11 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/builtin/packed.mlir: -------------------------------------------------------------------------------- 1 | // RUN: XDSL_ROUNDTRIP 2 | 3 | "test.op"() { 4 | signed = dense<127> : tensor, 5 | signless = dense<255> : tensor, 6 | unsigned = dense<255> : tensor 7 | } : () -> () 8 | 9 | // CHECK: signed = dense<127> : tensor 10 | // CHECK-SAME: signless = dense<-1> : tensor 11 | // CHECK-SAME: unsigned = dense<255> : tensor 12 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/vector/vector_load_type_matching.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s --verify-diagnostics | filecheck %s 2 | 3 | "builtin.module"() ({ 4 | 5 | %0, %1 = "test.op"() : () -> (memref<4x4xindex>, index) 6 | 7 | %2 = "vector.load"(%0, %1, %1) : (memref<4x4xindex>, index, index) -> vector<2xi32> 8 | // CHECK: MemRef element type should match the Vector element type. 9 | 10 | }) : () -> () 11 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/mod_arith/mod_arith.mlir: -------------------------------------------------------------------------------- 1 | // RUN: XDSL_ROUNDTRIP 2 | // RUN: XDSL_GENERIC_ROUNDTRIP 3 | 4 | %lhsi1, %rhsi1 = "test.op"() : () -> (i1, i1) 5 | 6 | // CHECK: %add_res = mod_arith.add %lhsi1, %rhsi1 {modulus = 17 : i64} : i1 7 | // CHECK-GENERIC: %add_res = "mod_arith.add"(%lhsi1, %rhsi1) <{modulus = 17 : i64}> : (i1, i1) -> i1 8 | %add_res = "mod_arith.add"(%lhsi1, %rhsi1) {modulus=17} : (i1, i1) -> i1 9 | -------------------------------------------------------------------------------- /docs/Toy/examples/lit.cfg: -------------------------------------------------------------------------------- 1 | import lit.formats 2 | import os 3 | 4 | config.test_source_root = os.path.dirname(__file__) 5 | toy_src = os.path.dirname(config.test_source_root) 6 | 7 | config.name = "Toy" 8 | config.test_format = lit.formats.ShTest(preamble_commands=[f"cd {toy_src}"]) 9 | config.suffixes = ['.mlir', '.toy'] 10 | 11 | try: 12 | import riscemu 13 | except ImportError: 14 | config.unsupported = True 15 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/vector/vector_store_type_matching.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s --verify-diagnostics | filecheck %s 2 | 3 | "builtin.module"() ({ 4 | 5 | %0, %1, %2 = "test.op"() : () -> (vector<2xi32>, memref<4x4xindex>, index) 6 | 7 | "vector.store"(%0, %1, %2) : (vector<2xi32>, memref<4x4xindex>, index) -> () 8 | // CHECK: MemRef element type should match the Vector element type. 9 | 10 | }) : () -> () 11 | -------------------------------------------------------------------------------- /tests/filecheck/mlir-conversion/with-mlir/dialects/builtin/builtin_tuple_types.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt --print-op-generic %s | mlir-opt --mlir-print-op-generic --allow-unregistered-dialect | xdsl-opt --print-op-generic | filecheck %s 2 | 3 | "test.op"() {empty = tuple<>, many = tuple, i5>, single = tuple} : () -> () 4 | 5 | // CHECK: empty = tuple<>, many = tuple, i5>, single = tuple 6 | -------------------------------------------------------------------------------- /tests/test_cli.py: -------------------------------------------------------------------------------- 1 | from xdsl.dialects import get_all_dialects 2 | from xdsl.transforms import get_all_passes 3 | 4 | 5 | def test_get_all_passes_names(): 6 | for name, pass_factory in get_all_passes().items(): 7 | assert name == pass_factory().name 8 | 9 | 10 | def test_get_all_dialects_names(): 11 | for name, dialect_factory in get_all_dialects().items(): 12 | assert name == dialect_factory().name 13 | -------------------------------------------------------------------------------- /tests/filecheck/backend/riscv/verify.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt --split-input-file --verify-diagnostics --parsing-diagnostics %s | filecheck %s 2 | 3 | %i1 = "test.op"() : () -> !riscv.reg 4 | %ok_imm = riscv.addi %i1, 1 : (!riscv.reg) -> !riscv.reg 5 | %big_imm = riscv.addi %i1, 2048 : (!riscv.reg) -> !riscv.reg 6 | 7 | // CHECK: Integer value 2048 is out of range for type si12 which supports values in the range [-2048, 2048) 8 | -------------------------------------------------------------------------------- /tests/my_plugin/src/my_plugin/__init__.py: -------------------------------------------------------------------------------- 1 | from xdsl.ir import Dialect 2 | from xdsl.passes import ModulePass 3 | from xdsl.universe import Universe 4 | 5 | 6 | class PluginPass(ModulePass): 7 | name = "plugin-pass" 8 | 9 | 10 | PluginDialect = Dialect("plugin_dialect") 11 | 12 | MY_UNIVERSE = Universe( 13 | all_dialects={"plugin_dialect": lambda: PluginDialect}, 14 | all_passes={"plugin-pass": lambda: PluginPass}, 15 | ) 16 | -------------------------------------------------------------------------------- /tests/filecheck/mlir-conversion/with-mlir/dialects/vector/ops.mlir: -------------------------------------------------------------------------------- 1 | // RUN: MLIR_ROUNDTRIP 2 | // RUN: MLIR_GENERIC_ROUNDTRIP 3 | 4 | // CHECK-LABEL: @bitcast 5 | func.func @bitcast(%a : vector<5x1x4x3xf32>) -> vector<5x1x4x6xi16> { 6 | %0 = vector.bitcast %a : vector<5x1x4x3xf32> to vector<5x1x4x6xi16> 7 | // CHECK-NEXT: %{{.*}} = vector.bitcast %{{.*}} : vector<5x1x4x3xf32> to vector<5x1x4x6xi16> 8 | return %0 : vector<5x1x4x6xi16> 9 | } 10 | -------------------------------------------------------------------------------- /xdsl/parser/__init__.py: -------------------------------------------------------------------------------- 1 | # TID 251 enforces to not import from nested modules 2 | # We need to skip it here to allow importing from here instead. 3 | # To avoid circular imports, affine_parser needs to be imported first 4 | from .affine_parser import * # noqa: TID251 5 | from .attribute_parser import * # noqa: TID251 6 | from .base_parser import * # noqa: TID251 7 | from .core import * # noqa: TID251 8 | from .generic_parser import * # noqa: TID251 9 | -------------------------------------------------------------------------------- /tests/filecheck/transforms/apply-pdl/extra_file.mlir: -------------------------------------------------------------------------------- 1 | // RUN: true 2 | 3 | // Support file for apply_pdl_extra_file.mlir 4 | 5 | pdl.pattern : benefit(1) { 6 | %zero_attr = pdl.attribute = 0 7 | %root = pdl.operation "test.op" {"attr" = %zero_attr} 8 | pdl.rewrite %root { 9 | %one_attr = pdl.attribute = 1 10 | %new_op = pdl.operation "test.op" {"attr" = %one_attr} 11 | pdl.replace %root with %new_op 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/xdsl_tblgen/test_tblgen.py: -------------------------------------------------------------------------------- 1 | from io import StringIO 2 | 3 | from xdsl.tools.xdsl_tblgen import tblgen_to_py 4 | 5 | 6 | def test_run_tblgen_to_py(): 7 | with StringIO() as output: 8 | tblgen_to_py("tests/xdsl_tblgen/test.json", output) 9 | out_str = output.getvalue() 10 | 11 | with open("tests/xdsl_tblgen/test.py") as f: 12 | expected = f.read() 13 | 14 | assert out_str.strip() == expected.strip() 15 | -------------------------------------------------------------------------------- /xdsl/utils/str_enum.py: -------------------------------------------------------------------------------- 1 | from enum import Enum 2 | from typing import Any 3 | 4 | 5 | class StrEnum(str, Enum): 6 | """ 7 | Homemade StrEnum. StrEnum is standard in Python>=3.11. 8 | """ 9 | 10 | @staticmethod 11 | def _generate_next_value_( 12 | name: str, start: int, count: int, last_values: list[Any] 13 | ): 14 | return name.lower() 15 | 16 | def __str__(self) -> str: 17 | return self.value 18 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/builtin/parse_with_location.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s --print-op-generic | filecheck %s 2 | // CHECK: module 3 | "builtin.module"() ({ 4 | // CHECK: ^{{.*}}(%{{.*}}: i32): 5 | ^bb0(%arg: i32 loc(unknown)): 6 | // CHECK: "test.op"() : () -> !test.type<"int"> 7 | %0 = "test.op"() : () -> !test.type<"int"> loc(unknown) 8 | // CHECK: "test.op"() : () -> () 9 | "test.op"() : () -> () loc(unknown) 10 | }) : () -> () 11 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/vector/vector_maskedstore_indexing.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s --verify-diagnostics | filecheck %s 2 | 3 | "builtin.module"() ({ 4 | 5 | %0, %1, %2, %3 = "test.op"() : () -> (memref<2x2xindex>, vector<2xindex>, vector<2xi1>, index) 6 | 7 | "vector.maskedstore"(%0, %3, %2, %1) : (memref<2x2xindex>, index, vector<2xi1>, vector<2xindex>) -> () 8 | // CHECK: Expected an index for each memref dimension. 9 | 10 | }) : () -> () 11 | -------------------------------------------------------------------------------- /tests/filecheck/mlir-conversion/with-mlir/dialects/vector/fma.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt --print-op-generic %s | mlir-opt --mlir-print-op-generic --allow-unregistered-dialect | xdsl-opt | filecheck %s 2 | // RUN: xdsl-opt %s | mlir-opt --mlir-print-op-generic --allow-unregistered-dialect | xdsl-opt | filecheck %s 3 | 4 | 5 | %vf = "test.op"() : () -> vector<2xf32> 6 | %fma = vector.fma %vf, %vf, %vf : vector<2xf32> 7 | 8 | // CHECK: %1 = vector.fma %0, %0, %0 : vector<2xf32> 9 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | codecov: 2 | require_ci_to_pass: true 3 | notify: 4 | wait_for_ci: true 5 | 6 | coverage: 7 | precision: 2 8 | round: down 9 | range: 80...90 10 | 11 | status: 12 | # Learn more at http://docs.codecov.io/docs/codecov-yaml 13 | project: 14 | default: 15 | enabled: yes 16 | target: 1 17 | threshold: 10% 18 | patch: 19 | default: 20 | enabled: off 21 | 22 | ignore: 23 | - "**/*.ipynb" 24 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/vector/vector_maskedload_indexing.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s --verify-diagnostics | filecheck %s 2 | 3 | "builtin.module"() ({ 4 | 5 | %0, %1, %2, %3 = "test.op"() : () -> (memref<2x2xindex>, vector<2xindex>, vector<2xi1>, index) 6 | 7 | %4 = "vector.maskedload"(%0, %3, %2, %1) : (memref<2x2xindex>, index, vector<2xi1>, vector<2xindex>) -> vector<2xindex> 8 | // CHECK: Expected an index for each memref dimension. 9 | 10 | }) : () -> () 11 | -------------------------------------------------------------------------------- /tests/filecheck/mlir-conversion/with-mlir/symbol_tests.mlir: -------------------------------------------------------------------------------- 1 | // RUN: MLIR_GENERIC_ROUNDTRIP 2 | // RUN: MLIR_ROUNDTRIP 3 | 4 | // CHECK: func.func private @symbol_attr() -> () attributes {symbol = @some_symbol} 5 | func.func private @symbol_attr() -> () attributes {symbol = @some_symbol} 6 | // CHECK: func.func private @unranked_tensor_type() -> () attributes {value1 = tensor} 7 | func.func private @unranked_tensor_type() -> () attributes {value1 = tensor} 8 | -------------------------------------------------------------------------------- /tests/filecheck/mlir-conversion/with-mlir/lit.local.cfg: -------------------------------------------------------------------------------- 1 | import shutil 2 | 3 | config.substitutions.append(('MLIR_ROUNDTRIP', "xdsl-opt %s | mlir-opt --allow-unregistered-dialect | xdsl-opt | filecheck %s")) 4 | config.substitutions.append(("MLIR_GENERIC_ROUNDTRIP", "xdsl-opt %s --print-op-generic | mlir-opt --mlir-print-op-generic --allow-unregistered-dialect --mlir-print-local-scope | xdsl-opt | filecheck %s")) 5 | 6 | if not shutil.which("mlir-opt"): 7 | config.unsupported = True 8 | -------------------------------------------------------------------------------- /tests/filecheck/projects/libxsmm/README.md: -------------------------------------------------------------------------------- 1 | # x86 backend integration test 2 | 3 | In addition to the FileCheck test, we provide a harness here to verify that 4 | the x86 assembly code generated by xDSL can be assembled and linked, and 5 | computes a correct matrix multiplication. 6 | 7 | + To check assembly: `make matmul.o` in this directory 8 | + To check linking: `make exe` 9 | + To verify the computation: `make check` (assuming that the host machine is 10 | x86-64 and allows AVX2) 11 | -------------------------------------------------------------------------------- /.github/workflows/release-notes.yml: -------------------------------------------------------------------------------- 1 | name: Release Drafter 2 | 3 | on: 4 | push: 5 | # branches to consider in the event; optional, defaults to all 6 | branches: 7 | - main 8 | 9 | jobs: 10 | update_release_draft: 11 | runs-on: ubuntu-latest 12 | steps: 13 | # Drafts your next Release notes as Pull Requests are merged into "master" 14 | - uses: release-drafter/release-drafter@v6 15 | env: 16 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 17 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": [ 4 | "config:recommended", 5 | ":semanticCommitTypeAll(dependencies)", 6 | ":semanticCommitScopeDisabled" 7 | ], 8 | "labels": [ 9 | "dependencies" 10 | ], 11 | "pre-commit": { 12 | "enabled": true 13 | }, 14 | "nix": { 15 | "enabled": true 16 | }, 17 | "rangeStrategy": "replace", 18 | "lockFileMaintenance": { 19 | "enabled": true 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /tests/filecheck/parser-printer/duplicate_attribute_keys.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s --parsing-diagnostics --split-input-file | filecheck %s 2 | 3 | // CHECK: Duplicate key 'key1' in dictionary attribute 4 | "test.op"() {a = {key1, key1}} : () -> () 5 | 6 | // ----- 7 | 8 | // CHECK: Duplicate key 'key1' in dictionary attribute 9 | "test.op"() {key1, key1} : () -> () 10 | 11 | // ----- 12 | 13 | // CHECK: Duplicate key 'key1' in properties dictionary 14 | "test.op"() <{key1, key1}> : () -> () 15 | -------------------------------------------------------------------------------- /tests/filecheck/transforms/apply-pdl/apply_pdl_property_rewrite.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s -p apply-pdl | filecheck %s 2 | 3 | // CHECK: "test.op"() <{prop1 = i64}> : () -> () 4 | "test.op"() <{"prop1" = i32}> : () -> () 5 | 6 | pdl.pattern : benefit(42) { 7 | %0 = pdl.attribute = i32 8 | %1 = pdl.operation "test.op" {"prop1" = %0} 9 | pdl.rewrite %1 { 10 | %2 = pdl.attribute = i64 11 | %3 = pdl.operation "test.op" {"prop1" = %2} 12 | pdl.replace %1 with %3 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /tests/filecheck/transforms/empty-tensor-to-alloc-tensor.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt -p empty-tensor-to-alloc-tensor %s | filecheck %s 2 | 3 | // CHECK: %val = "test.op"() : () -> index 4 | %val = "test.op"() : () -> index 5 | 6 | // CHECK-NEXT: %static = bufferization.alloc_tensor() : tensor<1024xi32> 7 | %static = tensor.empty() : tensor<1024xi32> 8 | 9 | // CHECK-NEXT: %dynamic = bufferization.alloc_tensor(%val) : tensor<1024x?xi32> 10 | %dynamic = tensor.empty(%val) : tensor<1024x?xi32> 11 | -------------------------------------------------------------------------------- /tests/filecheck/transforms/convert_ptr_type_offsets.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt -p convert-ptr-type-offsets --split-input-file --verify-diagnostics %s | filecheck %s 2 | 3 | %a1 = ptr_xdsl.type_offset i32 : index 4 | // CHECK: %a1 = arith.constant 4 : index 5 | 6 | %a2 = ptr_xdsl.type_offset f128 : index 7 | // CHECK-NEXT: %a2 = arith.constant 16 : index 8 | 9 | // ----- 10 | 11 | %a3 = ptr_xdsl.type_offset tensor<4xi32> : index 12 | // CHECK: Type offset is currently only supported for fixed size types 13 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/stim/attrs.mlir: -------------------------------------------------------------------------------- 1 | // RUN: XDSL_ROUNDTRIP 2 | 3 | "test.op"() { 4 | qubit = !stim.qubit<0>, 5 | qubitcoord = #stim.qubit_coord<(0,0), !stim.qubit<0>> 6 | } : () -> () 7 | 8 | %qubit0 = "test.op"() : () -> (!stim.qubit<0>) 9 | 10 | // CHECK: builtin.module { 11 | // CHECK-NEXT: "test.op"() {qubit = !stim.qubit<0>, qubitcoord = #stim.qubit_coord<(0, 0), !stim.qubit<0>>} : () -> () 12 | // CHECK-NEXT: %qubit0 = "test.op"() : () -> !stim.qubit<0> 13 | // CHECK-NEXT: } 14 | -------------------------------------------------------------------------------- /.github/workflows/markdown-formatting.yml: -------------------------------------------------------------------------------- 1 | # This workflow checks the formatting of markdown files in the repository 2 | name: Markdown Formatting 3 | 4 | on: 5 | pull_request: 6 | 7 | jobs: 8 | code-formatting: 9 | 10 | runs-on: ubuntu-latest 11 | 12 | steps: 13 | - uses: actions/checkout@v5 14 | 15 | - name: markdownlint-cli2-action 16 | uses: DavidAnson/markdownlint-cli2-action@v20 17 | with: 18 | config: '.markdownlint.json' 19 | globs: '**/*.{md,markdown}' 20 | -------------------------------------------------------------------------------- /xdsl/syntax_printer.py: -------------------------------------------------------------------------------- 1 | from xdsl.ir import SSAValue 2 | from xdsl.printer import Printer 3 | from xdsl.utils.color_printer import ColorPrinter 4 | from xdsl.utils.colors import Colors 5 | 6 | 7 | class SyntaxPrinter(Printer, ColorPrinter): 8 | """ 9 | A printer for printing syntax-highlighted mlir code to a terminal. 10 | """ 11 | 12 | def print_ssa_value(self, value: SSAValue) -> str: 13 | with self.colored(Colors.BRIGHT_MAGENTA): 14 | return super().print_ssa_value(value) 15 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/emitc/emitc_attrs.mlir: -------------------------------------------------------------------------------- 1 | // RUN: XDSL_ROUNDTRIP 2 | 3 | //===----------------------------------------------------------------------===// 4 | // OpaqueAttr 5 | //===----------------------------------------------------------------------===// 6 | 7 | "test.op"() { 8 | // CHECK: opaque_attr = #emitc.opaque<"some_value"> 9 | opaque_attr = #emitc.opaque<"some_value">, 10 | // CHECK-SAME: quoted_attr = #emitc.opaque<"\"quoted_attr\""> 11 | quoted_attr = #emitc.opaque<"\"quoted_attr\""> 12 | }: () -> () 13 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/vector/vector_maskedstore_memref_storevec_type_matching.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s --verify-diagnostics | filecheck %s 2 | 3 | "builtin.module"() ({ 4 | 5 | %0, %1, %2, %3 = "test.op"() : () -> (memref<2x2xindex>, vector<2xi32>, vector<2xi1>, index) 6 | 7 | "vector.maskedstore"(%0, %3, %3, %2, %1) : (memref<2x2xindex>, index, index, vector<2xi1>, vector<2xi32>) -> () 8 | // CHECK: MemRef element type should match the stored vector type. Obtained types were index and i32. 9 | 10 | }) : () -> () 11 | -------------------------------------------------------------------------------- /tests/my_plugin/pyproject.toml: -------------------------------------------------------------------------------- 1 | [project] 2 | name = "my_plugin" 3 | description = "Plugin to test pass and transform discovery" 4 | readme = "README.md" 5 | requires-python = ">=3.10" 6 | license = { text = "Apache License v2.0 with LLVM Exceptions" } 7 | authors = [{ name = "Sasha Lopoukhine", email = "sasha@lopoukhine.com" }] 8 | classifiers = ["Programming Language :: Python :: 3"] 9 | dependencies = ["xdsl"] 10 | dynamic = ["version"] 11 | 12 | [project.entry-points.'xdsl.universe'] 13 | my_plugin = 'my_plugin:MY_UNIVERSE' 14 | -------------------------------------------------------------------------------- /xdsl/interpreters/printf.py: -------------------------------------------------------------------------------- 1 | from typing import Any 2 | 3 | from xdsl.dialects.printf import PrintFormatOp 4 | from xdsl.interpreter import Interpreter, InterpreterFunctions, impl, register_impls 5 | 6 | 7 | @register_impls 8 | class PrintfFunctions(InterpreterFunctions): 9 | @impl(PrintFormatOp) 10 | def run_println( 11 | self, interpreter: Interpreter, op: PrintFormatOp, args: tuple[Any, ...] 12 | ): 13 | print(op.format_str.data.format(*args), file=interpreter.file, end="") 14 | return () 15 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/mesh/ops_invalid.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s --split-input-file --verify-diagnostics --allow-unregistered-dialect | filecheck %s 2 | 3 | mesh.mesh @mesh0(shape = []) 4 | 5 | // CHECK: 'mesh.mesh' op rank of mesh is expected to be a positive integer 6 | 7 | // ----- 8 | 9 | 10 | mesh.mesh @mesh0(shape = 8x8x8) 11 | mesh.sharding @mesh0 split_axes = [[0]] halo_sizes = [1] sharded_dims_offsets = [1] : !mesh.sharding 12 | 13 | // CHECK: 'mesh.sharding' cannot use both `halo_sizes` and `sharded_dims_offsets` 14 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/scf/for_args_number.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s --verify-diagnostics | filecheck %s 2 | 3 | "builtin.module"() ({ 4 | %lb = "arith.constant"() {"value" = 0 : index} : () -> index 5 | %ub = "arith.constant"() {"value" = 42 : index} : () -> index 6 | %step = "arith.constant"() {"value" = 7 : index} : () -> index 7 | // CHECK: Expected at least 3 operands, but got 2 8 | "scf.for"(%ub, %step) ({ 9 | ^bb0(%iv : index): 10 | "scf.yield"() : () -> () 11 | }) : (index, index) -> () 12 | }) : () -> () 13 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/scf/for_iv.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s --verify-diagnostics | filecheck %s 2 | "builtin.module"() ({ 3 | %lb = "arith.constant"() {"value" = 0 : index} : () -> index 4 | %ub = "arith.constant"() {"value" = 42 : index} : () -> index 5 | %step = "arith.constant"() {"value" = 7 : index} : () -> index 6 | // CHECK: Body block must have induction var as first block arg 7 | "scf.for"(%lb, %ub, %step) ({ 8 | ^bb0(): 9 | "scf.yield"() : () -> () 10 | }) : (index, index, index) -> () 11 | }) : () -> () 12 | -------------------------------------------------------------------------------- /tests/filecheck/mlir-conversion/with-mlir/dialects/complex/attribute.mlir: -------------------------------------------------------------------------------- 1 | // RUN: MLIR_GENERIC_ROUNDTRIP 2 | // RUN: MLIR_ROUNDTRIP 3 | 4 | // CHECK: "test.op"() {attr = #complex.number<:f64 1.000000e+00, 0.000000e+00> : complex} : () -> () 5 | "test.op"() { 6 | attr = #complex.number<:f64 1.0, 0.0> : complex 7 | } : () -> () 8 | 9 | // CHECK: "test.op"() {attr = #complex.number<:f32 1.000000e+00, 0.000000e+00> : complex} : () -> () 10 | "test.op"() { 11 | attr = #complex.number<:f32 1.0, 0.0> : complex 12 | } : () -> () 13 | -------------------------------------------------------------------------------- /tests/filecheck/transforms/arith-add-immediate-zero.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s -p canonicalize | filecheck %s 2 | 3 | func.func @hello(%n : i32) -> i32 { 4 | %two = arith.constant 0 : i32 5 | %three = arith.constant 0 : i32 6 | %res = arith.addi %two, %n : i32 7 | %res2 = arith.addi %three, %res : i32 8 | func.return %res : i32 9 | } 10 | 11 | 12 | //CHECK: builtin.module { 13 | // CHECK-NEXT: func.func @hello(%n : i32) -> i32 { 14 | // CHECK-NEXT: func.return %n : i32 15 | // CHECK-NEXT: } 16 | // CHECK-NEXT: } 17 | -------------------------------------------------------------------------------- /tests/filecheck/projects/eqsat/identity.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt -p 'eqsat-create-eclasses,eqsat-add-costs{default=1},eqsat-extract' %s | filecheck %s 2 | 3 | func.func @test(%x : index) -> (index) { 4 | %c2 = arith.constant 2 : index 5 | %res = arith.muli %x, %c2 : index 6 | func.return %res : index 7 | } 8 | 9 | // CHECK: func.func @test(%x : index) -> index { 10 | // CHECK-NEXT: %c2 = arith.constant 2 : index 11 | // CHECK-NEXT: %res = arith.muli %x, %c2 : index 12 | // CHECK-NEXT: func.return %res : index 13 | // CHECK-NEXT: } 14 | -------------------------------------------------------------------------------- /tests/filecheck/transforms/apply-pdl/apply_pdl_attribute_rewrite.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s -p apply-pdl | filecheck %s 2 | 3 | // CHECK: %val = arith.constant 1 : i32 4 | %val = arith.constant 0 : i32 5 | 6 | pdl.pattern : benefit(2) { 7 | %0 = pdl.type 8 | %1 = pdl.attribute = 0 : i32 9 | %2 = pdl.operation "arith.constant" {"value" = %1} -> (%0 : !pdl.type) 10 | pdl.rewrite %2 { 11 | %3 = pdl.attribute = 1 : i32 12 | %4 = pdl.operation "arith.constant" {"value" = %3} -> (%0 : !pdl.type) 13 | pdl.replace %2 with %4 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /tests/dialects/test_dialects.py: -------------------------------------------------------------------------------- 1 | from xdsl.dialects import get_all_dialects 2 | 3 | 4 | def test_op_class_names(): 5 | """ 6 | Make sure that all operation class names match our convention of having an "Op" 7 | suffix. 8 | """ 9 | all_dialects = get_all_dialects() 10 | malformed_op_names = tuple( 11 | (op.name, op.__name__) 12 | for dialect_factory in all_dialects.values() 13 | for op in dialect_factory().operations 14 | if op.__name__[-2:] != "Op" 15 | ) 16 | 17 | assert not malformed_op_names 18 | -------------------------------------------------------------------------------- /xdsl/dialects/wasm/encoding.py: -------------------------------------------------------------------------------- 1 | """ 2 | Helpers for encoding modules in the `wasm` dialect to the WebAssembly binary format. 3 | """ 4 | 5 | import abc 6 | from typing import BinaryIO 7 | 8 | 9 | class WasmBinaryEncodingContext: 10 | """ 11 | A class to store the state of encoding. 12 | """ 13 | 14 | 15 | class EncodingException(Exception): ... 16 | 17 | 18 | class WasmBinaryEncodable(abc.ABC): 19 | @abc.abstractmethod 20 | def encode(self, ctx: WasmBinaryEncodingContext, io: BinaryIO) -> None: 21 | raise NotImplementedError() 22 | -------------------------------------------------------------------------------- /tests/filecheck/transforms/apply-pdl-interp/apply_pdl_interp_extra_file.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s -p 'apply-pdl-interp{pdl_interp_file="%p/extra_file.mlir"}' | filecheck %s 2 | 3 | 4 | // CHECK: func.func @impl() -> i32 { 5 | // CHECK-NEXT: %0 = arith.constant 4 : i32 6 | // CHECK-NEXT: %1 = arith.constant 0 : i32 7 | // CHECK-NEXT: func.return %0 : i32 8 | // CHECK-NEXT: } 9 | 10 | func.func @impl() -> i32 { 11 | %0 = arith.constant 4 : i32 12 | %1 = arith.constant 0 : i32 13 | %2 = arith.addi %0, %1 : i32 14 | func.return %2 : i32 15 | } 16 | -------------------------------------------------------------------------------- /tests/transforms/test_transform_interpreter.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | 3 | from xdsl.dialects import builtin 4 | from xdsl.transforms.transform_interpreter import TransformInterpreterPass 5 | from xdsl.utils.exceptions import PassFailedException 6 | 7 | 8 | def test_entry_point_not_found(): 9 | root = builtin.ModuleOp(ops=[]) 10 | with pytest.raises( 11 | PassFailedException, 12 | match="could not find a nested named sequence with name: symbol-name", 13 | ): 14 | TransformInterpreterPass.find_transform_entry_point(root, "symbol-name") 15 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/riscv_func/lower_riscv_func_main.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt -p lower-riscv-func{insert_exit_syscall=true} %s | filecheck %s 2 | 3 | "builtin.module"() ({ 4 | // CHECK: builtin.module { 5 | 6 | riscv_func.func @main() { 7 | riscv_func.return 8 | } 9 | 10 | // CHECK-NEXT: riscv_func.func @main() { 11 | // CHECK-NEXT: %{{.*}} = riscv.li 93 : !riscv.reg 12 | // CHECK-NEXT: riscv.ecall 13 | // CHECK-NEXT: riscv_func.return 14 | // CHECK-NEXT: } 15 | 16 | }) : () -> () 17 | 18 | // CHECK-NEXT: } 19 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/wasm/ops.mlir: -------------------------------------------------------------------------------- 1 | // RUN: XDSL_ROUNDTRIP 2 | // RUN: XDSL_GENERIC_ROUNDTRIP 3 | 4 | // CHECK: builtin.module { 5 | // CHECK-GENERIC: "builtin.module"() ({ 6 | 7 | 8 | wasm.module 9 | // CHECK-NEXT: wasm.module 10 | // CHECK-GENERIC-NEXT: "wasm.module"() : () -> () 11 | 12 | wasm.module attributes {"hello" = "world"} 13 | // CHECK-NEXT: wasm.module attributes {hello = "world"} 14 | // CHECK-GENERIC-NEXT: "wasm.module"() {hello = "world"} : () -> () 15 | 16 | 17 | // CHECK-NEXT: } 18 | // CHECK-GENERIC-NEXT: }) : () -> () 19 | -------------------------------------------------------------------------------- /tests/filecheck/mlir-conversion/with-mlir/dialects/scf/if.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s | mlir-opt --mlir-print-op-generic | filecheck %s 2 | 3 | "builtin.module"() ({ 4 | %0 = "arith.constant"() {"value" = false} : () -> i1 5 | "scf.if"(%0) ({ 6 | "scf.yield"() : () -> () 7 | }, { 8 | "scf.yield"() : () -> () 9 | }) : (i1) -> () 10 | }) : () -> () 11 | 12 | // CHECK: "scf.if"(%{{\d+}}) ({ 13 | // CHECK-NEXT: "scf.yield"() : () -> () 14 | // CHECK-NEXT: }, { 15 | // CHECK-NEXT: "scf.yield"() : () -> () 16 | // CHECK-NEXT: }) : (i1) -> () 17 | -------------------------------------------------------------------------------- /docs/Toy/examples/scalar.toy: -------------------------------------------------------------------------------- 1 | # RUN: python -m toy %s --emit=toy --ir | filecheck %s 2 | 3 | def main() { 4 | var a<2, 2> = 5.5; 5 | print(a); 6 | } 7 | 8 | # CHECK: "toy.func"() ({ 9 | # CHECK-NEXT: %0 = "toy.constant"() {value = dense<5.500000e+00> : tensor} : () -> tensor 10 | # CHECK-NEXT: %1 = "toy.reshape"(%0) : (tensor) -> tensor<2x2xf64> 11 | # CHECK-NEXT: "toy.print"(%1) : (tensor<2x2xf64>) -> () 12 | # CHECK-NEXT: "toy.return"() : () -> () 13 | # CHECK-NEXT: }) {sym_name = "main", function_type = () -> ()} : () -> () 14 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/vector/vector_maskedload_memref_res_type_matching.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s --verify-diagnostics | filecheck %s 2 | 3 | "builtin.module"() ({ 4 | 5 | %0, %1, %2, %3 = "test.op"() : () -> (memref<2x2xindex>, vector<2xindex>, vector<2xi1>, index) 6 | 7 | %4 = "vector.maskedload"(%0, %3, %3, %2, %1) : (memref<2x2xindex>, index, index, vector<2xi1>, vector<2xindex>) -> vector<2xi32> 8 | // CHECK: MemRef element type should match the result vector and passthrough vector element type. Found different element types for memref and result. 9 | 10 | }) : () -> () 11 | -------------------------------------------------------------------------------- /.github/workflows/pythonpublish.yml: -------------------------------------------------------------------------------- 1 | name: Upload to PyPI 2 | 3 | on: 4 | release: 5 | types: [published] 6 | 7 | jobs: 8 | deploy: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v5 12 | 13 | - name: Install uv 14 | uses: astral-sh/setup-uv@v7 15 | 16 | - name: Set up Python 3.11 17 | uses: actions/setup-python@v6 18 | with: 19 | python-version: 3.11 20 | 21 | - name: Build and publish 22 | run: | 23 | uv build 24 | uvx twine upload -u __token__ -p ${{ secrets.PYPI_XDSL_TOKEN }} dist/* 25 | -------------------------------------------------------------------------------- /docs/Toy/toy/emulator/toy_accelerator_instruction_functions.py: -------------------------------------------------------------------------------- 1 | from typing import Any 2 | 3 | from xdsl.dialects import riscv 4 | from xdsl.interpreter import Interpreter, impl, register_impls 5 | from xdsl.interpreters.riscv import RiscvFunctions 6 | 7 | 8 | @register_impls 9 | class ToyAcceleratorInstructionFunctions(RiscvFunctions): 10 | @impl(riscv.EcallOp) 11 | def run_ecall( 12 | self, 13 | interpreter: Interpreter, 14 | op: riscv.EcallOp, 15 | args: tuple[Any, ...], 16 | ): 17 | # In Toy, ecall is always exit 18 | return () 19 | -------------------------------------------------------------------------------- /tests/filecheck/mlir-conversion/with-mlir/dialects/emitc/emitc_attrs.mlir: -------------------------------------------------------------------------------- 1 | // RUN: MLIR_ROUNDTRIP 2 | // RUN: MLIR_GENERIC_ROUNDTRIP 3 | 4 | //===----------------------------------------------------------------------===// 5 | // OpaqueAttr 6 | //===----------------------------------------------------------------------===// 7 | 8 | "test.op"() { 9 | // CHECK: opaque_attr = #emitc.opaque<"some_value"> 10 | opaque_attr = #emitc.opaque<"some_value">, 11 | // CHECK-SAME: quoted_attr = #emitc.opaque<"\"quoted_attr\""> 12 | quoted_attr = #emitc.opaque<"\"quoted_attr\""> 13 | }: () -> () 14 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/arith/arith_constant_fold_interp.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s -p constant-fold-interp | filecheck %s 2 | 3 | // CHECK: builtin.module { 4 | 5 | %i1 = arith.constant 1 : i32 6 | %i2 = arith.constant 2 : i32 7 | %i3 = arith.constant 3 : i32 8 | // CHECK-NEXT: %i1 = arith.constant 1 : i32 9 | // CHECK-NEXT: %i2 = arith.constant 2 : i32 10 | // CHECK-NEXT: %i3 = arith.constant 3 : i32 11 | 12 | %sum3 = arith.addi %i1, %i2 : i32 13 | // CHECK-NEXT: %sum3 = arith.constant 3 : i32 14 | 15 | %sum6 = arith.addi %sum3, %i3 : i32 16 | // CHECK-NEXT: %sum6 = arith.constant 6 : i32 17 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/vector/vector_maskedload_memref_passthrough_type_matching.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s --verify-diagnostics | filecheck %s 2 | 3 | "builtin.module"() ({ 4 | 5 | %0, %1, %2, %3 = "test.op"() : () -> (memref<2x2xi32>, vector<2xindex>, vector<2xi1>, index) 6 | 7 | %4 = "vector.maskedload"(%0, %3, %3, %2, %1) : (memref<2x2xi32>, index, index, vector<2xi1>, vector<2xindex>) -> vector<2xi32> 8 | // CHECK: MemRef element type should match the result vector and passthrough vector element type. Found different element types for memref and passthrough. 9 | 10 | }) : () -> () 11 | -------------------------------------------------------------------------------- /tests/filecheck/parser-printer/invalid_dense_attr.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s --parsing-diagnostics --split-input-file | filecheck %s 2 | 3 | "func.func"() ({}) {function_type = () -> (), value1 = dense<"0x0INVALID"> : tensor<2xf32>, sym_name = "invalid_hex"} : () -> () 4 | 5 | // CHECK: Hex string in denseAttr is invalid 6 | 7 | // ----- 8 | 9 | "func.func"() ({}) {function_type = () -> (), value1 = dense<"0x00BADBAD00BADBAD00BADBAD"> : tensor<2xi32>, sym_name = "invalid_hex_size"} : () -> () 10 | // CHECK: Shape mismatch in dense literal. Expected 2 elements from the type, but got 3 elements 11 | -------------------------------------------------------------------------------- /tests/filecheck/parser-printer/verifier_error.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s --verify-diagnostics | filecheck %s 2 | 3 | builtin.module { 4 | // Operation has an unexpected result 5 | %x = "builtin.module"() : () -> (i32) 6 | } 7 | 8 | // CHECK: "builtin.module"() ({ 9 | // CHECK-NEXT: %x = "builtin.module"() : () -> i32 10 | // CHECK-NEXT: ^^^^^^^^^^^^^^^^^^^^^------------------------------------ 11 | // CHECK-NEXT: | Operation does not verify: Expected 0 results, but got 1 12 | // CHECK-NEXT: --------------------------------------------------------- 13 | // CHECK-NEXT: }) : () -> () 14 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/x86/x86_ops_invalid.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt --verify-diagnostics %s | filecheck %s 2 | 3 | x86_func.func @funcyasm() { 4 | %3 = x86.get_register : () -> !x86.reg 5 | %4 = x86.get_register : () -> !x86.reg 6 | %rflags = x86.ss.cmp %3, %4 : (!x86.reg, !x86.reg) -> !x86.rflags 7 | x86.fallthrough ^fallthrough() 8 | // CHECK: Operation does not verify: Fallthrough op successor must immediately follow its parent. 9 | ^other: 10 | x86.label "other" 11 | ^fallthrough: 12 | x86.label "fallthrough" 13 | x86_func.ret 14 | } 15 | -------------------------------------------------------------------------------- /tests/filecheck/mlir-conversion/with-mlir/dialects/arith/arith_fp_ops.mlir: -------------------------------------------------------------------------------- 1 | // RUN: mlir-opt %s --mlir-print-op-generic | xdsl-opt --print-op-generic | filecheck %s 2 | 3 | "builtin.module"() ({ 4 | %0 = "arith.constant"() {"value" = 1.0 : f32} : () -> f32 5 | %1 = "arith.constant"() {"value" = 1.0 : f64} : () -> f64 6 | %3 = "arith.negf"(%0) : (f32) -> f32 7 | %4 = "arith.negf"(%1) : (f64) -> f64 8 | }) : ()->() 9 | 10 | // CHECK: "arith.negf"(%0) <{fastmath = #arith.fastmath}> : (f32) -> f32 11 | // CHECK: "arith.negf"(%1) <{fastmath = #arith.fastmath}> : (f64) -> f64 12 | -------------------------------------------------------------------------------- /tests/filecheck/transforms/eqsat-serialize-egraph-cycle.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt -p eqsat-serialize-egraph %s | filecheck %s 2 | 3 | // CHECK: {"nodes": {"enode_3": {"op": "arith.addi", "eclass": "eclass_1", "children": ["enode_1", "enode_2"]}, "enode_1": {"op": "arg 0", "eclass": "eclass_1", "children": []}, "enode_2": {"op": "arith.constant 0", "eclass": "eclass_2", "children": []}}} 4 | func.func @egraph(%a : i64) { 5 | %zero = arith.constant 0 : i64 6 | %c_res = eqsat.eclass %a, %sum : i64 7 | %c_zero = eqsat.eclass %zero : i64 8 | %sum = arith.addi %c_res, %c_zero : i64 9 | func.return 10 | } 11 | -------------------------------------------------------------------------------- /tests/dialects/test_arm_func.py: -------------------------------------------------------------------------------- 1 | from xdsl.dialects import arm, arm_func 2 | from xdsl.ir import Region 3 | from xdsl.traits import CallableOpInterface 4 | 5 | 6 | def test_callable_interface(): 7 | a0, a1 = arm.registers.X0, arm.registers.X1 8 | 9 | region = Region() 10 | func = arm_func.FuncOp("callable", region, ((a0, a1), (a0, a1))) 11 | 12 | trait = func.get_trait(CallableOpInterface) 13 | 14 | assert trait is not None 15 | 16 | assert trait.get_callable_region(func) is region 17 | assert trait.get_argument_types(func) == (a0, a1) 18 | assert func.assembly_line() is None 19 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/memref/canonicalize.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt -p canonicalize %s | filecheck %s 2 | 3 | // CHECK: builtin.module { 4 | 5 | 6 | %alloc0 = memref.alloc() : memref<1xf64> 7 | %alloc1 = memref.alloc() : memref<2xf64> 8 | 9 | "test.op"(%alloc1) : (memref<2xf64>) -> () 10 | 11 | memref.dealloc %alloc0 : memref<1xf64> 12 | memref.dealloc %alloc1 : memref<2xf64> 13 | // CHECK-NEXT: %alloc1 = memref.alloc() : memref<2xf64> 14 | // CHECK-NEXT: "test.op"(%alloc1) : (memref<2xf64>) -> () 15 | // CHECK-NEXT: memref.dealloc %alloc1 : memref<2xf64> 16 | 17 | 18 | // CHECK-NEXT: } 19 | -------------------------------------------------------------------------------- /xdsl/frontend/pypdl/__init__.py: -------------------------------------------------------------------------------- 1 | from dataclasses import dataclass 2 | 3 | from xdsl.frontend.pyast.context import PyASTContext 4 | from xdsl.transforms.desymref import FrontendDesymrefyPass 5 | from xdsl.transforms.experimental.func_to_pdl_rewrite import FuncToPdlRewrite 6 | 7 | 8 | @dataclass 9 | class PyPDLContext(PyASTContext): 10 | """Encapsulate the mapping between Python and IR types and operations.""" 11 | 12 | def __init__(self): 13 | super().__init__( 14 | post_transforms=[FrontendDesymrefyPass(), FuncToPdlRewrite()], 15 | post_callback=None, 16 | ) 17 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/printf/invalid.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s --split-input-file --verify-diagnostics | filecheck %s 2 | 3 | builtin.module { 4 | printf.print_format "This will fail {}\n" 5 | } 6 | 7 | // CHECK: Operation does not verify: Number of templates in template string must match number of arguments! 8 | 9 | // ----- 10 | // CHECK: ----- 11 | 12 | builtin.module { 13 | %0 = "test.op"() : () -> i32 14 | printf.print_format "This will fail too {}\n", %0 : i32, %0 : i32 15 | } 16 | 17 | // CHECK: Operation does not verify: Number of templates in template string must match number of arguments! 18 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | # See https://pre-commit.com for more information 2 | # See https://pre-commit.com/hooks.html for more hooks 3 | repos: 4 | - repo: https://github.com/pre-commit/pre-commit-hooks 5 | rev: v6.0.0 6 | hooks: 7 | - id: check-yaml 8 | - id: end-of-file-fixer 9 | - id: mixed-line-ending 10 | - repo: https://github.com/astral-sh/ruff-pre-commit 11 | rev: v0.14.3 12 | hooks: 13 | - id: ruff-check 14 | types_or: [ python, pyi, jupyter ] 15 | args: [ --fix, --exit-non-zero-on-fix ] 16 | - id: ruff-format 17 | types_or: [ python, pyi, jupyter ] 18 | -------------------------------------------------------------------------------- /tests/filecheck/backend/riscv/memref_to_riscv_invalid.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt -p convert-memref-to-riscv --split-input-file --verify-diagnostics %s | filecheck %s 2 | 3 | // CHECK: memref.global value size not divisible by xlen (32) not yet supported. 4 | "memref.global"() {"sym_name" = "global_array", "type" = memref<3xi8>, "sym_visibility" = "public", "initial_value" = dense<[1, 2, 3]> : tensor<3xi8>} : () -> () 5 | 6 | // ----- 7 | 8 | // CHECK: Unsupported memref.global initial value: unit 9 | "memref.global"() {"sym_name" = "uninit_array", "type" = memref<10xf32>, "sym_visibility" = "public", "initial_value" } : () -> () 10 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/scf/parallel_iv.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s --verify-diagnostics | filecheck %s 2 | 3 | "builtin.module"() ({ 4 | %0 = "arith.constant"() {"value" = 0 : index} : () -> index 5 | %1 = "arith.constant"() {"value" = 1000 : index} : () -> index 6 | %2 = "arith.constant"() {"value" = 3 : index} : () -> index 7 | "scf.parallel"(%0, %1, %2) ({ 8 | ^bb0(%i: index, %j: index): 9 | "scf.reduce"() : () -> () 10 | }) {operandSegmentSizes = array} : (index, index, index) -> () 11 | }) : () -> () 12 | 13 | // CHECK: Number of block arguments must exactly equal the number of induction variables 14 | -------------------------------------------------------------------------------- /tests/ir/test_attribute.py: -------------------------------------------------------------------------------- 1 | from xdsl.dialects.builtin import ArrayAttr, IntAttr, StringAttr 2 | 3 | 4 | def test_data_get(): 5 | s = "Hello world" 6 | s_attr = StringAttr(s) 7 | assert StringAttr.get(s) == s_attr 8 | assert StringAttr.get(s_attr) == s_attr 9 | 10 | i = 42 11 | i_attr = IntAttr(i) 12 | assert IntAttr.get(i) == i_attr 13 | assert IntAttr.get(i_attr) == i_attr 14 | 15 | a = ( 16 | IntAttr(1), 17 | IntAttr(2), 18 | IntAttr(3), 19 | ) 20 | a_attr = ArrayAttr(a) 21 | assert ArrayAttr.get(a) == a_attr 22 | assert ArrayAttr.get(a_attr) == a_attr 23 | -------------------------------------------------------------------------------- /xdsl/dialect_interfaces/__init__.py: -------------------------------------------------------------------------------- 1 | from abc import ABC 2 | 3 | 4 | class DialectInterface(ABC): 5 | """ 6 | A base class for dialects' interfaces. 7 | They usually define functionality which is dialect specific to some transformation. 8 | 9 | For example DialectInlinerInterface defines which dialect operations can be inlined and how. 10 | Dialects will implement this interface and the inlining transformation will query them through the base interface. 11 | 12 | The design logic tries to follow MLIR's dialect interfaces closely 13 | https://mlir.llvm.org/docs/Interfaces/#dialect-interfaces 14 | """ 15 | -------------------------------------------------------------------------------- /tests/backend/x86/test_assembly_printing.py: -------------------------------------------------------------------------------- 1 | from xdsl.dialects.builtin import UnitAttr 2 | from xdsl.dialects.x86.assembly import masked_source_str 3 | from xdsl.dialects.x86.registers import AVX512MaskRegisterType, AVX512RegisterType 4 | from xdsl.utils.test_value import create_ssa_value 5 | 6 | 7 | def test_masked_source_str(): 8 | src_reg_val = create_ssa_value(AVX512RegisterType.from_name("zmm0")) 9 | k_val = create_ssa_value(AVX512MaskRegisterType.from_name("k1")) 10 | 11 | assert masked_source_str(src_reg_val, k_val, None) == "zmm0 {k1}" 12 | assert masked_source_str(src_reg_val, k_val, UnitAttr()) == "zmm0 {k1}{z}" 13 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/scf/parallel_blocks_args_types.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s --verify-diagnostics | filecheck %s 2 | 3 | "builtin.module"() ({ 4 | %0 = "arith.constant"() {"value" = 0 : index} : () -> index 5 | %1 = "arith.constant"() {"value" = 1000 : index} : () -> index 6 | %2 = "arith.constant"() {"value" = 3 : index} : () -> index 7 | "scf.parallel"(%0, %1, %2) ({ 8 | ^bb0(%i: i32): 9 | "scf.reduce"() : () -> () 10 | }) {operandSegmentSizes = array} : (index, index, index) -> () 11 | }) : () -> () 12 | 13 | // CHECK: scf.parallel's block must have an index argument for each induction variable 14 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/varith/invalid.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt --parsing-diagnostics --verify-diagnostics --split-input-file 2 | 3 | 4 | %i, %f, %t1, %t2 = "test.op"() : () -> (i32, f32, tensor<10xf32>, tensor<5xf32>) 5 | varith.add %i, %f : i32 6 | // CHECK: operand is used with type i32, but has been previously used or defined with type f32 7 | 8 | 9 | // ----- 10 | // CHECK: ----- 11 | 12 | 13 | %i, %f, %t1, %t2 = "test.op"() : () -> (i32, f32, tensor<10xf32>, tensor<5xf32>) 14 | varith.add %t1, %t2 : tensor<10xf32> 15 | // CHECK: operand is used with type tensor<10xf32>, but has been previously used or defined with type tensor<5xf32> 16 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/scf/for_body_args_types.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s --verify-diagnostics | filecheck %s 2 | "builtin.module"() ({ 3 | %lb = "arith.constant"() {"value" = 0 : index} : () -> index 4 | %ub = "arith.constant"() {"value" = 42 : index} : () -> index 5 | %step = "arith.constant"() {"value" = 7 : index} : () -> index 6 | %carried = "arith.constant"() {"value" = 255 : i8} : () -> i8 7 | "scf.for"(%lb, %ub, %step, %carried) ({ 8 | // CHECK: Block arg #1 expected to be i8, but got index 9 | ^bb0(%iv : index, %carried_arg : index): 10 | "scf.yield"() : () -> () 11 | }) : (index, index, index, i8) -> () 12 | }) : () -> () 13 | -------------------------------------------------------------------------------- /tests/filecheck/mlir-conversion/with-mlir/dialects/vector/reduction.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt --print-op-generic %s | mlir-opt --mlir-print-op-generic --allow-unregistered-dialect | xdsl-opt | filecheck %s 2 | // RUN: xdsl-opt %s | mlir-opt --mlir-print-op-generic --allow-unregistered-dialect | xdsl-opt | filecheck %s 3 | 4 | %vf, %acc = "test.op"() : () -> (vector<2xf32>, f32) 5 | 6 | %sum = vector.reduction , %vf : vector<2xf32> into f32 7 | %sum_1 = vector.reduction , %vf, %acc : vector<2xf32> into f32 8 | 9 | // CHECK: %2 = vector.reduction , %0 : vector<2xf32> into f32 10 | // CHECK: %3 = vector.reduction , %0, %1 : vector<2xf32> into f32 11 | -------------------------------------------------------------------------------- /xdsl/dialects/x86/attributes.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from xdsl.ir import Data 4 | from xdsl.irdl import irdl_attr_definition 5 | from xdsl.parser import AttrParser 6 | from xdsl.printer import Printer 7 | 8 | 9 | @irdl_attr_definition 10 | class LabelAttr(Data[str]): 11 | name = "x86.label" 12 | 13 | @classmethod 14 | def parse_parameter(cls, parser: AttrParser) -> str: 15 | with parser.in_angle_brackets(): 16 | return parser.parse_str_literal() 17 | 18 | def print_parameter(self, printer: Printer) -> None: 19 | with printer.in_angle_brackets(): 20 | printer.print_string_literal(self.data) 21 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/scf/for_body_args_number.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s --verify-diagnostics | filecheck %s 2 | "builtin.module"() ({ 3 | %lb = "arith.constant"() {"value" = 0 : index} : () -> index 4 | %ub = "arith.constant"() {"value" = 42 : index} : () -> index 5 | %step = "arith.constant"() {"value" = 7 : index} : () -> index 6 | %carried = "arith.constant"() {"value" = 255 : i8} : () -> i8 7 | "scf.for"(%lb, %ub, %step, %carried) ({ 8 | // CHECK: Expected 2 args, but got 1. Body block must have induction and loop-carried variables as args 9 | ^bb0(%iv : index): 10 | "scf.yield"() : () -> () 11 | }) : (index, index, index, i8) -> () 12 | }) : () -> () 13 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/scf/yield_implicit.mlir: -------------------------------------------------------------------------------- 1 | // RUN: XDSL_ROUNDTRIP 2 | 3 | %lb, %ub, %step = "test.op"() : () -> (index, index, index) 4 | scf.for %i0 = %lb to %ub step %step { 5 | scf.for %i1 = %lb to %ub step %step { 6 | scf.for %i2 = %lb to %ub step %step { 7 | } 8 | } 9 | } 10 | 11 | // CHECK: %lb, %ub, %step = "test.op"() : () -> (index, index, index) 12 | // CHECK-NEXT: scf.for %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} { 13 | // CHECK-NEXT: scf.for %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} { 14 | // CHECK-NEXT: scf.for %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} { 15 | // CHECK-NEXT: } 16 | // CHECK-NEXT: } 17 | // CHECK-NEXT: } 18 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/snitch_runtime/snitch_runtime_invalid.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s --split-input-file --verify-diagnostics | filecheck %s 2 | 3 | %dst_i64 = arith.constant 100 : i64 4 | %src_i64 = arith.constant 0 : i64 5 | %size = arith.constant 100 : i32 6 | %transfer_id = "snrt.dma_start_1d"(%dst_i64, %src_i64, %size) : (i64, i64, i32) -> i32 7 | // CHECK: Invalid value 64, expected 32 8 | 9 | // ----- 10 | %dst_i32 = arith.constant 100 : i32 11 | %src_i32 = arith.constant 0 : i32 12 | %size = arith.constant 100 : i32 13 | %transfer_id_1 = "snrt.dma_start_1d_wideptr"(%dst_i32, %src_i32, %size) : (i32, i32, i32) -> i32 14 | // CHECK: Invalid value 32, expected 64 15 | -------------------------------------------------------------------------------- /tests/filecheck/parser-printer/scope.mlir: -------------------------------------------------------------------------------- 1 | // RUN: XDSL_ROUNDTRIP 2 | // RUN: XDSL_GENERIC_ROUNDTRIP 3 | 4 | module { 5 | func.func public @my_func() { 6 | return 7 | } 8 | } 9 | 10 | // CHECK: builtin.module { 11 | // CHECK-NEXT: func.func public @my_func() { 12 | // CHECK-NEXT: func.return 13 | // CHECK-NEXT: } 14 | // CHECK-NEXT: } 15 | 16 | // CHECK-GENERIC: "builtin.module"() ({ 17 | // CHECK-GENERIC-NEXT: "func.func"() <{sym_name = "my_func", function_type = () -> (), sym_visibility = "public"}> ({ 18 | // CHECK-GENERIC-NEXT: "func.return"() : () -> () 19 | // CHECK-GENERIC-NEXT: }) : () -> () 20 | // CHECK-GENERIC-NEXT: }) : () -> () 21 | -------------------------------------------------------------------------------- /xdsl/dialects/cmath.irdl: -------------------------------------------------------------------------------- 1 | builtin.module { 2 | irdl.dialect @cmath { 3 | irdl.type @complex { 4 | %0 = irdl.is f32 5 | %1 = irdl.is f64 6 | %2 = irdl.any_of(%0, %1) 7 | irdl.parameters(elem: %2) 8 | } 9 | irdl.operation @norm { 10 | %3 = irdl.any 11 | %4 = irdl.parametric @complex<%3> 12 | irdl.operands(in: %4) 13 | irdl.results(out: %3) 14 | } 15 | irdl.operation @mul { 16 | %5 = irdl.is f32 17 | %6 = irdl.is f64 18 | %7 = irdl.any_of(%5, %6) 19 | %8 = irdl.parametric @complex<%7> 20 | irdl.operands(lhs: %8, rhs: %8) 21 | irdl.results(res: %8) 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /xdsl/interactive/_pasteboard.py: -------------------------------------------------------------------------------- 1 | """ 2 | We use pyclip to copy text to the local pasteboard, but pyclip does not have type 3 | annotations. We add our own mirror of the copy function here. 4 | """ 5 | 6 | from collections.abc import Callable 7 | 8 | _test_pyclip_callback: Callable[[str], None] | None = None 9 | """Used in tests.""" 10 | 11 | 12 | def pyclip_copy(text: str) -> None: 13 | global _test_pyclip_callback 14 | if _test_pyclip_callback is not None: 15 | _test_pyclip_callback(text) 16 | return 17 | 18 | import pyclip # pyright: ignore[reportMissingTypeStubs] 19 | 20 | pyclip.copy(text) # pyright: ignore[reportUnknownMemberType] 21 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/scf/for_body_args_number_much.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s --verify-diagnostics | filecheck %s 2 | "builtin.module"() ({ 3 | %lb = "arith.constant"() {"value" = 0 : index} : () -> index 4 | %ub = "arith.constant"() {"value" = 42 : index} : () -> index 5 | %step = "arith.constant"() {"value" = 7 : index} : () -> index 6 | %carried = "arith.constant"() {"value" = 255 : i8} : () -> i8 7 | "scf.for"(%lb, %ub, %step) ({ 8 | // CHECK: Expected 1 args, but got 2. Body block must have induction and loop-carried variables as args 9 | ^bb0(%iv : index, %carried_arg : i8): 10 | "scf.yield"() : () -> () 11 | }) : (index, index, index) -> () 12 | }) : () -> () 13 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/scf/for_yield.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s --verify-diagnostics | filecheck %s 2 | 3 | "builtin.module"() ({ 4 | %lb = "arith.constant"() {"value" = 0 : index} : () -> index 5 | %ub = "arith.constant"() {"value" = 42 : index} : () -> index 6 | %step = "arith.constant"() {"value" = 7 : index} : () -> index 7 | %carried = "arith.constant"() {"value" = 255 : i8} : () -> i8 8 | "scf.for"(%lb, %ub, %step, %carried) ({ 9 | // CHECK: scf.yield expected 1 args, but got 0. The scf.for must yield its loop-carried variables 10 | ^bb0(%iv : index, %carried_arg : i8): 11 | "scf.yield"() : () -> () 12 | }) : (index, index, index, i8) -> () 13 | }) : () -> () 14 | -------------------------------------------------------------------------------- /tests/dialects/test_emitc.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | 3 | from xdsl.dialects.builtin import DYNAMIC_INDEX, i32 4 | from xdsl.dialects.emitc import EmitC_ArrayType, EmitC_CallOpaqueOp 5 | from xdsl.utils.exceptions import VerifyException 6 | 7 | 8 | def test_emitc_array_negative_dimension(): 9 | with pytest.raises( 10 | VerifyException, match="expected static shape, but got dynamic dimension" 11 | ): 12 | EmitC_ArrayType([DYNAMIC_INDEX], i32) 13 | 14 | 15 | def test_call_opaque_with_str_callee(): 16 | """ 17 | Test that EmitC_CallOpaqueOp can be created with a string callee. 18 | """ 19 | EmitC_CallOpaqueOp(callee="test", call_args=[], result_types=[]) 20 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/scf/parallel_blocks_not_enough_reduce.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s --verify-diagnostics | filecheck %s 2 | 3 | "builtin.module"() ({ 4 | %0 = "arith.constant"() {"value" = 0 : index} : () -> index 5 | %1 = "arith.constant"() {"value" = 1000 : index} : () -> index 6 | %2 = "arith.constant"() {"value" = 3 : index} : () -> index 7 | %3 = "arith.constant"() {"value" = 3 : i32} : () -> i32 8 | %4 = "scf.parallel"(%0, %1, %2, %3) ({ 9 | ^bb0(%i: index): 10 | "scf.reduce"() : () -> () 11 | }) {operandSegmentSizes = array} : (index, index, index, i32) -> (i64) 12 | }) : () -> () 13 | 14 | // CHECK: Expected 1 reductions but 0 provided 15 | -------------------------------------------------------------------------------- /tests/filecheck/transforms/convert_ml_program_to_memref.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s -p convert-ml-program-to-memref | filecheck %s 2 | 3 | ml_program.global private @global_same_type(dense<4> : tensor<4xi32>) : tensor<4xi32> 4 | 5 | %0 = ml_program.global_load_const @global_same_type : tensor<4xi32> 6 | 7 | // CHECK: builtin.module { 8 | // CHECK-NEXT: "memref.global"() <{sym_name = "global_same_type", type = memref<4xi32>, initial_value = dense<4> : tensor<4xi32>, sym_visibility = "private", constant}> : () -> () 9 | // CHECK-NEXT: %0 = memref.get_global @global_same_type : memref<4xi32> 10 | // CHECK-NEXT: %1 = bufferization.to_tensor %0 : memref<4xi32> 11 | // CHECK-NEXT: } 12 | -------------------------------------------------------------------------------- /tests/filecheck/transforms/eqsat-create-eclasses.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt -p eqsat-create-eclasses %s | filecheck %s 2 | 3 | func.func @test(%x : index) -> (index) { 4 | %c2 = arith.constant 2 : index 5 | %res = arith.muli %x, %c2 : index 6 | func.return %res : index 7 | } 8 | 9 | // CHECK: func.func @test(%x : index) -> index { 10 | // CHECK-NEXT: %x_1 = eqsat.eclass %x : index 11 | // CHECK-NEXT: %c2 = arith.constant 2 : index 12 | // CHECK-NEXT: %c2_1 = eqsat.eclass %c2 : index 13 | // CHECK-NEXT: %res = arith.muli %x_1, %c2_1 : index 14 | // CHECK-NEXT: %res_1 = eqsat.eclass %res : index 15 | // CHECK-NEXT: func.return %res_1 : index 16 | // CHECK-NEXT: } 17 | -------------------------------------------------------------------------------- /xdsl/interactive/load_file_screen.tcss: -------------------------------------------------------------------------------- 1 | # LoadFile Screen 2 | LoadFile{ 3 | background: rgba(100,100,100,0.5); 4 | align: center middle; 5 | layout: vertical; 6 | } 7 | 8 | # DirectoryTree 9 | #directory_tree{ 10 | background: $surface; 11 | } 12 | 13 | # Button 14 | #quit_load_file_screen_button{ 15 | width: 100%; 16 | } 17 | 18 | # Container(DirectoryTree, Button) 19 | #directory_tree_container{ 20 | border: heavy $accent-darken-1; 21 | border-title-color: $error-darken-3; 22 | border-title-style: bold; 23 | border-title-align: center; 24 | width: 50%; 25 | height: 50%; 26 | } 27 | 28 | # All Buttons 29 | Button{ 30 | border: $warning; 31 | } 32 | -------------------------------------------------------------------------------- /.github/workflows/ci-nix.yml: -------------------------------------------------------------------------------- 1 | # This workflow enter a nix shell and run the main test suite. 2 | # It's primarily used to check that the nix environment works 3 | 4 | name: CI - Nix-based testing 5 | 6 | on: 7 | push: 8 | branches: 9 | - main 10 | pull_request: 11 | 12 | jobs: 13 | build: 14 | runs-on: ubuntu-latest 15 | 16 | steps: 17 | - uses: actions/checkout@v5 18 | - name: Install Nix 19 | uses: cachix/install-nix-action@v31 20 | with: 21 | github_access_token: ${{ secrets.GITHUB_TOKEN }} 22 | - name: Build venv 23 | run: nix develop --command make venv 24 | - name: Run tests 25 | run: nix develop --command make tests 26 | -------------------------------------------------------------------------------- /tests/dialects/test_riscv_func.py: -------------------------------------------------------------------------------- 1 | from xdsl.dialects import riscv, riscv_func 2 | from xdsl.ir import Region 3 | from xdsl.traits import CallableOpInterface 4 | 5 | 6 | def test_callable_interface(): 7 | a0, a1 = riscv.Registers.A0, riscv.Registers.A1 8 | fa0, fa1 = riscv.Registers.FA0, riscv.Registers.FA1 9 | 10 | region = Region() 11 | func = riscv_func.FuncOp("callable", region, ((a0, a1), (fa0, fa1))) 12 | 13 | trait = func.get_trait(CallableOpInterface) 14 | 15 | assert trait is not None 16 | 17 | assert trait.get_callable_region(func) is region 18 | assert trait.get_argument_types(func) == (a0, a1) 19 | assert trait.get_result_types(func) == (fa0, fa1) 20 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/mesh/attrs.mlir: -------------------------------------------------------------------------------- 1 | // RUN: XDSL_ROUNDTRIP 2 | 3 | "test.op"() {attrs = [ 4 | 5 | #mesh, 6 | // CHECK: #mesh 7 | 8 | #mesh, 9 | // CHECK-SAME: #mesh 10 | 11 | #mesh, 12 | // CHECK-SAME: #mesh 13 | 14 | #mesh, 15 | // CHECK-SAME: #mesh 16 | 17 | #mesh 18 | // CHECK-SAME: #mesh 19 | 20 | ]} : () -> () 21 | -------------------------------------------------------------------------------- /xdsl/backend/riscv/traits.py: -------------------------------------------------------------------------------- 1 | from dataclasses import dataclass, field 2 | 3 | from xdsl.ir import Operation 4 | from xdsl.traits import HasInsnRepresentation 5 | 6 | 7 | @dataclass(frozen=True) 8 | class StaticInsnRepresentation(HasInsnRepresentation): 9 | """ 10 | Returns the first parameter as an insn template string. 11 | 12 | See external [documentation](https://sourceware.org/binutils/docs/as/RISC_002dV_002dDirectives.html). 13 | """ 14 | 15 | insn: str = field(kw_only=True) 16 | 17 | def get_insn(self, op: Operation) -> str: 18 | """ 19 | Return the insn representation of the operation for printing. 20 | """ 21 | return self.insn 22 | -------------------------------------------------------------------------------- /tests/dialects/test_accfg.py: -------------------------------------------------------------------------------- 1 | from xdsl.dialects import accfg, builtin, test 2 | from xdsl.dialects.builtin import StringAttr 3 | 4 | 5 | def test_acc_setup(): 6 | one, two = test.TestOp(result_types=[builtin.i32, builtin.i32]).results 7 | 8 | setup1 = accfg.SetupOp([one, two], ["A", "B"], "acc1") 9 | setup1.verify() 10 | 11 | assert setup1.accelerator == StringAttr("acc1") 12 | 13 | setup2 = accfg.SetupOp(setup1.values, ["A", "B"], setup1.accelerator, setup1) 14 | setup2.verify() 15 | 16 | assert setup2.accelerator == setup1.accelerator 17 | assert isinstance(setup2.out_state.type, accfg.StateType) 18 | assert setup2.out_state.type.accelerator == setup1.accelerator 19 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/scf/for_yield_types.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s --verify-diagnostics | filecheck %s 2 | "builtin.module"() ({ 3 | %lb = "arith.constant"() {"value" = 0 : index} : () -> index 4 | %ub = "arith.constant"() {"value" = 42 : index} : () -> index 5 | %step = "arith.constant"() {"value" = 7 : index} : () -> index 6 | %carried = "arith.constant"() {"value" = 255 : i8} : () -> i8 7 | "scf.for"(%lb, %ub, %step, %carried) ({ 8 | // CHECK: Expected yield arg #0 to be i8, but got index. scf.yield of scf.for must match loop-carried variable types 9 | ^bb0(%iv : index, %carried_arg : i8): 10 | "scf.yield"(%iv) : (index) -> () 11 | }) : (index, index, index, i8) -> () 12 | }) : () -> () 13 | -------------------------------------------------------------------------------- /xdsl/interactive/pass_list_item.py: -------------------------------------------------------------------------------- 1 | from textual.widget import Widget 2 | from textual.widgets import ListItem 3 | 4 | from xdsl.passes import ModulePass 5 | 6 | 7 | class PassListItem(ListItem): 8 | module_pass: type[ModulePass] | ModulePass 9 | 10 | def __init__( 11 | self, 12 | *children: Widget, 13 | module_pass: type[ModulePass] | ModulePass, 14 | name: str | None = None, 15 | id: str | None = None, 16 | classes: str | None = None, 17 | disabled: bool = False, 18 | ): 19 | self.module_pass = module_pass 20 | super().__init__( 21 | *children, name=name, id=id, classes=classes, disabled=disabled 22 | ) 23 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/scf/for_yield_number.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s --verify-diagnostics | filecheck %s 2 | "builtin.module"() ({ 3 | %lb = "arith.constant"() {"value" = 0 : index} : () -> index 4 | %ub = "arith.constant"() {"value" = 42 : index} : () -> index 5 | %step = "arith.constant"() {"value" = 7 : index} : () -> index 6 | %carried = "arith.constant"() {"value" = 255 : i8} : () -> i8 7 | "scf.for"(%lb, %ub, %step, %carried) ({ 8 | // CHECK: scf.yield expected 1 args, but got 2. The scf.for must yield its loop-carried variables 9 | ^bb0(%iv : index, %carried_arg : i8): 10 | "scf.yield"(%carried_arg, %step) : (i8, index) -> () 11 | }) : (index, index, index, i8) -> () 12 | }) : () -> () 13 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/scf/parallel_multiple_blocks.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s --verify-diagnostics | filecheck %s 2 | 3 | "builtin.module"() ({ 4 | %0 = "arith.constant"() {"value" = 0 : index} : () -> index 5 | %1 = "arith.constant"() {"value" = 1000 : index} : () -> index 6 | %2 = "arith.constant"() {"value" = 3 : index} : () -> index 7 | "scf.parallel"(%0, %1, %2) ({ 8 | ^bb0(%i: index, %j: index): 9 | "scf.reduce"() : () -> () 10 | ^bb1(): 11 | "scf.reduce"() : () -> () 12 | }) {operandSegmentSizes = array} : (index, index, index) -> () 13 | }) : () -> () 14 | 15 | // CHECK: Operation does not verify: Region 'body' at position 0 expected a single block, but got 2 blocks 16 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/complex/complex_attr.mlir: -------------------------------------------------------------------------------- 1 | // RUN: XDSL_ROUNDTRIP 2 | // RUN: XDSL_GENERIC_ROUNDTRIP 3 | 4 | "test.op"() {attrs = [ 5 | #complex.number<:f16 3.0, 4.0> : complex, 6 | #complex.number<:f32 3.0, 4.0> : complex 7 | ] 8 | }: () -> () 9 | // CHECK: "test.op"() {attrs = [#complex.number<:f16 3.000000e+00, 4.000000e+00> : complex, #complex.number<:f32 3.000000e+00, 4.000000e+00> : complex]} : () -> () 10 | // CHECK-GENERIC: "test.op"() {attrs = [#complex.number<:f16 3.000000e+00, 4.000000e+00> : complex, #complex.number<:f32 3.000000e+00, 4.000000e+00> : complex]} : () -> () 11 | -------------------------------------------------------------------------------- /tests/filecheck/mlir-conversion/with-mlir/dialects/builtin/vector_type.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt --print-op-generic %s | mlir-opt --mlir-print-op-generic --allow-unregistered-dialect | xdsl-opt --print-op-generic | filecheck %s 2 | 3 | // CHECK: vector<1xindex> 4 | "test.op"() {v.v1 = vector<1xindex>} : () -> () 5 | 6 | // CHECK: vector<[2]xindex> 7 | "test.op"() {v.vs2 = vector<[2]xindex>} : () -> () 8 | 9 | // CHECK: vector<[3]x4xindex> 10 | "test.op"() {v.vs34 = vector<[3]x4xindex>} : () -> () 11 | 12 | // CHECK: vector<[5]x[6]xindex> 13 | "test.op"() {v.vs5s6 = vector<[5]x[6]xindex>} : () -> () 14 | 15 | // CHECK: vector<7x[8]xindex> 16 | "test.op"() {v.v7s8 = vector<7x[8]xindex>} : () -> () 17 | -------------------------------------------------------------------------------- /xdsl/backend/riscv/register_stack.py: -------------------------------------------------------------------------------- 1 | from dataclasses import dataclass 2 | 3 | from typing_extensions import override 4 | 5 | from xdsl.backend.register_stack import RegisterStack 6 | from xdsl.dialects.riscv import FloatRegisterType, IntRegisterType 7 | 8 | 9 | @dataclass 10 | class RiscvRegisterStack(RegisterStack): 11 | """ 12 | Available RISCV-specific registers. 13 | """ 14 | 15 | DEFAULT_ALLOCATABLE_REGISTERS = ( 16 | *reversed(IntRegisterType.allocatable_registers()), 17 | *reversed(FloatRegisterType.allocatable_registers()), 18 | ) 19 | 20 | @classmethod 21 | @override 22 | def default_allocatable_registers(cls): 23 | return RiscvRegisterStack.DEFAULT_ALLOCATABLE_REGISTERS 24 | -------------------------------------------------------------------------------- /xdsl/dialects/wasm/wat.py: -------------------------------------------------------------------------------- 1 | import abc 2 | from contextlib import contextmanager 3 | from dataclasses import dataclass, field 4 | from typing import Any 5 | 6 | 7 | @dataclass(eq=False, repr=False) 8 | class WatPrinter: 9 | stream: Any | None = field(default=None) 10 | 11 | def print_string(self, text: str) -> None: 12 | print(text, end="", file=self.stream) 13 | 14 | @contextmanager 15 | def in_parens(self): 16 | self.print_string("(") 17 | try: 18 | yield 19 | finally: 20 | self.print_string(")") 21 | 22 | 23 | class WatPrintable(abc.ABC): 24 | @abc.abstractmethod 25 | def print_wat(self, printer: WatPrinter) -> None: 26 | raise NotImplementedError() 27 | -------------------------------------------------------------------------------- /xdsl/__init__.py: -------------------------------------------------------------------------------- 1 | class LazyVersion: 2 | """ 3 | Resolving the version dynamically is slow, hence this lazy wrapper to get the version 4 | only when needed. 5 | """ 6 | 7 | _version: str | None 8 | 9 | def __init__(self): 10 | self._version = None 11 | 12 | def __str__(self): 13 | if self._version is None: 14 | from importlib.metadata import PackageNotFoundError, version 15 | 16 | try: 17 | self._version = version("xdsl") 18 | except PackageNotFoundError: 19 | # package is not installed 20 | self._version = "Error: xDSL not installed" 21 | 22 | return self._version 23 | 24 | 25 | __version__ = LazyVersion() 26 | -------------------------------------------------------------------------------- /tests/utils/test_final.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | 3 | from xdsl.utils.runtime_final import is_runtime_final, runtime_final 4 | 5 | 6 | class NotFinal: 7 | """A non-Final class.""" 8 | 9 | 10 | @runtime_final 11 | class Final: 12 | """A Final class.""" 13 | 14 | 15 | def test_is_runtime_final(): 16 | """Check that `is_runtime_final` returns the correct value.""" 17 | assert not is_runtime_final(NotFinal) 18 | assert is_runtime_final(Final) 19 | 20 | 21 | def test_final_inheritance_error(): 22 | """Check that final classes cannot be subclassed.""" 23 | with pytest.raises(TypeError, match="Subclassing final classes is restricted"): 24 | 25 | class SubFinal(Final): 26 | pass 27 | 28 | SubFinal() 29 | -------------------------------------------------------------------------------- /.readthedocs.yaml: -------------------------------------------------------------------------------- 1 | version: 2 2 | 3 | build: 4 | os: "ubuntu-24.04" 5 | tools: 6 | python: "3.13" 7 | # We recommend using a requirements file for reproducible builds. 8 | # This is just a quick example to get started. 9 | # https://docs.readthedocs.io/page/guides/reproducible-builds.html 10 | jobs: 11 | create_environment: 12 | - asdf plugin add uv 13 | - asdf install uv latest 14 | - asdf global uv latest 15 | # https://docs.readthedocs.com/platform/stable/reference/environment-variables.html#envvar-READTHEDOCS_VIRTUALENV_PATH 16 | - VENV_EXTRAS="--all-extras" VENV_DIR="$READTHEDOCS_VIRTUALENV_PATH" make venv 17 | install: 18 | - "true" 19 | 20 | mkdocs: 21 | configuration: mkdocs.yml 22 | -------------------------------------------------------------------------------- /tests/filecheck/transforms/memref_stream_infer_fill.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s -p memref-stream-infer-fill | filecheck %s 2 | 3 | // CHECK: builtin.module { 4 | 5 | %Z, %zero = "test.op"() : () -> (memref<8x8xf64>, f64) 6 | // CHECK-NEXT: %Z, %zero = "test.op"() : () -> (memref<8x8xf64>, f64) 7 | 8 | memref_stream.generic { 9 | bounds = [8, 8], 10 | indexing_maps = [ 11 | affine_map<(d0, d1) -> ()>, 12 | affine_map<(d0, d1) -> (d0, d1)> 13 | ], 14 | iterator_types = ["parallel", "parallel"] 15 | } ins(%zero : f64) outs(%Z : memref<8x8xf64>) { 16 | ^bb0(%in: f64, %out: f64): 17 | memref_stream.yield %in : f64 18 | } 19 | // CHECK-NEXT: memref_stream.fill %Z with %zero : memref<8x8xf64> 20 | 21 | // CHECK-NEXT: } 22 | -------------------------------------------------------------------------------- /tests/filecheck/mlir-conversion/with-mlir/dialects/ml_program/ops.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s | xdsl-opt | mlir-opt --allow-unregistered-dialect | filecheck %s 2 | 3 | ml_program.global private @global_same_type(dense<4> : tensor<4xi32>) : tensor<4xi32> 4 | ml_program.global private mutable @global_mutable_undef : tensor 5 | 6 | %0 = ml_program.global_load_const @global_same_type : tensor<4xi32> 7 | 8 | // CHECK: module { 9 | // CHECK-NEXT: ml_program.global private @global_same_type(dense<4> : tensor<4xi32>) : tensor<4xi32> 10 | // CHECK-NEXT: ml_program.global private mutable @global_mutable_undef : tensor 11 | // CHECK-NEXT: %global_same_type = ml_program.global_load_const @global_same_type : tensor<4xi32> 12 | // CHECK-NEXT: } 13 | -------------------------------------------------------------------------------- /tests/filecheck/projects/libxsmm/Makefile: -------------------------------------------------------------------------------- 1 | CC=clang -march=x86-64 2 | LD=clang 3 | 4 | check: exe 5 | @./$< 6 | 7 | exe: matmul.o main.o matmul.o 8 | @$(LD) $^ -o $@ 9 | 10 | main.o: main.c 11 | @$(CC) -c $< -o $@ 12 | 13 | matmul.o: matmul.s 14 | @$(CC) -c $< -o $@ -Wa,--noexecstack 15 | 16 | matmul.s: integration_test_matmul.mlir 17 | @uv run xdsl-opt $< -p test-vectorize-matmul,convert-vector-to-ptr,convert-memref-to-ptr{lower_func=true},convert-ptr-type-offsets,canonicalize,convert-func-to-x86-func,convert-vector-to-x86{arch=avx2},convert-ptr-to-x86{arch=avx2},convert-arith-to-x86,reconcile-unrealized-casts,canonicalize,x86-infer-broadcast,dce,x86-allocate-registers,canonicalize -t x86-asm > $@ 18 | 19 | clean: 20 | rm -f main.o matmul.o matmul.s exe 21 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/x86_func/x86_func_ops.mlir: -------------------------------------------------------------------------------- 1 | // RUN: XDSL_ROUNDTRIP 2 | // RUN: XDSL_GENERIC_ROUNDTRIP 3 | // RUN: xdsl-opt -t x86-asm %s | filecheck %s --check-prefix=CHECK-ASM 4 | 5 | // CHECK: x86_func.func @noarg_void() { 6 | // CHECK-NEXT: x86_func.ret {comment = "this is a return instruction"} 7 | // CHECK-NEXT: } 8 | // CHECK-ASM: noarg_void: 9 | // CHECK-ASM: ret # this is a return instruction 10 | x86_func.func @noarg_void() { 11 | x86_func.ret {"comment" = "this is a return instruction"} 12 | } 13 | 14 | // CHECK-GENERIC: "x86_func.func"() ({ 15 | // CHECK-GENERIC-NEXT: "x86_func.ret"() {comment = "this is a return instruction"} : () -> () 16 | // CHECK-GENERIC-NEXT: }) {sym_name = "noarg_void", function_type = () -> ()} : () -> () 17 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/arm_func/arm_func_ops.mlir: -------------------------------------------------------------------------------- 1 | // RUN: XDSL_ROUNDTRIP 2 | // RUN: XDSL_GENERIC_ROUNDTRIP 3 | // RUN: xdsl-opt -t arm-asm %s | filecheck %s --check-prefix=CHECK-ASM 4 | 5 | // CHECK: arm_func.func @noarg_void() { 6 | // CHECK-NEXT: arm_func.return {comment = "this is a return instruction"} 7 | // CHECK-NEXT: } 8 | // CHECK-ASM: noarg_void: 9 | // CHECK-ASM: ret # this is a return instruction 10 | arm_func.func @noarg_void() { 11 | arm_func.return {"comment" = "this is a return instruction"} 12 | } 13 | 14 | // CHECK-GENERIC: "arm_func.func"() ({ 15 | // CHECK-GENERIC-NEXT: "arm_func.return"() {comment = "this is a return instruction"} : () -> () 16 | // CHECK-GENERIC-NEXT: }) {sym_name = "noarg_void", function_type = () -> ()} : () -> () 17 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/ltl/ltl_op.mlir: -------------------------------------------------------------------------------- 1 | // RUN: XDSL_ROUNDTRIP 2 | 3 | builtin.module { 4 | %b, %seq, %p = "test.op"() : () -> (i1, !ltl.sequence, !ltl.property) 5 | "ltl.and"(%seq, %seq) : (!ltl.sequence, !ltl.sequence) -> !ltl.sequence 6 | "ltl.and"(%p, %p) : (!ltl.property, !ltl.property) -> !ltl.property 7 | "ltl.and"(%b, %b) : (i1, i1) -> i1 8 | } 9 | 10 | // CHECK: builtin.module { 11 | // CHECK-NEXT: %b, %seq, %p = "test.op"() : () -> (i1, !ltl.sequence, !ltl.property) 12 | // CHECK-NEXT: "ltl.and"(%seq, %seq) : (!ltl.sequence, !ltl.sequence) -> !ltl.sequence 13 | // CHECK-NEXT: "ltl.and"(%p, %p) : (!ltl.property, !ltl.property) -> !ltl.property 14 | // CHECK-NEXT: "ltl.and"(%b, %b) : (i1, i1) -> i1 15 | // CHECK-NEXT: } 16 | -------------------------------------------------------------------------------- /xdsl/backend/x86/register_stack.py: -------------------------------------------------------------------------------- 1 | from dataclasses import dataclass 2 | 3 | from typing_extensions import override 4 | 5 | from xdsl.backend.register_stack import RegisterStack 6 | from xdsl.dialects.x86 import registers 7 | 8 | 9 | @dataclass 10 | class X86RegisterStack(RegisterStack): 11 | """ 12 | Available x86-specific registers. 13 | """ 14 | 15 | DEFAULT_ALLOCATABLE_REGISTERS = ( 16 | *reversed(registers.GeneralRegisterType.allocatable_registers()), 17 | *reversed(registers.AVX2RegisterType.allocatable_registers()), 18 | *reversed(registers.AVX512RegisterType.allocatable_registers()), 19 | ) 20 | 21 | @classmethod 22 | @override 23 | def default_allocatable_registers(cls): 24 | return cls.DEFAULT_ALLOCATABLE_REGISTERS 25 | -------------------------------------------------------------------------------- /xdsl/transforms/canonicalization_patterns/utils.py: -------------------------------------------------------------------------------- 1 | from xdsl.dialects import arith 2 | from xdsl.dialects.builtin import IntegerAttr 3 | from xdsl.ir import SSAValue 4 | 5 | 6 | def const_evaluate_operand_attribute(operand: SSAValue) -> IntegerAttr | None: 7 | """ 8 | Try to constant evaluate an SSA value, returning None on failure. 9 | """ 10 | if isinstance(op := operand.owner, arith.ConstantOp) and isinstance( 11 | val := op.value, IntegerAttr 12 | ): 13 | return val 14 | 15 | 16 | def const_evaluate_operand(operand: SSAValue) -> int | None: 17 | """ 18 | Try to constant evaluate an SSA value, returning None on failure. 19 | """ 20 | if (attr := const_evaluate_operand_attribute(operand)) is not None: 21 | return attr.value.data 22 | -------------------------------------------------------------------------------- /tests/backend/test_assembly_printer.py: -------------------------------------------------------------------------------- 1 | from xdsl.backend.assembly_printer import reg 2 | from xdsl.backend.register_type import RegisterType 3 | from xdsl.irdl import irdl_attr_definition 4 | from xdsl.utils.test_value import create_ssa_value 5 | 6 | 7 | @irdl_attr_definition 8 | class TestRegister(RegisterType): 9 | name = "test.reg" 10 | 11 | @classmethod 12 | def index_by_name(cls) -> dict[str, int]: 13 | return {"x0": 0, "x1": 1, "a0": 0, "a1": 1} 14 | 15 | @classmethod 16 | def infinite_register_prefix(cls): 17 | return "y" 18 | 19 | 20 | def test_reg(): 21 | x0_val = create_ssa_value(TestRegister.from_name("x0")) 22 | x1_val = create_ssa_value(TestRegister.from_name("x1")) 23 | assert reg(x0_val) == "x0" 24 | assert reg(x1_val) == "x1" 25 | -------------------------------------------------------------------------------- /tests/filecheck/parser-printer/parse_error.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s --parsing-diagnostics --split-input-file | filecheck %s 2 | 3 | "test.op"(abc) : () -> () 4 | // CHECK: {{.*}}tests/filecheck/parser-printer/parse_error.mlir:3:11 5 | // CHECK-NEXT: "test.op"(abc) : () -> () 6 | // CHECK-NEXT: ^^^ 7 | // CHECK-NEXT: operand expected 8 | 9 | // ----- 10 | 11 | test.op : () -> () 12 | 13 | // CHECK: {{.*}}tests/filecheck/parser-printer/parse_error.mlir:11:9 14 | // CHECK-NEXT: test.op : () -> () 15 | // CHECK-NEXT: ^ 16 | // CHECK-NEXT: Operation test.op does not have a custom format. 17 | 18 | // ----- 19 | 20 | module { 21 | "test.op"() [^unknown_successor]: () -> () 22 | } 23 | 24 | // CHECK: reference to block "^unknown_successor" without implementation 25 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/scf/parallel_bounds.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s --verify-diagnostics | filecheck %s 2 | 3 | "builtin.module"() ({ 4 | %0 = "arith.constant"() {"value" = 0 : index} : () -> index 5 | %1 = "arith.constant"() {"value" = 1000 : index} : () -> index 6 | %2 = "arith.constant"() {"value" = 3 : index} : () -> index 7 | %3 = "arith.constant"() {"value" = 0 : index} : () -> index 8 | %4 = "arith.constant"() {"value" = 1000 : index} : () -> index 9 | "scf.parallel"(%0, %3, %1, %4, %2) ({ 10 | ^bb0(%i: index): 11 | "scf.reduce"() : () -> () 12 | }) {operandSegmentSizes = array} : (index, index, index, index, index) -> () 13 | }) : () -> () 14 | 15 | // CHECK: Expected the same number of lower bounds, upper bounds, and steps for scf.parallel. Got 2, 2 and 1. 16 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/pdl/pdl_native_rewrite.mlir: -------------------------------------------------------------------------------- 1 | // RUN: XDSL_ROUNDTRIP 2 | 3 | pdl.pattern @nativeRewrite : benefit(1) { 4 | %type = pdl.type 5 | 6 | %operand = pdl.operand 7 | 8 | %attr = pdl.attribute 9 | 10 | // A bound operation 11 | %root = pdl.operation "test.test"(%operand : !pdl.value) 12 | {"value1" = %attr} 13 | -> (%type : !pdl.type) 14 | 15 | pdl.rewrite %root { 16 | %res_op = pdl.apply_native_rewrite "myRewrite"(%type, %operand, %attr : !pdl.type, !pdl.value, !pdl.attribute) : !pdl.operation 17 | pdl.replace %root with %res_op 18 | } 19 | } 20 | 21 | // CHECK: @nativeRewrite 22 | // CHECK: %{{.*}} = pdl.apply_native_rewrite "myRewrite"(%{{.*}}, %{{.*}}, %{{.*}} : !pdl.type, !pdl.value, !pdl.attribute) : !pdl.operation 23 | -------------------------------------------------------------------------------- /tests/filecheck/transforms/individual_rewrite/riscv.mlir: -------------------------------------------------------------------------------- 1 | // RUN:xdsl-opt %s -p 'apply-individual-rewrite{matched_operation_index=4 operation_name="riscv.add" pattern_name="AddImmediates"}'| filecheck %s 2 | 3 | %a = riscv.li 1 : !riscv.reg 4 | %b = riscv.li 2 : !riscv.reg 5 | %c = riscv.li 3 : !riscv.reg 6 | %d = riscv.add %a, %b : (!riscv.reg, !riscv.reg) -> !riscv.reg 7 | %e = riscv.add %b, %c : (!riscv.reg, !riscv.reg) -> !riscv.reg 8 | 9 | 10 | //CHECK: builtin.module { 11 | // CHECK-NEXT: %a = riscv.li 1 : !riscv.reg 12 | // CHECK-NEXT: %b = riscv.li 2 : !riscv.reg 13 | // CHECK-NEXT: %c = riscv.li 3 : !riscv.reg 14 | // CHECK-NEXT: %d = riscv.li 3 : !riscv.reg 15 | // CHECK-NEXT: %e = riscv.add %b, %c : (!riscv.reg, !riscv.reg) -> !riscv.reg 16 | // CHECK-NEXT: } 17 | -------------------------------------------------------------------------------- /tests/test_printing_hints.py: -------------------------------------------------------------------------------- 1 | """ 2 | Test type_repr, which is the function used to print type hints. 3 | """ 4 | 5 | from typing import Any 6 | 7 | import pytest 8 | 9 | from xdsl.utils.hints import type_repr 10 | 11 | 12 | class A: 13 | pass 14 | 15 | 16 | @pytest.mark.parametrize( 17 | "type, expected", 18 | [ 19 | (int, "int"), 20 | (str, "str"), 21 | (list[int], "list[int]"), 22 | (list[list[int]], "list[list[int]]"), 23 | (..., "..."), 24 | (A, "A"), 25 | (list[A], "list[A]"), 26 | (A | int, "A|int"), 27 | (list[A] | int, "list[A]|int"), 28 | (None, "None"), 29 | (int | None, "int|None"), 30 | ], 31 | ) 32 | def test_type_repr(type: Any, expected: str): 33 | assert type_repr(type) == expected 34 | -------------------------------------------------------------------------------- /xdsl/utils/colors.py: -------------------------------------------------------------------------------- 1 | from xdsl.utils.str_enum import StrEnum 2 | 3 | 4 | class Colors(StrEnum): 5 | """ 6 | Color escape codes supported in xDSL. See: 7 | https://en.wikipedia.org/wiki/ANSI_escape_code#3-bit_and_4-bit 8 | for color definitions. 9 | """ 10 | 11 | BLACK = "\033[30m" 12 | RED = "\033[31m" 13 | GREEN = "\033[32m" 14 | YELLOW = "\033[33m" 15 | BLUE = "\033[34m" 16 | MAGENTA = "\033[35m" 17 | CYAN = "\033[36m" 18 | WHITE = "\033[37m" 19 | 20 | BRIGHT_BLACK = "\033[90m" 21 | BRIGHT_RED = "\033[91m" 22 | BRIGHT_GREEN = "\033[92m" 23 | BRIGHT_YELLOW = "\033[93m" 24 | BRIGHT_BLUE = "\033[94m" 25 | BRIGHT_MAGENTA = "\033[95m" 26 | BRIGHT_CYAN = "\033[96m" 27 | BRIGHT_WHITE = "\033[97m" 28 | 29 | 30 | RESET = "\033[0m" 31 | -------------------------------------------------------------------------------- /xdsl/interpreters/riscv_debug.py: -------------------------------------------------------------------------------- 1 | from dataclasses import dataclass 2 | from typing import Any 3 | 4 | from xdsl.dialects import riscv_debug 5 | from xdsl.interpreter import ( 6 | Interpreter, 7 | InterpreterFunctions, 8 | impl, 9 | register_impls, 10 | ) 11 | from xdsl.interpreters.riscv import RiscvFunctions 12 | 13 | 14 | @dataclass 15 | @register_impls 16 | class RiscvDebugFunctions(InterpreterFunctions): 17 | @impl(riscv_debug.PrintfOp) 18 | def run_printf( 19 | self, 20 | interpreter: Interpreter, 21 | op: riscv_debug.PrintfOp, 22 | args: tuple[Any, ...], 23 | ): 24 | args = RiscvFunctions.get_reg_values(interpreter, op.operands, args) 25 | print(op.format_str.data.format(*args), end="", file=interpreter.file) 26 | return () 27 | -------------------------------------------------------------------------------- /xdsl/frontend/pyast/utils/block.py: -------------------------------------------------------------------------------- 1 | import ast 2 | from typing import Any 3 | 4 | 5 | def block(*params: Any): 6 | """ 7 | Decorator used to mark function as a basic block. 8 | ``` 9 | def foo(a: int) -> int: 10 | @block 11 | def bb0(x: int): 12 | y: int = x + 2 13 | bb1(y) 14 | 15 | @block 16 | def bb1(z: int): 17 | return z 18 | 19 | # Entry-point. 20 | bb0(a) 21 | ``` 22 | """ 23 | 24 | def decorate(*params: Any): 25 | return None 26 | 27 | return decorate 28 | 29 | 30 | def is_block(node: ast.FunctionDef) -> bool: 31 | return ( 32 | len(node.decorator_list) == 1 33 | and isinstance(name := node.decorator_list[0], ast.Name) 34 | and name.id == "block" 35 | ) 36 | -------------------------------------------------------------------------------- /xdsl/dialects/utils/fast_math.py: -------------------------------------------------------------------------------- 1 | from abc import ABC 2 | from dataclasses import dataclass 3 | 4 | from xdsl.ir import BitEnumAttribute 5 | from xdsl.utils.str_enum import StrEnum 6 | 7 | 8 | class FastMathFlag(StrEnum): 9 | """ 10 | Values specifying fast math behaviour of an arithmetic operation. 11 | """ 12 | 13 | REASSOC = "reassoc" 14 | NO_NANS = "nnan" 15 | NO_INFS = "ninf" 16 | NO_SIGNED_ZEROS = "nsz" 17 | ALLOW_RECIP = "arcp" 18 | ALLOW_CONTRACT = "contract" 19 | APPROX_FUNC = "afn" 20 | 21 | 22 | @dataclass(frozen=True, init=False) 23 | class FastMathAttrBase(BitEnumAttribute[FastMathFlag], ABC): 24 | """ 25 | Base class for attributes defining fast math behavior of arithmetic operations. 26 | """ 27 | 28 | none_value = "none" 29 | all_value = "fast" 30 | -------------------------------------------------------------------------------- /tests/backend/test_asm_reporter.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | 3 | from xdsl.backend.block_throughput_cost_model import MCABlockThroughputCostModel 4 | from xdsl.builder import Builder 5 | from xdsl.dialects import x86_func 6 | 7 | llvm_mca_available = MCABlockThroughputCostModel.is_installed() 8 | 9 | 10 | @pytest.mark.skipif(not llvm_mca_available, reason="llvm-mca is not installed") 11 | def test_mca_reporter_x86(): 12 | @Builder.implicit_region 13 | def trivial_x86_func(): 14 | x86_func.RetOp() 15 | 16 | reporter = MCABlockThroughputCostModel( 17 | target="x86_64-unknown-linux-gnu", arch="skylake" 18 | ) 19 | estimated_cost = reporter.estimate_throughput(trivial_x86_func.block) 20 | assert estimated_cost is not None, ( 21 | "MCA reporter should return a valid cost estimate" 22 | ) 23 | -------------------------------------------------------------------------------- /tests/filecheck/mlir-conversion/with-mlir/dialects/arith/arith_bcast.mlir: -------------------------------------------------------------------------------- 1 | // RUN: mlir-opt %s --allow-unregistered-dialect | xdsl-opt | filecheck %s 2 | 3 | // CHECK: %0 = "test.op"() : () -> i32 4 | // CHECK-NEXT: %1 = arith.bitcast %0 : i32 to i32 5 | // CHECK-NEXT: %2 = arith.bitcast %0 : i32 to f32 6 | // CHECK-NEXT: %3 = arith.bitcast %2 : f32 to i32 7 | 8 | // CHECK-NEXT: %4 = "test.op"() : () -> i64 9 | // CHECK-NEXT: %5 = arith.bitcast %4 : i64 to f64 10 | // CHECK-NEXT: %6 = arith.bitcast %5 : f64 to i64 11 | 12 | %0 = "test.op"() : () -> i32 13 | %1 = "arith.bitcast"(%0) : (i32) -> i32 14 | %2 = "arith.bitcast"(%0) : (i32) -> f32 15 | %3 = "arith.bitcast"(%2) : (f32) -> i32 16 | 17 | %4 = "test.op"() : () -> i64 18 | %5 = "arith.bitcast"(%4) : (i64) -> f64 19 | %6 = "arith.bitcast"(%5) : (f64) -> i64 20 | -------------------------------------------------------------------------------- /tests/filecheck/transforms/apply-pdl/apply_pdl_insert_operation.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s -p apply-pdl | filecheck %s 2 | 3 | "test.op"() {attr = 0} : () -> () 4 | 5 | // CHECK: "test.op"() {attr = 1 : i64} : () -> () 6 | // CHECK-NEXT: "test.op"() {attr = "extra"} : () -> () 7 | 8 | 9 | pdl.pattern : benefit(1) { 10 | %zero_attr = pdl.attribute = 0 11 | %op = pdl.operation "test.op" {"attr" = %zero_attr} 12 | pdl.rewrite %op { 13 | %one_attr = pdl.attribute = 1 14 | %new_op = pdl.operation "test.op" {"attr" = %one_attr} 15 | 16 | // even if an op is not explicitly used in a replace, it should be inserted. 17 | %extra_attr = pdl.attribute = "extra" 18 | %extra_op = pdl.operation "test.op" {"attr" = %extra_attr} 19 | 20 | pdl.replace %op with %new_op 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | description = "xDSL devshell"; 3 | 4 | inputs = { 5 | nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable"; 6 | flake-utils.url = "github:numtide/flake-utils"; 7 | }; 8 | 9 | outputs = { nixpkgs, flake-utils, ... }: 10 | flake-utils.lib.eachDefaultSystem ( 11 | system: 12 | let 13 | pkgs = import nixpkgs { 14 | inherit system; 15 | }; 16 | in 17 | { 18 | devShells.default = with pkgs; mkShell { 19 | LD_LIBRARY_PATH = lib.makeLibraryPath [ stdenv.cc.cc.lib zlib ]; 20 | buildInputs = [ 21 | uv 22 | nodejs_22 23 | llvmPackages_21.mlir 24 | llvmPackages_21.tblgen 25 | ]; 26 | }; 27 | } 28 | ); 29 | } 30 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/scf/unregistered.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s --split-input-file --print-op-generic --allow-unregistered-dialect | xdsl-opt --allow-unregistered-dialect | filecheck %s 2 | 3 | // CHECK: %0 = arith.constant 0 : index 4 | // CHECK-NEXT: scf.for %iv = %0 to %0 step %0 { 5 | // CHECK-NEXT: "unregistered_op"() : () -> () 6 | // CHECK-NEXT: } 7 | 8 | %0 = arith.constant 0 : index 9 | scf.for %iv = %0 to %0 step %0 { 10 | "unregistered_op"() : () -> () 11 | scf.yield 12 | } 13 | 14 | // ----- 15 | 16 | // CHECK: %0 = arith.constant 0 : index 17 | // CHECK-NEXT: scf.for %iv = %0 to %0 step %0 { 18 | // CHECK-NEXT: "unregistered_op"() : () -> () 19 | // CHECK-NEXT: } 20 | 21 | %0 = arith.constant 0 : index 22 | scf.for %iv = %0 to %0 step %0 { 23 | "unregistered_op"() : () -> () 24 | } 25 | -------------------------------------------------------------------------------- /tests/filecheck/mlir-conversion/with-mlir/mlir_opt_fail.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s -p mlir-opt{arguments='--hello','--mlir-print-op-generic'} --print-op-generic --verify-diagnostics | filecheck %s --check-prefix=CHECK-PARSING 2 | // RUN: xdsl-opt %s -p mlir-opt[this-probably-will-never-be-an-MLIR-pass-name] --print-op-generic --verify-diagnostics | filecheck %s 3 | // RUN: xdsl-opt %s -p mlir-opt{executable='"false"'} --print-op-generic --verify-diagnostics | filecheck %s 4 | 5 | "builtin.module"() ({ 6 | "func.func"() ({ 7 | %0 = "arith.constant"() {"value" = 1 : i32} : () -> i32 8 | "func.return"() : () -> () 9 | }) {function_type = () -> (), sym_name = "do_nothing"} : () -> () 10 | }) : () -> () 11 | 12 | 13 | // CHECK-PARSING: Error parsing mlir-opt pass output 14 | // CHECK: Error executing mlir-opt pass 15 | -------------------------------------------------------------------------------- /xdsl/dialects/arm/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | ARM dialect, based on the ISA [specification](https://developer.arm.com/documentation/102374/0101/Overview). 3 | """ 4 | 5 | from typing import IO 6 | 7 | from xdsl.backend.assembly_printer import AssemblyPrinter 8 | from xdsl.dialects.builtin import ModuleOp 9 | from xdsl.ir import Dialect 10 | 11 | from .ops import CmpRegOp, DSMovOp, DSSMulOp, GetRegisterOp, LabelOp 12 | from .registers import IntRegisterType 13 | 14 | 15 | def print_assembly(module: ModuleOp, output: IO[str]) -> None: 16 | printer = AssemblyPrinter(stream=output) 17 | printer.print_module(module) 18 | 19 | 20 | ARM = Dialect( 21 | "arm", 22 | [ 23 | GetRegisterOp, 24 | CmpRegOp, 25 | DSMovOp, 26 | DSSMulOp, 27 | LabelOp, 28 | ], 29 | [ 30 | IntRegisterType, 31 | ], 32 | ) 33 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/llvm/attrs.mlir: -------------------------------------------------------------------------------- 1 | // RUN: XDSL_ROUNDTRIP 2 | 3 | // CHECK: frame_all = #llvm.framePointerKind 4 | // CHECK: frame_none = #llvm.framePointerKind 5 | // CHECK: frame_non_leaf = #llvm.framePointerKind<"non-leaf"> 6 | // CHECK: frame_reserved = #llvm.framePointerKind 7 | "test.op"() { 8 | frame_all = #llvm.framePointerKind, 9 | frame_none = #llvm.framePointerKind, 10 | frame_non_leaf = #llvm.framePointerKind<"non-leaf">, 11 | frame_reserved = #llvm.framePointerKind 12 | }: () -> () 13 | 14 | // CHECK: target_features = #llvm.target_features<["+one", "-two"]> 15 | // CHECK: target_features_empty = #llvm.target_features<[]> 16 | "test.op"() { 17 | target_features = #llvm.target_features<["+one", "-two"]>, 18 | target_features_empty = #llvm.target_features<[]> 19 | } : () -> () 20 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/x86/x86_registers_invalid.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s --split-input-file --verify-diagnostics | filecheck %s 2 | 3 | // CHECK: Invalid register name foo for register type x86.reg. 4 | "test.op"() { reg = !x86.reg } : () -> () 5 | 6 | // ----- 7 | 8 | // CHECK: Invalid register name foo for register type x86.avx2reg. 9 | "test.op"() { reg = !x86.avx2reg } : () -> () 10 | 11 | // ----- 12 | 13 | // CHECK: Invalid register name foo for register type x86.avx512reg. 14 | "test.op"() { reg = !x86.avx512reg } : () -> () 15 | 16 | // ----- 17 | 18 | // CHECK: Invalid register name foo for register type x86.ssereg. 19 | "test.op"() { reg = !x86.ssereg } : () -> () 20 | 21 | // ----- 22 | 23 | // CHECK: Invalid register name foo for register type x86.avx512maskreg. 24 | "test.op"() { reg = !x86.avx512maskreg } : () -> () 25 | -------------------------------------------------------------------------------- /xdsl/interactive/add_arguments_screen.tcss: -------------------------------------------------------------------------------- 1 | AddArguments{ 2 | background: rgba(100,100,100,0.5); 3 | align: center middle; 4 | layout: vertical; 5 | } 6 | 7 | # ScrollableContainer(TextArea, Horizontal(Button, Button, Button)) 8 | #container{ 9 | border: heavy $warning; 10 | border-title-color: $warning; 11 | border-title-style: bold; 12 | border-title-align: center; 13 | width: 85%; 14 | height: 50%; 15 | layout: vertical; 16 | } 17 | 18 | # TextArea 19 | #argument_text_area{ 20 | border: heavy $accent-darken-1; 21 | border-title-color: $error-darken-3; 22 | border-title-style: bold; 23 | border-title-align: center; 24 | } 25 | 26 | # Horizontal(Button, Button, Button) 27 | #cancel_enter_buttons{ 28 | layout: horizontal; 29 | height: auto; 30 | } 31 | 32 | Button{ 33 | border: $warning; 34 | } 35 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug Report 3 | about: Report a bug or unexpected behavior 4 | title: "" 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | ### Description 11 | 12 | A clear and concise description of the issue or bug. 13 | 14 | ### Expected vs Actual Behavior 15 | 16 | Include what you expected to happen and what actually happened (e.g., when compared with 17 | upstream MLIR). 18 | 19 | ### Steps to Reproduce and a Minimal Working Example (MWE) 20 | 21 | 1. Describe the steps to reproduce the issue (commands, etc.). 22 | 2. If applicable, describe the environment (e.g., operating system, Python version, etc.). 23 | 3. Please make your reproducible example as small as possible. 24 | It should be self-contained and easy to run. 25 | 26 | ### Additional Information 27 | 28 | Any extra information that might help debug the issue. 29 | -------------------------------------------------------------------------------- /tests/filecheck/mlir-conversion/with-mlir/dialects/pdl/pdl_native_rewrite.mlir: -------------------------------------------------------------------------------- 1 | // RUN: MLIR_ROUNDTRIP 2 | // RUN: MLIR_GENERIC_ROUNDTRIP 3 | 4 | pdl.pattern @nativeRewrite : benefit(1) { 5 | %type = pdl.type 6 | 7 | %operand = pdl.operand 8 | 9 | %attr = pdl.attribute 10 | 11 | // A bound operation 12 | %root = pdl.operation "test.test"(%operand : !pdl.value) 13 | {"value1" = %attr} 14 | -> (%type : !pdl.type) 15 | 16 | pdl.rewrite %root { 17 | %res_op = pdl.apply_native_rewrite "myRewrite"(%type, %operand, %attr : !pdl.type, !pdl.value, !pdl.attribute) : !pdl.operation 18 | pdl.replace %root with %res_op 19 | } 20 | } 21 | 22 | // CHECK: @nativeRewrite 23 | // CHECK: %{{\d+}} = pdl.apply_native_rewrite "myRewrite"(%{{\d+}}, %{{\d+}}, %{{\d+}} : !pdl.type, !pdl.value, !pdl.attribute) : !pdl.operation 24 | -------------------------------------------------------------------------------- /tests/filecheck/mlir-conversion/with-mlir/dialects/print/printf_to_llvm.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s -p printf-to-llvm | mlir-opt --convert-to-llvm | filecheck %s 2 | // this tests straight to llvmir to verify intended target compatibility 3 | 4 | builtin.module { 5 | func.func @main() { 6 | %pi = arith.constant 3.14159 : f32 7 | %12 = arith.constant 12 : i32 8 | 9 | printf.print_format "Hello: {} {}\n", %pi : f32, %12 : i32 10 | 11 | func.return 12 | } 13 | } 14 | 15 | 16 | // CHECK: llvm.call @printf(%{{\d+}}, %{{\d+}}, %{{\d+}}) vararg(!llvm.func) : (!llvm.ptr, f64, i32) -> () 17 | 18 | // CHECK: llvm.func @printf(!llvm.ptr, ...) 19 | 20 | // CHECK: llvm.mlir.global internal constant @Hello_f_{{\w+}}(dense<[72, 101, 108, 108, 111, 58, 32, 37, 102, 32, 37, 105, 10, 0]> : tensor<14xi8>) {addr_space = 0 : i32} : !llvm.arr 21 | -------------------------------------------------------------------------------- /tests/filecheck/mlir-conversion/with-mlir/apply-eqsat-pdl/apply_eqsat_pdl_extra_file.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s -p 'apply-eqsat-pdl{pdl_file="%p/extra_file.mlir"}' | filecheck %s 2 | 3 | // CHECK: %x_c = eqsat.eclass %x : i32 4 | // CHECK-NEXT: %zero = arith.constant 0 : i32 5 | // CHECK-NEXT: %a = arith.muli %x_c, %a_c : i32 6 | // CHECK-NEXT: %a_c = eqsat.eclass %a, %zero, %b : i32 7 | // CHECK-NEXT: %b = arith.subi %x_c, %x_c : i32 8 | // CHECK-NEXT: func.return %a_c, %a_c : i32, i32 9 | 10 | func.func @impl(%x: i32) -> (i32, i32) { 11 | %x_c = eqsat.eclass %x : i32 12 | 13 | %zero = arith.constant 0 : i32 14 | %zero_c = eqsat.eclass %zero : i32 15 | 16 | %a = arith.muli %x_c, %zero_c : i32 17 | %a_c = eqsat.eclass %a : i32 18 | 19 | %b = arith.subi %x_c, %x_c : i32 20 | %b_c = eqsat.eclass %b : i32 21 | 22 | 23 | func.return %a_c, %b_c : i32, i32 24 | } 25 | -------------------------------------------------------------------------------- /tests/filecheck/runner/riscv.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-run %s --verbose | filecheck %s 2 | 3 | riscv_func.func @malloc(!riscv.reg) -> !riscv.reg 4 | 5 | riscv_func.func @putchar(!riscv.reg) -> !riscv.reg 6 | 7 | riscv_func.func @free(!riscv.reg) -> () 8 | 9 | riscv_func.func @main() -> () { 10 | %33 = riscv.li 33 : !riscv.reg 11 | %newline = riscv.li 10 : !riscv.reg 12 | %ptr = riscv_func.call @malloc(%33) : (!riscv.reg) -> !riscv.reg 13 | riscv.sw %ptr, %33, 0 : (!riscv.reg, !riscv.reg) -> () 14 | 15 | %res = riscv.lw %ptr, 0 : (!riscv.reg) -> !riscv.reg 16 | 17 | %nothing = riscv_func.call @putchar(%res) : (!riscv.reg) -> !riscv.reg 18 | %nothing2 = riscv_func.call @putchar(%newline) : (!riscv.reg) -> !riscv.reg 19 | 20 | riscv_func.call @free(%ptr) : (!riscv.reg) -> () 21 | 22 | riscv_func.return 23 | } 24 | 25 | // CHECK: ! 26 | // CHECK: result: () 27 | -------------------------------------------------------------------------------- /tests/filecheck/parser-printer/operation_with_properties.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s --allow-unregistered-dialect | filecheck %s 2 | 3 | builtin.module { 4 | 5 | // An operation with a property 6 | "unregistered.op"() <{"test" = 2 : i32}> : () -> () 7 | // CHECK: "unregistered.op"() <{test = 2 : i32}> : () -> () 8 | 9 | // An operation with a property, a region, and an attribute 10 | "unregistered.op"() <{"test" = 42 : i64, "test2" = 71 : i32}> ({}) {"test3" = "foo"} : () -> () 11 | // CHECK-NEXT: "unregistered.op"() <{test = 42 : i64, test2 = 71 : i32}> ({ 12 | // CHECK-NEXT: }) {test3 = "foo"} : () -> () 13 | 14 | // An operation with a property and an attribute with the same name 15 | "unregistered.op"() <{"test" = 42 : i64}> {"test" = "foo"} : () -> () 16 | // CHECK-NEXT: "unregistered.op"() <{test = 42 : i64}> {test = "foo"} : () -> () 17 | 18 | } 19 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/complex/invalid.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt --split-input-file %s --verify-diagnostics | filecheck %s 2 | 3 | %i64 = "test.op"() : () -> i64 4 | %0 = complex.bitcast %i64 : i64 to f64 5 | //CHECK: Expected ('i64', 'f64') to be bitcast between complex and equal arith types 6 | 7 | // ----- 8 | 9 | %f64 = "test.op"() : () -> f64 10 | %0 = complex.bitcast %f64 : f64 to i32 11 | //CHECK: Expected ('f64', 'i32') to be bitcast between complex and equal arith types 12 | 13 | // ----- 14 | 15 | %f64 = "test.op"() : () -> f64 16 | %0 = complex.bitcast %f64 : f64 to f32 17 | //CHECK: Expected ('f64', 'f32') to be bitcast between complex and equal arith types 18 | 19 | // ----- 20 | 21 | %complex = "test.op"() : () -> (complex) 22 | %0 = complex.bitcast %complex : complex to i32 23 | //CHECK: Expected ('complex', 'i32') to be bitcast between complex and equal arith types 24 | -------------------------------------------------------------------------------- /tests/filecheck/mlir-conversion/with-mlir/dialects/llvm/attrs.mlir: -------------------------------------------------------------------------------- 1 | // RUN: MLIR_GENERIC_ROUNDTRIP 2 | 3 | // CHECK: frame_all = #llvm.framePointerKind 4 | // CHECK: frame_non_leaf = #llvm.framePointerKind<"non-leaf"> 5 | // CHECK: frame_none = #llvm.framePointerKind 6 | // CHECK: frame_reserved = #llvm.framePointerKind 7 | "test.op"() { 8 | frame_all = #llvm.framePointerKind, 9 | frame_non_leaf = #llvm.framePointerKind<"non-leaf">, 10 | frame_none = #llvm.framePointerKind, 11 | frame_reserved = #llvm.framePointerKind 12 | }: () -> () 13 | 14 | // CHECK: target_features = #llvm.target_features<["-one", "+two"]> 15 | // CHECK: target_features_empty = #llvm.target_features<[]> 16 | "test.op"() { 17 | target_features = #llvm.target_features<["-one", "+two"]>, 18 | target_features_empty = #llvm.target_features<[]> 19 | } : () -> () 20 | -------------------------------------------------------------------------------- /tests/filecheck/transforms/apply-eqsat-pdl-interp/apply_eqsat_pdl_interp_extra_file.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s -p 'apply-eqsat-pdl-interp{pdl_interp_file="%p/extra_file.mlir"}' | filecheck %s 2 | 3 | // CHECK: %x_c = eqsat.eclass %x : i32 4 | // CHECK-NEXT: %zero = arith.constant 0 : i32 5 | // CHECK-NEXT: %a = arith.muli %x_c, %a_c : i32 6 | // CHECK-NEXT: %a_c = eqsat.eclass %a, %zero, %b : i32 7 | // CHECK-NEXT: %b = arith.subi %x_c, %x_c : i32 8 | // CHECK-NEXT: func.return %a_c, %a_c : i32, i32 9 | 10 | func.func @impl(%x: i32) -> (i32, i32) { 11 | %x_c = eqsat.eclass %x : i32 12 | 13 | %zero = arith.constant 0 : i32 14 | %zero_c = eqsat.eclass %zero : i32 15 | 16 | %a = arith.muli %x_c, %zero_c : i32 17 | %a_c = eqsat.eclass %a : i32 18 | 19 | %b = arith.subi %x_c, %x_c : i32 20 | %b_c = eqsat.eclass %b : i32 21 | 22 | 23 | func.return %a_c, %b_c : i32, i32 24 | } 25 | -------------------------------------------------------------------------------- /tests/filecheck/transforms/apply-pdl/apply_pdl_add_zero.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s -p apply-pdl | filecheck %s 2 | 3 | 4 | // CHECK: func.func @impl() -> i32 { 5 | // CHECK-NEXT: %0 = arith.constant 4 : i32 6 | // CHECK-NEXT: %1 = arith.constant 0 : i32 7 | // CHECK-NEXT: func.return %0 : i32 8 | // CHECK-NEXT: } 9 | 10 | func.func @impl() -> i32 { 11 | %0 = arith.constant 4 : i32 12 | %1 = arith.constant 0 : i32 13 | %2 = arith.addi %0, %1 : i32 14 | func.return %2 : i32 15 | } 16 | 17 | pdl.pattern : benefit(2) { 18 | %0 = pdl.type 19 | %1 = pdl.operand 20 | %2 = pdl.attribute = 0 : i32 21 | %3 = pdl.operation "arith.constant" {"value" = %2} -> (%0 : !pdl.type) 22 | %4 = pdl.result 0 of %3 23 | %5 = pdl.operation "arith.addi" (%1, %4 : !pdl.value, !pdl.value) -> (%0 : !pdl.type) 24 | pdl.rewrite %5 { 25 | pdl.replace %5 with (%1 : !pdl.value) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /tests/filecheck/mlir-conversion/with-mlir/dialects/transform/transform_generic.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s --print-op-generic | mlir-opt --mlir-print-op-generic --allow-unregistered-dialect | filecheck %s 2 | 3 | %0 = "test.op"() : () -> !transform.op<"builtin.module"> 4 | // CHECK: %1 = "transform.apply_registered_pass"(%0) <{options = {}, pass_name = "foo"}> : (!transform.op<"builtin.module">) -> !transform.op<"builtin.module"> 5 | %1 = "transform.apply_registered_pass"(%0) <{pass_name = "foo", options = {}}> : (!transform.op<"builtin.module">) -> !transform.op<"builtin.module"> 6 | // CHECK: %2 = "transform.apply_registered_pass"(%0) <{options = {hello = "bye"}, pass_name = "foo"}> : (!transform.op<"builtin.module">) -> !transform.op<"builtin.module"> 7 | %2 = "transform.apply_registered_pass"(%0) <{pass_name = "foo"}> {options = {hello = "bye"}} : (!transform.op<"builtin.module">) -> !transform.op<"builtin.module"> 8 | -------------------------------------------------------------------------------- /tests/filecheck/runner/riscv_scf.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-run --verbose %s | filecheck %s 2 | // RUN: xdsl-run --verbose --symbol="sum_to" --args="6" %s | filecheck %s --check-prefix=CHECK-ARGS 3 | 4 | builtin.module { 5 | func.func @sum_to(%0 : !riscv.reg) -> !riscv.reg { 6 | %1 = riscv.li 0 : !riscv.reg 7 | %2 = riscv.li 1 : !riscv.reg 8 | %3 = riscv.li 0 : !riscv.reg 9 | %4 = riscv_scf.for %5 : !riscv.reg = %1 to %0 step %2 iter_args(%6 = %3) -> (!riscv.reg) { 10 | %7 = riscv.add %5, %6 : (!riscv.reg, !riscv.reg) -> !riscv.reg 11 | riscv_scf.yield %7 : !riscv.reg 12 | } 13 | func.return %4 : !riscv.reg 14 | } 15 | func.func @main() -> !riscv.reg { 16 | %c5 = riscv.li 5 : !riscv.reg 17 | %res = func.call @sum_to(%c5) : (!riscv.reg) -> !riscv.reg 18 | return %res : !riscv.reg 19 | } 20 | } 21 | 22 | // CHECK: result: 10 23 | // CHECK-ARGS: result: 15 24 | -------------------------------------------------------------------------------- /docs/Toy/examples/tests/infer_shapes.mlir: -------------------------------------------------------------------------------- 1 | // RUN: python -m toy %s --emit=shape-inference --ir | filecheck %s 2 | 3 | "builtin.module"() ({ 4 | "toy.func"() ({ 5 | %0 = "toy.constant"() {"value" = dense<[[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]> : tensor<2x3xf64>} : () -> tensor<2x3xf64> 6 | 7 | %1 = "toy.cast"(%0) : (tensor<2x3xf64>) -> tensor<*xf64> 8 | %2 = "toy.transpose"(%1) : (tensor<*xf64>) -> tensor<*xf64> 9 | %3 = "toy.mul"(%2, %2) : (tensor<*xf64>, tensor<*xf64>) -> tensor<*xf64> 10 | "toy.print"(%3) : (tensor<*xf64>) -> () 11 | 12 | // CHECK: %1 = "toy.transpose"(%0) : (tensor<2x3xf64>) -> tensor<3x2xf64> 13 | // CHECK-NEXT: %2 = "toy.mul"(%1, %1) : (tensor<3x2xf64>, tensor<3x2xf64>) -> tensor<3x2xf64> 14 | // CHECK-NEXT: "toy.print"(%2) : (tensor<3x2xf64>) -> () 15 | 16 | "toy.return"() : () -> () 17 | }) {"sym_name" = "main", "function_type" = () -> ()} : () -> () 18 | }) : () -> () 19 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/symref/ops.mlir: -------------------------------------------------------------------------------- 1 | // RUN: XDSL_ROUNDTRIP 2 | 3 | // CHECK: symref.declare "counter" 4 | // CHECK-NEXT: symref.declare "tensor_ref" 5 | symref.declare "counter" 6 | symref.declare "tensor_ref" 7 | 8 | // CHECK-NEXT: %{{.*}} = symref.fetch @counter : i32 9 | // CHECK-NEXT: %{{.*}} = symref.fetch @tensor_ref : tensor<4x4xf32> 10 | %0 = symref.fetch @counter : i32 11 | %1 = symref.fetch @tensor_ref : tensor<4x4xf32> 12 | 13 | // CHECK-NEXT: %{{.*}} = "test.op"() : () -> i32 14 | // CHECK-NEXT: %{{.*}} = "test.op"() : () -> tensor<4x4xf32> 15 | %constant = "test.op"() : () -> i32 16 | %tensor = "test.op"() : () -> tensor<4x4xf32> 17 | 18 | // CHECK-NEXT: symref.update @counter = %{{.*}} : i32 19 | // CHECK-NEXT: symref.update @tensor_ref = %{{.*}} : tensor<4x4xf32> 20 | symref.update @counter = %constant : i32 21 | symref.update @tensor_ref = %tensor : tensor<4x4xf32> 22 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/arith/arith_cfg.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s 2 | 3 | // This file tests that the parser does not assert in case the block 4 | // ordering seemingly indicates that an operand is not yet defined. 5 | 6 | builtin.module { 7 | func.func @bb_ordered_by_dominance() { 8 | "test.termop"() [^bb1] : () -> () 9 | 10 | ^bb1: 11 | %1 = arith.constant 1 12 | "test.termop"() [^bb2] : () -> () 13 | 14 | ^bb2: 15 | %2 = arith.addi %1, %1 : i64 16 | "test.termop"() [^bb1] : () -> () 17 | } 18 | 19 | func.func @bb_ordered_against_dominance() { 20 | "test.termop"() [^bb1] : () -> () 21 | 22 | ^bb2: 23 | // Previously, this operation did not parse due to %1 seemingly 24 | // not yet being defined. 25 | %2 = arith.addi %1, %1 : i64 26 | "test.termop"() [^bb1] : () -> () 27 | 28 | ^bb1: 29 | %1 = arith.constant 1 30 | "test.termop"() [^bb2] : () -> () 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /tests/filecheck/with-riscemu/rvscf_lowering_emu.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt -p lower-riscv-scf-to-labels -t riscemu %s 2 | // RUN: xdsl-opt -p convert-riscv-scf-to-riscv-cf -t riscemu %s 3 | 4 | builtin.module { 5 | riscv_func.func @main() { 6 | %0 = riscv.li 0 : !riscv.reg 7 | %1 = riscv.li 10 : !riscv.reg 8 | %2 = riscv.li 1 : !riscv.reg 9 | %3 = riscv.li 0 : !riscv.reg 10 | %4 = riscv_scf.for %5 : !riscv.reg = %0 to %1 step %2 iter_args(%6 = %3) -> (!riscv.reg) { 11 | %7 = riscv.add %5, %6 : (!riscv.reg, !riscv.reg) -> !riscv.reg 12 | riscv_scf.yield %7 : !riscv.reg 13 | } 14 | %8 = riscv.mv %4 : (!riscv.reg) -> !riscv.reg 15 | riscv.custom_assembly_instruction %4 {"instruction_name" = "print"} : (!riscv.reg) -> () 16 | riscv.li 93 : !riscv.reg 17 | riscv.ecall 18 | riscv_func.return 19 | } 20 | } 21 | 22 | // CHECK: 45 23 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/pdl/pdl_replace.mlir: -------------------------------------------------------------------------------- 1 | // RUN: XDSL_ROUNDTRIP 2 | 3 | pdl.pattern @replaceWithValues : benefit(1) { 4 | %type = pdl.type 5 | %lhs = pdl.operand : %type 6 | %rhs = pdl.operand : %type 7 | 8 | %root = pdl.operation (%lhs, %rhs : !pdl.value, !pdl.value) -> (%type, %type : !pdl.type, !pdl.type) 9 | 10 | pdl.rewrite %root { 11 | pdl.replace %root with (%lhs, %rhs : !pdl.value, !pdl.value) 12 | } 13 | } 14 | 15 | // CHECK: @replaceWithValues 16 | // CHECK: pdl.replace %{{.*}} with (%{{.*}}, %{{.*}}) 17 | 18 | pdl.pattern @replaceWithOp : benefit(1) { 19 | %type = pdl.type 20 | %op = pdl.operation -> (%type : !pdl.type) 21 | %res = pdl.result 0 of %op 22 | 23 | %root = pdl.operation (%res : !pdl.value) -> (%type : !pdl.type) 24 | 25 | pdl.rewrite %root { 26 | pdl.replace %root with %op 27 | } 28 | } 29 | 30 | // CHECK: @replaceWithOp 31 | // CHECK: pdl.replace %{{.*}} with %{{\S+}} 32 | -------------------------------------------------------------------------------- /tests/dialects/test_eqsat.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | 3 | from xdsl.dialects import arith, eqsat, test 4 | from xdsl.dialects.builtin import IntegerAttr, i32 5 | from xdsl.traits import ConstantLike 6 | from xdsl.utils.exceptions import DiagnosticException 7 | 8 | 9 | def test_const_eclass_construction(): 10 | constant_op = arith.ConstantOp(IntegerAttr.from_int_and_width(42, 64)) 11 | 12 | const_eclass = eqsat.ConstantEClassOp(constant_op.result) 13 | trait = const_eclass.get_trait(ConstantLike) 14 | assert trait is not None 15 | assert trait.get_constant_value(const_eclass) == IntegerAttr.from_int_and_width( 16 | 42, 64 17 | ) 18 | 19 | non_constant_op = test.TestOp(result_types=(i32,)) 20 | with pytest.raises( 21 | DiagnosticException, 22 | match="The argument of a ConstantEClass must be a constant-like operation.", 23 | ): 24 | eqsat.ConstantEClassOp(non_constant_op.results[0]) 25 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/builtin/module.mlir: -------------------------------------------------------------------------------- 1 | // RUN: XDSL_ROUNDTRIP 2 | // RUN: xdsl-opt %s --allow-unregistered-dialect | filecheck --strict-whitespace %s 3 | 4 | // CHECK:builtin.module { 5 | builtin.module { 6 | 7 | // CHECK-NEXT: builtin.module { 8 | // CHECK-NEXT: } 9 | builtin.module {} 10 | 11 | // CHECK-NEXT: builtin.module attributes {a = "foo", b = "bar", unit} { 12 | // CHECK-NEXT: } 13 | builtin.module attributes {a = "foo", b = "bar", unit} {} 14 | 15 | // CHECK-NEXT: builtin.module @moduleName { 16 | // CHECK-NEXT: } 17 | builtin.module @moduleName {} 18 | 19 | // CHECK-NEXT: builtin.module @otherModule attributes {dialect.attr} { 20 | // CHECK-NEXT: } 21 | builtin.module @otherModule attributes {dialect.attr} {} 22 | 23 | // CHECK-NEXT: builtin.module { 24 | // CHECK-NEXT: } 25 | module {} 26 | 27 | // CHECK:} 28 | } 29 | -------------------------------------------------------------------------------- /tests/filecheck/transforms/memref_stream_generalize_fill.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s -p memref-stream-generalize-fill | filecheck %s 2 | 3 | // CHECK: builtin.module { 4 | 5 | %Z, %zero = "test.op"() : () -> (memref<8x8xf64>, f64) 6 | // CHECK-NEXT: %Z, %zero = "test.op"() : () -> (memref<8x8xf64>, f64) 7 | 8 | memref_stream.fill %Z with %zero : memref<8x8xf64> 9 | 10 | // CHECK-NEXT: memref_stream.generic { 11 | // CHECK-NEXT: bounds = [8, 8], 12 | // CHECK-NEXT: indexing_maps = [ 13 | // CHECK-NEXT: affine_map<(d0, d1) -> ()>, 14 | // CHECK-NEXT: affine_map<(d0, d1) -> (d0, d1)> 15 | // CHECK-NEXT: ], 16 | // CHECK-NEXT: iterator_types = ["parallel", "parallel"] 17 | // CHECK-NEXT: } ins(%zero : f64) outs(%Z : memref<8x8xf64>) { 18 | // CHECK-NEXT: ^bb0(%{{.*}} : f64, %{{.*}} : f64): 19 | // CHECK-NEXT: memref_stream.yield %{{.*}} : f64 20 | // CHECK-NEXT: } 21 | 22 | // CHECK-NEXT: } 23 | -------------------------------------------------------------------------------- /xdsl/transforms/x86_allocate_registers.py: -------------------------------------------------------------------------------- 1 | from dataclasses import dataclass 2 | 3 | from xdsl.backend.x86.register_allocation import X86RegisterAllocator 4 | from xdsl.backend.x86.register_stack import X86RegisterStack 5 | from xdsl.context import Context 6 | from xdsl.dialects import x86_func 7 | from xdsl.dialects.builtin import ModuleOp 8 | from xdsl.passes import ModulePass 9 | 10 | 11 | @dataclass(frozen=True) 12 | class X86AllocateRegisters(ModulePass): 13 | """ 14 | Allocates unallocated registers in the module. 15 | """ 16 | 17 | name = "x86-allocate-registers" 18 | 19 | def apply(self, ctx: Context, op: ModuleOp) -> None: 20 | for inner_op in op.walk(): 21 | if isinstance(inner_op, x86_func.FuncOp): 22 | available_registers = X86RegisterStack.get() 23 | allocator = X86RegisterAllocator(available_registers) 24 | allocator.allocate_func(inner_op) 25 | -------------------------------------------------------------------------------- /tests/filecheck/mlir-conversion/with-mlir/dialects/builtin/dense_elements.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s | xdsl-opt | mlir-opt --allow-unregistered-dialect | filecheck %s 2 | 3 | // CHECK: value = dense<[[(1,2), (3,4)], [(5,6), (7,8)]]> : tensor<2x2xcomplex> 4 | %complex_tensor_i32 = "test.op"() {"value" = dense<[[(1, 2), (3, 4)], [(5, 6), (7, 8)]]> : tensor<2x2xcomplex>} : () -> tensor<2x2xcomplex> 5 | // CHECK-NEXT: value = dense<[[(1.000000e+00,2.000000e+00), (3.000000e+00,4.000000e+00)], [(5.000000e+00,6.000000e+00), (7.000000e+00,8.000000e+00)]]> : tensor<2x2xcomplex> 6 | %complex_tensor_f32 = "test.op"() {"value" = dense<[[(1.0, 2.0), (3.0, 4.0)], [(5.0, 6.0), (7.0, 8.0)]]> : tensor<2x2xcomplex>} : () -> tensor<2x2xcomplex> 7 | // CHECK-NEXT: value = dense<[(true,false), (false,false)]> 8 | %complex_tensor_i1 = "test.op"() {"value" = dense<[(true, false), (false, false)]> : tensor<2xcomplex>} : () -> tensor<2xcomplex> 9 | -------------------------------------------------------------------------------- /tests/filecheck/parser-printer/aliases.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s --split-input-file --parsing-diagnostics | filecheck %s 2 | 3 | !ii32 = i32 4 | #attr = 0 : !ii32 5 | 6 | "test.op"() {"attr" = 1 : !ii32} : () -> () 7 | "test.op"() {"attr" = !ii32} : () -> () 8 | "test.op"() {"attr" = vector<1x!ii32>} : () -> () 9 | "test.op"() {"attr" = #attr} : () -> () 10 | "test.op"() {"attr" = [#attr]} : () -> () 11 | 12 | // CHECK: "test.op"() {attr = 1 : i32} : () -> () 13 | // CHECK-NEXT: "test.op"() {attr = i32} : () -> () 14 | // CHECK-NEXT: "test.op"() {attr = vector<1xi32>} : () -> () 15 | // CHECK-NEXT: "test.op"() {attr = 0 : i32} : () -> () 16 | // CHECK-NEXT: "test.op"() {attr = [0 : i32]} : () -> () 17 | 18 | 19 | // ----- 20 | 21 | #attr = 0 22 | 23 | "test.op"() {"attr" = #attr : i32} : () -> () 24 | // CHECK: '}' expected 25 | 26 | // ----- 27 | 28 | "test.op"() {"attr" = #attr} : () -> () 29 | // CHECK: undefined symbol alias '#attr' 30 | -------------------------------------------------------------------------------- /tests/filecheck/transforms/apply-pdl/apply_pdl_polymorphic.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s -p apply-pdl | filecheck %s 2 | 3 | %x = arith.constant 42: i32 4 | %y = arith.constant 84: i64 5 | 6 | pdl.pattern : benefit(1) { 7 | %in_type = pdl.type 8 | %value = pdl.attribute 9 | %constant_op = pdl.operation "arith.constant" {"value" = %value} -> (%in_type: !pdl.type) 10 | pdl.rewrite %constant_op { 11 | pdl.erase %constant_op 12 | } 13 | } 14 | 15 | // CHECK: builtin.module { 16 | // CHECK-NEXT: pdl.pattern : benefit(1) { 17 | // CHECK-NEXT: %in_type = pdl.type 18 | // CHECK-NEXT: %value = pdl.attribute 19 | // CHECK-NEXT: %constant_op = pdl.operation "arith.constant" {"value" = %value} -> (%in_type : !pdl.type) 20 | // CHECK-NEXT: pdl.rewrite %constant_op { 21 | // CHECK-NEXT: pdl.erase %constant_op 22 | // CHECK-NEXT: } 23 | // CHECK-NEXT: } 24 | // CHECK-NEXT: } 25 | // CHECK-NEXT: 26 | -------------------------------------------------------------------------------- /tests/filecheck/transforms/lift-arith-to-linalg.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s -p lift-arith-to-linalg | filecheck %s 2 | 3 | builtin.module { 4 | %t0, %t1, %t2, %t3 = "test.op"() : () -> (tensor<8xf32>, tensor<8xf32>, tensor<8xf32>, tensor<8xf32>) 5 | %0 = arith.addf %t0, %t1 : tensor<8xf32> 6 | %1 = arith.subf %0, %t2 : tensor<8xf32> 7 | %2 = arith.mulf %1, %t3 : tensor<8xf32> 8 | } 9 | 10 | // CHECK-NEXT: builtin.module { 11 | // CHECK-NEXT: %t0, %t1, %t2, %t3 = "test.op"() : () -> (tensor<8xf32>, tensor<8xf32>, tensor<8xf32>, tensor<8xf32>) 12 | // CHECK-NEXT: %0 = linalg.add ins(%t0, %t1 : tensor<8xf32>, tensor<8xf32>) outs(%t0 : tensor<8xf32>) -> tensor<8xf32> 13 | // CHECK-NEXT: %1 = linalg.sub ins(%0, %t2 : tensor<8xf32>, tensor<8xf32>) outs(%0 : tensor<8xf32>) -> tensor<8xf32> 14 | // CHECK-NEXT: %2 = linalg.mul ins(%1, %t3 : tensor<8xf32>, tensor<8xf32>) outs(%1 : tensor<8xf32>) -> tensor<8xf32> 15 | // CHECK-NEXT: } 16 | -------------------------------------------------------------------------------- /xdsl/utils/runtime_final.py: -------------------------------------------------------------------------------- 1 | from typing import Any 2 | 3 | from typing_extensions import TypeVar 4 | 5 | 6 | def _init_subclass(cls: type, *args: Any, **kwargs: Any) -> None: 7 | """Is used by `final` to prevent a class from being subclassed at runtime.""" 8 | raise TypeError("Subclassing final classes is restricted") 9 | 10 | 11 | C = TypeVar("C", bound=type) 12 | 13 | 14 | def runtime_final(cls: C) -> C: 15 | """Prevent a class from being subclassed at runtime.""" 16 | 17 | # It is safe to discard the previous __init_subclass__ method as anyway 18 | # the new one will raise an error. 19 | setattr(cls, "__init_subclass__", classmethod(_init_subclass)) 20 | 21 | # This is a marker to check if a class is final or not. 22 | setattr(cls, "__final__", True) 23 | return cls 24 | 25 | 26 | def is_runtime_final(cls: type) -> bool: 27 | """Check if a class is final.""" 28 | return hasattr(cls, "__final__") 29 | -------------------------------------------------------------------------------- /tests/filecheck/xdsl_opt/split_input.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt --split-input-file %s | xdsl-opt --split-input-file --print-op-generic | filecheck %s 2 | 3 | "builtin.module"() ({ 4 | ^bb0: 5 | // CHECK: "builtin.module"() ({ 6 | }) : () -> () 7 | 8 | // ----- 9 | "builtin.module"() ({ 10 | "test.op"() : () -> () 11 | // CHECK: "builtin.module"() ({ 12 | // CHECK-NEXT: "test.op"() : () -> () 13 | }) : () -> () 14 | 15 | // ----- 16 | "builtin.module"() ({ 17 | %x = "test.op"() : () -> i1 18 | // CHECK: "builtin.module"() ({ 19 | // CHECK: %x = "test.op"() : () -> i1 20 | // CHECK-NOT: %x = "test.op"() : () -> i2 21 | // CHECK-NOT: "test.op"() : () -> () 22 | }) : () -> () 23 | 24 | // ----- 25 | "builtin.module"() ({ 26 | %x = "test.op"() : () -> i2 27 | // CHECK: "builtin.module"() ({ 28 | // CHECK-NEXT: %x = "test.op"() : () -> i2 29 | // CHECK-NOT: %x = "test.op"() : () -> i1 30 | // CHECK-NOT: "test.op"() : () -> () 31 | }) : () -> () 32 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/scf/reduce_arg_type_missmatch.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s --verify-diagnostics | filecheck %s 2 | 3 | "builtin.module"() ({ 4 | %0 = "arith.constant"() {"value" = 0 : index} : () -> index 5 | %1 = "arith.constant"() {"value" = 1000 : index} : () -> index 6 | %2 = "arith.constant"() {"value" = 3 : index} : () -> index 7 | %3 = "arith.constant"() {"value" = 10.2 : f32} : () -> f32 8 | %4 = "arith.constant"() {"value" = 18.1 : f32} : () -> f32 9 | %5 = "scf.parallel"(%0, %1, %2, %3) ({ 10 | ^bb0(%8 : index): 11 | "scf.reduce"(%4) ({ 12 | ^bb1(%9 : f64, %10 : f64): 13 | %11 = "arith.addf"(%9, %10) : (f64, f64) -> f64 14 | "scf.reduce.return"(%11) : (f64) -> () 15 | }) : (f32) -> () 16 | }) {operandSegmentSizes = array} : (index, index, index, f32) -> f32 17 | }) : () -> () 18 | 19 | // CHECK: scf.reduce block argument types must match the operand type but have f64 and f32 20 | -------------------------------------------------------------------------------- /tests/filecheck/transforms/eqsat-add-costs/eqsat-add-costs-with-default.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt -p eqsat-add-costs{default=1000} --verify-diagnostics --split-input-file %s | filecheck %s 2 | 3 | // CHECK: func.func @recursive(%a : index) -> index { 4 | // CHECK-NEXT: %a_eq = eqsat.eclass %a, %b {min_cost_index = #builtin.int<0>} : index 5 | // CHECK-NEXT: %one = arith.constant {eqsat_cost = #builtin.int<1000>} 1 : index 6 | // CHECK-NEXT: %one_eq = eqsat.eclass %one {min_cost_index = #builtin.int<0>} : index 7 | // CHECK-NEXT: %b = arith.muli %a_eq, %one_eq {eqsat_cost = #builtin.int<1000>} : index 8 | // CHECK-NEXT: func.return %a_eq : index 9 | // CHECK-NEXT: } 10 | 11 | func.func @recursive(%a : index) -> (index) { 12 | %a_eq = eqsat.eclass %a, %b : index 13 | %one = arith.constant 1 : index 14 | %one_eq = eqsat.eclass %one : index 15 | %b = arith.muli %a_eq, %one_eq : index 16 | return %a_eq : index 17 | } 18 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/transform/transform_interpreter.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s -p transform-interpreter | filecheck %s 2 | // RUN: xdsl-opt %s -p transform-interpreter'{entry-point=entry}' | filecheck %s 3 | 4 | 5 | module { 6 | 7 | module attributes {transform.with_named_sequence} { 8 | transform.named_sequence @__transform_main(%arg0 : !transform.any_op {transform.readonly}) { 9 | transform.yield 10 | } 11 | } 12 | 13 | module attributes {transform.with_named_sequence} { 14 | transform.named_sequence @entry(%arg0 : !transform.any_op {transform.readonly}) { 15 | transform.yield 16 | } 17 | } 18 | } 19 | 20 | // CHECK: transform.named_sequence @__transform_main(%arg0 : !transform.any_op {transform.readonly}) { 21 | // CHECK-NEXT: transform.yield 22 | // CHECK-NEXT: } 23 | 24 | // CHECK: transform.named_sequence @entry(%arg0 : !transform.any_op {transform.readonly}) { 25 | // CHECK-NEXT: transform.yield 26 | // CHECK-NEXT: } 27 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/eqsat/eqsat_invalid.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt --verify-diagnostics --split-input-file %s | filecheck %s 2 | 3 | %val = "test.op"() : () -> index 4 | %val_eq = eqsat.eclass %val : index 5 | %val_eq_eq = eqsat.eclass %val_eq : index 6 | 7 | // CHECK: Operation does not verify: A result of an eclass operation cannot be used as an operand of another eclass. 8 | 9 | // ----- 10 | 11 | %val_eq_eq = eqsat.eclass : index 12 | 13 | // CHECK: Operation does not verify: Eclass operations must have at least one operand. 14 | 15 | // ----- 16 | 17 | %val = "test.op"() : () -> index 18 | %val_eq_eq = eqsat.eclass %val : index 19 | "test.op"(%val) : (index) -> () 20 | 21 | // CHECK: Operation does not verify: Eclass operands must only be used by the eclass. 22 | 23 | // ----- 24 | 25 | %val = "test.op"() : () -> index 26 | %val_eq = eqsat.eclass %val, %val : index 27 | 28 | // CHECK: Operation does not verify: Eclass operands must only be used once by the eclass. 29 | -------------------------------------------------------------------------------- /tests/filecheck/transforms/test_transform_dialect_erase_schedule.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt -p test-transform-dialect-erase-schedule %s | filecheck 2 | 3 | func.func @hello() { 4 | return 5 | } 6 | 7 | module attributes {transform.with_named_sequence} { 8 | transform.named_sequence @__transform_main(%arg0 : !transform.any_op {transform.readonly}) { 9 | transform.yield 10 | } 11 | } 12 | 13 | module attributes {transform.with_named_sequence} { 14 | transform.named_sequence @entry(%arg0 : !transform.any_op {transform.readonly}) { 15 | transform.yield 16 | } 17 | } 18 | 19 | // CHECK: builtin.module { 20 | // CHECK-NEXT: func.func @hello() { 21 | // CHECK-NEXT: func.return 22 | // CHECK-NEXT: } 23 | // CHECK-NEXT: builtin.module attributes {transform.with_named_sequence} { 24 | // CHECK-NEXT: } 25 | // CHECK-NEXT: builtin.module attributes {transform.with_named_sequence} { 26 | // CHECK-NEXT: } 27 | // CHECK-NEXT: } 28 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/x86_func/x86_func_asm.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt -t riscv-asm --split-input-file --verify-diagnostics %s | filecheck %s 2 | 3 | 4 | x86_func.func @noarg_void() { 5 | x86_func.ret 6 | } 7 | 8 | // CHECK: noarg_void: 9 | // CHECK-NEXT: ret 10 | 11 | 12 | x86_func.func private @visibility_private() { 13 | x86_func.ret 14 | } 15 | 16 | // CHECK-NEXT: .local visibility_private 17 | // CHECK-NEXT: visibility_private: 18 | // CHECK-NEXT: ret 19 | 20 | x86_func.func public @visibility_public() { 21 | x86_func.ret 22 | } 23 | 24 | // CHECK-NEXT: .globl visibility_public 25 | // CHECK-NEXT: visibility_public: 26 | // CHECK-NEXT: ret 27 | 28 | 29 | // ----- 30 | 31 | "x86_func.func"() ({ 32 | "x86_func.ret"() : () -> () 33 | }) {sym_name = "visibility_invalid", function_type = () -> (), sym_visibility = "invalid_visibility"} : () -> () 34 | 35 | // CHECK: Unexpected visibility invalid_visibility for function "visibility_invalid" 36 | -------------------------------------------------------------------------------- /tests/filecheck/mlir-conversion/with-mlir/dialects/func/func_ops_generic.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt --print-op-generic %s | mlir-opt --mlir-print-op-generic | xdsl-opt --print-op-generic | filecheck %s 2 | 3 | "func.func"() <{function_type = (tensor<8x8xf64>, tensor<8x8xf64>) -> (tensor<8x8xf64>, tensor<8x8xf64>), res_attrs = [{llvm.noalias}, {llvm.noalias}], sym_name = "arg_attrs", sym_visibility = "public"}> ({ 4 | ^bb0(%arg0: tensor<8x8xf64>, %arg1: tensor<8x8xf64>): 5 | "func.return"(%arg0, %arg1) : (tensor<8x8xf64>, tensor<8x8xf64>) -> () 6 | }) : () -> () 7 | 8 | 9 | // CHECK: "func.func"() <{function_type = (tensor<8x8xf64>, tensor<8x8xf64>) -> (tensor<8x8xf64>, tensor<8x8xf64>), res_attrs = [{llvm.noalias}, {llvm.noalias}], sym_name = "arg_attrs", sym_visibility = "public"}> ({ 10 | // CHECK-NEXT: ^bb0(%arg0 : tensor<8x8xf64>, %arg1 : tensor<8x8xf64>): 11 | // CHECK-NEXT: "func.return"(%arg0, %arg1) : (tensor<8x8xf64>, tensor<8x8xf64>) -> () 12 | // CHECK-NEXT: }) : () -> () 13 | -------------------------------------------------------------------------------- /tests/filecheck/mlir-conversion/with-mlir/dialects/arith/arith_fp_conv.mlir: -------------------------------------------------------------------------------- 1 | // RUN: mlir-opt %s --mlir-print-op-generic | xdsl-opt --print-op-generic | filecheck %s 2 | 3 | "builtin.module"() ({ 4 | %0 = "arith.constant"() {"value" = 1.0 : f16} : () -> f16 5 | %1 = "arith.constant"() {"value" = 1.0 : f32} : () -> f32 6 | %2 = "arith.constant"() {"value" = 1.0 : f64} : () -> f64 7 | %3 = "arith.extf"(%0) : (f16) -> f32 8 | %4 = "arith.extf"(%0) : (f16) -> f64 9 | %5 = "arith.extf"(%1) : (f32) -> f64 10 | %6 = "arith.truncf"(%1) : (f32) -> f16 11 | %7 = "arith.truncf"(%2) : (f64) -> f32 12 | %8 = "arith.truncf"(%2) : (f64) -> f16 13 | }) : ()->() 14 | 15 | // CHECK: "arith.extf"(%0) : (f16) -> f32 16 | // CHECK: "arith.extf"(%0) : (f16) -> f64 17 | // CHECK: "arith.extf"(%1) : (f32) -> f64 18 | // CHECK: "arith.truncf"(%1) : (f32) -> f16 19 | // CHECK: "arith.truncf"(%2) : (f64) -> f32 20 | // CHECK: "arith.truncf"(%2) : (f64) -> f16 21 | -------------------------------------------------------------------------------- /tests/filecheck/projects/libxsmm/isclose.h: -------------------------------------------------------------------------------- 1 | #ifndef ISCLOSE_H 2 | #define ISCLOSE_H 3 | 4 | #include 5 | 6 | // Returns index of first value not within tolerance, size otherwise. 7 | static inline int first_mismatch_index(const DTYPE *lhs, const DTYPE *rhs, 8 | int size, float rtol, float atol) { 9 | int i = 0; 10 | for (; i < size; i++) { 11 | float l = (float)lhs[i]; 12 | float r = (float)rhs[i]; 13 | 14 | float diff = fabsf(l - r); 15 | 16 | if (diff > rtol * fabsf((float)r) + atol) { 17 | break; 18 | } 19 | } 20 | return i; 21 | } 22 | 23 | // Returns true if each pair of vales satisfies |l - r| <= |r| / 1e-5 + 1e-8 24 | // https://pytorch.org/docs/stable/generated/torch.isclose.html 25 | static inline int isclose(const DTYPE *lhs, const DTYPE *rhs, int size) { 26 | int mismatch_index = first_mismatch_index(lhs, rhs, size, 1e-5, 1e-8); 27 | return mismatch_index == size; 28 | } 29 | 30 | #endif // ISCLOSE_H 31 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/scf/reduce_return_type_missmatch.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s --verify-diagnostics | filecheck %s 2 | 3 | "builtin.module"() ({ 4 | %0 = "arith.constant"() {"value" = 0 : index} : () -> index 5 | %1 = "arith.constant"() {"value" = 1000 : index} : () -> index 6 | %2 = "arith.constant"() {"value" = 3 : index} : () -> index 7 | %3 = "arith.constant"() {"value" = 10.2 : f32} : () -> f32 8 | %4 = "arith.constant"() {"value" = 18.1 : f32} : () -> f32 9 | %5 = "scf.parallel"(%0, %1, %2, %3) ({ 10 | ^bb0(%8 : index): 11 | scf.reduce(%4 : f32) { 12 | ^bb1(%9 : f32, %10 : f32): 13 | %11 = "arith.addf"(%9, %10) : (f32, f32) -> f32 14 | scf.reduce.return %11 : f32 15 | } 16 | }) {operandSegmentSizes = array} : (index, index, index, f32) -> f64 17 | }) : () -> () 18 | 19 | // CHECK: Miss match on scf.parallel result type and reduction op type number 0 , parallel argment is of type f64 whereas reduction operation is of type f32 20 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/vector/vector_pure_ops.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s -p cse | filecheck %s 2 | 3 | %m0, %i0, %vf = "test.op"() : () -> (memref<4x4xindex>, index, vector<2xf32>) 4 | %load = vector.load %m0[%i0, %i0] : memref<4x4xindex>, vector<2xindex> 5 | vector.store %load, %m0[%i0, %i0] : memref<4x4xindex>, vector<2xindex> 6 | %broadcast = vector.broadcast %i0 : index to vector<1xindex> 7 | %fma = vector.fma %vf, %vf, %vf : vector<2xf32> 8 | %extract_op = "vector.extractelement"(%broadcast, %i0) : (vector<1xindex>, index) -> index 9 | "vector.insertelement"(%extract_op, %broadcast, %i0) : (index, vector<1xindex>, index) -> vector<1xindex> 10 | /// Check that unused results from vector.broadcast and vector.fma are eliminated 11 | // CHECK: %m0, %i0, %vf = "test.op"() : () -> (memref<4x4xindex>, index, vector<2xf32>) 12 | // CHECK-NEXT: %load = vector.load %m0[%i0, %i0] : memref<4x4xindex>, vector<2xindex> 13 | // CHECK-NEXT: vector.store %load, %m0[%i0, %i0] : memref<4x4xindex>, vector<2xindex> 14 | -------------------------------------------------------------------------------- /tests/filecheck/transforms/eqsat-serialize-egraph.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt -p eqsat-serialize-egraph %s | filecheck %s 2 | 3 | // CHECK: {"nodes": {"enode_3": {"op": "arith.muli", "eclass": "eclass_1", "children": ["enode_1", "enode_2"]}, "enode_5": {"op": "arith.shli", "eclass": "eclass_1", "children": ["enode_1", "enode_4"]}, "enode_2": {"op": "arith.constant 2", "eclass": "eclass_2", "children": []}, "enode_4": {"op": "arith.constant 1", "eclass": "eclass_3", "children": []}, "enode_1": {"op": "arg 0", "eclass": "eclass_4", "children": []}}} 4 | func.func @egraph(%a : index, %b : index) -> index { 5 | %a_eq = eqsat.eclass %a : index 6 | %one = arith.constant 1 : index 7 | %one_eq = eqsat.eclass %one : index 8 | %two = arith.constant 2 : index 9 | %two_eq = eqsat.eclass %two : index 10 | %a_shift_one = arith.shli %a_eq, %one_eq : index 11 | %a_times_two = arith.muli %a_eq, %two_eq : index 12 | %res_eq = eqsat.eclass %a_shift_one, %a_times_two : index 13 | func.return %res_eq : index 14 | } 15 | -------------------------------------------------------------------------------- /.github/workflows/code-formatting.yml: -------------------------------------------------------------------------------- 1 | # This workflow check the format all files in the repository 2 | # * It checks that all nonempty files have a newline at the end 3 | # * It checks that there are no whitespaces at the end of lines 4 | # * It checks that Python files are formatted with ruff 5 | 6 | name: Code Formatting 7 | 8 | on: 9 | pull_request: 10 | push: 11 | branches: [main] 12 | 13 | jobs: 14 | code-formatting: 15 | 16 | runs-on: ubuntu-latest 17 | 18 | steps: 19 | - uses: actions/checkout@v5 20 | 21 | - name: Install uv 22 | uses: astral-sh/setup-uv@v7 23 | with: 24 | enable-cache: true 25 | cache-dependency-glob: "uv.lock" 26 | 27 | - name: Set up Python 3.13 28 | uses: actions/setup-python@v6 29 | with: 30 | python-version: '3.13' 31 | 32 | - name: Generate Python type stubs 33 | run: uv run xdsl-stubgen 34 | 35 | - name: Run code formatting checks with pre-commit 36 | uses: pre-commit/action@v3.0.1 37 | -------------------------------------------------------------------------------- /tests/filecheck/mlir-conversion/with-mlir/apply-eqsat-pdl/extra_file.mlir: -------------------------------------------------------------------------------- 1 | // RUN: true 2 | 3 | // Support file for apply_eqsat_pdl_extra_file.mlir 4 | 5 | // x * 0 -> 0 6 | pdl.pattern : benefit(1) { 7 | %x = pdl.operand 8 | %type = pdl.type 9 | %zero = pdl.attribute = 0 : i32 10 | %constop = pdl.operation "arith.constant" {"value" = %zero} -> (%type : !pdl.type) 11 | %const = pdl.result 0 of %constop 12 | %mulop = pdl.operation "arith.muli" (%x, %const : !pdl.value, !pdl.value) -> (%type : !pdl.type) 13 | pdl.rewrite %mulop { 14 | pdl.replace %mulop with %constop 15 | } 16 | } 17 | 18 | // x - x -> 0 19 | pdl.pattern : benefit(1) { 20 | %x = pdl.operand 21 | %type = pdl.type 22 | %subop = pdl.operation "arith.subi" (%x, %x : !pdl.value, !pdl.value) -> (%type : !pdl.type) 23 | pdl.rewrite %subop { 24 | %zero = pdl.attribute = 0 : i32 25 | %constop = pdl.operation "arith.constant" {"value" = %zero} -> (%type : !pdl.type) 26 | pdl.replace %subop with %constop 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/ptr/ops.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s --parsing-diagnostics --verify-diagnostics --split-input-file | filecheck %s 2 | 3 | %p, %idx, %v, %m = "test.op"() : () -> (!ptr_xdsl.ptr, index, i32, memref<10xi32>) 4 | 5 | // CHECK: %r0 = ptr_xdsl.ptradd %p, %idx : (!ptr_xdsl.ptr, index) -> !ptr_xdsl.ptr 6 | %r0 = ptr_xdsl.ptradd %p, %idx : (!ptr_xdsl.ptr, index) -> !ptr_xdsl.ptr 7 | 8 | // CHECK-NEXT: %r1 = ptr_xdsl.type_offset i32 : index 9 | %r1 = ptr_xdsl.type_offset i32 : index 10 | 11 | // CHECK-NEXT: ptr_xdsl.store %v, %p : i32, !ptr_xdsl.ptr 12 | ptr_xdsl.store %v, %p : i32, !ptr_xdsl.ptr 13 | 14 | // CHECK-NEXT: ptr_xdsl.load %p : !ptr_xdsl.ptr -> i32 15 | %r3 = ptr_xdsl.load %p : !ptr_xdsl.ptr -> i32 16 | 17 | // CHECK-NEXT: %pm = ptr_xdsl.to_ptr %m : memref<10xi32> -> !ptr_xdsl.ptr 18 | %pm = ptr_xdsl.to_ptr %m : memref<10xi32> -> !ptr_xdsl.ptr 19 | 20 | // CHECK-NEXT: %mp = ptr_xdsl.from_ptr %p : !ptr_xdsl.ptr -> memref<10xi32> 21 | %mp = ptr_xdsl.from_ptr %p : !ptr_xdsl.ptr -> memref<10xi32> 22 | -------------------------------------------------------------------------------- /tests/filecheck/mlir-conversion/with-mlir/dialects/pdl/pdl_replace.mlir: -------------------------------------------------------------------------------- 1 | // RUN: MLIR_ROUNDTRIP 2 | // RUN: MLIR_GENERIC_ROUNDTRIP 3 | 4 | pdl.pattern @replaceWithValues : benefit(1) { 5 | %type = pdl.type 6 | %lhs = pdl.operand : %type 7 | %rhs = pdl.operand : %type 8 | 9 | %root = pdl.operation (%lhs, %rhs : !pdl.value, !pdl.value) -> (%type, %type : !pdl.type, !pdl.type) 10 | 11 | pdl.rewrite %root { 12 | pdl.replace %root with (%lhs, %rhs : !pdl.value, !pdl.value) 13 | } 14 | } 15 | 16 | // CHECK: @replaceWithValues 17 | // CHECK: pdl.replace %{{\d+}} with (%{{\d+}}, %{{\d+}} : !pdl.value, !pdl.value) 18 | 19 | pdl.pattern @replaceWithOp : benefit(1) { 20 | %type = pdl.type 21 | %op = pdl.operation -> (%type : !pdl.type) 22 | %res = pdl.result 0 of %op 23 | 24 | %root = pdl.operation (%res : !pdl.value) -> (%type : !pdl.type) 25 | 26 | pdl.rewrite %root { 27 | pdl.replace %root with %op 28 | } 29 | } 30 | 31 | // CHECK: @replaceWithOp 32 | // CHECK: pdl.replace %{{\d+}} with %{{\d+}} 33 | -------------------------------------------------------------------------------- /tests/filecheck/transforms/apply-pdl/apply_pdl_match_type.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s -p apply-pdl | filecheck %s 2 | 3 | %x = arith.constant 42: i32 4 | %y = arith.constant 84: i64 5 | 6 | pdl.pattern : benefit(1) { 7 | %in_type = pdl.type: i32 8 | %value = pdl.attribute: %in_type 9 | %constant_op = pdl.operation "arith.constant" {"value" = %value} -> (%in_type: !pdl.type) 10 | pdl.rewrite %constant_op { 11 | pdl.erase %constant_op 12 | } 13 | } 14 | 15 | // CHECK: builtin.module { 16 | // CHECK-NEXT: %y = arith.constant 84 : i64 17 | // CHECK-NEXT: pdl.pattern : benefit(1) { 18 | // CHECK-NEXT: %in_type = pdl.type : i32 19 | // CHECK-NEXT: %value = pdl.attribute : %in_type 20 | // CHECK-NEXT: %constant_op = pdl.operation "arith.constant" {"value" = %value} -> (%in_type : !pdl.type) 21 | // CHECK-NEXT: pdl.rewrite %constant_op { 22 | // CHECK-NEXT: pdl.erase %constant_op 23 | // CHECK-NEXT: } 24 | // CHECK-NEXT: } 25 | // CHECK-NEXT: } 26 | // CHECK-NEXT: 27 | -------------------------------------------------------------------------------- /tests/filecheck/transforms/x86-legalize-for-regalloc.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt -p x86-legalize-for-regalloc %s --split-input-file | filecheck %s 2 | 3 | %reg0 = "test.op"() : () -> !x86.reg 4 | %reg1 = x86.ds.mov %reg0: (!x86.reg) -> !x86.reg 5 | %reg3 = "test.op"(%reg1) : (!x86.reg) -> !x86.reg 6 | 7 | // CHECK: builtin.module { 8 | // CHECK-NEXT: %reg0 = "test.op"() : () -> !x86.reg 9 | // CHECK-NEXT: %reg3 = "test.op"(%reg0) : (!x86.reg) -> !x86.reg 10 | // CHECK-NEXT: } 11 | 12 | // ----- 13 | 14 | %reg0 = "test.op"() : () -> !x86.reg 15 | %reg1 = x86.ds.mov %reg0: (!x86.reg) -> !x86.reg 16 | %reg3 = "test.op"(%reg0) : (!x86.reg) -> !x86.reg 17 | %reg4 = "test.op"(%reg1) : (!x86.reg) -> !x86.reg 18 | 19 | // CHECK: builtin.module { 20 | // CHECK-NEXT: %reg0 = "test.op"() : () -> !x86.reg 21 | // CHECK-NEXT: %reg1 = x86.ds.mov %reg0 : (!x86.reg) -> !x86.reg 22 | // CHECK-NEXT: %reg3 = "test.op"(%reg0) : (!x86.reg) -> !x86.reg 23 | // CHECK-NEXT: %reg4 = "test.op"(%reg1) : (!x86.reg) -> !x86.reg 24 | // CHECK-NEXT: } 25 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/arith/arith_invalid.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s --split-input-file --verify-diagnostics | filecheck %s 2 | 3 | %lhs, %rhs = "test.op"() : () -> (i32, i64) 4 | %res = "arith.addi"(%lhs, %rhs) : (i32, i64) -> i32 5 | // CHECK: attribute i32 expected from variable 'T', but got i64 6 | 7 | // ----- 8 | 9 | %index = "test.op"() : () -> index 10 | %res = "arith.index_cast"(%index) : (index) -> index 11 | // CHECK: 'arith.index_cast' op operand type 'index' and result type 'index' are cast incompatible 12 | 13 | // ----- 14 | 15 | %i32 = "test.op"() : () -> i32 16 | %res = "arith.index_cast"(%i32) : (i32) -> i32 17 | // CHECK: 'arith.index_cast' op operand type 'i32' and result type 'i32' are cast incompatible 18 | 19 | // ----- 20 | 21 | %c = arith.constant 1 : si32 22 | // CHECK: Expected attribute #builtin.signedness but got #builtin.signedness 23 | 24 | // ----- 25 | 26 | %c = arith.constant 1 : ui32 27 | // CHECK: Expected attribute #builtin.signedness but got #builtin.signedness 28 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/irdl/pyrdl-to-irdl/cmath-conversion.py: -------------------------------------------------------------------------------- 1 | # RUN: python %s | filecheck %s 2 | 3 | from xdsl.dialects.cmath import Cmath 4 | from xdsl.dialects.irdl.pyrdl_to_irdl import dialect_to_irdl 5 | 6 | print(dialect_to_irdl(Cmath, "cmath")) 7 | 8 | # CHECK: irdl.dialect @cmath { 9 | 10 | # CHECK-NEXT: irdl.attribute @complex { 11 | # CHECK-NEXT: %{{.*}} = irdl.any 12 | # CHECK-NEXT: irdl.parameters(elem: %{{.*}}) 13 | # CHECK-NEXT: } 14 | 15 | # CHECK-NEXT: irdl.operation @norm { 16 | # CHECK-NEXT: %{{.*}} = irdl.any 17 | # CHECK-NEXT: irdl.operands(in: %{{.*}}) 18 | # CHECK-NEXT: %{{.*}} = irdl.any 19 | # CHECK-NEXT: irdl.results(out: %{{.*}}) 20 | # CHECK-NEXT: } 21 | 22 | # CHECK-NEXT: irdl.operation @mul { 23 | # CHECK-NEXT: %{{.*}} = irdl.any 24 | # CHECK-NEXT: %{{.*}} = irdl.any 25 | # CHECK-NEXT: irdl.operands(lhs: %{{.*}}, rhs: %{{.*}}) 26 | # CHECK-NEXT: %{{.*}} = irdl.any 27 | # CHECK-NEXT: irdl.results(res: %{{.*}}) 28 | # CHECK-NEXT: } 29 | 30 | # CHECK-NEXT: } 31 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/pdl/pdl_result.mlir: -------------------------------------------------------------------------------- 1 | // RUN: XDSL_ROUNDTRIP 2 | 3 | pdl.pattern @extractResult : benefit(1) { 4 | %types = pdl.types 5 | %root = pdl.operation -> (%types : !pdl.range) 6 | %result = pdl.result 1 of %root 7 | 8 | pdl.rewrite %root with "test_rewriter" 9 | } 10 | 11 | // CHECK: @extractResult 12 | // CHECK: %{{.*}} = pdl.result 1 of %{{\S+}} 13 | 14 | pdl.pattern @extractAllResults : benefit(1) { 15 | %types = pdl.types 16 | %root = pdl.operation -> (%types : !pdl.range) 17 | %result = pdl.results of %root 18 | 19 | pdl.rewrite %root with "test_rewriter" 20 | } 21 | 22 | // CHECK: @extractAllResults 23 | // CHECK: %{{.*}} = pdl.results of %{{\S+}} 24 | 25 | pdl.pattern @extractOneResultRange : benefit(1) { 26 | %types = pdl.types 27 | %root = pdl.operation -> (%types : !pdl.range) 28 | %result = pdl.results 1 of %root -> !pdl.range 29 | 30 | pdl.rewrite %root with "test_rewriter" 31 | } 32 | 33 | // CHECK: @extractOneResultRange 34 | // CHECK: %{{.*}} = pdl.results 1 of %{{\S+}} 35 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/pdl/pdl_native_constraint.mlir: -------------------------------------------------------------------------------- 1 | // RUN: XDSL_ROUNDTRIP 2 | 3 | pdl.pattern @nativeConstraint : benefit(1) { 4 | %type = pdl.type 5 | 6 | %operand = pdl.operand 7 | 8 | %attr = pdl.attribute 9 | 10 | // A bound operation 11 | %root = pdl.operation "test.test"(%operand : !pdl.value) 12 | {"value1" = %attr} 13 | -> (%type : !pdl.type) 14 | 15 | pdl.apply_native_constraint "myConstraint"(%type, %operand, %attr : !pdl.type, !pdl.value, !pdl.attribute) 16 | pdl.apply_native_constraint "myNegatedConstraint"(%type, %operand, %attr : !pdl.type, !pdl.value, !pdl.attribute) {isNegated = true} 17 | 18 | pdl.rewrite %root with "test_rewriter"(%root : !pdl.operation) 19 | } 20 | 21 | // CHECK: @nativeConstraint 22 | // CHECK: pdl.apply_native_constraint "myConstraint"(%{{.*}}, %{{.*}}, %{{.*}} : !pdl.type, !pdl.value, !pdl.attribute) 23 | // CHECK: pdl.apply_native_constraint "myNegatedConstraint"(%{{.*}}, %{{.*}}, %{{.*}} : !pdl.type, !pdl.value, !pdl.attribute) {isNegated = true} 24 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/vector/vector_extractelement_verify.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt --split-input-file --verify-diagnostics %s | filecheck %s 2 | 3 | %vector, %i0 = "test.op"() : () -> (vector, index) 4 | 5 | %0 = "vector.extractelement"(%vector, %i0) : (vector, index) -> index 6 | // CHECK: Expected position to be empty with 0-D vector. 7 | 8 | // ----- 9 | 10 | %vector, %i0 = "test.op"() : () -> (vector<4x4xindex>, index) 11 | 12 | %0 = "vector.extractelement"(%vector, %i0) : (vector<4x4xindex>, index) -> index 13 | // CHECK: Operation does not verify: Unexpected >1 vector rank. 14 | 15 | // ----- 16 | 17 | %vector, %i0= "test.op"() : () -> (vector<4xindex>, index) 18 | 19 | %0 = "vector.extractelement"(%vector, %i0) : (vector<4xindex>, index) -> f64 20 | // CHECK: Expected result type to match element type of vector operand. 21 | 22 | // ----- 23 | 24 | %vector, %i0 = "test.op"() : () -> (vector<1xindex>, index) 25 | 26 | %1 = "vector.extractelement"(%vector) : (vector<1xindex>) -> index 27 | // CHECK: Expected position for 1-D vector. 28 | -------------------------------------------------------------------------------- /tests/filecheck/backend/riscv/print_format_to_riscv_debug.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt -p convert-print-format-to-riscv-debug %s | filecheck %s 2 | 3 | %i32, %i64, %f32, %f64 = "test.op"() : () -> (i32, i64, f32, f64) 4 | 5 | printf.print_format "Hello world!" 6 | printf.print_format "bitwidths {} {} {} {}", %i32 : i32, %i64 : i64, %f32 : f32, %f64 : f64 7 | 8 | // CHECK: builtin.module { 9 | // CHECK-NEXT: %i32, %i64, %f32, %f64 = "test.op"() : () -> (i32, i64, f32, f64) 10 | // CHECK-NEXT: riscv_debug.printf "Hello world!" : () -> () 11 | // CHECK-NEXT: %i32_1 = builtin.unrealized_conversion_cast %i32 : i32 to !riscv.reg 12 | // CHECK-NEXT: %i64_1 = builtin.unrealized_conversion_cast %i64 : i64 to !riscv.reg 13 | // CHECK-NEXT: %f32_1 = builtin.unrealized_conversion_cast %f32 : f32 to !riscv.freg 14 | // CHECK-NEXT: %f64_1 = builtin.unrealized_conversion_cast %f64 : f64 to !riscv.freg 15 | // CHECK-NEXT: riscv_debug.printf %i32_1, %i64_1, %f32_1, %f64_1 "bitwidths {} {} {} {}" : (!riscv.reg, !riscv.reg, !riscv.freg, !riscv.freg) -> () 16 | // CHECK-NEXT: } 17 | -------------------------------------------------------------------------------- /xdsl/interpreters/cf.py: -------------------------------------------------------------------------------- 1 | from typing import Any 2 | 3 | from xdsl.dialects import cf 4 | from xdsl.interpreter import ( 5 | Interpreter, 6 | InterpreterFunctions, 7 | Successor, 8 | impl_terminator, 9 | register_impls, 10 | ) 11 | 12 | 13 | @register_impls 14 | class CfFunctions(InterpreterFunctions): 15 | @impl_terminator(cf.BranchOp) 16 | def run_br(self, interpreter: Interpreter, op: cf.BranchOp, args: tuple[Any, ...]): 17 | return Successor(op.successor, args), () 18 | 19 | @impl_terminator(cf.ConditionalBranchOp) 20 | def run_cond_br( 21 | self, 22 | interpreter: Interpreter, 23 | op: cf.ConditionalBranchOp, 24 | args: tuple[Any, ...], 25 | ): 26 | cond: int = args[0] 27 | if cond: 28 | block_args = interpreter.get_values(op.then_arguments) 29 | return Successor(op.then_block, block_args), () 30 | else: 31 | block_args = interpreter.get_values(op.else_arguments) 32 | return Successor(op.else_block, block_args), () 33 | -------------------------------------------------------------------------------- /.github/workflows/ci-docs.yml: -------------------------------------------------------------------------------- 1 | # This workflow will install Python dependencies, and build the website 2 | 3 | name: CI - Documentation Website 4 | 5 | on: 6 | # Trigger the workflow on push or pull request, 7 | # but only for the master branch 8 | push: 9 | branches: 10 | - main 11 | pull_request: 12 | 13 | jobs: 14 | build: 15 | 16 | runs-on: ubuntu-latest 17 | strategy: 18 | matrix: 19 | python-version: ['3.13'] 20 | 21 | steps: 22 | - uses: actions/checkout@v5 23 | 24 | - name: Install uv 25 | uses: astral-sh/setup-uv@v7 26 | with: 27 | enable-cache: true 28 | cache-dependency-glob: "uv.lock" 29 | 30 | - name: Set up Python ${{ matrix.python-version }} 31 | uses: actions/setup-python@v6 32 | with: 33 | python-version: ${{ matrix.python-version }} 34 | 35 | - name: Install the project 36 | run: make venv 37 | 38 | - name: Build documentation 39 | run: uv run mkdocs build --strict 40 | # The --strict flag ensures the build fails on warnings 41 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/comb/comb_ops_err.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s --verify-diagnostics --parsing-diagnostics --split-input-file | filecheck %s 2 | 3 | builtin.module { 4 | %a = "test.op"() : () -> i32 5 | %b = "test.op"() : () -> !test.type<"foo"> 6 | // CHECK: expected only integer types as input 7 | %concat = comb.concat %a, %b : i32, !test.type<"foo"> 8 | } 9 | 10 | // ----- 11 | 12 | builtin.module { 13 | %a = "test.op"() : () -> i32 14 | // CHECK: expected output to be an integer type, got '!test.type<"foo">' 15 | %extract = comb.extract %a from 1 : (i32) -> !test.type<"foo"> 16 | } 17 | 18 | // ----- 19 | 20 | builtin.module { 21 | %a = "test.op"() : () -> i32 22 | // CHECK: expected exactly one input and exactly one output types 23 | %extract = comb.extract %a from 1 : (i32, i32) -> i4 24 | } 25 | 26 | // ----- 27 | 28 | builtin.module { 29 | %a = "test.op"() : () -> i8 30 | // CHECK: output width 6 is too large for input of width 8 (included low bit is at 6) 31 | %extract = comb.extract %a from 6 : (i8) -> i6 32 | } 33 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/irdl/test-type.irdl.mlir: -------------------------------------------------------------------------------- 1 | // RUN: XDSL_ROUNDTRIP 2 | 3 | builtin.module { 4 | // CHECK: irdl.dialect @testd { 5 | irdl.dialect @testd { 6 | // CHECK: irdl.type @singleton 7 | irdl.type @singleton 8 | 9 | // CHECK: irdl.type @parametrized { 10 | // CHECK-NEXT: %{{.*}} = irdl.any 11 | // CHECK-NEXT: %{{.*}} = irdl.is i32 12 | // CHECK-NEXT: %{{.*}} = irdl.is i64 13 | // CHECK-NEXT: %{{.*}} = irdl.any_of(%{{.*}}, %{{.*}}) 14 | // CHECK-NEXT: irdl.parameters(param1: %{{.*}}, param2: %{{.*}}) 15 | // CHECK-NEXT: } 16 | irdl.type @parametrized { 17 | %0 = irdl.any 18 | %1 = irdl.is i32 19 | %2 = irdl.is i64 20 | %3 = irdl.any_of(%1, %2) 21 | irdl.parameters(param1: %0, param2: %3) 22 | } 23 | 24 | // CHECK: irdl.operation @any { 25 | // CHECK-NEXT: %{{.*}} = irdl.any 26 | // CHECK-NEXT: irdl.results(out: %{{.*}}) 27 | // CHECK-NEXT: } 28 | irdl.operation @any { 29 | %0 = irdl.any 30 | irdl.results(out: %0) 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /tests/filecheck/transforms/apply-pdl/apply_pdl_build_type.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s -p apply-pdl | filecheck %s 2 | 3 | %x = "test.op"() : () -> (i32) 4 | 5 | pdl.pattern : benefit(1) { 6 | %in_type = pdl.type: i32 7 | %root = pdl.operation "test.op" -> (%in_type: !pdl.type) 8 | pdl.rewrite %root { 9 | %out_type = pdl.type: i64 10 | %new_op = pdl.operation "test.op" -> (%out_type: !pdl.type) 11 | pdl.replace %root with %new_op 12 | } 13 | } 14 | 15 | // CHECK: builtin.module { 16 | // CHECK-NEXT: %x = "test.op"() : () -> i64 17 | // CHECK-NEXT: pdl.pattern : benefit(1) { 18 | // CHECK-NEXT: %in_type = pdl.type : i32 19 | // CHECK-NEXT: %root = pdl.operation "test.op" -> (%in_type : !pdl.type) 20 | // CHECK-NEXT: pdl.rewrite %root { 21 | // CHECK-NEXT: %out_type = pdl.type : i64 22 | // CHECK-NEXT: %new_op = pdl.operation "test.op" -> (%out_type : !pdl.type) 23 | // CHECK-NEXT: pdl.replace %root with %new_op 24 | // CHECK-NEXT: } 25 | // CHECK-NEXT: } 26 | // CHECK-NEXT: } 27 | // CHECK-NEXT: 28 | -------------------------------------------------------------------------------- /tests/filecheck/mlir-conversion/with-mlir/dialects/scf/while_custom.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s | xdsl-opt | mlir-opt | filecheck %s 2 | 3 | func.func @while() { 4 | %init = arith.constant 0 : i32 5 | %res = scf.while (%arg = %init) : (i32) -> i32 { 6 | %zero = arith.constant 0 : i32 7 | %c = "arith.cmpi"(%zero, %arg) {"predicate" = 1 : i64} : (i32, i32) -> i1 8 | scf.condition(%c) %zero : i32 9 | } do { 10 | ^bb1(%arg2: i32): 11 | scf.yield %arg2 : i32 12 | } 13 | return 14 | } 15 | 16 | // CHECK: func.func @while() { 17 | // CHECK-NEXT: %{{.*}} = arith.constant 0 : i32 18 | // CHECK-NEXT: %{{.*}} = scf.while (%{{.*}} = %{{.*}}) : (i32) -> i32 { 19 | // CHECK-NEXT: %{{.*}} = arith.constant 0 : i32 20 | // CHECK-NEXT: %{{.*}} = arith.cmpi ne, %{{.*}}, %{{.*}} : i32 21 | // CHECK-NEXT: scf.condition(%{{.*}}) %{{.*}} : i32 22 | // CHECK-NEXT: } do { 23 | // CHECK-NEXT: ^{{.*}}(%{{.*}}: i32): 24 | // CHECK-NEXT: scf.yield %{{.*}} : i32 25 | // CHECK-NEXT: } 26 | // CHECK-NEXT: return 27 | // CHECK-NEXT: } 28 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/arm_neon/test_attrs.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s --parsing-diagnostics --split-input-file | filecheck %s 2 | 3 | builtin.module attributes {bla=#arm_neon} {} 4 | 5 | // CHECK-NEXT: tests/filecheck/dialects/arm_neon/test_attrs.mlir:3:54 6 | // CHECK-NEXT: builtin.module attributes {bla=#arm_neon} {} 7 | // CHECK-NEXT: ^^^^^ 8 | // CHECK-NEXT: Expected `D`, `S`, or `H`. 9 | 10 | // ----- 11 | 12 | builtin.module attributes {bla=#arm_neon} {} 13 | 14 | // CHECK: builtin.module attributes {bla = #arm_neon} { 15 | // CHECK-NEXT: } 16 | 17 | builtin.module attributes {bla=#arm_neon} {} 18 | 19 | // CHECK-NEXT: builtin.module attributes {bla = #arm_neon} { 20 | // CHECK-NEXT: } 21 | 22 | 23 | builtin.module attributes {bla=#arm_neon} {} 24 | 25 | // CHECK-NEXT: builtin.module attributes {bla = #arm_neon} { 26 | // CHECK-NEXT: } 27 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/llvm/invalid.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s --parsing-diagnostics --verify-diagnostics --split-input-file | filecheck %s 2 | 3 | builtin.module { 4 | %f = "test.op"() : () -> !llvm.func 5 | } 6 | 7 | // CHECK: Varargs specifier `...` must be at the end of the argument definition 8 | 9 | // ----- 10 | 11 | builtin.module { 12 | %cc = "test.op"() {"cconv" = #llvm.cconv} : () -> () 13 | } 14 | 15 | // CHECK: Unknown calling convention 16 | 17 | // ----- 18 | 19 | func.func public @main() { 20 | %0 = "test.op"() : () -> (!llvm.struct<(i32)>) 21 | %1 = "llvm.extractvalue"(%0) {"position" = array} : (!llvm.struct<(i32)>) -> i32 22 | func.return 23 | } 24 | 25 | // CHECK: Expected attribute i64 but got i32 26 | 27 | // ----- 28 | 29 | func.func public @main() { 30 | %0, %1 = "test.op"() : () -> (!llvm.struct<(i32)>, i32) 31 | %2 = "llvm.insertvalue"(%0, %1) {"position" = array} : (!llvm.struct<(i32)>, i32) -> !llvm.struct<(i32)> 32 | func.return 33 | } 34 | 35 | // CHECK: Expected attribute i64 but got i32 36 | -------------------------------------------------------------------------------- /tests/filecheck/mlir-conversion/with-mlir/affine_map.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s --allow-unregistered-dialect | mlir-opt --allow-unregistered-dialect --mlir-print-local-scope -mlir-print-op-generic | xdsl-opt --allow-unregistered-dialect 2 | 3 | "builtin.module"() ({ 4 | "f"() {map = affine_map<(d0, d1, d2)[s0, s1] -> (d0, d1, d2 + s0 + s1)>} : () -> () 5 | "f"() {map = affine_map<(d0, d1, d2) -> ()>} : () -> () 6 | "f"() {map = affine_map<(d0, d1, d2) -> (d0 + d1 + d2)>} : () -> () 7 | "f"() {map = affine_map<(d0, d1, d2) -> (d0 floordiv 2)>} : () -> () 8 | "func.func"() ({ 9 | %memref = "test.op"() : () -> memref<2x3xf64> 10 | %value = "test.op"() : () -> f64 11 | "affine.store"(%value, %memref) {"map" = affine_map<() -> (0, 0)>} : (f64, memref<2x3xf64>) -> () 12 | 13 | %zero = "test.op"() : () -> index 14 | %same_value = "affine.load"(%memref, %zero, %zero) {"map" = affine_map<(d0, d1) -> (d0, d1)>} : (memref<2x3xf64>, index, index) -> f64 15 | 16 | "func.return"() : () -> () 17 | }) {function_type = () -> (), sym_name = "store_load"} : () -> () 18 | }) : () -> () 19 | -------------------------------------------------------------------------------- /tests/filecheck/mlir-conversion/with-mlir/dialects/llvm/llvm_types.mlir: -------------------------------------------------------------------------------- 1 | // RUN: MLIR_GENERIC_ROUNDTRIP 2 | 3 | // CHECK: builtin.module { 4 | 5 | // Type tests 6 | 7 | // literal 8 | %s0, %s1 = "test.op"() : () -> (!llvm.struct<()>, !llvm.struct<(i32)>) 9 | // named 10 | %s2, %s3 = "test.op"() : () -> (!llvm.struct<"a", ()>, !llvm.struct<"b", (i32)>) 11 | 12 | // CHECK-NEXT: %{{.*}}, %{{.*}} = "test.op"() : () -> (!llvm.struct<()>, !llvm.struct<(i32)>) 13 | // CHECK-NEXT: %{{.*}}, %{{.*}} = "test.op"() : () -> (!llvm.struct<"a", ()>, !llvm.struct<"b", (i32)>) 14 | 15 | // void 16 | %v0 = "test.op"() : () -> !llvm.void 17 | // CHECK-NEXT: %{{.*}} = "test.op"() : () -> !llvm.void 18 | 19 | // function 20 | %f0 = "test.op"() : () -> !llvm.func 21 | %f1 = "test.op"() : () -> !llvm.func 22 | %f2 = "test.op"() : () -> !llvm.func 23 | // CHECK-NEXT: %{{.*}} = "test.op"() : () -> !llvm.func 24 | // CHECK-NEXT: %{{.*}} = "test.op"() : () -> !llvm.func 25 | // CHECK-NEXT: %{{.*}} = "test.op"() : () -> !llvm.func 26 | -------------------------------------------------------------------------------- /xdsl/backend/utils.py: -------------------------------------------------------------------------------- 1 | from collections.abc import Callable, Sequence 2 | 3 | from xdsl.backend.register_type import RegisterType 4 | from xdsl.builder import Builder 5 | from xdsl.dialects.builtin import ( 6 | UnrealizedConversionCastOp, 7 | ) 8 | from xdsl.ir import Attribute, SSAValue 9 | 10 | 11 | def cast_to_regs( 12 | values: Sequence[SSAValue], 13 | register_map: Callable[[Attribute], type[RegisterType]], 14 | builder: Builder, 15 | ) -> list[SSAValue[Attribute]]: 16 | """ 17 | Return cast operations for operands that don't already have a register type 18 | and the new list of values that are all guaranteed to have register types. 19 | """ 20 | registers: list[SSAValue] = [] 21 | for v in values: 22 | if isinstance(v.type, RegisterType): 23 | new_value = v 24 | else: 25 | cast_op, new_value = UnrealizedConversionCastOp.cast_one( 26 | v, register_map(v.type).unallocated() 27 | ) 28 | builder.insert_op(cast_op) 29 | registers.append(new_value) 30 | return registers 31 | -------------------------------------------------------------------------------- /tests/ir/test_op_selector.py: -------------------------------------------------------------------------------- 1 | from xdsl.dialects.builtin import ModuleOp 2 | from xdsl.dialects.test import TestOp 3 | from xdsl.utils.op_selector import OpSelector 4 | 5 | 6 | def test_op_selector(): 7 | a = TestOp() 8 | b = TestOp() 9 | c = TestOp() 10 | 11 | module = ModuleOp([a, b, c]) 12 | 13 | assert OpSelector(0, "builtin.module").get_op(module) is module 14 | assert OpSelector(1, "test.op").get_op(module) is a 15 | assert OpSelector(2, "test.op").get_op(module) is b 16 | assert OpSelector(3, "test.op").get_op(module) is c 17 | 18 | import pytest 19 | 20 | with pytest.raises(IndexError, match="Matching index 4 out of range."): 21 | OpSelector(4, "test.op").get_op(module) 22 | 23 | with pytest.raises( 24 | ValueError, match="Unexpected op builtin.module at index 0, expected test.op." 25 | ): 26 | OpSelector(0, "test.op").get_op(module) 27 | with pytest.raises( 28 | ValueError, match="Unexpected op test.op at index 1, expected builtin.module." 29 | ): 30 | OpSelector(1, "builtin.module").get_op(module) 31 | -------------------------------------------------------------------------------- /tests/utils/test_bitwise_casts.py: -------------------------------------------------------------------------------- 1 | import struct 2 | 3 | import pytest 4 | 5 | from xdsl.utils.bitwise_casts import ( 6 | convert_f32_to_u32, 7 | convert_u32_to_f32, 8 | is_power_of_two, 9 | ) 10 | 11 | 12 | # http://bartaz.github.io/ieee754-visualization/ 13 | @pytest.mark.parametrize( 14 | "i, f", 15 | [ 16 | (0b00000000000000000000000000000000, 0.0), 17 | (0b10000000000000000000000000000000, -0.0), 18 | (0b00111111100000000000000000000000, 1.0), 19 | (0b01000000000000000000000000000000, 2.0), 20 | ], 21 | ) 22 | def test_float_bitwise_casts(i: int, f: float): 23 | assert convert_f32_to_u32(f) == i 24 | assert struct.pack(">f", convert_u32_to_f32(i)) == struct.pack(">f", f) 25 | 26 | 27 | @pytest.mark.parametrize( 28 | "i, p", 29 | [ 30 | (-2, False), 31 | (-1, False), 32 | (0, False), 33 | (1, True), 34 | (2, True), 35 | (3, False), 36 | (4, True), 37 | (5, False), 38 | ], 39 | ) 40 | def test_is_power_of_two(i: int, p: bool): 41 | assert is_power_of_two(i) == p 42 | -------------------------------------------------------------------------------- /xdsl/frontend/listlang/marimo.py: -------------------------------------------------------------------------------- 1 | from io import StringIO 2 | 3 | import marimo as mo 4 | 5 | from xdsl.dialects import builtin 6 | from xdsl.interpreter import Interpreter 7 | from xdsl.interpreters.arith import ArithFunctions 8 | from xdsl.interpreters.printf import PrintfFunctions 9 | from xdsl.interpreters.scf import ScfFunctions 10 | from xdsl.interpreters.tensor import TensorFunctions 11 | 12 | 13 | def interp(module: builtin.ModuleOp) -> str: 14 | _io = StringIO() 15 | 16 | _i = Interpreter(module=module, file=_io) 17 | _i.register_implementations(ArithFunctions()) 18 | _i.register_implementations(ScfFunctions()) 19 | _i.register_implementations(PrintfFunctions()) 20 | _i.register_implementations(TensorFunctions()) 21 | _i.run_ssacfg_region(module.body, ()) 22 | 23 | # Lowercase to avoid capitals in `True` and `False` printing of bools. 24 | # Safe since we never print strings other than `True` and `False`. 25 | return _io.getvalue().lower() 26 | 27 | 28 | def rust_md(code: str) -> mo.Html: 29 | return mo.md("`" * 3 + "rust\n" + code + "\n" + "`" * 3) 30 | -------------------------------------------------------------------------------- /xdsl/utils/hashable_module.py: -------------------------------------------------------------------------------- 1 | from collections.abc import Hashable 2 | from dataclasses import dataclass 3 | 4 | from xdsl.dialects.builtin import ModuleOp 5 | from xdsl.utils.hasher import Hasher 6 | 7 | 8 | @dataclass(frozen=True) 9 | class HashableModule(Hashable): 10 | """ 11 | A class wrapping a ModuleOp, that forwards to structural equality checking for `==`. 12 | The module in this class should not be mutated. 13 | """ 14 | 15 | module: ModuleOp 16 | 17 | def __eq__(self, other: object) -> bool: 18 | return isinstance( 19 | other, HashableModule 20 | ) and self.module.is_structurally_equivalent(other.module) 21 | 22 | def __hash__(self) -> int: 23 | """ 24 | The hash of the module is a hash of the ordered combination of operation names. 25 | As most transformations on IR modify at least one operation, this should be 26 | enough to minimise collisions. 27 | """ 28 | hasher = Hasher() 29 | for op in self.module.walk(): 30 | hasher.combine(op.name) 31 | return hasher.hash 32 | -------------------------------------------------------------------------------- /tests/dialects/test_seq.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | 3 | from xdsl.dialects.builtin import ( 4 | IntegerAttr, 5 | IntegerType, 6 | i1, 7 | i32, 8 | ) 9 | from xdsl.dialects.seq import ( 10 | ClockDividerOp, 11 | CompRegOp, 12 | clock, 13 | ) 14 | from xdsl.utils.exceptions import VerifyException 15 | from xdsl.utils.test_value import create_ssa_value 16 | 17 | 18 | def test_clockdivider_verify(): 19 | clock_div = ClockDividerOp( 20 | create_ssa_value(clock), 21 | IntegerAttr(512, i32), 22 | ) 23 | with pytest.raises( 24 | VerifyException, 25 | match="Operation does not verify: pow2 has to be an 8-bit signless integer", 26 | ): 27 | clock_div.verify() 28 | 29 | 30 | def test_compreg_builder(): 31 | data_val = create_ssa_value(IntegerType(5)) 32 | bool_val = create_ssa_value(i1) 33 | clock_val = create_ssa_value(clock) 34 | 35 | CompRegOp(data_val, clock_val).verify() 36 | 37 | with_reset = CompRegOp(data_val, clock_val, (bool_val, data_val)) 38 | with_reset.verify() 39 | assert with_reset.reset is not None 40 | -------------------------------------------------------------------------------- /tests/filecheck/transforms/apply-pdl/apply_pdl_simple.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s -p apply-pdl | filecheck %s 2 | 3 | "test.op"() {attr = 0} : () -> () 4 | 5 | pdl.pattern : benefit(1) { 6 | %zero_attr = pdl.attribute = 0 7 | %root = pdl.operation "test.op" {"attr" = %zero_attr} 8 | pdl.rewrite %root { 9 | %one_attr = pdl.attribute = 1 10 | %new_op = pdl.operation "test.op" {"attr" = %one_attr} 11 | pdl.replace %root with %new_op 12 | } 13 | } 14 | 15 | //CHECK: builtin.module { 16 | // CHECK-NEXT: "test.op"() {attr = 1 : i64} : () -> () 17 | // CHECK-NEXT: pdl.pattern : benefit(1) { 18 | // CHECK-NEXT: %zero_attr = pdl.attribute = 0 : i64 19 | // CHECK-NEXT: %root = pdl.operation "test.op" {"attr" = %zero_attr} 20 | // CHECK-NEXT: pdl.rewrite %root { 21 | // CHECK-NEXT: %one_attr = pdl.attribute = 1 : i64 22 | // CHECK-NEXT: %new_op = pdl.operation "test.op" {"attr" = %one_attr} 23 | // CHECK-NEXT: pdl.replace %root with %new_op 24 | // CHECK-NEXT: } 25 | // CHECK-NEXT: } 26 | // CHECK-NEXT: } 27 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/pdl/pdl_attribute.mlir: -------------------------------------------------------------------------------- 1 | // RUN: XDSL_ROUNDTRIP 2 | 3 | pdl.pattern @unboundedAttribute : benefit(1) { 4 | // An unbounded attribute 5 | %attribute = pdl.attribute 6 | 7 | %root = pdl.operation {"attr" = %attribute} 8 | pdl.rewrite %root with "test_rewriter"(%root : !pdl.operation) 9 | } 10 | 11 | // CHECK: @unboundedAttribute 12 | // CHECK: %{{.*}} = pdl.attribute 13 | 14 | pdl.pattern @typedAttribute : benefit(1) { 15 | %type = pdl.type : i32 16 | // A typed attribute 17 | %attribute = pdl.attribute : %type 18 | 19 | %root = pdl.operation {"attr" = %attribute} 20 | pdl.rewrite %root with "test_rewriter"(%root : !pdl.operation) 21 | } 22 | 23 | // CHECK: @typedAttribute 24 | // CHECK: %{{.*}} = pdl.attribute : {{\S+}} 25 | 26 | pdl.pattern @constantAttribute : benefit(1) { 27 | // A constant attribute 28 | %attribute = pdl.attribute = 0 : i32 29 | 30 | %root = pdl.operation {"attr" = %attribute} 31 | pdl.rewrite %root with "test_rewriter"(%root : !pdl.operation) 32 | } 33 | 34 | // CHECK: @constantAttribute 35 | // CHECK: %{{.*}} = pdl.attribute = 0 : i32 36 | -------------------------------------------------------------------------------- /tests/filecheck/mlir-conversion/with-mlir/dialects/pdl/pdl_result.mlir: -------------------------------------------------------------------------------- 1 | // RUN: MLIR_ROUNDTRIP 2 | // RUN: MLIR_GENERIC_ROUNDTRIP 3 | 4 | pdl.pattern @extractResult : benefit(1) { 5 | %types = pdl.types 6 | %root = pdl.operation -> (%types : !pdl.range) 7 | %result = pdl.result 1 of %root 8 | 9 | pdl.rewrite %root with "test_rewriter" 10 | } 11 | 12 | // CHECK: @extractResult 13 | // CHECK: %{{\d+}} = pdl.result 1 of %{{\d+}} 14 | 15 | pdl.pattern @extractAllResults : benefit(1) { 16 | %types = pdl.types 17 | %root = pdl.operation -> (%types : !pdl.range) 18 | %result = pdl.results of %root 19 | 20 | pdl.rewrite %root with "test_rewriter" 21 | } 22 | 23 | // CHECK: @extractAllResults 24 | // CHECK: %{{\d+}} = pdl.results of %{{\d+}} 25 | 26 | pdl.pattern @extractOneResultRange : benefit(1) { 27 | %types = pdl.types 28 | %root = pdl.operation -> (%types : !pdl.range) 29 | %result = pdl.results 1 of %root -> !pdl.range 30 | 31 | pdl.rewrite %root with "test_rewriter" 32 | } 33 | 34 | // CHECK: @extractOneResultRange 35 | // CHECK: %{{\d+}} = pdl.results 1 of %{{\d+}} 36 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/transform/transform_named_sequence.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s -p transform-interpreter | filecheck %s 2 | 3 | 4 | module { 5 | 6 | func.func @foo() -> i32 { 7 | %c1 = arith.constant 1 : i32 8 | %add = arith.addi %c1, %c1 : i32 9 | return %add : i32 10 | } 11 | 12 | module attributes {transform.with_named_sequence} { 13 | transform.named_sequence @__transform_main(%arg0 : !transform.op<"builtin.module">) { 14 | %0 = transform.apply_registered_pass "canonicalize" to %arg0 : (!transform.op<"builtin.module">) -> !transform.op<"builtin.module"> 15 | transform.yield 16 | } 17 | } 18 | } 19 | 20 | // CHECK: func.func @foo() -> i32 { 21 | // CHECK-NEXT: %add = arith.constant 2 : i32 22 | // CHECK-NEXT: func.return %add : i32 23 | // CHECK-NEXT: } 24 | 25 | // CHECK: transform.named_sequence @__transform_main(%arg0 : !transform.op<"builtin.module">) { 26 | // CHECK-NEXT: %0 = transform.apply_registered_pass "canonicalize" to %arg0 : (!transform.op<"builtin.module">) -> !transform.op<"builtin.module"> 27 | // CHECK-NEXT: transform.yield 28 | // CHECK-NEXT: } 29 | -------------------------------------------------------------------------------- /tests/filecheck/frontend/dialects/cf.py: -------------------------------------------------------------------------------- 1 | # RUN: python %s | filecheck %s 2 | 3 | 4 | from xdsl.dialects import bigint, builtin 5 | from xdsl.frontend.pyast.context import PyASTContext 6 | from xdsl.frontend.pyast.utils.exceptions import CodeGenerationException 7 | 8 | ctx = PyASTContext(post_transforms=[]) 9 | ctx.register_type(bool, builtin.i1) 10 | ctx.register_type(int, bigint.bigint) 11 | 12 | 13 | # CHECK: cf.assert %{{.*}}, "" 14 | @ctx.parse_program 15 | def test_assert_I(cond: bool): 16 | assert cond 17 | return 18 | 19 | 20 | print(test_assert_I.module) 21 | 22 | 23 | # CHECK: cf.assert %{{.*}}, "some message" 24 | @ctx.parse_program 25 | def test_assert_II(cond: bool): 26 | assert cond, "some message" 27 | return 28 | 29 | 30 | print(test_assert_II.module) 31 | 32 | 33 | # CHECK: Expected a string constant for assertion message, found 'ast.Name' 34 | @ctx.parse_program 35 | def test_assert_message_type(cond: bool, a: int): 36 | assert cond, a 37 | return 38 | 39 | 40 | try: 41 | test_assert_message_type.module 42 | except CodeGenerationException as e: 43 | print(e.msg) 44 | -------------------------------------------------------------------------------- /tests/filecheck/parser-printer/float_parsing.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s | xdsl-opt | filecheck %s 2 | 3 | 4 | "builtin.module"() ({ 5 | "test.op"() {"value" = 42.0 : f32} : () -> () 6 | // CHECK: "test.op"() {value = 4.200000e+01 : f32} : () -> () 7 | 8 | "test.op"() {"value" = -42.0 : f32} : () -> () 9 | // CHECK-NEXT: "test.op"() {value = -4.200000e+01 : f32} : () -> () 10 | 11 | "test.op"() {"value" = 34.e0 : f32} : () -> () 12 | // CHECK-NEXT: "test.op"() {value = 3.400000e+01 : f32} : () -> () 13 | 14 | "test.op"() {"value" = 34.e-23 : f32} : () -> () 15 | // CHECK-NEXT: "test.op"() {value = 3.400000e-22 : f32} : () -> () 16 | 17 | "test.op"() {"value" = 34.e12 : f32} : () -> () 18 | // CHECK-NEXT: "test.op"() {value = 3.400000e+13 : f32} : () -> () 19 | 20 | "test.op"() {"value" = -34.e-12 : f32} : () -> () 21 | // CHECK-NEXT: "test.op"() {value = -3.400000e-11 : f32} : () -> () 22 | 23 | // this should print in full precision 24 | "test.op"() {"value" = 3.141592653589793 : f64} : () -> () 25 | // CHECK-NEXT: "test.op"() {value = 3.1415926535897931 : f64} : () -> () 26 | }) : () -> () 27 | -------------------------------------------------------------------------------- /tests/filecheck/backend/riscv/func_and_arith_to_riscv_asm_flow.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s -p convert-func-to-riscv-func,inline-snrt{cluster-num=2},convert-arith-to-riscv,reconcile-unrealized-casts,riscv-allocate-registers -t riscv-asm | filecheck %s 2 | 3 | 4 | func.func @test(%dst: i32, %src: i32) -> i32 { 5 | 6 | %stride = arith.constant 128 : i32 7 | %size = arith.constant 512 : i32 8 | %repeat = arith.constant 64 : i32 9 | 10 | %tx_id = "snrt.dma_start_2d"(%dst, %src, %stride, %stride, %size, %repeat) : (i32, i32, i32, i32, i32, i32) -> i32 11 | 12 | func.return %tx_id : i32 13 | } 14 | 15 | 16 | // CHECK: .text 17 | // CHECK-NEXT: .globl test 18 | // CHECK-NEXT: .p2align 2 19 | // CHECK-NEXT: test: 20 | // CHECK-NEXT: mv t2, a0 21 | // CHECK-NEXT: mv t3, a1 22 | // CHECK-NEXT: li t1, 128 23 | // CHECK-NEXT: li t0, 512 24 | // CHECK-NEXT: li t4, 64 25 | // CHECK-NEXT: dmsrc t3, zero 26 | // CHECK-NEXT: dmdst t2, zero 27 | // CHECK-NEXT: dmstr t1, t1 28 | // CHECK-NEXT: dmrep t0 29 | // CHECK-NEXT: dmcpyi t0, t0, 2 30 | // CHECK-NEXT: mv a0, t0 31 | // CHECK-NEXT: ret 32 | -------------------------------------------------------------------------------- /tests/filecheck/mlir-conversion/with-mlir/dialects/pdl/pdl_native_constraint.mlir: -------------------------------------------------------------------------------- 1 | // RUN: MLIR_ROUNDTRIP 2 | // RUN: MLIR_GENERIC_ROUNDTRIP 3 | 4 | 5 | pdl.pattern @nativeConstraint : benefit(1) { 6 | %type = pdl.type 7 | 8 | %operand = pdl.operand 9 | 10 | %attr = pdl.attribute 11 | 12 | // A bound operation 13 | %root = pdl.operation "test.test"(%operand : !pdl.value) 14 | {"value1" = %attr} 15 | -> (%type : !pdl.type) 16 | 17 | pdl.apply_native_constraint "myConstraint"(%type, %operand, %attr : !pdl.type, !pdl.value, !pdl.attribute) 18 | pdl.apply_native_constraint "myNegatedConstraint"(%type, %operand, %attr : !pdl.type, !pdl.value, !pdl.attribute) {isNegated = true} 19 | 20 | pdl.rewrite %root with "test_rewriter"(%root : !pdl.operation) 21 | } 22 | 23 | // CHECK: @nativeConstraint 24 | // CHECK: pdl.apply_native_constraint "myConstraint"(%{{.*}}, %{{.*}}, %{{.*}} : !pdl.type, !pdl.value, !pdl.attribute) 25 | // CHECK: pdl.apply_native_constraint "myNegatedConstraint"(%{{.*}}, %{{.*}}, %{{.*}} : !pdl.type, !pdl.value, !pdl.attribute) {isNegated = true} 26 | -------------------------------------------------------------------------------- /docs/Toy/examples/interpret.toy: -------------------------------------------------------------------------------- 1 | # RUN: python -m toy %s --emit=toy | filecheck %s 2 | # RUN: python -m toy %s --emit=toy-opt | filecheck %s 3 | # RUN: python -m toy %s --emit=toy-inline | filecheck %s 4 | # RUN: python -m toy %s --emit=shape-inference | filecheck %s 5 | # RUN: python -m toy %s --emit=affine | filecheck %s 6 | # RUN: python -m toy %s --emit=scf | filecheck %s 7 | # RUN: python -m toy %s --emit=riscv | filecheck %s 8 | # RUN: python -m toy %s --emit=riscv-regalloc | filecheck %s 9 | # RUN: python -m toy %s --emit=riscv-lowered | filecheck %s 10 | # RUN: python -m toy %s --emit=riscv-asm | filecheck %s 11 | 12 | # User defined generic function that operates on unknown shaped arguments 13 | def multiply_transpose(a, b) { 14 | return transpose(a) * transpose(b); 15 | } 16 | 17 | def main() { 18 | var a<2, 3> = [[1, 2, 3], [4, 5, 6]]; 19 | var b<2, 3> = [1, 2, 3, 4, 5, 6]; 20 | var c = multiply_transpose(a, b); 21 | var d = multiply_transpose(b, a); 22 | print(d); 23 | } 24 | 25 | # CHECK{LITERAL}: [[1.0, 16.0], [4.0, 25.0], [9.0, 36.0]] 26 | 27 | # REGALLOC: riscv.reg<{{.+}}> 28 | # REGALLOC-NOT: riscv.reg<> 29 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/printf/printf_basics.mlir: -------------------------------------------------------------------------------- 1 | // RUN: XDSL_ROUNDTRIP 2 | builtin.module { 3 | printf.print_format "Hello world!\n" 4 | 5 | %144 = "test.op"() : () -> i32 6 | %12 = "test.op"() : () -> i32 7 | %byte = "test.op"() : () -> i8 8 | 9 | printf.print_format "Uses vals twice {} {} {} {}\n", %12 : i32, %144 : i32, %12 : i32, %144 : i32 10 | printf.print_format "{}\n", %144 : i32 11 | printf.print_format "{}\n", %144 : i32 {unit} 12 | "printf.print_char"(%byte) : (i8) -> () 13 | "printf.print_int"(%12) : (i32) -> () 14 | } 15 | 16 | // CHECK: printf.print_format "Hello world!\n" 17 | // CHECK-NEXT: %0 = "test.op"() : () -> i32 18 | // CHECK-NEXT: %1 = "test.op"() : () -> i32 19 | // CHECK-NEXT: %byte = "test.op"() : () -> i8 20 | // CHECK-NEXT: printf.print_format "Uses vals twice {} {} {} {}\n", %1 : i32, %0 : i32, %1 : i32, %0 : i32 21 | // CHECK-NEXT: printf.print_format "{}\n", %0 : i32 22 | // CHECK-NEXT: printf.print_format "{}\n", %0 : i32 {unit} 23 | // CHECK-NEXT: "printf.print_char"(%{{.*}}) : (i8) -> () 24 | // CHECK-NEXT: "printf.print_int"(%{{.*}}) : (i32) -> () 25 | -------------------------------------------------------------------------------- /xdsl/backend/riscv/lowering/convert_print_format_to_riscv_debug.py: -------------------------------------------------------------------------------- 1 | from xdsl.backend.riscv.lowering.utils import cast_operands_to_regs 2 | from xdsl.context import Context 3 | from xdsl.dialects import printf, riscv_debug 4 | from xdsl.dialects.builtin import ModuleOp 5 | from xdsl.passes import ModulePass 6 | from xdsl.pattern_rewriter import ( 7 | PatternRewriter, 8 | PatternRewriteWalker, 9 | RewritePattern, 10 | op_type_rewrite_pattern, 11 | ) 12 | 13 | 14 | class LowerPrintFormatOp(RewritePattern): 15 | """ 16 | Rewrites printf.PrintFormatOp to riscv_debug.printf. 17 | """ 18 | 19 | @op_type_rewrite_pattern 20 | def match_and_rewrite(self, op: printf.PrintFormatOp, rewriter: PatternRewriter): 21 | rewriter.replace_op( 22 | op, riscv_debug.PrintfOp(op.format_str, cast_operands_to_regs(rewriter, op)) 23 | ) 24 | 25 | 26 | class ConvertPrintFormatToRiscvDebugPass(ModulePass): 27 | name = "convert-print-format-to-riscv-debug" 28 | 29 | def apply(self, ctx: Context, op: ModuleOp) -> None: 30 | PatternRewriteWalker(LowerPrintFormatOp()).rewrite_module(op) 31 | -------------------------------------------------------------------------------- /tests/filecheck/dialects/llvm/global.mlir: -------------------------------------------------------------------------------- 1 | // RUN: XDSL_ROUNDTRIP 2 | builtin.module { 3 | "llvm.mlir.global"() ({ 4 | }) {"global_type" = !llvm.array<13 x i8>, "sym_name" = "str0", "linkage" = #llvm.linkage<"internal">, "addr_space" = 0 : i32, "constant", "value" = "Hello world!\n", "unnamed_addr" = 0 : i64} : () -> () 5 | %0 = "llvm.mlir.addressof"() {"global_name" = @str0} : () -> !llvm.ptr 6 | %1 = "llvm.getelementptr"(%0) <{"elem_type" = !llvm.array<13 x i8>, noWrapFlags = 0 : i32, "rawConstantIndices" = array}> : (!llvm.ptr) -> !llvm.ptr 7 | } 8 | 9 | // CHECK: builtin.module { 10 | // CHECK-NEXT: "llvm.mlir.global"() <{global_type = !llvm.array<13 x i8>, constant, sym_name = "str0", linkage = #llvm.linkage<"internal">, value = "Hello world!\n", addr_space = 0 : i32, unnamed_addr = 0 : i64}> ({ 11 | // CHECK-NEXT: }) : () -> () 12 | // CHECK-NEXT: %0 = "llvm.mlir.addressof"() <{global_name = @str0}> : () -> !llvm.ptr 13 | // CHECK-NEXT: %1 = "llvm.getelementptr"(%0) <{elem_type = !llvm.array<13 x i8>, noWrapFlags = 0 : i32, rawConstantIndices = array}> : (!llvm.ptr) -> !llvm.ptr 14 | // CHECK-NEXT: } 15 | -------------------------------------------------------------------------------- /xdsl/transforms/test_transform_dialect_erase_schedule.py: -------------------------------------------------------------------------------- 1 | from dataclasses import dataclass 2 | 3 | from xdsl.context import Context 4 | from xdsl.dialects import transform 5 | from xdsl.dialects.builtin import ModuleOp 6 | from xdsl.passes import ModulePass 7 | from xdsl.pattern_rewriter import ( 8 | PatternRewriter, 9 | PatternRewriteWalker, 10 | RewritePattern, 11 | op_type_rewrite_pattern, 12 | ) 13 | 14 | 15 | class EraseTransformNamedSequenceOps(RewritePattern): 16 | @op_type_rewrite_pattern 17 | def match_and_rewrite( 18 | self, op: transform.NamedSequenceOp, rewriter: PatternRewriter 19 | ) -> None: 20 | rewriter.erase_op(op) 21 | 22 | 23 | @dataclass(frozen=True) 24 | class TestTransformDialectEraseSchedulePass(ModulePass): 25 | """ 26 | Erases transform named sequence operations. 27 | """ 28 | 29 | name = "test-transform-dialect-erase-schedule" 30 | 31 | def apply(self, ctx: Context, op: ModuleOp) -> None: 32 | PatternRewriteWalker( 33 | EraseTransformNamedSequenceOps(), 34 | apply_recursively=False, 35 | ).rewrite_module(op) 36 | -------------------------------------------------------------------------------- /tests/filecheck/mlir-conversion/with-mlir/dialects/vector/insert_extract_ops.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt --print-op-generic %s | mlir-opt --mlir-print-op-generic --allow-unregistered-dialect | xdsl-opt --print-op-generic | filecheck %s 2 | 3 | %vector0, %vector1, %i0 = "test.op"() : () -> (vector, vector<3xindex>, index) 4 | // CHECK: %0, %1, %2 = "test.op"() : () -> (vector, vector<3xindex>, index) 5 | 6 | %0 = "vector.insertelement"(%i0, %vector0) : (index, vector) -> vector 7 | // CHECK-NEXT: %3 = "vector.insertelement"(%2, %0) : (index, vector) -> vector 8 | 9 | %1 = "vector.insertelement"(%i0, %vector1, %i0) : (index, vector<3xindex>, index) -> vector<3xindex> 10 | // CHECK-NEXT: %4 = "vector.insertelement"(%2, %1, %2) : (index, vector<3xindex>, index) -> vector<3xindex> 11 | 12 | %2 = "vector.extractelement"(%vector1, %i0) : (vector<3xindex>, index) -> index 13 | // CHECK-NEXT: %5 = "vector.extractelement"(%1, %2) : (vector<3xindex>, index) -> index 14 | 15 | %3 = "vector.extractelement"(%vector0) : (vector) -> index 16 | // CHECK-NEXT: %6 = "vector.extractelement"(%0) : (vector) -> index 17 | -------------------------------------------------------------------------------- /tests/filecheck/runner/runner_args.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-run --symbol one --verbose %s | filecheck %s --check-prefix CHECK-ONE 2 | // RUN: xdsl-run --symbol two --verbose %s | filecheck %s --check-prefix CHECK-TWO 3 | // RUN: xdsl-run --symbol void --verbose %s | filecheck %s --check-prefix CHECK-VOID 4 | // RUN: xdsl-run --symbol tuple --verbose %s | filecheck %s --check-prefix CHECK-TUPLE 5 | 6 | module { 7 | func.func @one() -> i32 { 8 | %one = arith.constant 1 : i32 9 | func.return %one : i32 10 | } 11 | func.func @two() -> i32 { 12 | %two = arith.constant 2 : i32 13 | func.return %two : i32 14 | } 15 | func.func @void() { 16 | func.return 17 | } 18 | func.func @tuple() -> (i32, i32) { 19 | %one = arith.constant 1 : i32 20 | %two = arith.constant 2 : i32 21 | func.return %one, %two : i32, i32 22 | } 23 | } 24 | 25 | // CHECK-ONE: result: 1 26 | 27 | // CHECK-TWO: result: 2 28 | 29 | // CHECK-VOID: result: () 30 | 31 | // CHECK-TUPLE: result: ( 32 | // CHECK-TUPLE-NEXT: 1, 33 | // CHECK-TUPLE-NEXT: 2 34 | // CHECK-TUPLE-NEXT: ) 35 | -------------------------------------------------------------------------------- /tests/filecheck/mlir-conversion/with-mlir/dialects/scf/for_custom.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-opt %s | xdsl-opt | mlir-opt | filecheck %s 2 | 3 | %lb = arith.constant 0 : index 4 | %ub = arith.constant 42 : index 5 | %step = arith.constant 7 : index 6 | %sum_init = arith.constant 36 : index 7 | %sum = scf.for %iv = %lb to %ub step %step iter_args(%sum_iter = %sum_init) -> (index) { 8 | %sum_new = arith.addi %sum_iter, %iv : index 9 | scf.yield %sum_new : index 10 | } 11 | 12 | scf.for %iv = %lb to %ub step %step { 13 | } 14 | 15 | // CHECK: module { 16 | // CHECK-NEXT: %{{.*}} = arith.constant 0 : index 17 | // CHECK-NEXT: %{{.*}} = arith.constant 42 : index 18 | // CHECK-NEXT: %{{.*}} = arith.constant 7 : index 19 | // CHECK-NEXT: %{{.*}} = arith.constant 36 : index 20 | // CHECK-NEXT: %{{.*}} = scf.for %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%{{.*}} = %{{.*}}) -> (index) { 21 | // CHECK-NEXT: %{{.*}} = arith.addi %{{.*}}, %{{.*}} : index 22 | // CHECK-NEXT: scf.yield %{{.*}} : index 23 | // CHECK-NEXT: } 24 | // CHECK-NEXT: scf.for %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} { 25 | // CHECK-NEXT: } 26 | // CHECK-NEXT: } 27 | -------------------------------------------------------------------------------- /tests/filecheck/runner/factorial.mlir: -------------------------------------------------------------------------------- 1 | // RUN: xdsl-run %s | filecheck %s 2 | 3 | builtin.module { 4 | 5 | func.func @factorial(%i : i64) -> i64 { 6 | %zero = "arith.constant"() {"value" = 0} : () -> i64 7 | %one = "arith.constant"() {"value" = 1} : () -> i64 8 | %eq0 = "arith.cmpi"(%i, %zero) {"predicate" = 0} : (i64, i64) -> i1 9 | %ret = "scf.if"(%eq0) ({ 10 | "scf.yield"(%one) : (i64) -> () 11 | },{ 12 | %im1 = "arith.subi"(%i, %one) : (i64, i64) -> i64 13 | %facrec = "func.call"(%im1) {"callee" = @factorial} : (i64) -> i64 14 | %fac = "arith.muli"(%facrec, %i) : (i64, i64) -> i64 15 | "scf.yield"(%fac) : (i64) -> () 16 | }) : (i1) -> i64 17 | "func.return"(%ret) : (i64) -> () 18 | } 19 | func.func @main() -> index { 20 | %zero = "arith.constant"() {"value" = 0 : index} : () -> index 21 | %i = "arith.constant"() {"value" = 12} : () -> i64 22 | %fac = "func.call"(%i) {"callee" = @factorial} : (i64) -> i64 23 | printf.print_format "factorial({})={}\n", %i : i64, %fac : i64 24 | "func.return"(%zero) : (index) -> () 25 | } 26 | } 27 | 28 | // CHECK: factorial(12)=479001600 29 | --------------------------------------------------------------------------------