Skip to content

Commit 4f08de8

Browse files
committed
Add comprehensive test for no-ICE behaviour of SIMD FFI.
This just compiles a test using SIMD in FFI (mostly importing LLVM intrinsics) for almost all rustc's supported platforms, but not linking it or running it, so there's absolutely no guarantee that this is correct.
1 parent 9e83ae9 commit 4f08de8

File tree

2 files changed

+114
-0
lines changed

2 files changed

+114
-0
lines changed

src/test/run-make/simd-ffi/Makefile

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
-include ../tools.mk
2+
3+
# construct a fairly exhaustive list of platforms that we
4+
# support. These ones don't follow a pattern
5+
TARGETS=arm-linux-androideabi arm-unknown-linux-gnueabihf arm-unknown-linux-gnueabi
6+
7+
# these ones do, each OS lists the architectures it supports
8+
LINUX=aarch64 i686 x86_64 mips mipsel
9+
WINDOWS=i686 x86_64
10+
# fails with: failed to get iphonesimulator SDK path: no such file or directory
11+
#IOS=i386 aarch64 armv7
12+
DARWIN=i686 x86_64
13+
14+
$(foreach arch,$(LINUX),$(eval TARGETS += $(arch)-unknown-linux-gnu))
15+
$(foreach arch,$(WINDOWS),$(eval TARGETS += $(arch)-pc-windows-gnu))
16+
#$(foreach arch,$(IOS),$(eval TARGETS += $(arch)-apple-ios))
17+
$(foreach arch,$(DARWIN),$(eval TARGETS += $(arch)-apple-darwin))
18+
19+
all: $(TARGETS)
20+
21+
define MK_TARGETS
22+
# compile the rust file to the given target, but only to asm and IR
23+
# form, to avoid having to have an appropriate linker.
24+
#
25+
# we need some features because the integer SIMD instructions are not
26+
# enabled by-default for i686 and ARM; these features will be invalid
27+
# on some platforms, but LLVM just prints a warning so that's fine for
28+
# now.
29+
$(1): simd.rs
30+
$$(RUSTC) --target=$(1) --emit=llvm-ir,asm simd.rs -C target-feature='+neon,+sse2'
31+
endef
32+
33+
$(foreach targetxxx,$(TARGETS),$(eval $(call MK_TARGETS,$(targetxxx))))

src/test/run-make/simd-ffi/simd.rs

+81
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// ensures that public symbols are not removed completely
12+
#![crate_type = "lib"]
13+
// we can compile to a variety of platforms, because we don't need
14+
// cross-compiled standard libraries.
15+
#![no_std]
16+
17+
#![feature(simd, link_llvm_intrinsics, lang_items)]
18+
19+
20+
#[repr(C)]
21+
#[derive(Copy)]
22+
#[simd]
23+
pub struct f32x4(f32, f32, f32, f32);
24+
25+
26+
extern {
27+
#[link_name = "llvm.sqrt.v4f32"]
28+
fn vsqrt(x: f32x4) -> f32x4;
29+
}
30+
31+
pub fn foo(x: f32x4) -> f32x4 {
32+
unsafe {vsqrt(x)}
33+
}
34+
35+
#[repr(C)]
36+
#[derive(Copy)]
37+
#[simd]
38+
pub struct i32x4(i32, i32, i32, i32);
39+
40+
41+
extern {
42+
// _mm_sll_epi32
43+
#[cfg(any(target_arch = "x86",
44+
target_arch = "x86-64"))]
45+
#[link_name = "llvm.x86.sse2.psll.d"]
46+
fn integer(a: i32x4, b: i32x4) -> i32x4;
47+
48+
// vmaxq_s32
49+
#[cfg(any(target_arch = "arm"))]
50+
#[link_name = "llvm.arm.neon.vmaxs.v4i32"]
51+
fn integer(a: i32x4, b: i32x4) -> i32x4;
52+
// vmaxq_s32
53+
#[cfg(any(target_arch = "aarch64"))]
54+
#[link_name = "llvm.aarch64.neon.maxs.v4i32"]
55+
fn integer(a: i32x4, b: i32x4) -> i32x4;
56+
57+
// just some substitute foreign symbol, not an LLVM intrinsic; so
58+
// we still get type checking, but not as detailed as (ab)using
59+
// LLVM.
60+
#[cfg(not(any(target_arch = "x86",
61+
target_arch = "x86-64",
62+
target_arch = "arm",
63+
target_arch = "aarch64")))]
64+
fn integer(a: i32x4, b: i32x4) -> i32x4;
65+
}
66+
67+
pub fn bar(a: i32x4, b: i32x4) -> i32x4 {
68+
unsafe {integer(a, b)}
69+
}
70+
71+
#[lang = "sized"]
72+
trait Sized {}
73+
74+
#[lang = "copy"]
75+
trait Copy {}
76+
77+
mod std {
78+
pub mod marker {
79+
pub use Copy;
80+
}
81+
}

0 commit comments

Comments
 (0)