Skip to content

Commit 5e5a0c7

Browse files
committed
Add code generation tests
Introduces a suite of code generation tests to the `benches` folder. Each tests consists of a pair of files: a Rust source containing a function named `codegen_test`, and a `.x86-64.mca` file containing the llvm-mca analysis of `codegen_test`. In practice, these tests operate similarly to UI tests; CI checks a fresh llvm-mca analysis against that in the file, and fails if they mismatch. Changes can be expressly blessed via `BLESS=1`. gherrit-pr-id: G5964d13c9ffb7a47ed4662892ef92c90ddc51e12
1 parent b7fc71d commit 5e5a0c7

33 files changed

+1411
-4
lines changed

.github/workflows/ci.yml

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,8 @@ jobs:
379379
$FEATURES \
380380
--verbose \
381381
-- \
382-
--skip ui
382+
--skip ui \
383+
--skip codegen
383384
384385
# Only run tests when targetting Linux x86 (32- or 64-bit) - we're
385386
# executing on Linux x86_64, so we can't run tests for any non-x86 target.
@@ -609,6 +610,28 @@ jobs:
609610
matrix.target != 'wasm32-unknown-unknown' &&
610611
env.ZC_SKIP_CARGO_SEMVER_CHECKS != '1'
611612
613+
codegen:
614+
runs-on: ubuntu-latest
615+
name: Run codegen tests
616+
needs: generate_cache
617+
steps:
618+
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
619+
with:
620+
persist-credentials: false
621+
- name: Populate cache
622+
uses: ./.github/actions/cache
623+
- name: Run tests
624+
run: |
625+
set -eo pipefail
626+
sudo apt install -qq llvm
627+
./cargo.sh +nightly install --quiet cargo-show-asm
628+
./cargo.sh +nightly test \
629+
--package zerocopy \
630+
--target x86_64-unknown-linux-gnu \
631+
--all-features \
632+
--verbose \
633+
--test codegen
634+
612635
coverage:
613636
runs-on: ubuntu-latest
614637
name: Generate code coverage
@@ -631,7 +654,9 @@ jobs:
631654
--lcov \
632655
--output-path lcov.info \
633656
--verbose \
634-
-- --skip ui
657+
-- \
658+
--skip ui \
659+
--skip codegen
635660
- name: Upload coverage to Codecov
636661
uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5.5.2
637662
with:
@@ -885,6 +910,7 @@ jobs:
885910
cargo install --locked kani-verifier &> /dev/null &
886911
cargo install cargo-nextest &> /dev/null &
887912
cargo kani setup &> /dev/null &
913+
sudo apt-get install llvm &> /dev/null &
888914
889915
wait
890916
@@ -988,7 +1014,7 @@ jobs:
9881014
# https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/collaborating-on-repositories-with-code-quality-features/troubleshooting-required-status-checks#handling-skipped-but-required-checks
9891015
if: failure()
9901016
runs-on: ubuntu-latest
991-
needs: [build_test, coverage, kani, check_be_aarch64, check_avr_atmega, check_fmt, check_actions, check_readme, check_versions, check_msrv_is_minimal, check_stale_stderr, generate_cache, check-all-toolchains-tested, check-job-dependencies, check-todo, run-git-hooks, zizmor]
1017+
needs: [build_test, codegen, coverage, kani, check_be_aarch64, check_avr_atmega, check_fmt, check_actions, check_readme, check_versions, check_msrv_is_minimal, check_stale_stderr, generate_cache, check-all-toolchains-tested, check-job-dependencies, check-todo, run-git-hooks, zizmor]
9921018
steps:
9931019
- name: Mark the job as failed
9941020
run: exit 1

benches/formats/coco.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Copyright 2026 The Fuchsia Authors
2+
//
3+
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
4+
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
5+
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
6+
// This file may not be copied, modified, or distributed except according to
7+
// those terms.
8+
9+
use zerocopy_derive::*;
10+
11+
// The only valid value of this type are the bytes `0xC0C0`.
12+
#[derive(TryFromBytes, KnownLayout, Immutable)]
13+
#[repr(u16, align(2))]
14+
enum C0C0 {
15+
_XC0C0 = 0xC0C0,
16+
}
17+
18+
#[derive(TryFromBytes, KnownLayout, Immutable)]
19+
#[repr(C)]
20+
pub struct Packet {
21+
magic_number: C0C0,
22+
mug_size: u8,
23+
temperature: u8,
24+
marshmallows: [[u8; 2]],
25+
}

benches/formats/loco.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright 2026 The Fuchsia Authors
2+
//
3+
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
4+
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
5+
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
6+
// This file may not be copied, modified, or distributed except according to
7+
// those terms.
8+
9+
use zerocopy_derive::*;
10+
11+
#[derive(FromBytes, KnownLayout, Immutable)]
12+
#[repr(C, align(2))]
13+
pub struct Packet {
14+
magic_number: [u8; 2],
15+
mug_size: u8,
16+
temperature: u8,
17+
marshmallows: [[u8; 2]],
18+
}

benches/ref_from_bytes.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Copyright 2026 The Fuchsia Authors
2+
//
3+
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
4+
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
5+
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
6+
// This file may not be copied, modified, or distributed except according to
7+
// those terms.
8+
9+
use zerocopy::FromBytes;
10+
11+
#[path = "formats/loco.rs"]
12+
mod loco;
13+
14+
#[unsafe(no_mangle)]
15+
fn codegen_test(source: &[u8]) -> Option<&loco::Packet> {
16+
FromBytes::ref_from_bytes(source).ok()
17+
}

benches/ref_from_bytes.x86-64.mca

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
Iterations: 100
2+
Instructions: 1800
3+
Total Cycles: 704
4+
Total uOps: 2000
5+
6+
Dispatch Width: 4
7+
uOps Per Cycle: 2.84
8+
IPC: 2.56
9+
Block RThroughput: 5.0
10+
11+
12+
Instruction Info:
13+
[1]: #uOps
14+
[2]: Latency
15+
[3]: RThroughput
16+
[4]: MayLoad
17+
[5]: MayStore
18+
[6]: HasSideEffects (U)
19+
20+
[1] [2] [3] [4] [5] [6] Instructions:
21+
1 1 0.33 mov rdx, rsi
22+
1 1 0.33 cmp rsi, 4
23+
1 1 0.50 setb al
24+
1 1 0.33 or al, dil
25+
1 1 0.33 test al, 1
26+
1 1 1.00 je .LBB5_2
27+
1 0 0.25 xor eax, eax
28+
1 1 1.00 U ret
29+
1 1 0.50 lea rcx, [rdx - 4]
30+
1 1 0.33 mov rsi, rcx
31+
1 1 0.33 and rsi, -2
32+
1 1 0.33 add rsi, 4
33+
1 1 0.50 shr rcx
34+
1 0 0.25 xor eax, eax
35+
1 1 0.33 cmp rdx, rsi
36+
2 2 0.67 cmove rdx, rcx
37+
2 2 0.67 cmove rax, rdi
38+
1 1 1.00 U ret
39+
40+
41+
Resources:
42+
[0] - SBDivider
43+
[1] - SBFPDivider
44+
[2] - SBPort0
45+
[3] - SBPort1
46+
[4] - SBPort4
47+
[5] - SBPort5
48+
[6.0] - SBPort23
49+
[6.1] - SBPort23
50+
51+
52+
Resource pressure per iteration:
53+
[0] [1] [2] [3] [4] [5] [6.0] [6.1]
54+
- - 5.97 5.98 - 6.05 - -
55+
56+
Resource pressure by instruction:
57+
[0] [1] [2] [3] [4] [5] [6.0] [6.1] Instructions:
58+
- - 0.97 0.01 - 0.02 - - mov rdx, rsi
59+
- - 0.01 0.02 - 0.97 - - cmp rsi, 4
60+
- - 0.03 - - 0.97 - - setb al
61+
- - 0.01 0.02 - 0.97 - - or al, dil
62+
- - - 0.98 - 0.02 - - test al, 1
63+
- - - - - 1.00 - - je .LBB5_2
64+
- - - - - - - - xor eax, eax
65+
- - - - - 1.00 - - ret
66+
- - 0.98 0.02 - - - - lea rcx, [rdx - 4]
67+
- - 0.01 0.99 - - - - mov rsi, rcx
68+
- - - 0.98 - 0.02 - - and rsi, -2
69+
- - 0.98 0.01 - 0.01 - - add rsi, 4
70+
- - 0.99 - - 0.01 - - shr rcx
71+
- - - - - - - - xor eax, eax
72+
- - 0.02 0.97 - 0.01 - - cmp rdx, rsi
73+
- - 0.99 0.99 - 0.02 - - cmove rdx, rcx
74+
- - 0.98 0.99 - 0.03 - - cmove rax, rdi
75+
- - - - - 1.00 - - ret
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Copyright 2026 The Fuchsia Authors
2+
//
3+
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
4+
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
5+
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
6+
// This file may not be copied, modified, or distributed except according to
7+
// those terms.
8+
9+
use zerocopy::FromBytes;
10+
11+
#[path = "formats/loco.rs"]
12+
mod loco;
13+
14+
#[unsafe(no_mangle)]
15+
fn codegen_test(source: &[u8], count: usize) -> Option<&loco::Packet> {
16+
FromBytes::ref_from_bytes_with_elems(source, count).ok()
17+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
Iterations: 100
2+
Instructions: 1300
3+
Total Cycles: 439
4+
Total uOps: 1400
5+
6+
Dispatch Width: 4
7+
uOps Per Cycle: 3.19
8+
IPC: 2.96
9+
Block RThroughput: 3.5
10+
11+
12+
Instruction Info:
13+
[1]: #uOps
14+
[2]: Latency
15+
[3]: RThroughput
16+
[4]: MayLoad
17+
[5]: MayStore
18+
[6]: HasSideEffects (U)
19+
20+
[1] [2] [3] [4] [5] [6] Instructions:
21+
1 1 0.33 movabs rax, 9223372036854775805
22+
1 1 0.33 cmp rdx, rax
23+
2 2 1.00 seta cl
24+
1 1 0.33 mov rax, rdi
25+
1 1 0.33 or dil, cl
26+
1 1 0.33 test dil, 1
27+
1 1 1.00 jne .LBB5_2
28+
1 1 0.50 lea rcx, [2*rdx + 4]
29+
1 1 0.33 cmp rsi, rcx
30+
1 1 1.00 je .LBB5_3
31+
1 0 0.25 xor eax, eax
32+
1 1 0.33 mov rdx, rsi
33+
1 1 1.00 U ret
34+
35+
36+
Resources:
37+
[0] - SBDivider
38+
[1] - SBFPDivider
39+
[2] - SBPort0
40+
[3] - SBPort1
41+
[4] - SBPort4
42+
[5] - SBPort5
43+
[6.0] - SBPort23
44+
[6.1] - SBPort23
45+
46+
47+
Resource pressure per iteration:
48+
[0] [1] [2] [3] [4] [5] [6.0] [6.1]
49+
- - 4.32 4.33 - 4.35 - -
50+
51+
Resource pressure by instruction:
52+
[0] [1] [2] [3] [4] [5] [6.0] [6.1] Instructions:
53+
- - - 0.99 - 0.01 - - movabs rax, 9223372036854775805
54+
- - 0.33 0.67 - - - - cmp rdx, rax
55+
- - 1.98 - - 0.02 - - seta cl
56+
- - 0.01 0.99 - - - - mov rax, rdi
57+
- - 1.00 - - - - - or dil, cl
58+
- - 0.99 0.01 - - - - test dil, 1
59+
- - - - - 1.00 - - jne .LBB5_2
60+
- - - 1.00 - - - - lea rcx, [2*rdx + 4]
61+
- - 0.01 - - 0.99 - - cmp rsi, rcx
62+
- - - - - 1.00 - - je .LBB5_3
63+
- - - - - - - - xor eax, eax
64+
- - - 0.67 - 0.33 - - mov rdx, rsi
65+
- - - - - 1.00 - - ret

benches/ref_from_prefix.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Copyright 2026 The Fuchsia Authors
2+
//
3+
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
4+
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
5+
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
6+
// This file may not be copied, modified, or distributed except according to
7+
// those terms.
8+
9+
use zerocopy::FromBytes;
10+
11+
#[path = "formats/loco.rs"]
12+
mod loco;
13+
14+
#[unsafe(no_mangle)]
15+
fn codegen_test(source: &[u8]) -> Option<&loco::Packet> {
16+
match FromBytes::ref_from_prefix(source) {
17+
Ok((packet, _rest)) => Some(packet),
18+
_ => None,
19+
}
20+
}

benches/ref_from_prefix.x86-64.mca

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
Iterations: 100
2+
Instructions: 1400
3+
Total Cycles: 405
4+
Total uOps: 1400
5+
6+
Dispatch Width: 4
7+
uOps Per Cycle: 3.46
8+
IPC: 3.46
9+
Block RThroughput: 4.0
10+
11+
12+
Instruction Info:
13+
[1]: #uOps
14+
[2]: Latency
15+
[3]: RThroughput
16+
[4]: MayLoad
17+
[5]: MayStore
18+
[6]: HasSideEffects (U)
19+
20+
[1] [2] [3] [4] [5] [6] Instructions:
21+
1 0 0.25 xor edx, edx
22+
1 1 0.33 mov eax, 0
23+
1 1 0.33 test dil, 1
24+
1 1 1.00 jne .LBB5_4
25+
1 1 0.33 cmp rsi, 4
26+
1 1 1.00 jae .LBB5_3
27+
1 1 0.33 mov edx, 1
28+
1 0 0.25 xor eax, eax
29+
1 1 1.00 U ret
30+
1 1 0.33 add rsi, -4
31+
1 1 0.50 shr rsi
32+
1 1 0.33 mov rdx, rsi
33+
1 1 0.33 mov rax, rdi
34+
1 1 1.00 U ret
35+
36+
37+
Resources:
38+
[0] - SBDivider
39+
[1] - SBFPDivider
40+
[2] - SBPort0
41+
[3] - SBPort1
42+
[4] - SBPort4
43+
[5] - SBPort5
44+
[6.0] - SBPort23
45+
[6.1] - SBPort23
46+
47+
48+
Resource pressure per iteration:
49+
[0] [1] [2] [3] [4] [5] [6.0] [6.1]
50+
- - 3.99 3.99 - 4.02 - -
51+
52+
Resource pressure by instruction:
53+
[0] [1] [2] [3] [4] [5] [6.0] [6.1] Instructions:
54+
- - - - - - - - xor edx, edx
55+
- - 0.01 0.98 - 0.01 - - mov eax, 0
56+
- - 0.98 0.02 - - - - test dil, 1
57+
- - - - - 1.00 - - jne .LBB5_4
58+
- - 0.02 0.98 - - - - cmp rsi, 4
59+
- - - - - 1.00 - - jae .LBB5_3
60+
- - 0.98 0.01 - 0.01 - - mov edx, 1
61+
- - - - - - - - xor eax, eax
62+
- - - - - 1.00 - - ret
63+
- - 0.01 0.99 - - - - add rsi, -4
64+
- - 1.00 - - - - - shr rsi
65+
- - - 1.00 - - - - mov rdx, rsi
66+
- - 0.99 0.01 - - - - mov rax, rdi
67+
- - - - - 1.00 - - ret
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Copyright 2026 The Fuchsia Authors
2+
//
3+
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
4+
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
5+
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
6+
// This file may not be copied, modified, or distributed except according to
7+
// those terms.
8+
9+
use zerocopy::FromBytes;
10+
11+
#[path = "formats/loco.rs"]
12+
mod loco;
13+
14+
#[unsafe(no_mangle)]
15+
fn codegen_test(source: &[u8], count: usize) -> Option<&loco::Packet> {
16+
match FromBytes::ref_from_prefix_with_elems(source, count) {
17+
Ok((packet, _rest)) => Some(packet),
18+
_ => None,
19+
}
20+
}

0 commit comments

Comments
 (0)