1*dbb99499SAndroid Build Coastguard Worker# Assembly Tests 2*dbb99499SAndroid Build Coastguard Worker 3*dbb99499SAndroid Build Coastguard WorkerThe Benchmark library provides a number of functions whose primary 4*dbb99499SAndroid Build Coastguard Workerpurpose in to affect assembly generation, including `DoNotOptimize` 5*dbb99499SAndroid Build Coastguard Workerand `ClobberMemory`. In addition there are other functions, 6*dbb99499SAndroid Build Coastguard Workersuch as `KeepRunning`, for which generating good assembly is paramount. 7*dbb99499SAndroid Build Coastguard Worker 8*dbb99499SAndroid Build Coastguard WorkerFor these functions it's important to have tests that verify the 9*dbb99499SAndroid Build Coastguard Workercorrectness and quality of the implementation. This requires testing 10*dbb99499SAndroid Build Coastguard Workerthe code generated by the compiler. 11*dbb99499SAndroid Build Coastguard Worker 12*dbb99499SAndroid Build Coastguard WorkerThis document describes how the Benchmark library tests compiler output, 13*dbb99499SAndroid Build Coastguard Workeras well as how to properly write new tests. 14*dbb99499SAndroid Build Coastguard Worker 15*dbb99499SAndroid Build Coastguard Worker 16*dbb99499SAndroid Build Coastguard Worker## Anatomy of a Test 17*dbb99499SAndroid Build Coastguard Worker 18*dbb99499SAndroid Build Coastguard WorkerWriting a test has two steps: 19*dbb99499SAndroid Build Coastguard Worker 20*dbb99499SAndroid Build Coastguard Worker* Write the code you want to generate assembly for. 21*dbb99499SAndroid Build Coastguard Worker* Add `// CHECK` lines to match against the verified assembly. 22*dbb99499SAndroid Build Coastguard Worker 23*dbb99499SAndroid Build Coastguard WorkerExample: 24*dbb99499SAndroid Build Coastguard Worker```c++ 25*dbb99499SAndroid Build Coastguard Worker 26*dbb99499SAndroid Build Coastguard Worker// CHECK-LABEL: test_add: 27*dbb99499SAndroid Build Coastguard Workerextern "C" int test_add() { 28*dbb99499SAndroid Build Coastguard Worker extern int ExternInt; 29*dbb99499SAndroid Build Coastguard Worker return ExternInt + 1; 30*dbb99499SAndroid Build Coastguard Worker 31*dbb99499SAndroid Build Coastguard Worker // CHECK: movl ExternInt(%rip), %eax 32*dbb99499SAndroid Build Coastguard Worker // CHECK: addl %eax 33*dbb99499SAndroid Build Coastguard Worker // CHECK: ret 34*dbb99499SAndroid Build Coastguard Worker} 35*dbb99499SAndroid Build Coastguard Worker 36*dbb99499SAndroid Build Coastguard Worker``` 37*dbb99499SAndroid Build Coastguard Worker 38*dbb99499SAndroid Build Coastguard Worker#### LLVM Filecheck 39*dbb99499SAndroid Build Coastguard Worker 40*dbb99499SAndroid Build Coastguard Worker[LLVM's Filecheck](https://llvm.org/docs/CommandGuide/FileCheck.html) 41*dbb99499SAndroid Build Coastguard Workeris used to test the generated assembly against the `// CHECK` lines 42*dbb99499SAndroid Build Coastguard Workerspecified in the tests source file. Please see the documentation 43*dbb99499SAndroid Build Coastguard Workerlinked above for information on how to write `CHECK` directives. 44*dbb99499SAndroid Build Coastguard Worker 45*dbb99499SAndroid Build Coastguard Worker#### Tips and Tricks: 46*dbb99499SAndroid Build Coastguard Worker 47*dbb99499SAndroid Build Coastguard Worker* Tests should match the minimal amount of output required to establish 48*dbb99499SAndroid Build Coastguard Workercorrectness. `CHECK` directives don't have to match on the exact next line 49*dbb99499SAndroid Build Coastguard Workerafter the previous match, so tests should omit checks for unimportant 50*dbb99499SAndroid Build Coastguard Workerbits of assembly. ([`CHECK-NEXT`](https://llvm.org/docs/CommandGuide/FileCheck.html#the-check-next-directive) 51*dbb99499SAndroid Build Coastguard Workercan be used to ensure a match occurs exactly after the previous match). 52*dbb99499SAndroid Build Coastguard Worker 53*dbb99499SAndroid Build Coastguard Worker* The tests are compiled with `-O3 -g0`. So we're only testing the 54*dbb99499SAndroid Build Coastguard Workeroptimized output. 55*dbb99499SAndroid Build Coastguard Worker 56*dbb99499SAndroid Build Coastguard Worker* The assembly output is further cleaned up using `tools/strip_asm.py`. 57*dbb99499SAndroid Build Coastguard WorkerThis removes comments, assembler directives, and unused labels before 58*dbb99499SAndroid Build Coastguard Workerthe test is run. 59*dbb99499SAndroid Build Coastguard Worker 60*dbb99499SAndroid Build Coastguard Worker* The generated and stripped assembly file for a test is output under 61*dbb99499SAndroid Build Coastguard Worker`<build-directory>/test/<test-name>.s` 62*dbb99499SAndroid Build Coastguard Worker 63*dbb99499SAndroid Build Coastguard Worker* Filecheck supports using [`CHECK` prefixes](https://llvm.org/docs/CommandGuide/FileCheck.html#cmdoption-check-prefixes) 64*dbb99499SAndroid Build Coastguard Workerto specify lines that should only match in certain situations. 65*dbb99499SAndroid Build Coastguard WorkerThe Benchmark tests use `CHECK-CLANG` and `CHECK-GNU` for lines that 66*dbb99499SAndroid Build Coastguard Workerare only expected to match Clang or GCC's output respectively. Normal 67*dbb99499SAndroid Build Coastguard Worker`CHECK` lines match against all compilers. (Note: `CHECK-NOT` and 68*dbb99499SAndroid Build Coastguard Worker`CHECK-LABEL` are NOT prefixes. They are versions of non-prefixed 69*dbb99499SAndroid Build Coastguard Worker`CHECK` lines) 70*dbb99499SAndroid Build Coastguard Worker 71*dbb99499SAndroid Build Coastguard Worker* Use `extern "C"` to disable name mangling for specific functions. This 72*dbb99499SAndroid Build Coastguard Workermakes them easier to name in the `CHECK` lines. 73*dbb99499SAndroid Build Coastguard Worker 74*dbb99499SAndroid Build Coastguard Worker 75*dbb99499SAndroid Build Coastguard Worker## Problems Writing Portable Tests 76*dbb99499SAndroid Build Coastguard Worker 77*dbb99499SAndroid Build Coastguard WorkerWriting tests which check the code generated by a compiler are 78*dbb99499SAndroid Build Coastguard Workerinherently non-portable. Different compilers and even different compiler 79*dbb99499SAndroid Build Coastguard Workerversions may generate entirely different code. The Benchmark tests 80*dbb99499SAndroid Build Coastguard Workermust tolerate this. 81*dbb99499SAndroid Build Coastguard Worker 82*dbb99499SAndroid Build Coastguard WorkerLLVM Filecheck provides a number of mechanisms to help write 83*dbb99499SAndroid Build Coastguard Worker"more portable" tests; including [matching using regular expressions](https://llvm.org/docs/CommandGuide/FileCheck.html#filecheck-pattern-matching-syntax), 84*dbb99499SAndroid Build Coastguard Workerallowing the creation of [named variables](https://llvm.org/docs/CommandGuide/FileCheck.html#filecheck-variables) 85*dbb99499SAndroid Build Coastguard Workerfor later matching, and [checking non-sequential matches](https://llvm.org/docs/CommandGuide/FileCheck.html#the-check-dag-directive). 86*dbb99499SAndroid Build Coastguard Worker 87*dbb99499SAndroid Build Coastguard Worker#### Capturing Variables 88*dbb99499SAndroid Build Coastguard Worker 89*dbb99499SAndroid Build Coastguard WorkerFor example, say GCC stores a variable in a register but Clang stores 90*dbb99499SAndroid Build Coastguard Workerit in memory. To write a test that tolerates both cases we "capture" 91*dbb99499SAndroid Build Coastguard Workerthe destination of the store, and then use the captured expression 92*dbb99499SAndroid Build Coastguard Workerto write the remainder of the test. 93*dbb99499SAndroid Build Coastguard Worker 94*dbb99499SAndroid Build Coastguard Worker```c++ 95*dbb99499SAndroid Build Coastguard Worker// CHECK-LABEL: test_div_no_op_into_shr: 96*dbb99499SAndroid Build Coastguard Workerextern "C" void test_div_no_op_into_shr(int value) { 97*dbb99499SAndroid Build Coastguard Worker int divisor = 2; 98*dbb99499SAndroid Build Coastguard Worker benchmark::DoNotOptimize(divisor); // hide the value from the optimizer 99*dbb99499SAndroid Build Coastguard Worker return value / divisor; 100*dbb99499SAndroid Build Coastguard Worker 101*dbb99499SAndroid Build Coastguard Worker // CHECK: movl $2, [[DEST:.*]] 102*dbb99499SAndroid Build Coastguard Worker // CHECK: idivl [[DEST]] 103*dbb99499SAndroid Build Coastguard Worker // CHECK: ret 104*dbb99499SAndroid Build Coastguard Worker} 105*dbb99499SAndroid Build Coastguard Worker``` 106*dbb99499SAndroid Build Coastguard Worker 107*dbb99499SAndroid Build Coastguard Worker#### Using Regular Expressions to Match Differing Output 108*dbb99499SAndroid Build Coastguard Worker 109*dbb99499SAndroid Build Coastguard WorkerOften tests require testing assembly lines which may subtly differ 110*dbb99499SAndroid Build Coastguard Workerbetween compilers or compiler versions. A common example of this 111*dbb99499SAndroid Build Coastguard Workeris matching stack frame addresses. In this case regular expressions 112*dbb99499SAndroid Build Coastguard Workercan be used to match the differing bits of output. For example: 113*dbb99499SAndroid Build Coastguard Worker 114*dbb99499SAndroid Build Coastguard Worker<!-- {% raw %} --> 115*dbb99499SAndroid Build Coastguard Worker```c++ 116*dbb99499SAndroid Build Coastguard Workerint ExternInt; 117*dbb99499SAndroid Build Coastguard Workerstruct Point { int x, y, z; }; 118*dbb99499SAndroid Build Coastguard Worker 119*dbb99499SAndroid Build Coastguard Worker// CHECK-LABEL: test_store_point: 120*dbb99499SAndroid Build Coastguard Workerextern "C" void test_store_point() { 121*dbb99499SAndroid Build Coastguard Worker Point p{ExternInt, ExternInt, ExternInt}; 122*dbb99499SAndroid Build Coastguard Worker benchmark::DoNotOptimize(p); 123*dbb99499SAndroid Build Coastguard Worker 124*dbb99499SAndroid Build Coastguard Worker // CHECK: movl ExternInt(%rip), %eax 125*dbb99499SAndroid Build Coastguard Worker // CHECK: movl %eax, -{{[0-9]+}}(%rsp) 126*dbb99499SAndroid Build Coastguard Worker // CHECK: movl %eax, -{{[0-9]+}}(%rsp) 127*dbb99499SAndroid Build Coastguard Worker // CHECK: movl %eax, -{{[0-9]+}}(%rsp) 128*dbb99499SAndroid Build Coastguard Worker // CHECK: ret 129*dbb99499SAndroid Build Coastguard Worker} 130*dbb99499SAndroid Build Coastguard Worker``` 131*dbb99499SAndroid Build Coastguard Worker<!-- {% endraw %} --> 132*dbb99499SAndroid Build Coastguard Worker 133*dbb99499SAndroid Build Coastguard Worker## Current Requirements and Limitations 134*dbb99499SAndroid Build Coastguard Worker 135*dbb99499SAndroid Build Coastguard WorkerThe tests require Filecheck to be installed along the `PATH` of the 136*dbb99499SAndroid Build Coastguard Workerbuild machine. Otherwise the tests will be disabled. 137*dbb99499SAndroid Build Coastguard Worker 138*dbb99499SAndroid Build Coastguard WorkerAdditionally, as mentioned in the previous section, codegen tests are 139*dbb99499SAndroid Build Coastguard Workerinherently non-portable. Currently the tests are limited to: 140*dbb99499SAndroid Build Coastguard Worker 141*dbb99499SAndroid Build Coastguard Worker* x86_64 targets. 142*dbb99499SAndroid Build Coastguard Worker* Compiled with GCC or Clang 143*dbb99499SAndroid Build Coastguard Worker 144*dbb99499SAndroid Build Coastguard WorkerFurther work could be done, at least on a limited basis, to extend the 145*dbb99499SAndroid Build Coastguard Workertests to other architectures and compilers (using `CHECK` prefixes). 146*dbb99499SAndroid Build Coastguard Worker 147*dbb99499SAndroid Build Coastguard WorkerFurthermore, the tests fail for builds which specify additional flags 148*dbb99499SAndroid Build Coastguard Workerthat modify code generation, including `--coverage` or `-fsanitize=`. 149*dbb99499SAndroid Build Coastguard Worker 150