diff options
| author | bors <bors@rust-lang.org> | 2023-07-29 18:51:45 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2023-07-29 18:51:45 +0000 |
| commit | 03a57254b56886c43464e23b74af484d11374623 (patch) | |
| tree | 8e2f8f5d282b946b0cbb03f2987ffdf1d32b1f17 /compiler/rustc_codegen_llvm/src | |
| parent | a04e649c09183b35ac0309266468c037396b6b88 (diff) | |
| parent | ce4a48f41f4555ad56be404e2e28c86ed4fea4c6 (diff) | |
| download | rust-03a57254b56886c43464e23b74af484d11374623.tar.gz rust-03a57254b56886c43464e23b74af484d11374623.zip | |
Auto merge of #114156 - calebzulawski:simd-bswap, r=compiler-errors
Add simd_bswap, simd_bitreverse, simd_ctlz, and simd_cttz intrinsics cc `@workingjubilee`
Diffstat (limited to 'compiler/rustc_codegen_llvm/src')
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/intrinsic.rs | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 6df1b708ccd..623c08ce86b 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -2074,6 +2074,53 @@ fn generic_simd_intrinsic<'ll, 'tcx>( simd_neg: Int => neg, Float => fneg; } + // Unary integer intrinsics + if matches!(name, sym::simd_bswap | sym::simd_bitreverse | sym::simd_ctlz | sym::simd_cttz) { + let vec_ty = bx.cx.type_vector( + match *in_elem.kind() { + ty::Int(i) => bx.cx.type_int_from_ty(i), + ty::Uint(i) => bx.cx.type_uint_from_ty(i), + _ => return_error!(InvalidMonomorphization::UnsupportedOperation { + span, + name, + in_ty, + in_elem + }), + }, + in_len as u64, + ); + let intrinsic_name = match name { + sym::simd_bswap => "bswap", + sym::simd_bitreverse => "bitreverse", + sym::simd_ctlz => "ctlz", + sym::simd_cttz => "cttz", + _ => unreachable!(), + }; + let llvm_intrinsic = &format!( + "llvm.{}.v{}i{}", + intrinsic_name, + in_len, + in_elem.int_size_and_signed(bx.tcx()).0.bits(), + ); + + return Ok(if matches!(name, sym::simd_ctlz | sym::simd_cttz) { + let fn_ty = bx.type_func(&[vec_ty, bx.type_i1()], vec_ty); + let f = bx.declare_cfn(llvm_intrinsic, llvm::UnnamedAddr::No, fn_ty); + bx.call( + fn_ty, + None, + None, + f, + &[args[0].immediate(), bx.const_int(bx.type_i1(), 0)], + None, + ) + } else { + let fn_ty = bx.type_func(&[vec_ty], vec_ty); + let f = bx.declare_cfn(llvm_intrinsic, llvm::UnnamedAddr::No, fn_ty); + bx.call(fn_ty, None, None, f, &[args[0].immediate()], None) + }); + } + if name == sym::simd_arith_offset { // This also checks that the first operand is a ptr type. let pointee = in_elem.builtin_deref(true).unwrap_or_else(|| { |
