Skip to content

Commit 7cb3ee4

Browse files
committed
Auto merge of #58304 - gnzlbg:simd_saturated, r=nagisa
Add generic simd saturated add/sub intrinsics r? @eddyb
2 parents f573049 + f0783d5 commit 7cb3ee4

26 files changed

+895
-9
lines changed

src/librustc_codegen_llvm/context.rs

+18-8
Original file line numberDiff line numberDiff line change
@@ -515,14 +515,24 @@ impl CodegenCx<'b, 'tcx> {
515515
let t_f32 = self.type_f32();
516516
let t_f64 = self.type_f64();
517517

518-
let t_v2f32 = self.type_vector(t_f32, 2);
519-
let t_v4f32 = self.type_vector(t_f32, 4);
520-
let t_v8f32 = self.type_vector(t_f32, 8);
521-
let t_v16f32 = self.type_vector(t_f32, 16);
522-
523-
let t_v2f64 = self.type_vector(t_f64, 2);
524-
let t_v4f64 = self.type_vector(t_f64, 4);
525-
let t_v8f64 = self.type_vector(t_f64, 8);
518+
macro_rules! vector_types {
519+
($id_out:ident: $elem_ty:ident, $len:expr) => {
520+
let $id_out = self.type_vector($elem_ty, $len);
521+
};
522+
($($id_out:ident: $elem_ty:ident, $len:expr;)*) => {
523+
$(vector_types!($id_out: $elem_ty, $len);)*
524+
}
525+
}
526+
vector_types! {
527+
t_v2f32: t_f32, 2;
528+
t_v4f32: t_f32, 4;
529+
t_v8f32: t_f32, 8;
530+
t_v16f32: t_f32, 16;
531+
532+
t_v2f64: t_f64, 2;
533+
t_v4f64: t_f64, 4;
534+
t_v8f64: t_f64, 8;
535+
}
526536

527537
ifn!("llvm.memset.p0i8.i16", fn(i8p, t_i8, t_i16, t_i32, i1) -> void);
528538
ifn!("llvm.memset.p0i8.i32", fn(i8p, t_i8, t_i32, t_i32, i1) -> void);

src/librustc_codegen_llvm/intrinsic.rs

+45
Original file line numberDiff line numberDiff line change
@@ -1848,7 +1848,52 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#,
18481848
simd_xor: Uint, Int => xor;
18491849
simd_fmax: Float => maxnum;
18501850
simd_fmin: Float => minnum;
1851+
1852+
}
1853+
1854+
if name == "simd_saturating_add" || name == "simd_saturating_sub" {
1855+
let lhs = args[0].immediate();
1856+
let rhs = args[1].immediate();
1857+
let is_add = name == "simd_saturating_add";
1858+
let ptr_bits = bx.tcx().data_layout.pointer_size.bits() as _;
1859+
let (signed, elem_width, elem_ty) = match in_elem.sty {
1860+
ty::Int(i) =>
1861+
(
1862+
true,
1863+
i.bit_width().unwrap_or(ptr_bits),
1864+
bx.cx.type_int_from_ty(i)
1865+
),
1866+
ty::Uint(i) =>
1867+
(
1868+
false,
1869+
i.bit_width().unwrap_or(ptr_bits),
1870+
bx.cx.type_uint_from_ty(i)
1871+
),
1872+
_ => {
1873+
return_error!(
1874+
"expected element type `{}` of vector type `{}` \
1875+
to be a signed or unsigned integer type",
1876+
arg_tys[0].simd_type(tcx).sty, arg_tys[0]
1877+
);
1878+
}
1879+
};
1880+
let llvm_intrinsic = &format!(
1881+
"llvm.{}{}.sat.v{}i{}",
1882+
if signed { 's' } else { 'u' },
1883+
if is_add { "add" } else { "sub" },
1884+
in_len, elem_width
1885+
);
1886+
let vec_ty = bx.cx.type_vector(elem_ty, in_len as u64);
1887+
1888+
let f = bx.declare_cfn(
1889+
&llvm_intrinsic,
1890+
bx.type_func(&[vec_ty, vec_ty], vec_ty)
1891+
);
1892+
llvm::SetUnnamedAddr(f, false);
1893+
let v = bx.call(f, &[lhs, rhs], None);
1894+
return Ok(v);
18511895
}
1896+
18521897
span_bug!(span, "unknown SIMD intrinsic");
18531898
}
18541899

src/librustc_typeck/check/intrinsic.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,8 @@ pub fn check_platform_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
410410
"simd_add" | "simd_sub" | "simd_mul" | "simd_rem" |
411411
"simd_div" | "simd_shl" | "simd_shr" |
412412
"simd_and" | "simd_or" | "simd_xor" |
413-
"simd_fmin" | "simd_fmax" | "simd_fpow" => {
413+
"simd_fmin" | "simd_fmax" | "simd_fpow" |
414+
"simd_saturating_add" | "simd_saturating_sub" => {
414415
(1, vec![param(0), param(0)], param(0))
415416
}
416417
"simd_fsqrt" | "simd_fsin" | "simd_fcos" | "simd_fexp" | "simd_fexp2" |

0 commit comments

Comments
 (0)