diff options
Diffstat (limited to 'tests/run-make/cross-lang-lto-clang')
-rw-r--r-- | tests/run-make/cross-lang-lto-clang/Makefile | 25 | ||||
-rw-r--r-- | tests/run-make/cross-lang-lto-clang/clib.c | 9 | ||||
-rw-r--r-- | tests/run-make/cross-lang-lto-clang/cmain.c | 12 | ||||
-rw-r--r-- | tests/run-make/cross-lang-lto-clang/main.rs | 11 | ||||
-rw-r--r-- | tests/run-make/cross-lang-lto-clang/rustlib.rs | 12 |
5 files changed, 69 insertions, 0 deletions
diff --git a/tests/run-make/cross-lang-lto-clang/Makefile b/tests/run-make/cross-lang-lto-clang/Makefile new file mode 100644 index 000000000..acaebf439 --- /dev/null +++ b/tests/run-make/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) -Clinker-plugin-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_BIN_DIR)"/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_BIN_DIR)"/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) -Clinker-plugin-lto=on -L$(TMPDIR) -Copt-level=2 -Clinker=$(CLANG) -Clink-arg=-fuse-ld=lld ./main.rs -o $(TMPDIR)/rsmain + "$(LLVM_BIN_DIR)"/llvm-objdump -d $(TMPDIR)/rsmain | $(CGREP) -e "call.*c_never_inlined" + "$(LLVM_BIN_DIR)"/llvm-objdump -d $(TMPDIR)/rsmain | $(CGREP) -v -e "call.*c_always_inlined" diff --git a/tests/run-make/cross-lang-lto-clang/clib.c b/tests/run-make/cross-lang-lto-clang/clib.c new file mode 100644 index 000000000..90f33f24d --- /dev/null +++ b/tests/run-make/cross-lang-lto-clang/clib.c @@ -0,0 +1,9 @@ +#include <stdint.h> + +uint32_t c_always_inlined() { + return 1234; +} + +__attribute__((noinline)) uint32_t c_never_inlined() { + return 12345; +} diff --git a/tests/run-make/cross-lang-lto-clang/cmain.c b/tests/run-make/cross-lang-lto-clang/cmain.c new file mode 100644 index 000000000..e62a40117 --- /dev/null +++ b/tests/run-make/cross-lang-lto-clang/cmain.c @@ -0,0 +1,12 @@ +#include <stdint.h> + +// 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/tests/run-make/cross-lang-lto-clang/main.rs b/tests/run-make/cross-lang-lto-clang/main.rs new file mode 100644 index 000000000..8129dcb85 --- /dev/null +++ b/tests/run-make/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/tests/run-make/cross-lang-lto-clang/rustlib.rs b/tests/run-make/cross-lang-lto-clang/rustlib.rs new file mode 100644 index 000000000..8a74d74a4 --- /dev/null +++ b/tests/run-make/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 +} |