Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/intrinsic/llvm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1061,13 +1061,18 @@ pub fn intrinsic<'gcc, 'tcx>(name: &str, cx: &CodegenCx<'gcc, 'tcx>) -> Function

"llvm.x86.xgetbv" => "__builtin_ia32_xgetbv",
// NOTE: this doc specifies the equivalent GCC builtins: http://huonw.github.io/llvmint/llvmint/x86/index.html
// FIXME: Should handle other targets than `ia32`.
"llvm.sqrt.v2f64" => "__builtin_ia32_sqrtpd",
// FIXME: Should handle other targets than `ia32`.
"llvm.sqrt.v4f32" => "__builtin_ia32_sqrtps",
"llvm.sqrt.f32" => {
let gcc_name = "__builtin_sqrtf";
let func = cx.context.get_builtin_function(gcc_name);
cx.functions.borrow_mut().insert(gcc_name.to_string(), func);
return func;
}
// FIXME: Should handle other targets than `ia32`.
"llvm.smax.v4i32" => "__builtin_ia32_pmaxsd128",
"llvm.x86.avx512.pmul.dq.512" => "__builtin_ia32_pmuldq512_mask",
"llvm.x86.avx512.pmulu.dq.512" => "__builtin_ia32_pmuludq512_mask",
"llvm.x86.avx512.max.ps.512" => "__builtin_ia32_maxps512_mask",
Expand Down
102 changes: 102 additions & 0 deletions tests/run/simd-ffi.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
// Compiler:
//
// Run-time:
// status: 0

// FIXME: Remove this test once <tests/run-make/simd-ffi/simd.rs> stops
// ignoring GCC backend.

#![allow(internal_features, non_camel_case_types)]
// we can compile to a variety of platforms, because we don't need
// cross-compiled standard libraries.
#![feature(no_core, auto_traits)]
#![no_core]
#![feature(repr_simd, simd_ffi, link_llvm_intrinsics, lang_items, rustc_attrs)]

#[derive(Copy)]
#[repr(simd)]
pub struct f32x4([f32; 4]);

extern "C" {
#[link_name = "llvm.sqrt.v4f32"]
fn vsqrt(x: f32x4) -> f32x4;
}

pub fn foo(x: f32x4) -> f32x4 {
unsafe { vsqrt(x) }
}

#[derive(Copy)]
#[repr(simd)]
pub struct i32x4([i32; 4]);

extern "C" {
// _mm_sll_epi32
#[cfg(all(any(target_arch = "x86", target_arch = "x86-64"), target_feature = "sse2"))]
#[link_name = "llvm.x86.sse2.psll.d"]
fn integer(a: i32x4, b: i32x4) -> i32x4;

// vmaxq_s32
#[cfg(target_arch = "arm")]
#[link_name = "llvm.arm.neon.vmaxs.v4i32"]
fn integer(a: i32x4, b: i32x4) -> i32x4;
// vmaxq_s32
#[cfg(target_arch = "aarch64")]
#[link_name = "llvm.aarch64.neon.maxs.v4i32"]
fn integer(a: i32x4, b: i32x4) -> i32x4;

// Use a generic LLVM intrinsic to do type checking on other platforms
#[cfg(not(any(
all(any(target_arch = "x86", target_arch = "x86-64"), target_feature = "sse2"),
target_arch = "arm",
target_arch = "aarch64"
)))]
#[link_name = "llvm.smax.v4i32"]
fn integer(a: i32x4, b: i32x4) -> i32x4;
}

pub fn bar(a: i32x4, b: i32x4) -> i32x4 {
unsafe { integer(a, b) }
}

#[lang = "pointee_sized"]
pub trait PointeeSized {}

#[lang = "meta_sized"]
pub trait MetaSized: PointeeSized {}

#[lang = "sized"]
pub trait Sized: MetaSized {}

#[lang = "copy"]
pub trait Copy {}

impl Copy for f32 {}
impl Copy for i32 {}
impl Copy for [f32; 4] {}
impl Copy for [i32; 4] {}

pub mod marker {
pub use Copy;
}

#[lang = "freeze"]
auto trait Freeze {}

#[macro_export]
#[rustc_builtin_macro]
macro_rules! Copy {
() => {};
}
#[macro_export]
#[rustc_builtin_macro]
macro_rules! derive {
() => {};
}

#[lang = "start"]
fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const u8, _sigpipe: u8) -> isize {
0
}

fn main() {}