{"id":14991184,"url":"https://github.com/alivetoolkit/alive2","last_synced_at":"2025-05-14T15:09:16.270Z","repository":{"id":37432493,"uuid":"136746484","full_name":"AliveToolkit/alive2","owner":"AliveToolkit","description":"Automatic verification of LLVM optimizations","archived":false,"fork":false,"pushed_at":"2024-10-24T07:41:03.000Z","size":6428,"stargazers_count":781,"open_issues_count":54,"forks_count":99,"subscribers_count":24,"default_branch":"master","last_synced_at":"2024-10-29T15:23:22.300Z","etag":null,"topics":["automatic-verification","llvm","llvm-ir","model-checking","smt","symbolic-execution","translation-validation","verification"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/AliveToolkit.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":"AUTHORS","dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-06-09T18:03:14.000Z","updated_at":"2024-10-29T04:28:35.000Z","dependencies_parsed_at":"2024-05-22T17:33:47.648Z","dependency_job_id":"0322409e-afa7-4f0b-be8e-8b457ad4d691","html_url":"https://github.com/AliveToolkit/alive2","commit_stats":{"total_commits":2369,"total_committers":39,"mean_commits":"60.743589743589745","dds":"0.49852258336850996","last_synced_commit":"9f7f1f103f83b0dead7143051bbed7822876a5ef"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AliveToolkit%2Falive2","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AliveToolkit%2Falive2/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AliveToolkit%2Falive2/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AliveToolkit%2Falive2/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/AliveToolkit","download_url":"https://codeload.github.com/AliveToolkit/alive2/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248631669,"owners_count":21136554,"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","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":["automatic-verification","llvm","llvm-ir","model-checking","smt","symbolic-execution","translation-validation","verification"],"created_at":"2024-09-24T14:21:41.536Z","updated_at":"2025-04-12T20:41:02.411Z","avatar_url":"https://github.com/AliveToolkit.png","language":"C++","readme":"Alive2\n======\n\n![Alive2 logo](imgs/alive2.png)\n\nAlive2 consists of several libraries and tools for analysis and verification\nof LLVM code and transformations.\nAlive2 includes the following libraries:\n* Alive2 IR\n* Symbolic executor\n* LLVM → Alive2 IR converter\n* Refinement check (aka optimization verifier)\n* SMT abstraction layer\n\nIncluded tools:\n* Alive drop-in replacement\n* Translation validation plugins for clang and LLVM's `opt`\n* Standalone translation validation tool: `alive-tv` ([online](https://alive2.llvm.org))\n* Clang drop-in replacement with translation validation (`alivecc` and\n  `alive++`)\n* An LLVM IR interpreter that is UB precise (`alive-exec`)\n\nFor a technical introduction to Alive2, please see [our paper from\nPLDI 2021](https://web.ist.utl.pt/nuno.lopes/pubs/alive2-pldi21.pdf).\n\n\nWARNING\n-------\nAlive2 does not support inter-procedural transformations. Alive2 may produce\nspurious counterexamples if run with such passes.\n\n\nSponsors\n--------\nWe thank the continuous support of all of our sponsors! Alive2 wouldn't be possible without their support.\n\n[![Google](imgs/google.svg)](https://research.google)\n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\n[![NLNet](imgs/nlnet.svg)](https://nlnet.nl)\n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\n[![Woven by Toyota](imgs/woven.svg)](https://woven.toyota)\n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\n[![Matter Labs](imgs/matterlabs.svg)](https://matter-labs.io)\n\nIf your company has benefitted from Alive2 (including having a less buggy LLVM), please consider sponsoring our research lab.\n\n\nPrerequisites\n-------------\nTo build Alive2 you need recent versions of:\n* [cmake](https://cmake.org)\n* [gcc](https://gcc.gnu.org)/[clang](https://clang.llvm.org)\n* [re2c](https://re2c.org/)\n* [Z3](https://github.com/Z3Prover/z3)\n* [LLVM](https://github.com/llvm/llvm-project) (optional)\n* [hiredis](https://github.com/redis/hiredis) (optional, needed for caching)\n\n\nBuilding\n--------\n\n```\nexport ALIVE2_HOME=$PWD\nexport LLVM2_HOME=$PWD/llvm-project\nexport LLVM2_BUILD=$LLVM2_HOME/build\ngit clone git@github.com:AliveToolkit/alive2.git\ncd alive2\nmkdir build\ncd build\ncmake -GNinja -DCMAKE_BUILD_TYPE=Release ..\nninja\n```\n\nIf CMake cannot find the Z3 include directory (or finds the wrong one) pass\nthe ``-DZ3_INCLUDE_DIR=/path/to/z3/include`` and ``-DZ3_LIBRARIES=/path/to/z3/lib/libz3.so`` arguments to CMake.\n\n\nBuilding and Running Translation Validation\n--------\n\nAlive2's `opt` and `clang` translation validation requires a build of LLVM with\nRTTI and exceptions turned on. The latest version of Alive2 is always intended\nto be built against the latest version of LLVM, using the main branch from\nthe LLVM repo on Github.\nLLVM can be built in the following way.\n* You may prefer to add `-DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++` to the CMake step if your default compiler is `gcc`.\n* Explicitly setting the target may not be necessary.\n* `BUILD_SHARED_LIBS` may not be necessary, and for LLVM forks not normally\nbuilt with the option, may interfere with CMake files’ use of `USEDLIBS` and\n`LLVMLIBS`, and perhaps `dd_llvm_target`.\n* To build with Xcode rather than Ninja, replace `-GNinja` with `-GXcode` in\nthe `cmake` step below, and append `-DLLVM_MAIN_SRC_DIR=$LLVM2_HOME/llvm`. \n  * It may be necessary to disable warnings for “Implicit Conversion to 32 Bit\n  Type” in the project build settings.\n  * Xcode may place `tv.dylib` in a different location; a symbolic link from the\nactual location to that in the resultant error message may help.\n\n```\ncd $LLVM2_HOME\nmkdir build\ncd build\ncmake -GNinja -DLLVM_ENABLE_RTTI=ON -DBUILD_SHARED_LIBS=ON -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_ASSERTIONS=ON -DLLVM_ENABLE_PROJECTS=\"llvm;clang\" ../llvm\nninja\n```\n\nAlive2 should then be configured and built as follows:\n```\ncd $ALIVE2_HOME/alive2/build\ncmake -GNinja -DCMAKE_PREFIX_PATH=$LLVM2_BUILD -DBUILD_TV=1 -DCMAKE_BUILD_TYPE=Release ..\nninja\n```\n\nTranslation validation of one or more LLVM passes transforming an IR file on Linux:\n```\n$LLVM2_BUILD/bin/opt -load $ALIVE2_HOME/alive2/build/tv/tv.so -load-pass-plugin $ALIVE2_HOME/alive2/build/tv/tv.so -tv -instcombine -tv -o /dev/null foo.ll\n```\nFor the new pass manager:\n```\n$LLVM2_BUILD/bin/opt -load $ALIVE2_HOME/alive2/build/tv/tv.so -load-pass-plugin $ALIVE2_HOME/alive2/build/tv/tv.so -passes=tv -passes=instcombine -passes=tv -o /dev/null $LLVM2_HOME/llvm/test/Analysis/AssumptionCache/basic.ll\n```\n\n\nOn a Mac with the old pass manager:\n```\n$LLVM2_BUILD/bin/opt -load $ALIVE2_HOME/alive2/build/tv/tv.dylib -load-pass-plugin $ALIVE2_HOME/alive2/build/tv/tv.dylib -tv -instcombine -tv -o /dev/null foo.ll\n```\nOn a Mac with the new pass manager:\n```\n$LLVM2_BUILD/bin/opt -load $ALIVE2_HOME/alive2/build/tv/tv.dylib -load-pass-plugin $ALIVE2_HOME/alive2/build/tv/tv.dylib -passes=tv -passes=instcombine -passes=tv -o /dev/null $LLVM2_HOME/llvm/test/Analysis/AssumptionCache/basic.ll\n```\nYou can run any pass or combination of passes, but on the command line\nthey must be placed in between the two invocations of the Alive2 `-tv`\npass.\n\n\nTranslation validation of a single LLVM unit test, using lit:\n```\n$LLVM2_BUILD/bin/llvm-lit -vv -Dopt=$ALIVE2_HOME/alive2/build/opt-alive.sh $LLVM2_HOME/llvm/test/Transforms/InstCombine/canonicalize-constant-low-bit-mask-and-icmp-sge-to-icmp-sle.ll\n```\n\nThe output should be:\n```\n-- Testing: 1 tests, 1 threads --\nPASS: LLVM :: Transforms/InstCombine/canonicalize-constant-low-bit-mask-and-icmp-sge-to-icmp-sle.ll (1 of 1)\nTesting Time: 0.11s\n  Expected Passes    : 1\n```\n\nTo run translation validation on all the LLVM unit tests for IR-level\ntransformations:\n\n```\n$LLVM2_BUILD/bin/llvm-lit -s -Dopt=$ALIVE2_HOME/alive2/build/opt-alive.sh $LLVM2_HOME/llvm/test/Transforms\n```\n\nWe run this command on the main LLVM branch each day, and keep track of the results\n[here](https://web.ist.utl.pt/nuno.lopes/alive2/).  To detect unsound transformations in a local run:\n\n```\nfgrep -r \"(unsound)\" $ALIVE2_HOME/alive2/build/logs/\n```\n\n\nRunning Alive2 as a Clang Plugin\n--------------------------------\n\nThis plugin tries to validate every IR-level transformation performed\nby LLVM.  Invoke the plugin like this:\n\n```\nclang -O3 $LLVM2_HOME/clang/test/C/C99/n505.c -S -emit-llvm \\\n  -fpass-plugin=$ALIVE2_HOME/alive2/build/tv/tv.so \\\n  -Xclang -load -Xclang $ALIVE2_HOME/alive2/build/tv/tv.so\n```\n\nOr, more conveniently:\n\n```\n$ALIVE2_HOME/alive2/build/alivecc -O3 -c $LLVM2_HOME/clang/test/C/C99/n505.c\n\n$ALIVE2_HOME/alive2/build/alive++ -O3 -c $LLVM2_HOME/clang/test/Analysis/aggrinit-cfg-output.cpp\n```\n\nThe Clang plugin can optionally use multiple cores. To enable parallel\ntranslation validation, add the `-mllvm -tv-parallel=XXX` command line\noptions to Clang, where XXX is one of two parallelism managers\nsupported by Alive2. The first (XXX=fifo) uses alive-jobserver: for\ndetails about how to use this program, please consult its help output\nby running it without any command line arguments. The second\nparallelism manager (XXX=unrestricted) does not restrict parallelism\nat all, but rather calls fork() freely. This is mainly intended for\ndeveloper use; it tends to use a lot of RAM.\n\nUse the `-mllvm -tv-report-dir=dir` to tell Alive2 to place its output\nfiles into a specific directory.\n\nThe Clang plugin's output can be voluminous. To help control this, it\nsupports an option to reduce the amount of output (`-mllvm\n-tv-quiet`).\n\nOur goal is for the `alivecc` and `alive++` compiler drivers to be\ndrop-in replacements for `clang` and `clang++`. So, for example, they\ntry to detect when they are being invoked as assemblers or linkers, in\nwhich case they do not load the Alive2 plugin. This means that some\nprojects cannot be built if you manually specify command line options\nto Alive2, for example using `-DCMAKE_C_FLAGS=...`. Instead, you can\ntell `alivecc` and `alive++` what to do using a collection of\nenvironment variables that generally mirror the plugin's command line\ninterface. For example:\n\n```\nALIVECC_PARALLEL_UNRESTRICTED=1\nALIVECC_PARALLEL_FIFO=1\nALIVECC_DISABLE_UNDEF_INPUT=1\nALIVECC_DISABLE_POISON_INPUT=1\nALIVECC_SMT_TO=timeout in milliseconds\nALIVECC_SUBPROCESS_TIMEOUT=timeout in seconds\nALIVECC_OVERWRITE_REPORTS=1\nALIVECC_REPORT_DIR=dir\n```\n\nIf validating the program takes a long time, you can batch optimizations to\nverify.\nPlease set `ALIVECC_BATCH_OPTS=1` and run `alivecc`/`alive++`.\n\n\nRunning the Standalone Translation Validation Tool (alive-tv)\n--------\n\nThis tool has two modes.\n\nIn the first mode, specify either a source (original) and target (optimized) IR\nfile, or a single file containing a function called “src” and also a function\ncalled “tgt”. For example, let’s prove that removing `nsw` is correct for\naddition:\n\n```\n$ALIVE2_HOME/alive2/build/alive-tv src.ll tgt.ll\n\n----------------------------------------\ndefine i32 @f(i32 %a, i32 %b) {\n  %add = add nsw i32 %b, %a\n  ret i32 %add\n}\n=\u003e\ndefine i32 @f(i32 %a, i32 %b) {\n  %add = add i32 %b, %a\n  ret i32 %add\n}\n\nTransformation seems to be correct!\n```\n\nFlipping the inputs yields a counterexample, since it's not correct, in general,\nto add `nsw`.\nIf you are not interested in counterexamples using `undef`, you can use the\ncommand-line argument `-disable-undef-input`.\n\nIn the second mode, specify a single unoptimized IR file. alive-tv\nwill optimize it using an optimization pipeline similar to -O2, but\nwithout any interprocedural passes, and then attempt to validate the\ntranslation.\n\nFor example, as of February 6 2020, the `release/10.x` branch contains\nan optimizer bug that can be triggered as follows:\n\n```\ncat foo.ll\n\ndefine i3 @foo(i3) {\n  %x1 = sub i3 0, %0\n  %x2 = icmp ne i3 %0, 0\n  %x3 = zext i1 %x2 to i3\n  %x4 = lshr i3 %x1, %x3\n  %x5 = lshr i3 %x4, %x3\n  ret i3 %x5\n}\n\n$ALIVE2_HOME/alive2/build/alive-tv foo.ll\n\n----------------------------------------\ndefine i3 @foo(i3 %0) {\n  %x1 = sub i3 0, %0\n  %x2 = icmp ne i3 %0, 0\n  %x3 = zext i1 %x2 to i3\n  %x4 = lshr i3 %x1, %x3\n  %x5 = lshr i3 %x4, %x3\n  ret i3 %x5\n}\n=\u003e\ndefine i3 @foo(i3 %0) {\n  %x1 = sub i3 0, %0\n  ret i3 %x1\n}\nTransformation doesn't verify!\nERROR: Value mismatch\n\nExample:\ni3 %0 = #x5 (5, -3)\n\nSource:\ni3 %x1 = #x3 (3)\ni1 %x2 = #x1 (1)\ni3 %x3 = #x1 (1)\ni3 %x4 = #x1 (1)\ni3 %x5 = #x0 (0)\n\nTarget:\ni3 %x1 = #x3 (3)\nSource value: #x0 (0)\nTarget value: #x3 (3)\n\nSummary:\n  0 correct transformations\n  1 incorrect transformations\n  0 errors\n```\n\nPlease keep in mind that you do not have to compile Alive2 in order to\ntry out alive-tv; it is available online: https://alive2.llvm.org/ce/\n\n\nRunning the Standalone LLVM Execution Tool (alive-exec)\n-------------------------------------------------------\n\nThis tool uses Alive2 as an interpreter for an LLVM function. It is\ncurrently highly experimental and has many restrictions. For example,\nthe function cannot take inputs, cannot use memory, cannot depend on\nundefined behaviors, and cannot include loops that execute too many\niterations.\n\nCaching\n--------\n\nThe alive-tv tool and the Alive2 translation validation opt plugin\nsupport using an external Redis server to avoid performing redundant\nqueries. This feature is not intended for general use, but rather to\nspeed up certain systematic testing workloads that perform a lot of\nrepeated work. When it hits a repeated refinement check, it prints\n\"Skipping repeated query\" instead of performing the query.\n\nIf you want to use this functionality, you will need to manually start\nand stop, as appropriate, a Redis server instance on localhost. Alive2\nshould be the only user of this server.\n\nDiagnosing Unsoundness Reports\n------------------------------\n\n* Select a failing test file. It may be convenient to choose one whose path is\ngiven at the beginning of a log file containing the text \"(unsound)\" as above;\nthis is guaranteed to contain an unsoundness report.  Many log files, however,\ncontain only “Source: \\\u003cstdin\\\u003e” rather than a file path; the names of these\nfiles begin with “in_”.\n* Do a verbose run of Lit for just that file, with the `opt`  option\n`--print-after-all` appended.  (You may also append other `opt`  options, such\nas other optimizations.)  E.g.:\n```\n$LLVM2_BUILD/bin/llvm-lit -vva \"-Dopt=$ALIVE2_HOME/alive2/build/opt-alive.sh --print-after-all\" $LLVM2_HOME/llvm/test/Transforms/InstCombine/insert-const-shuf.ll\n```\n* Collect Lit’s LLVM IR terminal output, for comparison with Alive2’s Alive2 IR\noutput in the log file indicated by “Report written to…”.  Sometimes the Lit\noutput may not contain useful LLVM IR, in which case executing the output\nRUN command separately may give better results.\n* The Alive2 unsoundness report in the corresponding log file will have two\nversions of the misoptimized function.  The Alive2 IR function body may\nindicate the problem to a human, but for Alive2 translation validation\nyou will need LLVM IR.  Search for the function name in the terminal output.\n* Copy the first function definition and necessary declarations and metadata to\neither a new file or to the Alive2 Compiler Explorer instance,\n[https://alive2.llvm.org/ce/](https://alive2.llvm.org/ce/).\n(The `-allow-incomplete-ir` flag may make copying declarations and metadata\nunnecessary.)\nThe Alive2 Compiler Explorer instance will run automatically;\nto check with the standalone `alive-tv`, see its instructions above.\nWithout a second version of the function to compare, Alive2 just runs the\n`-O2` optimizations;\nif it reports unsoundness, your fork’s optimizations are not to blame.\n* If there is a second, unsound, function definition in the LLVM IR terminal\noutput, copy it and necessary declarations, and change the\nsecond function name.\n* If it now reports a misoptimization, presumably your fork has a bug,\ndemonstrated by the provided examples.\n* To screen out exact duplicate reports when comparing different test runs,\nmove the `logs` directory out of the way before each run.  After each run, copy\nthe relevant logs to a separate destination directory.  (Systems with a non-GNU\nversion of `cp` will need to use coreutils’ `gcp` instead.)\n```\nfgrep --files-with-matches --recursive \"(unsound)\" $ALIVE2_HOME/alive2/build/logs/ |  xargs cp -p --target-directory=\u003cDestination\u003e\n\n```\n* Unique unsoundness reports can then be found with a utility such as `jdupes --print-unique`.  \n  * If the tests are run on different LLVM directories, the “Source:” line in\n  files whose name does not begin with “in_”, as well as “Command line:” lines\n  on Linux, should be stripped before comparison.\n\n\nTroubleshooting\n---------------\n* Check the “LLVMConfig.cmake” and “CMAKE_PREFIX_PATH” output from CMake in\ncase of build problems. CMake may look for configuration information in old\ninstallations of LLVM, e.g., under `/opt/`, if these are not set properly.\n* Some combinations of Clang and MacOS versions may give link warnings \n“-undefined dynamic_lookup may not work with chained fixups,” and\nruntime errors with “symbol not found in flat namespace.”  Setting\n[CMAKE_OSX_DEPLOYMENT_TARGET](https://cmake.org/cmake/help/latest/variable/CMAKE_OSX_DEPLOYMENT_TARGET.html)\nas a cache entry to 11.0 or less at the beginning of CMakeLists.txt may work\naround this.\n* Building for Translation Validation is tightly coupled to LLVM top of tree\nsource.  Building a fork with older source may require reverting to the\ncorresponding Alive2 commit.  This in turn may require experimentation with\nClang and SDK versions and vendors.\n* Building older source on an up-to-date machine may require adjustments.  For\nexample, the now-deleted file `scripts/rewritepass.py` depended on the\ndeprecated Python 2; update the shebang line to `python3`.\n* The `opt` wrapper script `build/opt-alive.sh` accepts a `--verbose` option,\nwhich outputs the command passed to `opt`.  Note that this may interfere \nwith tests which check output.\n* The script also accepts a `--no-timeout` option, which disables the `opt`\nprocess timeout.  This timeout is not supported on Macintosh.  To change the\nSMT timeout, instead pass an `-smt-to:` option to the `alive` executable.\n\nLLVM Bugs Found by Alive2\n-------------------------\n\n[BugList.md](BugList.md) shows the list of LLVM bugs found by Alive2.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falivetoolkit%2Falive2","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falivetoolkit%2Falive2","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falivetoolkit%2Falive2/lists"}