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