blob: 3ddf5eec9c3c101741d38dd55ccc4d21c5be5e22 [file] [edit]
//@ compile-flags: -Copt-level=3
// LLVM IR isn't very portable and the one tested here depends on the ABI which is different between
// x86 (where we use SSE registers) and others. `x86-64` and `x86-32-sse2` are identical, but
// compiletest does not support taking the union of multiple `only` annotations.
//@ revisions: x86-64 x86-32-sse2 by-ref
//@[x86-64] only-x86_64
//@[x86-64] filecheck-flags: --check-prefix=by-val
//@[x86-32-sse2] only-rustc_abi-x86-sse2
//@[x86-32-sse2] filecheck-flags: --check-prefix=by-val
//@[by-ref] ignore-rustc_abi-x86-sse2
//@[by-ref] ignore-x86_64
#![crate_type = "lib"]
#![no_std]
#![feature(repr_simd, core_intrinsics)]
use core::intrinsics::simd::simd_splat;
#[path = "../../auxiliary/minisimd.rs"]
mod minisimd;
use minisimd::*;
// Test that `simd_splat` produces the canonical LLVM splat sequence.
#[no_mangle]
unsafe fn int(x: u16) -> u16x2 {
// CHECK-LABEL: int
// CHECK: start:
// CHECK-NEXT: %0 = insertelement <2 x i16> poison, i16 %x, i64 0
// CHECK-NEXT: [[VREG:%[a-z0-9_]+]] = shufflevector <2 x i16> %0, <2 x i16> poison, <2 x i32> zeroinitializer
// by-ref-NEXT: store <2 x i16> [[VREG]]
// by-ref-NEXT: ret
// by-val-NEXT: ret <2 x i16> [[VREG]]
simd_splat(x)
}
#[no_mangle]
unsafe fn float(x: f32) -> f32x4 {
// CHECK-LABEL: float
// CHECK: start:
// CHECK-NEXT: %0 = insertelement <4 x float> poison, float %x, i64 0
// CHECK-NEXT: [[VREG:%[a-z0-9_]+]] = shufflevector <4 x float> %0, <4 x float> poison, <4 x i32> zeroinitializer
// by-ref-NEXT: store <4 x float> [[VREG]]
// by-ref-NEXT: ret
// by-val-NEXT: ret <4 x float> [[VREG]]
simd_splat(x)
}