{"id":19572198,"url":"https://github.com/mull-project/libirm","last_synced_at":"2026-04-12T13:01:45.276Z","repository":{"id":42506501,"uuid":"205454078","full_name":"mull-project/libirm","owner":"mull-project","description":"Low-level IR mutations for LLVM Bitcode","archived":false,"fork":false,"pushed_at":"2023-10-22T17:59:58.000Z","size":112,"stargazers_count":41,"open_issues_count":1,"forks_count":6,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-09-20T22:45:54.628Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://github.com/mull-project","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mull-project.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-08-30T20:42:06.000Z","updated_at":"2025-06-22T18:08:19.000Z","dependencies_parsed_at":"2024-11-11T06:24:29.780Z","dependency_job_id":null,"html_url":"https://github.com/mull-project/libirm","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/mull-project/libirm","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mull-project%2Flibirm","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mull-project%2Flibirm/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mull-project%2Flibirm/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mull-project%2Flibirm/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mull-project","download_url":"https://codeload.github.com/mull-project/libirm/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mull-project%2Flibirm/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":276169664,"owners_count":25596956,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-20T02:00:10.207Z","response_time":63,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-11T06:24:24.377Z","updated_at":"2025-09-20T22:45:56.772Z","avatar_url":"https://github.com/mull-project.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# libirm\n\nLow-level IR mutations for [LLVM](https://llvm.org) Bitcode.\n\n## Build/Install\n\nThe easiest way (not necessarily the right one):\n\n```bash\ngit clone https://github.com/mull-project/libirm.git --recursive\nmkdir build.dir; cd build.dir\ncmake -G Ninja ../libirm\nninja all\nsudo ninja install\n```\n\nYou'll get `libirm.a` and required headers under `/usr/local/`.\n\n## Usage\n\nlibirm operates on the level of a single LLVM instruction.\n\nTo use it you need only two methods:\n\n```c++\nbool canMutate(llvm::Instruction *instruction);\nvoid mutate(llvm::Instruction *instruction);\n```\n\nThe code below changes every [`add`](https://llvm.org/docs/LangRef.html#add-instruction) instruction into [`sub`](https://llvm.org/docs/LangRef.html#sub-instruction) instruction.\n\n```c++\n#include \u003cirm/irm.h\u003e\n\nvoid doSmth() {\n  llvm::Function *function = getTheFunctionSomewhere();\n  irm::AddToSub mutation;\n  for (auto \u0026instruction : llvm::instructions(function)) {\n    if (mutation.canMutate(\u0026instruction)) {\n      mutation.mutate(\u0026instruction);\n    }\n  }\n}\n```\n\n## Available Mutations\n\nThe set of currently available mutation is driven by the needs of the [Mull](https://github.com/mull-project/mull) project,\nso it is not exhaustive.\n\n### BinaryOperatorReplacement\n\n```c++\nBinaryOperatorReplacement(llvm::Instruction::BinaryOps from,\n                          llvm::Instruction::BinaryOps to)\n```\n\nReplaces binary operator(`from`) with another one (`to`).\n\nExamples:\n\n - `irm::AddToSub`: `add i32 %a, i32 %b` -\u003e `sub i32 %a, i32 %b`\n - `irm::OrToAnd`: `or i32 %a, i32 %b` -\u003e `and i32 %a, i32 %b`\n\nYou can find the list of predefined mutations at [`BinaryOperatorReplacement.h`](include/irm/Mutations/BinaryOperatorReplacement.h).\n\nYou can also create any missing mutation manually:\n\n```c++\nirm::BinaryOperatorReplacement addToXor(llvm::Instruction::BinaryOps::Add,\n                                        llvm::Instruction::BinaryOps::Xor);\n```\n\nThis will yield the `add i32 %a, i32 %b` to `xor i32 %a, i32 %b` mutation.\n\n### SwapBinaryOperands\n\n```c++\nSwapBinaryOperands(llvm::Instruction::BinaryOps op)\n```\n\nSwaps operands of a binary operator(`op`).\n\nExamples:\n\n - `irm::SwapSubOperands`: `sub i32 %a, i32 %b` -\u003e `sub i32 %b, i32 %a`\n - `irm::SwapSDivOperands`: `sdiv i32 %a, i32 %b` -\u003e `sdiv i32 %b, i32 %a`\n\nYou can find the list of predefined mutations at [`SwapBinaryOperands.h`](include/irm/Mutations/SwapBinaryOperands.h).\n\nYou can also create any missing mutation manually:\n\n```c++\nirm::SwapBinaryOperands swapSub(llvm::Instruction::BinaryOps::Sub);\n```\n\nThis will yield the `sub i32 %a, i32 %b` to `sub i32 %b, i32 %a` mutation.\n\n### SwapInstructionWithOperand\n\n```c++\nSwapInstructionWithOperand(unsigned opcode, unsigned index);\n```\n\nReplaces all uses of the instruction of kind `opcode` with its `index` operand.\n\nExamples:\n\n - `irm::SwapAddWithOperand_0`: `add i32 %a, i32 %b` -\u003e `%a`\n - `irm::SwapFNegWithOperand`: `fneg float %a` -\u003e `%a`\n\nYou can find the list of predefined mutations at [`SwapInstructionWithOperand.h`](include/irm/Mutations/SwapInstructionWithOperand.h).\n\n### CallReplacement\n\n```c++\nCallReplacement(ConstValueConstructor *constConstructor, llvm::Type::TypeID returnTypeId)\n```\n\nReplaces a call with return type `returnTypeId` with a constant provided by `ConstValueConstructor`.\n\nFor example, `irm::IntCallReplacement mutation(42)` replaces `call i32 @bar()` with `42`.\n\nYou can find the list of predefined mutations at [`CallReplacement.h`](include/irm/Mutations/CallReplacement.h).\n\nYou can create any missing mutation manually:\n\n```c++\nirm::CallReplacement halfReplacement(new FloatingValueConstructor(18.f), llvm::Type::HalfTyID);\n```\n\nThis yields `call half @bar()` -\u003e `half 18` replacement.\n\n### CmpInstPredicateReplacement\n\n```c++\nCmpInstPredicateReplacement(llvm::Instruction::OtherOps cmpType,\n                            llvm::CmpInst::Predicate from,\n                            llvm::CmpInst::Predicate to)\n```\n\nReplaces comparison predicate.\nExamples:\n\n - `irm::ICMP_EQToICMP_NE`: `icmp eq %a, i32 %b` -\u003e `icmp ne i32 %a, i32 %b`\n - `irm::ICMP_SGTToICMP_SGE`: `icmp sgt i32 %a, i32 %b` -\u003e `icmp sge i32 %a, i32 %b`\n\nYou can find the list of predefined mutations at [`CmpInstPredicateReplacement.h`](include/irm/Mutations/CmpInstPredicateReplacement.h).\n\nYou can also create any missing mutation manually:\n\n```c++\nirm::CmpInstPredicateReplacement lessOrEqualToEqual(llvm::Instruction::FCmp,\n                                                    llvm::CmpInst::FCMP_OLE,\n                                                    llvm::CmpInst::FCMP_OEQ);\n```\n\nThis will yield the `fcmp ole i32 %a, i32 %b` to `fcmp oeq i32 %a, i32 %b` mutation.\n\n### ConstantReplacement\n\n```c++\nConstantReplacement(ConstValueConstructor *constConstructor,\n                    ConstValueConstructor *zeroConstConstructor,\n                    llvm::Value::ValueTy valueType,\n                    unsigned operandPosition)\n```\n\nReplaces a constant with a value provided by `constConstructor` if the constant is zero. If the constant is not zero, then it is replaces by zero value provided by `zeroConstConstructor`.\n\nApplies only to an `operandPosition` operand.\n\nFor example, `irm::ConstIntReplacement mutation(42, 1)` will mutate `add 22, 0` to `add 22, 42`, while\n `add i32 22, i32 15` mutates to `add i32 22, i32 0`.\n\nPlease note that only second operand is affected in both cases.\n\nYou can find the list of predefined mutations at [`ConstantReplacement.h`](include/irm/Mutations/ConstantReplacement.h).\n\n### IntrinsicReplacement\n\n```c++\nIntrinsicReplacement(llvm::Intrinsic::ID from,\n                     llvm::Intrinsic::ID to)\n```\n\nReplaces one intrinsic(`from`) with another(`to`). It is assumed that both intrinsics have the same signature.\n\nFor example, `irm::sadd_with_overflowTossub_with_overflow mutation` will replace any call to `llvm.sadd.with.overflow.*` with `llvm.ssub.with.overflow.*`.\n\nYou can find the list of predefined mutations at [`IntrinsicReplacement.h`](include/irm/Mutations/IntrinsicReplacement.h).\n\nYou can create custom mutations:\n\n```\nirm::IntrinsicReplacement sinToCos(llvm::Intrinsic::int_cos,\n                                   llvm::Intrinsic::int_sin);\n```\n\n### StoreValueReplacement\n\n```c++\nStoreValueReplacement(ConstValueConstructor *constConstructor,\n                      llvm::Type::TypeID typeID)\n```\n\nSimilar to `CallReplacement`, but replaces a `store` value with a constant provided by `constConstructor`.\nFor example, `irm::StoreIntReplacement mutation(15)` will change `store i32 %x, i32* %addr` to `store i32 15, i32* %addr`.\n\nYou can find the list of predefined mutations at [`StoreValueReplacement.h`](include/irm/Mutations/StoreValueReplacement.h).\n\nYou can create any missing mutation manually:\n\n```c++\nirm::StoreValueReplacement halfReplacement(new FloatingValueConstructor(18.f),\n                                           llvm::Type::HalfTyID);\n```\n\n### VoidCallRemoval\n\n```c++\nVoidCallRemoval(bool onlyIntrinsics)\n```\n\nRemoves a call to a `void` function or intrinsic. There are two shortcut classes `RemoveVoidFunctionCall` and `RemoveVoidIntrinsicsCall`, that remove only function calls and only intrinsics, respectively.\n\n## Contributing\n\nPull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.\nPlease make sure to update tests as appropriate.\n\n## License\n\n[Apache 2](LICENSE)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmull-project%2Flibirm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmull-project%2Flibirm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmull-project%2Flibirm/lists"}