From 0426aaae3724a175227b75381a970446a726e350 Mon Sep 17 00:00:00 2001 From: Julian Frimmel Date: Tue, 15 Oct 2024 21:04:06 +0200 Subject: [PATCH] Simplify test and make it more reliable The new `rmake`-content asserts the exact assembly sequence for the loop preventing false-negatives if some instructions would change and thus the label offset might need to change. --- .../avr-rjmp-offset/avr-rjmp-offsets.rs | 12 ++----- tests/run-make/avr-rjmp-offset/rmake.rs | 32 ++++++++++++++++--- 2 files changed, 29 insertions(+), 15 deletions(-) diff --git a/tests/run-make/avr-rjmp-offset/avr-rjmp-offsets.rs b/tests/run-make/avr-rjmp-offset/avr-rjmp-offsets.rs index a73fdd5e2d82..49161d0cb296 100644 --- a/tests/run-make/avr-rjmp-offset/avr-rjmp-offsets.rs +++ b/tests/run-make/avr-rjmp-offset/avr-rjmp-offsets.rs @@ -1,7 +1,7 @@ //! This test case is a `#![no_core]`-version of the MVCE presented in #129301. //! -//! The function [`delay()`] is minimized and does not actually contain a loop -//! in order to remove the need for additional lang items. +//! The function [`delay()`] is removed, as it is not necessary to trigger the +//! wrong behavior and would require some additional lang items. #![feature(no_core, lang_items, intrinsics, rustc_attrs, asm_experimental_arch)] #![no_core] #![no_main] @@ -22,18 +22,10 @@ pub fn main() -> ! { // sions did place it after the first loop instruction, causing unsoundness) loop { unsafe { ptr::write_volatile(port_b, 1) }; - delay(500_0000); unsafe { ptr::write_volatile(port_b, 2) }; - delay(500_0000); } } -#[inline(never)] -#[no_mangle] -fn delay(_: u32) { - unsafe { asm!("nop") }; -} - // FIXME: replace with proper minicore once available (#130693) mod minicore { #[lang = "sized"] diff --git a/tests/run-make/avr-rjmp-offset/rmake.rs b/tests/run-make/avr-rjmp-offset/rmake.rs index bc59efed918d..0589a7dd5165 100644 --- a/tests/run-make/avr-rjmp-offset/rmake.rs +++ b/tests/run-make/avr-rjmp-offset/rmake.rs @@ -19,9 +19,31 @@ fn main() { .output("compiled") .run(); - llvm_objdump() - .disassemble() - .input("compiled") - .run() - .assert_stdout_contains_regex(r"rjmp.*\.-14"); + let disassembly = llvm_objdump().disassemble().input("compiled").run().stdout_utf8(); + + // search for the following instruction sequence: + // ```disassembly + // 00000080
: + // 80: 81 e0 ldi r24, 0x1 + // 82: 92 e0 ldi r25, 0x2 + // 84: 85 b9 out 0x5, r24 + // 86: 95 b9 out 0x5, r25 + // 88: fd cf rjmp .-6 + // ``` + // This matches on all instructions, since the size of the instructions be- + // fore the relative jump has an impact on the label offset. Old versions + // of the Rust compiler did produce a label `rjmp .-4` (misses the first + // instruction in the loop). + disassembly + .trim() + .lines() + .skip_while(|&line| !line.contains("
")) + .skip(1) + .zip(["ldi\t", "ldi\t", "out\t", "out\t", "rjmp\t.-4"]) + .for_each(|(line, expected_instruction)| { + assert!( + line.contains(expected_instruction), + "expected instruction `{expected_instruction}`, got `{line}`" + ); + }); }