| # LLVM Testing Infrastructure Guide |
| |
| ```{contents} |
| :local: |
| ``` |
| |
| ```{toctree} |
| :hidden: |
| |
| TestSuiteGuide |
| ``` |
| |
| ## Overview |
| |
| This document is the reference manual for the LLVM testing |
| infrastructure. It documents the structure of the LLVM testing |
| infrastructure, the tools needed to use it, and how to add and run |
| tests. |
| |
| ## Requirements |
| |
| In order to use the LLVM testing infrastructure, you will need all of the |
| software required to build LLVM, as well as [Python](http://python.org) 3.8 or |
| later. |
| |
| ## LLVM Testing Infrastructure Organization |
| |
| The LLVM testing infrastructure contains three major categories of tests: |
| unit tests, regression tests, and whole programs. The unit tests and regression |
| tests are contained inside the LLVM repository itself under `llvm/unittests` |
| and `llvm/test` respectively and are expected to always pass. They should be |
| run before every commit. |
| |
| The whole-program tests are referred to as the "LLVM test suite" (or |
| "test-suite") and are in the `test-suite` |
| [repository on GitHub](https://github.com/llvm/llvm-test-suite.git). |
| For historical reasons, these tests are also referred to as the "nightly |
| tests" in places, which is less ambiguous than "test-suite" and remains |
| in use although we run them much more often than nightly. |
| |
| ### Unit tests |
| |
| Unit tests are written using [Google Test](https://github.com/google/googletest/blob/master/docs/primer.md) |
| and [Google Mock](https://github.com/google/googletest/blob/master/docs/gmock_for_dummies.md) |
| and are located in the `llvm/unittests` directory. |
| In general, unit tests are reserved for targeting the support library and other |
| generic data structure. We prefer relying on regression tests for testing |
| transformations and analysis on the IR. |
| |
| ### Regression tests |
| |
| The regression tests are small pieces of code that test a specific |
| feature of LLVM or trigger a specific bug in LLVM. The language they are |
| written in depends on the part of LLVM being tested. These tests are driven by |
| the {doc}`Lit <CommandGuide/lit>` testing tool (which is part of LLVM), and |
| are located in the `llvm/test` directory. |
| |
| Typically, when a bug is found in LLVM, a regression test containing just |
| enough code to reproduce the problem should be written and placed |
| somewhere underneath this directory. For example, it can be a small |
| piece of LLVM IR distilled from an actual application or benchmark. |
| |
| ### Testing Analysis |
| |
| An analysis is a pass to infer properties on some part of the IR without |
| transforming it. They are tested in general using the same infrastructure as the |
| regression tests, by creating a separate "Printer" pass to consume the analysis |
| result and print it on the standard output in a textual format suitable for |
| FileCheck. |
| See [llvm/test/Analysis/BranchProbabilityInfo/loop.ll](https://github.com/llvm/llvm-project/blob/main/llvm/test/Analysis/BranchProbabilityInfo/loop.ll) |
| for an example of such test. |
| |
| ### `test-suite` |
| |
| The test suite contains whole programs, which are pieces of code which |
| can be compiled and linked into a stand-alone program that can be |
| executed. These programs are generally written in high-level languages, |
| such as C and C++. |
| |
| These programs are compiled using a user-specified compiler and set of |
| flags, and then executed to capture the program output and timing |
| information. The output of these programs is compared to a reference |
| output to ensure that the program is being compiled correctly. |
| |
| In addition to compiling and executing programs, whole-program tests |
| serve as a way of benchmarking LLVM performance, both in terms of the |
| efficiency of the programs generated as well as the speed with which |
| LLVM compiles, optimizes, and generates code. |
| |
| The test-suite is located in the `test-suite` |
| [repository on GitHub](https://github.com/llvm/llvm-test-suite.git). |
| |
| See the {doc}`TestSuiteGuide` for details. |
| |
| ### Debugging Information tests |
| |
| The test suite contains tests to check the quality of debugging information. |
| The tests are written in C-based languages or in LLVM assembly language. |
| |
| These tests are compiled and run under a debugger. The debugger output |
| is checked to validate the debugging information. See `README.txt` in the |
| test suite for more information. This test suite is located in the |
| `cross-project-tests/debuginfo-tests` directory. |
| |
| ## Quick start |
| |
| The tests are located in two separate repositories. The unit and |
| regression tests are in the main "llvm"/ directory under the directories |
| `llvm/unittests` and `llvm/test` (so you get these tests for free with the |
| main LLVM tree). Use `make check-all` to run the unit and regression tests |
| after building LLVM. |
| |
| The `test-suite` module contains more comprehensive tests including whole C |
| and C++ programs. See the {doc}`TestSuiteGuide` for details. |
| |
| ### Unit and Regression tests |
| |
| To run all of the LLVM unit tests, use the `check-llvm-unit` target: |
| |
| ```bash |
| % make check-llvm-unit |
| ``` |
| |
| To run all of the LLVM regression tests, use the `check-llvm` target: |
| |
| ```bash |
| % make check-llvm |
| ``` |
| |
| In order to get reasonable testing performance, build LLVM and subprojects |
| in release mode, i.e., |
| |
| ```bash |
| % cmake -DCMAKE_BUILD_TYPE="Release" -DLLVM_ENABLE_ASSERTIONS=On |
| ``` |
| |
| If you have [Clang](https://clang.llvm.org/) checked out and built, you |
| can run the LLVM and Clang tests simultaneously using: |
| |
| ```bash |
| % make check-all |
| ``` |
| |
| To run the tests with Valgrind (Memcheck by default), use the `LIT_OPTS` make |
| variable to pass the required options to lit. For example, you can use: |
| |
| ```bash |
| % make check LIT_OPTS="-v --vg --vg-leak" |
| ``` |
| |
| to enable testing with Valgrind and with leak checking enabled. |
| |
| To run individual tests or subsets of tests, you can use the `llvm-lit` |
| script which is built as part of LLVM. For example, to run the |
| `Integer/BitPacked.ll` test by itself, you can run: |
| |
| ```bash |
| % llvm-lit <path to llvm-project>/llvm/test/Integer/BitPacked.ll |
| ``` |
| |
| ```{note} |
| The test files are in the `llvm-project` directory, not the directory you |
| are building LLVM in. |
| ``` |
| |
| Or you can run a whole folder of tests. To run all of the ARM CodeGen tests: |
| |
| ```bash |
| % llvm-lit <path to llvm-project>/llvm/test/CodeGen/ARM |
| ``` |
| |
| The regression tests will use the Python psutil module only if installed in a |
| **non-user** location. Under Linux, install with sudo or within a virtual |
| environment. Under Windows, install Python for all users and then run |
| `pip install psutil` in an elevated command prompt. |
| |
| For more information on using the {program}`lit` tool, see `llvm-lit --help` |
| or the {doc}`lit man page <CommandGuide/lit>`. |
| |
| ### Debugging Information tests |
| |
| To run debugging information tests simply add the `cross-project-tests` |
| project to your `LLVM_ENABLE_PROJECTS` define on the cmake |
| command-line. |
| |
| ## Regression test structure |
| |
| The LLVM regression tests are driven by {program}`lit` and are located in the |
| `llvm/test` directory. |
| |
| This directory contains a large array of small tests that exercise |
| various features of LLVM and to ensure that regressions do not occur. |
| The directory is broken into several subdirectories, each focused on a |
| particular area of LLVM. |
| |
| ### Writing new regression tests |
| |
| The regression test structure is very simple but does require some |
| information to be set. This information is gathered via `cmake` |
| and is written to a file, `test/lit.site.cfg.py` in the build directory. |
| The `llvm/test` Makefile does this work for you. |
| |
| In order for the regression tests to work, each directory of tests must |
| have a `lit.local.cfg` file. {program}`lit` looks for this file to determine |
| how to run the tests. This file is just Python code and thus is very |
| flexible, but we've standardized it for the LLVM regression tests. If |
| you're adding a directory of tests, just copy `lit.local.cfg` from |
| another directory to get running. The standard `lit.local.cfg` simply |
| specifies which files to look in for tests. Any directory that contains |
| only directories does not need the `lit.local.cfg` file. Read the |
| {doc}`Lit documentation <CommandGuide/lit>` for more information. |
| |
| Each test file must contain lines starting with "RUN:" that tell {program}`lit` |
| how to run it. If there are no `RUN` lines, {program}`lit` will issue an error |
| while running a test. |
| |
| `RUN` lines are specified in the comments of the test program using the |
| keyword `RUN` followed by a colon, and lastly the command (pipeline) |
| to execute. Together, these lines form the "script" that {program}`lit` |
| executes to run the test case. The syntax of the `RUN` lines is similar to a |
| shell's syntax for pipelines including I/O redirection and variable |
| substitution. However, even though these lines may *look* like a shell |
| script, they are not. `RUN` lines are interpreted by {program}`lit`. |
| Consequently, the syntax differs from shell in a few ways. You can specify |
| as many `RUN` lines as needed. |
| |
| {program}`lit` performs substitution on each `RUN` line to replace LLVM tool names |
| with the full paths to the executable built for each tool (in |
| `$(LLVM_OBJ_ROOT)/bin`). This ensures that {program}`lit` does |
| not invoke any stray LLVM tools in the user's path during testing. |
| |
| Each `RUN` line is executed on its own, distinct from other lines unless |
| its last character is `\`. This continuation character causes the `RUN` |
| line to be concatenated with the next one. In this way, you can build up |
| long pipelines of commands without making huge line lengths. The lines |
| ending in `\` are concatenated until a `RUN` line that doesn't end in |
| `\` is found. This concatenated set of `RUN` lines then constitutes one |
| execution. {program}`lit` will substitute variables and arrange for the pipeline |
| to be executed. If any process in the pipeline fails, the entire line (and |
| test case) fails too. |
| |
| Below is an example of legal `RUN` lines in a `.ll` file: |
| |
| ```llvm |
| ; RUN: llvm-as < %s | llvm-dis > %t1 |
| ; RUN: llvm-dis < %s.bc-13 > %t2 |
| ; RUN: diff %t1 %t2 |
| ``` |
| |
| As with a Unix shell, the `RUN` lines permit pipelines and I/O |
| redirection to be used. |
| |
| There are some quoting rules that you must pay attention to when writing |
| your `RUN` lines. In general, nothing needs to be quoted. {program}`lit` won't |
| strip off any quote characters, so they will get passed to the invoked program. |
| To avoid this use curly braces to tell {program}`lit` that it should treat |
| everything enclosed as one value. |
| |
| In general, you should strive to keep your `RUN` lines as simple as possible, |
| using them only to run tools that generate textual output you can then examine. |
| The recommended way to examine output to figure out if the test passes is using |
| the {doc}`FileCheck tool <CommandGuide/FileCheck>`. *[The usage of grep in `RUN` |
| lines is deprecated - please do not send or commit patches that use it.]* |
| |
| Put related tests into a single file rather than having a separate file per |
| test. Check if there are files already covering your feature and consider |
| adding your code there instead of creating a new file. |
| |
| ### Generating assertions in regression tests |
| |
| Some regression test cases are very large and complex to write/update by hand. |
| In that case, to reduce the manual work, we can use the scripts available in |
| `llvm/utils/` to generate the assertions. |
| |
| For example, to generate assertions in an {program}`llc`-based test, after |
| adding one or more `RUN` lines, use: |
| |
| ```bash |
| % llvm/utils/update_llc_test_checks.py --llc-binary build/bin/llc test.ll |
| ``` |
| |
| This will generate FileCheck assertions, and insert a `NOTE:` line at the |
| top to indicate that assertions were automatically generated. |
| |
| If you want to update assertions in an existing test case, pass the `-u` option |
| which first checks the `NOTE:` line exists and matches the script name. |
| |
| Sometimes, a test absolutely depends on hand-written assertions and should not |
| have assertions automatically generated. In that case, add the text `NOTE: Do |
| not autogenerate` to the first line, and the scripts will skip that test. It |
| is a good idea to explain why generated assertions will not work for the test |
| so future developers will understand what is going on. |
| |
| These are the most common scripts and their purposes/applications in generating |
| assertions: |
| |
| ``` |
| update_analyze_test_checks.py |
| opt -passes='print<cost-model>' |
| |
| update_cc_test_checks.py |
| C/C++, or clang/clang++ (IR checks) |
| |
| update_llc_test_checks.py |
| llc (assembly checks) |
| |
| update_mca_test_checks.py |
| llvm-mca |
| |
| update_mir_test_checks.py |
| llc (MIR checks) |
| |
| update_test_checks.py |
| opt |
| |
| update_llubi_test_checks.py |
| llubi |
| ``` |
| |
| ### Precommit workflow for tests |
| |
| If the test does not crash, assert, or infinite loop, commit the test with |
| baseline check-lines first. That is, the test will show a miscompile or |
| missing optimization. Add a "TODO" or "FIXME" comment to indicate that |
| something is expected to change in a test. |
| |
| A follow-up patch with code changes to the compiler will then show check-line |
| differences to the tests, so it is easier to see the effect of the patch. |
| Remove TODO/FIXME comments added in the previous step if a problem is solved. |
| |
| Baseline tests (no-functional-change or NFC patch) may be pushed to main |
| without pre-commit review if you have commit access. |
| |
| ### Best practices for regression tests |
| |
| - Use auto-generated check lines (produced by the scripts mentioned above) |
| whenever feasible. |
| - Include comments about what is tested/expected in a particular test. If there |
| are relevant issues in the bug tracker, add references to those bug reports |
| (for example, "See PR999 for more details"). |
| - Avoid undefined behavior and poison/undef values unless necessary. For |
| example, do not use patterns like `br i1 undef`, which are likely to break |
| as a result of future optimizations. |
| - Minimize tests by removing unnecessary instructions, metadata, attributes, |
| etc. Tools like `llvm-reduce` can partially automate this, but usually |
| some manual cleanup is still required. |
| - Outside PhaseOrdering tests, only run a minimal set of passes. For example, |
| prefer `opt -S -passes=instcombine` over `opt -S -O3`. |
| - Avoid unnamed instructions/blocks (such as `%0` or `1:`), because they may |
| require renumbering on future test modifications. These can be removed by |
| running the test through `opt -S -passes=instnamer`. |
| - Try to give values (including variables, blocks and functions) meaningful |
| names, and avoid retaining complex names generated by the optimization |
| pipeline (such as `%foo.0.0.0.0.0.0`). |
| - Omit target triples and datalayouts when possible. If the test case only |
| exercises the code path of interest with a specific target triple |
| and/or datalayout, then they should be in the test, but otherwise they |
| should be omitted to allow the test to run without requiring a specific |
| backend to be built. |
| - Put tests in the right place. Prefer to add additional test cases to |
| an existing file rather than creating a new one. If your test requires |
| a specific target, prefer putting it in a target-specific test |
| subdirectory rather than requiring a specific backend to be built with a |
| `REQUIRES:` line. |
| - Use a minimal number of non-default (`CHECK-<prefix>`) check prefixes. |
| Avoid setting a check prefix if all `FileCheck` invocations in the test |
| expect the same output. |
| |
| ### Extra files |
| |
| If your test requires extra files besides the file containing the `RUN:` lines, |
| and the extra files are small, consider specifying them in the same file and |
| using `split-file` to extract them. For example, |
| |
| ```llvm |
| ; RUN: split-file %s %t |
| ; RUN: llvm-link -S %t/a.ll %t/b.ll | FileCheck %s |
| |
| ; CHECK: ... |
| |
| ;--- a.ll |
| ... |
| ;--- b.ll |
| ... |
| ``` |
| |
| The parts are separated by the regex `^(.|//)--- <part>`. |
| |
| If you want to test relative line numbers like `[[#@LINE+1]]`, specify |
| `--leading-lines` to add leading empty lines to preserve line numbers. |
| |
| If the extra files are large, the idiomatic place to put them is in a subdirectory `Inputs`. |
| You can then refer to the extra files as `%S/Inputs/foo.bar`. |
| |
| For example, consider `test/Linker/ident.ll`. The directory structure is |
| as follows: |
| |
| ``` |
| test/ |
| Linker/ |
| ident.ll |
| Inputs/ |
| ident.a.ll |
| ident.b.ll |
| ``` |
| |
| For convenience, these are the contents: |
| |
| ```llvm |
| ;;;;; ident.ll: |
| |
| ; RUN: llvm-link %S/Inputs/ident.a.ll %S/Inputs/ident.b.ll -S | FileCheck %s |
| |
| ; Verify that multiple input llvm.ident metadata are linked together. |
| |
| ; CHECK-DAG: !llvm.ident = !{!0, !1, !2} |
| ; CHECK-DAG: "Compiler V1" |
| ; CHECK-DAG: "Compiler V2" |
| ; CHECK-DAG: "Compiler V3" |
| |
| ;;;;; Inputs/ident.a.ll: |
| |
| !llvm.ident = !{!0, !1} |
| !0 = metadata !{metadata !"Compiler V1"} |
| !1 = metadata !{metadata !"Compiler V2"} |
| |
| ;;;;; Inputs/ident.b.ll: |
| |
| !llvm.ident = !{!0} |
| !0 = metadata !{metadata !"Compiler V3"} |
| ``` |
| |
| For symmetry, `ident.ll` is just a dummy file that doesn't |
| actually participate in the test besides holding the `RUN:` lines. |
| |
| ```{note} |
| Some existing tests use `RUN: true` in extra files instead of just |
| putting the extra files in an `Inputs/` directory. This pattern is |
| deprecated. |
| ``` |
| |
| ### Elaborated tests |
| |
| Generally, IR and assembly test files benefit from being cleaned to remove |
| unnecessary details. However, for tests requiring elaborate IR or assembly |
| files where cleanup is less practical (e.g., a large amount of debug information |
| output from Clang), you can include generation instructions within |
| `split-file` part called `gen`. Then, run |
| `llvm/utils/update_test_body.py` on the test file to generate the needed |
| content. |
| |
| ``` |
| ; RUN: rm -rf %t && split-file %s %t && cd %t |
| ; RUN: opt -S a.ll ... | FileCheck %s |
| |
| ; CHECK: hello |
| |
| ;--- a.cc |
| int va; |
| ;--- gen |
| clang --target=x86_64-linux -S -emit-llvm -g a.cc -o - |
| |
| ;--- a.ll |
| # content generated by the script 'gen' |
| ``` |
| |
| ```bash |
| PATH=/path/to/clang_build/bin:$PATH llvm/utils/update_test_body.py path/to/test.ll |
| ``` |
| |
| The script will prepare extra files with `split-file`, invoke `gen`, and |
| then rewrite the part after `gen` with its stdout. |
| |
| For convenience, if the test needs a single assembly file, you can also wrap |
| `gen` and its required files with `.ifdef` and `.endif`. Then you can |
| skip `split-file` in `RUN` lines. |
| |
| ``` |
| # RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o a.o |
| # RUN: ... | FileCheck %s |
| |
| # CHECK: hello |
| |
| .ifdef GEN |
| #--- a.cc |
| int va; |
| #--- gen |
| clang --target=x86_64-linux -S -g a.cc -o - |
| .endif |
| # content generated by the script 'gen' |
| ``` |
| |
| ```{note} |
| Consider specifying an explicit target triple to avoid differences when |
| regeneration is needed on another machine. |
| |
| `gen` is invoked with `PWD` set to `/proc/self/cwd`. Clang commands |
| don't need `-fdebug-compilation-dir=` since its default value is `PWD`. |
| |
| Check prefixes should be placed before `.endif` since the part after |
| `.endif` is replaced. |
| ``` |
| |
| If the test body contains multiple files, you can print `---` separators and |
| utilize `split-file` in `RUN` lines. |
| |
| ``` |
| # RUN: rm -rf %t && split-file %s %t && cd %t |
| ... |
| |
| #--- a.cc |
| int va; |
| #--- b.cc |
| int vb; |
| #--- gen |
| clang --target=x86_64-linux -S -O1 -g a.cc -o - |
| echo '#--- b.s' |
| clang --target=x86_64-linux -S -O1 -g b.cc -o - |
| #--- a.s |
| ``` |
| |
| ### Fragile tests |
| |
| It is easy to write a fragile test that could fail spuriously if the tool being |
| tested outputs a full path to the input file. For example, {program}`opt` by |
| default outputs a `ModuleID`: |
| |
| ```console |
| $ cat example.ll |
| define i32 @main() nounwind { |
| ret i32 0 |
| } |
| |
| $ opt -S /path/to/example.ll |
| ; ModuleID = '/path/to/example.ll' |
| |
| define i32 @main() nounwind { |
| ret i32 0 |
| } |
| ``` |
| |
| `ModuleID` can unexpectedly match against `CHECK` lines. For example: |
| |
| ```llvm |
| ; RUN: opt -S %s | FileCheck |
| |
| define i32 @main() nounwind { |
| ; CHECK-NOT: load |
| ret i32 0 |
| } |
| ``` |
| |
| This test will fail if placed into a `download` directory. |
| |
| To make your tests robust, always use `opt ... < %s` in the `RUN` line. |
| {program}`opt` does not output a `ModuleID` when input comes from stdin. |
| |
| ### Platform-Specific Tests |
| |
| Whenever adding tests that require the knowledge of a specific platform, |
| either related to code generated, specific output or back-end features, |
| you must isolate the features, so that buildbots that |
| run on different architectures (and don't even compile all back-ends), |
| don't fail. |
| |
| The first problem is to check for target-specific output, for example sizes |
| of structures, paths and architecture names, for example: |
| |
| * Tests containing Windows paths will fail on Linux and vice versa. |
| * Tests that check for `x86_64` somewhere in the text will fail anywhere else. |
| * Tests where the debug information calculates the size of types and structures. |
| |
| Also, if the test relies on any behaviour that is coded in any back-end, it must |
| go in its own directory. So, for instance, code generator tests for ARM go |
| into `test/CodeGen/ARM` and so on. Those directories contain a special |
| `lit` configuration file that ensures all tests in that directory will |
| only run if a specific back-end is compiled and available. |
| |
| For instance, on `test/CodeGen/ARM`, the `lit.local.cfg` is: |
| |
| ```python |
| config.suffixes = ['.ll', '.c', '.cpp', '.test'] |
| if not 'ARM' in config.root.targets: |
| config.unsupported = True |
| ``` |
| |
| Other platform-specific tests are those that depend on a specific feature |
| of a specific sub-architecture, for example only to Intel chips that support `AVX2`. |
| |
| For instance, `test/CodeGen/X86/psubus.ll` tests three sub-architecture |
| variants: |
| |
| ```llvm |
| ; RUN: llc -mcpu=core2 < %s | FileCheck %s -check-prefix=SSE2 |
| ; RUN: llc -mcpu=corei7-avx < %s | FileCheck %s -check-prefix=AVX1 |
| ; RUN: llc -mcpu=core-avx2 < %s | FileCheck %s -check-prefix=AVX2 |
| ``` |
| |
| And the checks are different: |
| |
| ```llvm |
| ; SSE2: @test1 |
| ; SSE2: psubusw LCPI0_0(%rip), %xmm0 |
| ; AVX1: @test1 |
| ; AVX1: vpsubusw LCPI0_0(%rip), %xmm0, %xmm0 |
| ; AVX2: @test1 |
| ; AVX2: vpsubusw LCPI0_0(%rip), %xmm0, %xmm0 |
| ``` |
| |
| So, if you're testing for a behaviour that you know is platform-specific or |
| depends on special features of sub-architectures, you must add the specific |
| triple, test with the specific FileCheck and put it into the specific |
| directory that will filter out all other architectures. |
| |
| |
| ### Constraining test execution |
| |
| Some tests can be run only in specific configurations, such as |
| with debug builds or on particular platforms. Use `REQUIRES` |
| and `UNSUPPORTED` to control when the test is enabled. |
| |
| Some tests are expected to fail. For example, there may be a known bug |
| that the test detects. Use `XFAIL` to mark a test as an expected failure. |
| An `XFAIL` test will be successful if its execution fails, and |
| will be a failure if its execution succeeds. |
| |
| ```llvm |
| ; This test will be only enabled in the build with asserts. |
| ; REQUIRES: asserts |
| ; This test is disabled when running on Linux. |
| ; UNSUPPORTED: system-linux |
| ; This test is expected to fail when targeting PowerPC. |
| ; XFAIL: target=powerpc{{.*}} |
| ``` |
| |
| `REQUIRES` and `UNSUPPORTED` and `XFAIL` all accept a comma-separated |
| list of boolean expressions. The values in each expression may be: |
| |
| - Features added to `config.available_features` by configuration files such as `lit.cfg`. |
| String comparison of features is case-sensitive. Furthermore, a boolean expression can |
| contain any Python regular expression enclosed in `{{ }}`, in which case the boolean |
| expression is satisfied if any feature matches the regular expression. Regular |
| expressions can appear inside an identifier, so for example `he{{l+}}o` would match |
| `helo`, `hello`, `helllo`, and so on. |
| - The default target triple, preceded by the string `target=` (for example, |
| `target=x86_64-pc-windows-msvc`). Typically, regular expressions are used |
| to match parts of the triple (for example, `target={{.*}}-windows{{.*}}` |
| to match any Windows target triple). |
| |
| - `REQUIRES` enables the test if all expressions are true. |
| - `UNSUPPORTED` disables the test if any expression is true. |
| - `XFAIL` expects the test to fail if any expression is true. |
| |
| Use, `XFAIL: *` if the test is expected to fail everywhere. Similarly, use |
| `UNSUPPORTED: target={{.*}}` to disable the test everywhere. |
| |
| ```llvm |
| ; This test is disabled when running on Windows, |
| ; and is disabled when targeting Linux, except for Android Linux. |
| ; UNSUPPORTED: system-windows, target={{.*linux.*}} && !target={{.*android.*}} |
| ; This test is expected to fail when targeting PowerPC or running on Darwin. |
| ; XFAIL: target=powerpc{{.*}}, system-darwin |
| ``` |
| |
| ### Tips for writing constraints |
| |
| **`REQUIRES` and `UNSUPPORTED`** |
| |
| These are logical inverses. In principle, `UNSUPPORTED` isn't absolutely |
| necessary (the logical negation could be used with `REQUIRES` to get |
| exactly the same effect), but it can make these clauses easier to read and |
| understand. Generally, people use `REQUIRES` to state things that the test |
| depends on to operate correctly, and `UNSUPPORTED` to exclude cases where |
| the test is expected never to work. |
| |
| **`UNSUPPORTED` and `XFAIL`** |
| |
| Both of these indicate that the test isn't expected to work; however, they |
| have different effects. `UNSUPPORTED` causes the test to be skipped; |
| this saves execution time, but then you'll never know whether the test |
| actually would start working. Conversely, `XFAIL` actually runs the test |
| but expects a failure output, taking extra execution time but alerting you |
| if/when the test begins to behave correctly (an `XPASS` test result). You |
| need to decide which is more appropriate in each case. |
| |
| **Using `target=...`** |
| |
| Checking the target triple can be tricky; it's easy to mis-specify. For |
| example, `target=mips{{.*}}` will match not only mips, but also mipsel, |
| mips64, and mips64el. `target={{.*}}-linux-gnu` will match |
| x86_64-unknown-linux-gnu, but not armv8l-unknown-linux-gnueabihf. |
| Prefer to use hyphens to delimit triple components (`target=mips-{{.*}}`) |
| and it's generally a good idea to use a trailing wildcard to allow for |
| unexpected suffixes. |
| |
| Also, it's generally better to write regular expressions that use entire |
| triple components than to do something clever to shorten them. For |
| example, to match both freebsd and netbsd in an expression, you could write |
| `target={{.*(free|net)bsd.*}}` and that would work. However, it would |
| prevent a `grep freebsd` from finding this test. Better to use: |
| `target={{.+-freebsd.*}} || target={{.+-netbsd.*}}` |
| |
| |
| ### Substitutions |
| |
| Besides replacing LLVM tool names, the following substitutions are performed in |
| `RUN` lines: |
| |
| `%%` |
| |
| : Replaced by a single `%`. This allows escaping other substitutions. |
| |
| `%s` |
| |
| : File path to the test case's source. This is suitable for passing on the |
| command line as the input to an LLVM tool. |
| |
| Example: `/home/user/llvm/test/MC/ELF/foo_test.s` |
| |
| `%S` |
| |
| : Directory path to the test case's source. |
| |
| Example: `/home/user/llvm/test/MC/ELF` |
| |
| `%t` |
| |
| : File path to a temporary file name that can be used for this test case. |
| The file name won't conflict with other test cases. You can append to it |
| if you need multiple temporaries. This is useful as the destination of |
| some redirected output. |
| |
| Example: `/home/user/llvm.build/test/MC/ELF/Output/foo_test.s.tmp` |
| |
| `%T` |
| |
| : Directory of `%t`. Deprecated. Shouldn't be used, because it can be easily |
| misused and cause race conditions between tests. |
| |
| Use `rm -rf %t && mkdir %t` instead if a temporary directory is necessary. |
| |
| Example: `/home/user/llvm.build/test/MC/ELF/Output` |
| |
| `%{pathsep}` |
| |
| : Expands to the path separator, i.e. `:` (or `;` on Windows). |
| |
| `%{fs-src-root}` |
| |
| : Expands to the root component of file system paths for the source directory, |
| i.e. `/` on Unix systems or `C:\` (or another drive) on Windows. |
| |
| `%{fs-tmp-root}` |
| |
| : Expands to the root component of file system paths for the test's temporary |
| directory, i.e. `/` on Unix systems or `C:\` (or another drive) on |
| Windows. |
| |
| `%{fs-sep}` |
| |
| : Expands to the file system separator, i.e. `/` or `\` on Windows. |
| |
| `%/s, %/S, %/t, %/T` |
| |
| : Act like the corresponding substitution above but replace any `\` |
| character with a `/`. This is useful to normalize path separators. |
| |
| Example: `%s: C:\Desktop Files/foo_test.s.tmp` |
| |
| Example: `%/s: C:/Desktop Files/foo_test.s.tmp` |
| |
| `%{s:real}, %{S:real}, %{t:real}, %{T:real}` \ |
| `%{/s:real}, %{/S:real}, %{/t:real}, %{/T:real}` |
| |
| : Act like the corresponding substitution, including with `/`, but use |
| the real path by expanding all symbolic links and substitute drives. |
| |
| Example: `%s: S:\foo_test.s.tmp` |
| |
| Example: `%{/s:real}: C:/SDrive/foo_test.s.tmp` |
| |
| `%:s, %:S, %:t, %:T` |
| |
| : Act like the corresponding substitution above but remove colons at |
| the beginning of Windows paths. This is useful to allow concatenation |
| of absolute paths on Windows to produce a legal path. |
| |
| Example: `%s: C:\Desktop Files\foo_test.s.tmp` |
| |
| Example: `%:s: C\Desktop Files\foo_test.s.tmp` |
| |
| `%errc_<ERRCODE>` |
| |
| : Some error messages may be substituted to allow different spellings |
| based on the host platform. |
| |
| The following error codes are currently supported: |
| ENOENT, EISDIR, EINVAL, EACCES. |
| |
| Example: `Linux %errc_ENOENT: No such file or directory` |
| |
| Example: `Windows %errc_ENOENT: no such file or directory` |
| |
| `%if feature %{<if branch>%} %else %{<else branch>%}` |
| |
| : Conditional substitution: if `feature` is available it expands to |
| `<if branch>`, otherwise it expands to `<else branch>`. |
| `%else %{<else branch>%}` is optional and treated like `%else %{%}` |
| if not present. |
| |
| `%(line)`, `%(line+<number>)`, `%(line-<number>)` |
| |
| : The number of the line where this substitution is used, with an |
| optional integer offset. These expand only if they appear |
| immediately in `RUN:`, `DEFINE:`, and `REDEFINE:` directives. |
| Occurrences in substitutions defined elsewhere are never expanded. |
| For example, this can be used in tests with multiple `RUN` lines, |
| which reference the test file's line numbers. |
| |
| **LLVM-specific substitutions:** |
| |
| `%shlibext` |
| |
| : The suffix for the host platforms shared library files. This includes the |
| period as the first character. |
| |
| Example: `.so` (Linux), `.dylib` (macOS), `.dll` (Windows) |
| |
| `%exeext` |
| |
| : The suffix for the host platforms executable files. This includes the |
| period as the first character. |
| |
| Example: `.exe` (Windows), empty on Linux. |
| |
| **Clang-specific substitutions:** |
| |
| `%clang` |
| |
| : Invokes the Clang driver. |
| |
| `%clang_cpp` |
| |
| : Invokes the Clang driver as the preprocessor. |
| |
| `%clang_cl` |
| |
| : Invokes the CL-compatible Clang driver. |
| |
| `%clangxx` |
| |
| : Invokes the G++-compatible Clang driver. |
| |
| `%clang_cc1` |
| |
| : Invokes the Clang frontend. |
| |
| `%itanium_abi_triple`, `%ms_abi_triple` |
| |
| : These substitutions can be used to get the current target triple adjusted to |
| the desired ABI. For example, if the test suite is running with the |
| `i686-pc-win32` target, `%itanium_abi_triple` will expand to |
| `i686-pc-mingw32`. This allows a test to run with a specific ABI without |
| constraining it to a specific triple. |
| |
| **FileCheck-specific substitutions:** |
| |
| `%ProtectFileCheckOutput` |
| |
| : This should precede a `FileCheck` call if and only if the call's textual |
| output affects test results. It's usually easy to tell: just look for |
| redirection or piping of the `FileCheck` call's stdout or stderr. |
| |
| (Test-specific substitutions)= |
| |
| **Test-specific substitutions:** |
| |
| Additional substitutions can be defined as follows: |
| |
| - Lit configuration files (e.g., `lit.cfg` or `lit.local.cfg`) can define |
| substitutions for all tests in a test directory. They do so by extending the |
| substitution list, `config.substitutions`. Each item in the list is a tuple |
| consisting of a pattern and its replacement, which lit applies as plain text |
| (even if it contains sequences that Python's `re.sub` considers to be |
| escape sequences). |
| - To define substitutions within a single test file, lit supports the |
| `DEFINE:` and `REDEFINE:` directives, described in detail below. So that |
| they have no effect on other test files, these directives modify a copy of the |
| substitution list that is produced by lit configuration files. |
| |
| For example, the following directives can be inserted into a test file to define |
| `%{cflags}` and `%{fcflags}` substitutions with empty initial values, which |
| serve as the parameters of another newly defined `%{check}` substitution: |
| |
| ```llvm |
| ; DEFINE: %{cflags} = |
| ; DEFINE: %{fcflags} = |
| |
| ; DEFINE: %{check} = \ |
| ; DEFINE: %clang_cc1 -verify -fopenmp -fopenmp-version=51 %{cflags} \ |
| ; DEFINE: -emit-llvm -o - %s | \ |
| ; DEFINE: FileCheck %{fcflags} %s |
| ``` |
| |
| Alternatively, the above substitutions can be defined in a lit configuration |
| file to be shared with other test files. Either way, the test file can then |
| specify directives like the following to redefine the parameter substitutions as |
| desired before each use of `%{check}` in a `RUN:` line: |
| |
| ```llvm |
| ; REDEFINE: %{cflags} = -triple x86_64-apple-darwin10.6.0 -fopenmp-simd |
| ; REDEFINE: %{fcflags} = -check-prefix=SIMD |
| ; RUN: %{check} |
| |
| ; REDEFINE: %{cflags} = -triple x86_64-unknown-linux-gnu -fopenmp-simd |
| ; REDEFINE: %{fcflags} = -check-prefix=SIMD |
| ; RUN: %{check} |
| |
| ; REDEFINE: %{cflags} = -triple x86_64-apple-darwin10.6.0 |
| ; REDEFINE: %{fcflags} = -check-prefix=NO-SIMD |
| ; RUN: %{check} |
| |
| ; REDEFINE: %{cflags} = -triple x86_64-unknown-linux-gnu |
| ; REDEFINE: %{fcflags} = -check-prefix=NO-SIMD |
| ; RUN: %{check} |
| ``` |
| |
| Besides providing initial values, the initial `DEFINE:` directives for the |
| parameter substitutions in the above example serve a second purpose: they |
| establish the substitution order so that both `%{check}` and its parameters |
| expand as desired. There's a simple way to remember the required definition |
| order in a test file: define a substitution before any substitution that might |
| refer to it. |
| |
| In general, substitution expansion behaves as follows: |
| |
| - Upon arriving at each `RUN:` line, lit expands all substitutions in that |
| `RUN:` line using their current values from the substitution list. No |
| substitution expansion is performed immediately at `DEFINE:` and |
| `REDEFINE:` directives except `%(line)`, `%(line+<number>)`, and |
| `%(line-<number>)`. |
| - When expanding substitutions in a `RUN:` line, lit makes only one pass |
| through the substitution list by default. In this case, a substitution must |
| have been inserted earlier in the substitution list than any substitution |
| appearing in its value in order for the latter to expand. (For greater |
| flexibility, you can enable multiple passes through the substitution list by |
| setting {ref}`recursiveExpansionLimit <recursiveexpansionlimit>` in a lit |
| configuration file.) |
| - While lit configuration files can insert anywhere in the substitution list, |
| the insertion behavior of the `DEFINE:` and `REDEFINE:` directives is |
| specified below and is designed specifically for the use case presented in the |
| example above. |
| - Defining a substitution in terms of itself, whether directly or via other |
| substitutions, should be avoided. It usually produces an infinitely recursive |
| definition that cannot be fully expanded. It does *not* define the |
| substitution in terms of its previous value, even when using `REDEFINE:`. |
| |
| The relationship between the `DEFINE:` and `REDEFINE:` directive is |
| analogous to the relationship between a variable declaration and variable |
| assignment in many programming languages: |
| |
| - `DEFINE: %{name} = value` |
| |
| This directive assigns the specified value to a new substitution whose |
| pattern is `%{name}`, or it reports an error if there is already a |
| substitution whose pattern contains `%{name}` because that could produce |
| confusing expansions (e.g., a lit configuration file might define a |
| substitution with the pattern `%{name}\[0\]`). The new substitution is |
| inserted at the start of the substitution list so that it will expand first. |
| Thus, its value can contain any substitution previously defined, whether in |
| the same test file or in a lit configuration file, and both will expand. |
| |
| - `REDEFINE: %{name} = value` |
| |
| This directive assigns the specified value to an existing substitution whose |
| pattern is `%{name}`, or it reports an error if there are no substitutions |
| with that pattern or if there are multiple substitutions whose patterns |
| contain `%{name}`. The substitution's current position in the substitution |
| list does not change so that expansion order relative to other existing |
| substitutions is preserved. |
| |
| The following properties apply to both the `DEFINE:` and `REDEFINE:` |
| directives: |
| |
| - **Substitution name**: In the directive, whitespace immediately before or |
| after `%{name}` is optional and discarded. `%{name}` must start with |
| `%{`, it must end with `}`, and the rest must start with a letter or |
| underscore and contain only alphanumeric characters, hyphens, underscores, and |
| colons. This syntax has a few advantages: |
| |
| - It is impossible for `%{name}` to contain sequences that are special in |
| Python's `re.sub` patterns. Otherwise, attempting to specify |
| `%{name}` as a substitution pattern in a lit configuration file could |
| produce confusing expansions. |
| - The braces help avoid the possibility that another substitution's pattern |
| will match part of `%{name}` or vice-versa, producing confusing |
| expansions. However, the patterns of substitutions defined by lit |
| configuration files and by lit itself are not restricted to this form, so |
| overlaps are still theoretically possible. |
| |
| - **Substitution value**: The value includes all text from the first |
| non-whitespace character after `=` to the last non-whitespace character. If |
| there is no non-whitespace character after `=`, the value is the empty |
| string. Escape sequences that can appear in Python `re.sub` replacement |
| strings are treated as plain text in the value. |
| - **Line continuations**: If the last non-whitespace character on the line after |
| `:` is `\`, then the next directive must use the same directive keyword |
| (e.g., `DEFINE:`) , and it is an error if there is no additional directive. |
| That directive serves as a continuation. That is, before following the rules |
| above to parse the text after `:` in either directive, lit joins that text |
| together to form a single directive, replaces the `\` with a single space, |
| and removes any other whitespace that is now adjacent to that space. A |
| continuation can be continued in the same manner. A continuation containing |
| only whitespace after its `:` is an error. |
| |
| (recursiveExpansionLimit)= |
| |
| **recursiveExpansionLimit:** |
| |
| As described in the previous section, when expanding substitutions in a `RUN:` |
| line, lit makes only one pass through the substitution list by default. Thus, |
| if substitutions are not defined in the proper order, some will remain in the |
| `RUN:` line unexpanded. For example, the following directives refer to |
| `%{inner}` within `%{outer}` but do not define `%{inner}` until after |
| `%{outer}`: |
| |
| ```llvm |
| ; By default, this definition order does not enable full expansion. |
| |
| ; DEFINE: %{outer} = %{inner} |
| ; DEFINE: %{inner} = expanded |
| |
| ; RUN: echo '%{outer}' |
| ``` |
| |
| `DEFINE:` inserts substitutions at the start of the substitution list, so |
| `%{inner}` expands first but has no effect because the original `RUN:` line |
| does not contain `%{inner}`. Next, `%{outer}` expands, and the output of |
| the `echo` command becomes: |
| |
| ```shell |
| %{inner} |
| ``` |
| |
| Of course, one way to fix this simple case is to reverse the definitions of |
| `%{outer}` and `%{inner}`. However, if a test has a complex set of |
| substitutions that can all reference each other, there might not exist a |
| sufficient substitution order. |
| |
| To address such use cases, lit configuration files support |
| `config.recursiveExpansionLimit`, which can be set to a non-negative integer |
| to specify the maximum number of passes through the substitution list. Thus, in |
| the above example, setting the limit to 2 would cause lit to make a second pass |
| that expands `%{inner}` in the `RUN:` line, and the output from the `echo` |
| command would then be: |
| |
| ```shell |
| expanded |
| ``` |
| |
| To improve performance, lit will stop making passes when it notices the `RUN:` |
| line has stopped changing. In the above example, setting the limit higher than |
| 2 is thus harmless. |
| |
| To facilitate debugging, after reaching the limit, lit will make one extra pass |
| and report an error if the `RUN:` line changes again. In the above example, |
| setting the limit to 1 will thus cause lit to report an error instead of |
| producing incorrect output. |
| |
| ### Options |
| |
| The llvm lit configuration allows some things to be customized with user options: |
| |
| `llc`, `opt`, ... |
| |
| : Substitute the respective llvm tool name with a custom command line. This |
| allows to specify custom paths and default arguments for these tools. |
| Example: |
| |
| % llvm-lit "-Dllc=llc -verify-machineinstrs" |
| |
| `run_long_tests` |
| |
| : Enable the execution of long running tests. |
| |
| `llvm_site_config` |
| |
| : Load the specified lit configuration instead of the default one. |
| |
| |
| ### Other Features |
| |
| To make `RUN` line writing easier, several helper programs are available. These |
| helpers are in the `PATH` when running tests, so you can just call them using |
| their name. For example: |
| |
| `not` |
| |
| : This program runs its arguments and then inverts the result code from it. |
| Zero result codes become 1. Non-zero result codes become 0. |
| |
| To make the output more useful, {program}`lit` will scan |
| the lines of the test case for ones that contain a pattern that matches |
| `PR[0-9]+`. This is the syntax for specifying a PR (Problem Report) number |
| that is related to the test case. The number after "PR" specifies the |
| LLVM Bugzilla number. When a PR number is specified, it will be used in |
| the pass/fail reporting. This is useful to quickly get some context when |
| a test fails. |
| |
| Finally, any line that contains "END." will cause the special |
| interpretation of lines to terminate. This is generally done right after |
| the last `RUN:` line. This has two side effects: |
| |
| (a) it prevents special interpretation of lines that are part of the test |
| program, not the instructions to the test case, and |
| |
| (b) it speeds things up for really big test cases by avoiding |
| interpretation of the remainder of the file. |