Skip to content

Commit

Permalink
Auto merge of #58304 - gnzlbg:simd_saturated, r=nagisa
Browse files Browse the repository at this point in the history
Add generic simd saturated add/sub intrinsics

r? @eddyb
  • Loading branch information
bors committed Feb 24, 2019
2 parents f573049 + f0783d5 commit 7cb3ee4
Show file tree
Hide file tree
Showing 26 changed files with 895 additions and 9 deletions.
26 changes: 18 additions & 8 deletions src/librustc_codegen_llvm/context.rs
Expand Up @@ -515,14 +515,24 @@ impl CodegenCx<'b, 'tcx> {
let t_f32 = self.type_f32();
let t_f64 = self.type_f64();

let t_v2f32 = self.type_vector(t_f32, 2);
let t_v4f32 = self.type_vector(t_f32, 4);
let t_v8f32 = self.type_vector(t_f32, 8);
let t_v16f32 = self.type_vector(t_f32, 16);

let t_v2f64 = self.type_vector(t_f64, 2);
let t_v4f64 = self.type_vector(t_f64, 4);
let t_v8f64 = self.type_vector(t_f64, 8);
macro_rules! vector_types {
($id_out:ident: $elem_ty:ident, $len:expr) => {
let $id_out = self.type_vector($elem_ty, $len);
};
($($id_out:ident: $elem_ty:ident, $len:expr;)*) => {
$(vector_types!($id_out: $elem_ty, $len);)*
}
}
vector_types! {
t_v2f32: t_f32, 2;
t_v4f32: t_f32, 4;
t_v8f32: t_f32, 8;
t_v16f32: t_f32, 16;

t_v2f64: t_f64, 2;
t_v4f64: t_f64, 4;
t_v8f64: t_f64, 8;
}

ifn!("llvm.memset.p0i8.i16", fn(i8p, t_i8, t_i16, t_i32, i1) -> void);
ifn!("llvm.memset.p0i8.i32", fn(i8p, t_i8, t_i32, t_i32, i1) -> void);
Expand Down
45 changes: 45 additions & 0 deletions src/librustc_codegen_llvm/intrinsic.rs
Expand Up @@ -1848,7 +1848,52 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#,
simd_xor: Uint, Int => xor;
simd_fmax: Float => maxnum;
simd_fmin: Float => minnum;

}

if name == "simd_saturating_add" || name == "simd_saturating_sub" {
let lhs = args[0].immediate();
let rhs = args[1].immediate();
let is_add = name == "simd_saturating_add";
let ptr_bits = bx.tcx().data_layout.pointer_size.bits() as _;
let (signed, elem_width, elem_ty) = match in_elem.sty {
ty::Int(i) =>
(
true,
i.bit_width().unwrap_or(ptr_bits),
bx.cx.type_int_from_ty(i)
),
ty::Uint(i) =>
(
false,
i.bit_width().unwrap_or(ptr_bits),
bx.cx.type_uint_from_ty(i)
),
_ => {
return_error!(
"expected element type `{}` of vector type `{}` \
to be a signed or unsigned integer type",
arg_tys[0].simd_type(tcx).sty, arg_tys[0]
);
}
};
let llvm_intrinsic = &format!(
"llvm.{}{}.sat.v{}i{}",
if signed { 's' } else { 'u' },
if is_add { "add" } else { "sub" },
in_len, elem_width
);
let vec_ty = bx.cx.type_vector(elem_ty, in_len as u64);

let f = bx.declare_cfn(
&llvm_intrinsic,
bx.type_func(&[vec_ty, vec_ty], vec_ty)
);
llvm::SetUnnamedAddr(f, false);
let v = bx.call(f, &[lhs, rhs], None);
return Ok(v);
}

span_bug!(span, "unknown SIMD intrinsic");
}

Expand Down
3 changes: 2 additions & 1 deletion src/librustc_typeck/check/intrinsic.rs
Expand Up @@ -410,7 +410,8 @@ pub fn check_platform_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
"simd_add" | "simd_sub" | "simd_mul" | "simd_rem" |
"simd_div" | "simd_shl" | "simd_shr" |
"simd_and" | "simd_or" | "simd_xor" |
"simd_fmin" | "simd_fmax" | "simd_fpow" => {
"simd_fmin" | "simd_fmax" | "simd_fpow" |
"simd_saturating_add" | "simd_saturating_sub" => {
(1, vec![param(0), param(0)], param(0))
}
"simd_fsqrt" | "simd_fsin" | "simd_fcos" | "simd_fexp" | "simd_fexp2" |
Expand Down

0 comments on commit 7cb3ee4

Please sign in to comment.