From 75dcf9e35fb0a3f8e45ec9f4f7c0a4096fe60d2d Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Fri, 11 Jan 2019 13:43:18 +0100 Subject: [PATCH] Add an end-to-end run-make test for cross-lang LTO. --- .../cross-lang-lto-clang/Makefile | 25 +++++++++++++++++++ .../cross-lang-lto-clang/clib.c | 9 +++++++ .../cross-lang-lto-clang/cmain.c | 12 +++++++++ .../cross-lang-lto-clang/main.rs | 11 ++++++++ .../cross-lang-lto-clang/rustlib.rs | 12 +++++++++ 5 files changed, 69 insertions(+) create mode 100644 src/test/run-make-fulldeps/cross-lang-lto-clang/Makefile create mode 100644 src/test/run-make-fulldeps/cross-lang-lto-clang/clib.c create mode 100644 src/test/run-make-fulldeps/cross-lang-lto-clang/cmain.c create mode 100644 src/test/run-make-fulldeps/cross-lang-lto-clang/main.rs create mode 100644 src/test/run-make-fulldeps/cross-lang-lto-clang/rustlib.rs diff --git a/src/test/run-make-fulldeps/cross-lang-lto-clang/Makefile b/src/test/run-make-fulldeps/cross-lang-lto-clang/Makefile new file mode 100644 index 000000000000..1e5df8f88128 --- /dev/null +++ b/src/test/run-make-fulldeps/cross-lang-lto-clang/Makefile @@ -0,0 +1,25 @@ +# needs-matching-clang + +# This test makes sure that cross-language inlining actually works by checking +# the generated machine code. + +-include ../tools.mk + +all: cpp-executable rust-executable + +cpp-executable: + $(RUSTC) -Zcross-lang-lto=on -o $(TMPDIR)/librustlib-xlto.a -Copt-level=2 -Ccodegen-units=1 ./rustlib.rs + clang -flto=thin -fuse-ld=lld -L $(TMPDIR) -lrustlib-xlto -o $(TMPDIR)/cmain ./cmain.c -O3 + # Make sure we don't find a call instruction to the function we expect to + # always be inlined. + llvm-objdump -d $(TMPDIR)/cmain | $(CGREP) -v -e "call.*rust_always_inlined" + # As a sanity check, make sure we do find a call instruction to a + # non-inlined function + llvm-objdump -d $(TMPDIR)/cmain | $(CGREP) -e "call.*rust_never_inlined" + +rust-executable: + clang ./clib.c -flto=thin -c -o $(TMPDIR)/clib.o -O2 + (cd $(TMPDIR); $(AR) crus ./libxyz.a ./clib.o) + $(RUSTC) -Zcross-lang-lto=on -L$(TMPDIR) -Copt-level=2 -Clinker=clang -Clink-arg=-fuse-ld=lld ./main.rs -o $(TMPDIR)/rsmain + llvm-objdump -d $(TMPDIR)/rsmain | $(CGREP) -e "call.*c_never_inlined" + llvm-objdump -d $(TMPDIR)/rsmain | $(CGREP) -v -e "call.*c_always_inlined" diff --git a/src/test/run-make-fulldeps/cross-lang-lto-clang/clib.c b/src/test/run-make-fulldeps/cross-lang-lto-clang/clib.c new file mode 100644 index 000000000000..90f33f24dc42 --- /dev/null +++ b/src/test/run-make-fulldeps/cross-lang-lto-clang/clib.c @@ -0,0 +1,9 @@ +#include + +uint32_t c_always_inlined() { + return 1234; +} + +__attribute__((noinline)) uint32_t c_never_inlined() { + return 12345; +} diff --git a/src/test/run-make-fulldeps/cross-lang-lto-clang/cmain.c b/src/test/run-make-fulldeps/cross-lang-lto-clang/cmain.c new file mode 100644 index 000000000000..e62a40117ce8 --- /dev/null +++ b/src/test/run-make-fulldeps/cross-lang-lto-clang/cmain.c @@ -0,0 +1,12 @@ +#include + +// A trivial function defined in Rust, returning a constant value. This should +// always be inlined. +uint32_t rust_always_inlined(); + + +uint32_t rust_never_inlined(); + +int main(int argc, char** argv) { + return rust_never_inlined() + rust_always_inlined(); +} diff --git a/src/test/run-make-fulldeps/cross-lang-lto-clang/main.rs b/src/test/run-make-fulldeps/cross-lang-lto-clang/main.rs new file mode 100644 index 000000000000..8129dcb85d96 --- /dev/null +++ b/src/test/run-make-fulldeps/cross-lang-lto-clang/main.rs @@ -0,0 +1,11 @@ +#[link(name = "xyz")] +extern "C" { + fn c_always_inlined() -> u32; + fn c_never_inlined() -> u32; +} + +fn main() { + unsafe { + println!("blub: {}", c_always_inlined() + c_never_inlined()); + } +} diff --git a/src/test/run-make-fulldeps/cross-lang-lto-clang/rustlib.rs b/src/test/run-make-fulldeps/cross-lang-lto-clang/rustlib.rs new file mode 100644 index 000000000000..8a74d74a420b --- /dev/null +++ b/src/test/run-make-fulldeps/cross-lang-lto-clang/rustlib.rs @@ -0,0 +1,12 @@ +#![crate_type="staticlib"] + +#[no_mangle] +pub extern "C" fn rust_always_inlined() -> u32 { + 42 +} + +#[no_mangle] +#[inline(never)] +pub extern "C" fn rust_never_inlined() -> u32 { + 421 +}