From a09c91cf8c63dcccebb08fc518bd96445c1c3894 Mon Sep 17 00:00:00 2001 From: N1ark Date: Sun, 15 Mar 2026 22:41:07 +0000 Subject: [PATCH 1/7] Merge `fabsfN` into `fabs::` Add `bounds::FloatPrimitive` Exhaustive float pattern match Fix GCC --- .../src/intrinsics/mod.rs | 29 +++-- .../rustc_codegen_gcc/src/intrinsic/mod.rs | 103 ++++++++++-------- compiler/rustc_codegen_llvm/src/intrinsic.rs | 20 +++- .../src/interpret/intrinsics.rs | 51 ++++++--- .../rustc_hir_analysis/src/check/intrinsic.rs | 10 +- compiler/rustc_span/src/symbol.rs | 5 +- library/core/src/intrinsics/bounds.rs | 11 ++ library/core/src/intrinsics/mod.rs | 56 +++------- library/core/src/num/f128.rs | 2 +- library/core/src/num/f16.rs | 2 +- library/core/src/num/f32.rs | 2 +- library/core/src/num/f64.rs | 2 +- .../bad-intrinsic-monomorphization-float.rs | 18 +++ ...ad-intrinsic-monomorphization-float.stderr | 30 +++++ .../bad-intrinsic-monomorphization.rs | 5 - .../bad-intrinsic-monomorphization.stderr | 10 +- tests/ui/resolve/filter-intrinsics.rs | 4 +- tests/ui/resolve/filter-intrinsics.stderr | 8 +- 18 files changed, 216 insertions(+), 152 deletions(-) create mode 100644 tests/ui/intrinsics/bad-intrinsic-monomorphization-float.rs create mode 100644 tests/ui/intrinsics/bad-intrinsic-monomorphization-float.stderr diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs index 8b112e695275a..79d8835072ae8 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs @@ -346,10 +346,6 @@ fn codegen_float_intrinsic_call<'tcx>( sym::log10f32 => ("log10f", 1, fx.tcx.types.f32, types::F32), sym::log10f64 => ("log10", 1, fx.tcx.types.f64, types::F64), sym::log10f128 => ("log10f128", 1, fx.tcx.types.f128, types::F128), - sym::fabsf16 => ("fabsf16", 1, fx.tcx.types.f16, types::F16), - sym::fabsf32 => ("fabsf", 1, fx.tcx.types.f32, types::F32), - sym::fabsf64 => ("fabs", 1, fx.tcx.types.f64, types::F64), - sym::fabsf128 => ("fabsf128", 1, fx.tcx.types.f128, types::F128), sym::fmaf16 => ("fmaf16", 3, fx.tcx.types.f16, types::F16), sym::fmaf32 => ("fmaf", 3, fx.tcx.types.f32, types::F32), sym::fmaf64 => ("fma", 3, fx.tcx.types.f64, types::F64), @@ -441,11 +437,7 @@ fn codegen_float_intrinsic_call<'tcx>( sym::copysignf32 | sym::copysignf64 => { CValue::by_val(fx.bcx.ins().fcopysign(args[0], args[1]), layout) } - sym::fabsf16 => CValue::by_val(codegen_f16_f128::abs_f16(fx, args[0]), layout), - sym::fabsf128 => CValue::by_val(codegen_f16_f128::abs_f128(fx, args[0]), layout), - sym::fabsf32 - | sym::fabsf64 - | sym::floorf32 + sym::floorf32 | sym::floorf64 | sym::ceilf32 | sym::ceilf64 @@ -456,7 +448,6 @@ fn codegen_float_intrinsic_call<'tcx>( | sym::sqrtf32 | sym::sqrtf64 => { let val = match intrinsic { - sym::fabsf32 | sym::fabsf64 => fx.bcx.ins().fabs(args[0]), sym::floorf32 | sym::floorf64 => fx.bcx.ins().floor(args[0]), sym::ceilf32 | sym::ceilf64 => fx.bcx.ins().ceil(args[0]), sym::truncf32 | sym::truncf64 => fx.bcx.ins().trunc(args[0]), @@ -1179,6 +1170,24 @@ fn codegen_regular_intrinsic_call<'tcx>( ret.write_cvalue(fx, old); } + sym::fabs => { + intrinsic_args!(fx, args => (arg); intrinsic); + let layout = arg.layout(); + let ty::Float(float_ty) = layout.ty.kind() else { + bug!("expected float type for fabs intrinsic: {:?}", layout.ty); + }; + let x = arg.load_scalar(fx); + let val = match float_ty { + FloatTy::F32 | FloatTy::F64 => fx.bcx.ins().fabs(x), + // FIXME(bytecodealliance/wasmtime#8312): Use `fabsf16` once Cranelift + // backend lowerings are implemented. + FloatTy::F16 => codegen_f16_f128::abs_f16(fx, x), + FloatTy::F128 => codegen_f16_f128::abs_f128(fx, x), + }; + let val = CValue::by_val(val, layout); + ret.write_cvalue(fx, val); + } + sym::minimumf16 => { intrinsic_args!(fx, args => (a, b); intrinsic); let a = a.load_scalar(fx); diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs index 3f1b33c73e638..f3a7ac3b4c0fa 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs +++ b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs @@ -70,8 +70,6 @@ fn get_simple_intrinsic<'gcc, 'tcx>( // FIXME: calling `fma` from libc without FMA target feature uses expensive software emulation sym::fmuladdf32 => "fmaf", // FIXME: use gcc intrinsic analogous to llvm.fmuladd.f32 sym::fmuladdf64 => "fma", // FIXME: use gcc intrinsic analogous to llvm.fmuladd.f64 - sym::fabsf32 => "fabsf", - sym::fabsf64 => "fabs", sym::minimumf32 => "fminimumf", sym::minimumf64 => "fminimum", sym::minimumf128 => { @@ -196,56 +194,26 @@ fn get_simple_function<'gcc, 'tcx>( fn get_simple_function_f128<'gcc, 'tcx>( cx: &CodegenCx<'gcc, 'tcx>, name: Symbol, -) -> Option> { - if !cx.supports_f128_type { - return None; - } - +) -> Function<'gcc> { let f128_type = cx.type_f128(); let func_name = match name { sym::ceilf128 => "ceilf128", - sym::fabsf128 => "fabsf128", + sym::fabs => "fabsf128", sym::floorf128 => "floorf128", sym::truncf128 => "truncf128", sym::roundf128 => "roundf128", sym::round_ties_even_f128 => "roundevenf128", sym::sqrtf128 => "sqrtf128", - _ => return None, + _ => unreachable!(), }; - Some(cx.context.new_function( + cx.context.new_function( None, FunctionType::Extern, f128_type, &[cx.context.new_parameter(None, f128_type, "a")], func_name, false, - )) -} - -fn get_simple_function_f128_2args<'gcc, 'tcx>( - cx: &CodegenCx<'gcc, 'tcx>, - name: Symbol, -) -> Option> { - if !cx.supports_f128_type { - return None; - } - - let f128_type = cx.type_f128(); - let func_name = match name { - sym::copysignf128 => "copysignf128", - _ => return None, - }; - Some(cx.context.new_function( - None, - FunctionType::Extern, - f128_type, - &[ - cx.context.new_parameter(None, f128_type, "a"), - cx.context.new_parameter(None, f128_type, "b"), - ], - func_name, - false, - )) + ) } fn f16_builtin<'gcc, 'tcx>( @@ -257,7 +225,7 @@ fn f16_builtin<'gcc, 'tcx>( let builtin_name = match name { sym::ceilf16 => "__builtin_ceilf", sym::copysignf16 => "__builtin_copysignf", - sym::fabsf16 => "fabsf", + sym::fabs => "fabsf", sym::floorf16 => "__builtin_floorf", sym::fmaf16 => "fmaf", sym::powf16 => "__builtin_powf", @@ -297,11 +265,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc let fn_args = instance.args; let simple = get_simple_intrinsic(self, name); - // FIXME(antoyo): Only call get_simple_function_f128 and get_simple_function_f128_2args when - // it is the symbols for the supported f128 builtins. - let simple_func = get_simple_function(self, name) - .or_else(|| get_simple_function_f128(self, name)) - .or_else(|| get_simple_function_f128_2args(self, name)); + let simple_func = get_simple_function(self, name); let value = match name { _ if simple.is_some() => { @@ -322,7 +286,6 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc } sym::ceilf16 | sym::copysignf16 - | sym::fabsf16 | sym::floorf16 | sym::fmaf16 | sym::powf16 @@ -331,6 +294,40 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc | sym::round_ties_even_f16 | sym::sqrtf16 | sym::truncf16 => f16_builtin(self, name, args), + sym::ceilf128 + | sym::floorf128 + | sym::truncf128 + | sym::roundf128 + | sym::round_ties_even_f128 + | sym::sqrtf128 + if self.cx.supports_f128_type => + { + let func = get_simple_function_f128(self, name); + self.cx.context.new_call( + self.location, + func, + &args.iter().map(|arg| arg.immediate()).collect::>(), + ) + } + sym::copysignf128 if self.cx.supports_f128_type => { + let f128_type = self.cx.type_f128(); + let func = self.cx.context.new_function( + None, + FunctionType::Extern, + f128_type, + &[ + self.cx.context.new_parameter(None, f128_type, "a"), + self.cx.context.new_parameter(None, f128_type, "b"), + ], + "copysignf128", + false, + ); + self.cx.context.new_call( + self.location, + func, + &args.iter().map(|arg| arg.immediate()).collect::>(), + ) + } sym::fmaf128 => { let f128_type = self.cx.type_f128(); let func = self.cx.context.new_function( @@ -488,6 +485,24 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc } } } + sym::fabs => 'fabs: { + let ty = args[0].layout.ty; + let ty::Float(float_ty) = *ty.kind() else { + tcx.dcx().emit_err(InvalidMonomorphization::BasicFloatType { span, name, ty }); + return Ok(()); + }; + let func = match float_ty { + ty::FloatTy::F16 => break 'fabs f16_builtin(self, name, args), + ty::FloatTy::F32 => self.context.get_builtin_function("fabsf"), + ty::FloatTy::F64 => self.context.get_builtin_function("fabs"), + ty::FloatTy::F128 => get_simple_function_f128(self, name), + }; + self.cx.context.new_call( + self.location, + func, + &args.iter().map(|arg| arg.immediate()).collect::>(), + ) + } sym::raw_eq => { use rustc_abi::BackendRepr::*; diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index cc6ecee60b0e4..1dd1a021c25f3 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -107,11 +107,6 @@ fn call_simple_intrinsic<'ll, 'tcx>( sym::fmuladdf64 => ("llvm.fmuladd", &[bx.type_f64()]), sym::fmuladdf128 => ("llvm.fmuladd", &[bx.type_f128()]), - sym::fabsf16 => ("llvm.fabs", &[bx.type_f16()]), - sym::fabsf32 => ("llvm.fabs", &[bx.type_f32()]), - sym::fabsf64 => ("llvm.fabs", &[bx.type_f64()]), - sym::fabsf128 => ("llvm.fabs", &[bx.type_f128()]), - // FIXME: LLVM currently mis-compile those intrinsics, re-enable them // when llvm/llvm-project#{139380,139381,140445} are fixed. //sym::minimumf16 => ("llvm.minimum", &[bx.type_f16()]), @@ -502,6 +497,21 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { } } + sym::fabs => { + let ty = args[0].layout.ty; + let ty::Float(f) = ty.kind() else { + tcx.dcx().emit_err(InvalidMonomorphization::BasicFloatType { span, name, ty }); + return Ok(()); + }; + let llty = self.type_float_from_ty(*f); + let llvm_name = "llvm.fabs"; + self.call_intrinsic( + llvm_name, + &[llty], + &args.iter().map(|arg| arg.immediate()).collect::>(), + ) + } + sym::raw_eq => { use BackendRepr::*; let tp_ty = fn_args.type_at(0); diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index d5f69d78ea6ae..17311188879c1 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -575,10 +575,23 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { sym::copysignf64 => self.float_copysign_intrinsic::(args, dest)?, sym::copysignf128 => self.float_copysign_intrinsic::(args, dest)?, - sym::fabsf16 => self.float_abs_intrinsic::(args, dest)?, - sym::fabsf32 => self.float_abs_intrinsic::(args, dest)?, - sym::fabsf64 => self.float_abs_intrinsic::(args, dest)?, - sym::fabsf128 => self.float_abs_intrinsic::(args, dest)?, + sym::fabs => { + let arg = self.read_immediate(&args[0])?; + let ty::Float(float_ty) = arg.layout.ty.kind() else { + span_bug!( + self.cur_span(), + "non-float type for float intrinsic: {}", + arg.layout.ty, + ); + }; + let out_val = match float_ty { + FloatTy::F16 => self.unop_float_intrinsic::(intrinsic_name, arg)?, + FloatTy::F32 => self.unop_float_intrinsic::(intrinsic_name, arg)?, + FloatTy::F64 => self.unop_float_intrinsic::(intrinsic_name, arg)?, + FloatTy::F128 => self.unop_float_intrinsic::(intrinsic_name, arg)?, + }; + self.write_scalar(out_val, dest)?; + } sym::floorf16 => self.float_round_intrinsic::( args, @@ -1020,6 +1033,22 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { interp_ok(Scalar::from_bool(lhs_bytes == rhs_bytes)) } + fn unop_float_intrinsic( + &self, + name: Symbol, + arg: ImmTy<'tcx, M::Provenance>, + ) -> InterpResult<'tcx, Scalar> + where + F: rustc_apfloat::Float + rustc_apfloat::FloatConvert + Into>, + { + let x: F = arg.to_scalar().to_float()?; + match name { + // bitwise, no NaN adjustments + sym::fabs => interp_ok(x.abs().into()), + _ => bug!("not a unary float intrinsic: {}", name), + } + } + fn float_minmax( &self, a: Scalar, @@ -1078,20 +1107,6 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { interp_ok(()) } - fn float_abs_intrinsic( - &mut self, - args: &[OpTy<'tcx, M::Provenance>], - dest: &PlaceTy<'tcx, M::Provenance>, - ) -> InterpResult<'tcx, ()> - where - F: rustc_apfloat::Float + rustc_apfloat::FloatConvert + Into>, - { - let x: F = self.read_scalar(&args[0])?.to_float()?; - // bitwise, no NaN adjustments - self.write_scalar(x.abs(), dest)?; - interp_ok(()) - } - fn float_round( &mut self, x: Scalar, diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index 47420997a509a..e7cb6d2ba1645 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -111,10 +111,7 @@ fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -> hi | sym::expf32 | sym::expf64 | sym::expf128 - | sym::fabsf16 - | sym::fabsf32 - | sym::fabsf64 - | sym::fabsf128 + | sym::fabs | sym::fadd_algebraic | sym::fdiv_algebraic | sym::field_offset @@ -463,10 +460,7 @@ pub(crate) fn check_intrinsic_type( (0, 0, vec![tcx.types.f128, tcx.types.f128, tcx.types.f128], tcx.types.f128) } - sym::fabsf16 => (0, 0, vec![tcx.types.f16], tcx.types.f16), - sym::fabsf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32), - sym::fabsf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64), - sym::fabsf128 => (0, 0, vec![tcx.types.f128], tcx.types.f128), + sym::fabs => (1, 0, vec![param(0)], param(0)), sym::minimum_number_nsz_f16 => (0, 0, vec![tcx.types.f16, tcx.types.f16], tcx.types.f16), sym::minimum_number_nsz_f32 => (0, 0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32), diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 26ced79b822ac..eb95d3a0d9059 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -914,10 +914,7 @@ symbols! { f64_nan, f128, f128_nan, - fabsf16, - fabsf32, - fabsf64, - fabsf128, + fabs, fadd_algebraic, fadd_fast, fake_variadic, diff --git a/library/core/src/intrinsics/bounds.rs b/library/core/src/intrinsics/bounds.rs index 353908598d40b..21705005ed0ae 100644 --- a/library/core/src/intrinsics/bounds.rs +++ b/library/core/src/intrinsics/bounds.rs @@ -39,3 +39,14 @@ impl ChangePointee for *mut T { impl ChangePointee for *const T { type Output = *const U; } + +/// Built-in float types (f16, f32, f64 and f128). +/// +/// # Safety +/// Must actually *be* such a type. +pub unsafe trait FloatPrimitive: Sized + Copy {} + +unsafe impl FloatPrimitive for f16 {} +unsafe impl FloatPrimitive for f32 {} +unsafe impl FloatPrimitive for f64 {} +unsafe impl FloatPrimitive for f128 {} diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index 68e4f1c2aa787..a5c7cf76622d8 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -1573,7 +1573,7 @@ pub const fn roundf128(x: f128) -> f128; /// This intrinsic does not have a stable counterpart. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn fadd_fast(a: T, b: T) -> T; +pub unsafe fn fadd_fast(a: T, b: T) -> T; /// Float subtraction that allows optimizations based on algebraic rules. /// Requires that inputs and output of the operation are finite, causing UB otherwise. @@ -1581,7 +1581,7 @@ pub unsafe fn fadd_fast(a: T, b: T) -> T; /// This intrinsic does not have a stable counterpart. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn fsub_fast(a: T, b: T) -> T; +pub unsafe fn fsub_fast(a: T, b: T) -> T; /// Float multiplication that allows optimizations based on algebraic rules. /// Requires that inputs and output of the operation are finite, causing UB otherwise. @@ -1589,7 +1589,7 @@ pub unsafe fn fsub_fast(a: T, b: T) -> T; /// This intrinsic does not have a stable counterpart. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn fmul_fast(a: T, b: T) -> T; +pub unsafe fn fmul_fast(a: T, b: T) -> T; /// Float division that allows optimizations based on algebraic rules. /// Requires that inputs and output of the operation are finite, causing UB otherwise. @@ -1597,7 +1597,7 @@ pub unsafe fn fmul_fast(a: T, b: T) -> T; /// This intrinsic does not have a stable counterpart. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn fdiv_fast(a: T, b: T) -> T; +pub unsafe fn fdiv_fast(a: T, b: T) -> T; /// Float remainder that allows optimizations based on algebraic rules. /// Requires that inputs and output of the operation are finite, causing UB otherwise. @@ -1605,7 +1605,7 @@ pub unsafe fn fdiv_fast(a: T, b: T) -> T; /// This intrinsic does not have a stable counterpart. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn frem_fast(a: T, b: T) -> T; +pub unsafe fn frem_fast(a: T, b: T) -> T; /// Converts with LLVM’s fptoui/fptosi, which may return undef for values out of range /// () @@ -1613,42 +1613,43 @@ pub unsafe fn frem_fast(a: T, b: T) -> T; /// Stabilized as [`f32::to_int_unchecked`] and [`f64::to_int_unchecked`]. #[rustc_intrinsic] #[rustc_nounwind] -pub unsafe fn float_to_int_unchecked(value: Float) -> Int; +pub unsafe fn float_to_int_unchecked(value: Float) +-> Int; /// Float addition that allows optimizations based on algebraic rules. /// /// Stabilized as [`f16::algebraic_add`], [`f32::algebraic_add`], [`f64::algebraic_add`] and [`f128::algebraic_add`]. #[rustc_nounwind] #[rustc_intrinsic] -pub const fn fadd_algebraic(a: T, b: T) -> T; +pub const fn fadd_algebraic(a: T, b: T) -> T; /// Float subtraction that allows optimizations based on algebraic rules. /// /// Stabilized as [`f16::algebraic_sub`], [`f32::algebraic_sub`], [`f64::algebraic_sub`] and [`f128::algebraic_sub`]. #[rustc_nounwind] #[rustc_intrinsic] -pub const fn fsub_algebraic(a: T, b: T) -> T; +pub const fn fsub_algebraic(a: T, b: T) -> T; /// Float multiplication that allows optimizations based on algebraic rules. /// /// Stabilized as [`f16::algebraic_mul`], [`f32::algebraic_mul`], [`f64::algebraic_mul`] and [`f128::algebraic_mul`]. #[rustc_nounwind] #[rustc_intrinsic] -pub const fn fmul_algebraic(a: T, b: T) -> T; +pub const fn fmul_algebraic(a: T, b: T) -> T; /// Float division that allows optimizations based on algebraic rules. /// /// Stabilized as [`f16::algebraic_div`], [`f32::algebraic_div`], [`f64::algebraic_div`] and [`f128::algebraic_div`]. #[rustc_nounwind] #[rustc_intrinsic] -pub const fn fdiv_algebraic(a: T, b: T) -> T; +pub const fn fdiv_algebraic(a: T, b: T) -> T; /// Float remainder that allows optimizations based on algebraic rules. /// /// Stabilized as [`f16::algebraic_rem`], [`f32::algebraic_rem`], [`f64::algebraic_rem`] and [`f128::algebraic_rem`]. #[rustc_nounwind] #[rustc_intrinsic] -pub const fn frem_algebraic(a: T, b: T) -> T; +pub const fn frem_algebraic(a: T, b: T) -> T; /// Returns the number of bits set in an integer type `T` /// @@ -3385,39 +3386,14 @@ pub const fn maximumf128(x: f128, y: f128) -> f128 { } } -/// Returns the absolute value of an `f16`. +/// Returns the absolute value of a floating-point value. /// -/// The stabilized version of this intrinsic is -/// [`f16::abs`](../../std/primitive.f16.html#method.abs) -#[rustc_nounwind] -#[rustc_intrinsic] -pub const fn fabsf16(x: f16) -> f16; - -/// Returns the absolute value of an `f32`. -/// -/// The stabilized version of this intrinsic is -/// [`f32::abs`](../../std/primitive.f32.html#method.abs) +/// The stabilized versions of this intrinsic are available on the float +/// primitives via the `abs` method. For example, [`f32::abs`]. #[rustc_nounwind] #[rustc_intrinsic_const_stable_indirect] #[rustc_intrinsic] -pub const fn fabsf32(x: f32) -> f32; - -/// Returns the absolute value of an `f64`. -/// -/// The stabilized version of this intrinsic is -/// [`f64::abs`](../../std/primitive.f64.html#method.abs) -#[rustc_nounwind] -#[rustc_intrinsic_const_stable_indirect] -#[rustc_intrinsic] -pub const fn fabsf64(x: f64) -> f64; - -/// Returns the absolute value of an `f128`. -/// -/// The stabilized version of this intrinsic is -/// [`f128::abs`](../../std/primitive.f128.html#method.abs) -#[rustc_nounwind] -#[rustc_intrinsic] -pub const fn fabsf128(x: f128) -> f128; +pub const fn fabs(x: T) -> T; /// Copies the sign from `y` to `x` for `f16` values. /// diff --git a/library/core/src/num/f128.rs b/library/core/src/num/f128.rs index 68c87b48de94d..d833653fdba65 100644 --- a/library/core/src/num/f128.rs +++ b/library/core/src/num/f128.rs @@ -1409,7 +1409,7 @@ impl f128 { #[rustc_const_unstable(feature = "f128", issue = "116909")] #[must_use = "method returns a new number and does not mutate the original value"] pub const fn abs(self) -> Self { - intrinsics::fabsf128(self) + intrinsics::fabs(self) } /// Returns a number that represents the sign of `self`. diff --git a/library/core/src/num/f16.rs b/library/core/src/num/f16.rs index 3412e49c49cd0..b0664abcdc739 100644 --- a/library/core/src/num/f16.rs +++ b/library/core/src/num/f16.rs @@ -1393,7 +1393,7 @@ impl f16 { #[rustc_const_unstable(feature = "f16", issue = "116909")] #[must_use = "method returns a new number and does not mutate the original value"] pub const fn abs(self) -> Self { - intrinsics::fabsf16(self) + intrinsics::fabs(self) } /// Returns a number that represents the sign of `self`. diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs index e33cb098e4e8d..b85bd2b271588 100644 --- a/library/core/src/num/f32.rs +++ b/library/core/src/num/f32.rs @@ -1568,7 +1568,7 @@ impl f32 { #[rustc_const_stable(feature = "const_float_methods", since = "1.85.0")] #[inline] pub const fn abs(self) -> f32 { - intrinsics::fabsf32(self) + intrinsics::fabs(self) } /// Returns a number that represents the sign of `self`. diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs index 872f567efafdc..3e7c1e792ace6 100644 --- a/library/core/src/num/f64.rs +++ b/library/core/src/num/f64.rs @@ -1566,7 +1566,7 @@ impl f64 { #[rustc_const_stable(feature = "const_float_methods", since = "1.85.0")] #[inline] pub const fn abs(self) -> f64 { - intrinsics::fabsf64(self) + intrinsics::fabs(self) } /// Returns a number that represents the sign of `self`. diff --git a/tests/ui/intrinsics/bad-intrinsic-monomorphization-float.rs b/tests/ui/intrinsics/bad-intrinsic-monomorphization-float.rs new file mode 100644 index 0000000000000..6a32cd97c50b7 --- /dev/null +++ b/tests/ui/intrinsics/bad-intrinsic-monomorphization-float.rs @@ -0,0 +1,18 @@ +//@ check-fail + +#![feature(repr_simd, intrinsics, core_intrinsics)] +#![allow(warnings)] +#![crate_type = "rlib"] + +// Bad monomorphizations could previously cause LLVM asserts even though the +// error was caught in the compiler. + +use std::intrinsics; + +#[derive(Copy, Clone)] +pub struct Foo(i64); + +pub unsafe fn test_fadd_fast(a: Foo, b: Foo) -> Foo { + intrinsics::fadd_fast(a, b) + //~^ ERROR the trait bound `Foo: intrinsics::bounds::FloatPrimitive` is not satisfied +} diff --git a/tests/ui/intrinsics/bad-intrinsic-monomorphization-float.stderr b/tests/ui/intrinsics/bad-intrinsic-monomorphization-float.stderr new file mode 100644 index 0000000000000..284e21b3fd2df --- /dev/null +++ b/tests/ui/intrinsics/bad-intrinsic-monomorphization-float.stderr @@ -0,0 +1,30 @@ +error[E0277]: the trait bound `Foo: intrinsics::bounds::FloatPrimitive` is not satisfied + --> $DIR/bad-intrinsic-monomorphization-float.rs:16:5 + | +LL | intrinsics::fadd_fast(a, b) + | ^^^^^^^^^^^^^^^^^^^^^ unsatisfied trait bound + | +help: the nightly-only, unstable trait `intrinsics::bounds::FloatPrimitive` is not implemented for `Foo` + --> $DIR/bad-intrinsic-monomorphization-float.rs:13:1 + | +LL | pub struct Foo(i64); + | ^^^^^^^^^^^^^^ +help: the following other types implement trait `intrinsics::bounds::FloatPrimitive` + --> $SRC_DIR/core/src/intrinsics/bounds.rs:LL:COL + | + = note: `f16` + ::: $SRC_DIR/core/src/intrinsics/bounds.rs:LL:COL + | + = note: `f32` + ::: $SRC_DIR/core/src/intrinsics/bounds.rs:LL:COL + | + = note: `f64` + ::: $SRC_DIR/core/src/intrinsics/bounds.rs:LL:COL + | + = note: `f128` +note: required by a bound in `fadd_fast` + --> $SRC_DIR/core/src/intrinsics/mod.rs:LL:COL + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/intrinsics/bad-intrinsic-monomorphization.rs b/tests/ui/intrinsics/bad-intrinsic-monomorphization.rs index d68cbf26ef110..8849ed2a67add 100644 --- a/tests/ui/intrinsics/bad-intrinsic-monomorphization.rs +++ b/tests/ui/intrinsics/bad-intrinsic-monomorphization.rs @@ -17,11 +17,6 @@ pub fn test_cttz(v: Foo) -> u32 { //~^ ERROR `cttz` intrinsic: expected basic integer type, found `Foo` } -pub unsafe fn test_fadd_fast(a: Foo, b: Foo) -> Foo { - intrinsics::fadd_fast(a, b) - //~^ ERROR `fadd_fast` intrinsic: expected basic float type, found `Foo` -} - pub unsafe fn test_simd_add(a: Foo, b: Foo) -> Foo { intrinsics::simd::simd_add(a, b) //~^ ERROR `simd_add` intrinsic: expected SIMD input type, found non-SIMD `Foo` diff --git a/tests/ui/intrinsics/bad-intrinsic-monomorphization.stderr b/tests/ui/intrinsics/bad-intrinsic-monomorphization.stderr index 51ef71c9e2988..329bf214c03d7 100644 --- a/tests/ui/intrinsics/bad-intrinsic-monomorphization.stderr +++ b/tests/ui/intrinsics/bad-intrinsic-monomorphization.stderr @@ -1,21 +1,15 @@ error[E0511]: invalid monomorphization of `simd_add` intrinsic: expected SIMD input type, found non-SIMD `Foo` - --> $DIR/bad-intrinsic-monomorphization.rs:26:5 + --> $DIR/bad-intrinsic-monomorphization.rs:21:5 | LL | intrinsics::simd::simd_add(a, b) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0511]: invalid monomorphization of `fadd_fast` intrinsic: expected basic float type, found `Foo` - --> $DIR/bad-intrinsic-monomorphization.rs:21:5 - | -LL | intrinsics::fadd_fast(a, b) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - error[E0511]: invalid monomorphization of `cttz` intrinsic: expected basic integer type, found `Foo` --> $DIR/bad-intrinsic-monomorphization.rs:16:5 | LL | intrinsics::cttz(v) | ^^^^^^^^^^^^^^^^^^^ -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0511`. diff --git a/tests/ui/resolve/filter-intrinsics.rs b/tests/ui/resolve/filter-intrinsics.rs index 8d6d22817dc5c..9998bec1ad4fe 100644 --- a/tests/ui/resolve/filter-intrinsics.rs +++ b/tests/ui/resolve/filter-intrinsics.rs @@ -3,8 +3,8 @@ fn main() { let _ = transmute::(); //~^ ERROR cannot find - // Should suggest `std::intrinsics::fabsf64`, + // Should suggest `std::intrinsics::fabs`, // since there is no non-intrinsic to suggest. - let _ = fabsf64(1.0); + let _ = fabs(1.0); //~^ ERROR cannot find } diff --git a/tests/ui/resolve/filter-intrinsics.stderr b/tests/ui/resolve/filter-intrinsics.stderr index 9c9e92f6d4f83..3870cfcb1080a 100644 --- a/tests/ui/resolve/filter-intrinsics.stderr +++ b/tests/ui/resolve/filter-intrinsics.stderr @@ -9,15 +9,15 @@ help: consider importing this function LL + use std::mem::transmute; | -error[E0425]: cannot find function `fabsf64` in this scope +error[E0425]: cannot find function `fabs` in this scope --> $DIR/filter-intrinsics.rs:8:13 | -LL | let _ = fabsf64(1.0); - | ^^^^^^^ not found in this scope +LL | let _ = fabs(1.0); + | ^^^^ not found in this scope | help: consider importing this function | -LL + use std::intrinsics::fabsf64; +LL + use std::intrinsics::fabs; | error: aborting due to 2 previous errors From e21ccc5a49ead2af99faef46e22502831a2a55d8 Mon Sep 17 00:00:00 2001 From: N1ark Date: Sat, 14 Mar 2026 12:54:21 +0000 Subject: [PATCH 2/7] Remove `InvalidMonomorphization::FloatingPointType` --- compiler/rustc_codegen_gcc/src/intrinsic/simd.rs | 2 +- compiler/rustc_codegen_llvm/src/intrinsic.rs | 2 +- compiler/rustc_codegen_ssa/src/errors.rs | 8 -------- 3 files changed, 2 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs b/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs index 1263b2285a8d0..1900572eee7d3 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs +++ b/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs @@ -811,7 +811,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( }}; } let ty::Float(ref f) = *in_elem.kind() else { - return_error!(InvalidMonomorphization::FloatingPointType { span, name, in_ty }); + return_error!(InvalidMonomorphization::BasicFloatType { span, name, ty: in_ty }); }; let elem_ty = bx.cx.type_float_from_ty(*f); let (elem_ty_str, elem_ty, cast_type) = match f.bit_width() { diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 1dd1a021c25f3..d04892e28759f 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -1946,7 +1946,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>( } let ty::Float(f) = in_elem.kind() else { - return_error!(InvalidMonomorphization::FloatingPointType { span, name, in_ty }); + return_error!(InvalidMonomorphization::BasicFloatType { span, name, ty: in_ty }); }; let elem_ty = bx.cx.type_float_from_ty(*f); diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index 41337fc21a7b7..fad776d249e0e 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -739,14 +739,6 @@ pub enum InvalidMonomorphization<'tcx> { in_ty: Ty<'tcx>, }, - #[diag("invalid monomorphization of `{$name}` intrinsic: `{$in_ty}` is not a floating-point type", code = E0511)] - FloatingPointType { - #[primary_span] - span: Span, - name: Symbol, - in_ty: Ty<'tcx>, - }, - #[diag("invalid monomorphization of `{$name}` intrinsic: unrecognized intrinsic `{$name}`", code = E0511)] UnrecognizedIntrinsic { #[primary_span] From 169716f486dbf8145432e4a160a64e3ce0c34f76 Mon Sep 17 00:00:00 2001 From: N1ark Date: Sun, 15 Mar 2026 18:12:54 +0000 Subject: [PATCH 3/7] Cleanup cranelift float intrinsics handling --- .../src/intrinsics/mod.rs | 59 +++++-------------- 1 file changed, 16 insertions(+), 43 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs index 79d8835072ae8..2004de742a211 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs @@ -421,45 +421,19 @@ fn codegen_float_intrinsic_call<'tcx>( let layout = fx.layout_of(ty); // FIXME(bytecodealliance/wasmtime#8312): Use native Cranelift operations // for `f16` and `f128` once the lowerings have been implemented in Cranelift. - let res = match intrinsic { - sym::fmaf16 | sym::fmuladdf16 => { - CValue::by_val(codegen_f16_f128::fma_f16(fx, args[0], args[1], args[2]), layout) - } + let val = match intrinsic { + sym::fmaf16 | sym::fmuladdf16 => codegen_f16_f128::fma_f16(fx, args[0], args[1], args[2]), sym::fmaf32 | sym::fmaf64 | sym::fmuladdf32 | sym::fmuladdf64 => { - CValue::by_val(fx.bcx.ins().fma(args[0], args[1], args[2]), layout) - } - sym::copysignf16 => { - CValue::by_val(codegen_f16_f128::copysign_f16(fx, args[0], args[1]), layout) - } - sym::copysignf128 => { - CValue::by_val(codegen_f16_f128::copysign_f128(fx, args[0], args[1]), layout) - } - sym::copysignf32 | sym::copysignf64 => { - CValue::by_val(fx.bcx.ins().fcopysign(args[0], args[1]), layout) - } - sym::floorf32 - | sym::floorf64 - | sym::ceilf32 - | sym::ceilf64 - | sym::truncf32 - | sym::truncf64 - | sym::round_ties_even_f32 - | sym::round_ties_even_f64 - | sym::sqrtf32 - | sym::sqrtf64 => { - let val = match intrinsic { - sym::floorf32 | sym::floorf64 => fx.bcx.ins().floor(args[0]), - sym::ceilf32 | sym::ceilf64 => fx.bcx.ins().ceil(args[0]), - sym::truncf32 | sym::truncf64 => fx.bcx.ins().trunc(args[0]), - sym::round_ties_even_f32 | sym::round_ties_even_f64 => { - fx.bcx.ins().nearest(args[0]) - } - sym::sqrtf32 | sym::sqrtf64 => fx.bcx.ins().sqrt(args[0]), - _ => unreachable!(), - }; - - CValue::by_val(val, layout) + fx.bcx.ins().fma(args[0], args[1], args[2]) } + sym::copysignf16 => codegen_f16_f128::copysign_f16(fx, args[0], args[1]), + sym::copysignf128 => codegen_f16_f128::copysign_f128(fx, args[0], args[1]), + sym::copysignf32 | sym::copysignf64 => fx.bcx.ins().fcopysign(args[0], args[1]), + sym::floorf32 | sym::floorf64 => fx.bcx.ins().floor(args[0]), + sym::ceilf32 | sym::ceilf64 => fx.bcx.ins().ceil(args[0]), + sym::truncf32 | sym::truncf64 => fx.bcx.ins().trunc(args[0]), + sym::round_ties_even_f32 | sym::round_ties_even_f64 => fx.bcx.ins().nearest(args[0]), + sym::sqrtf32 | sym::sqrtf64 => fx.bcx.ins().sqrt(args[0]), // These intrinsics aren't supported natively by Cranelift. // Lower them to a libcall. @@ -474,12 +448,11 @@ fn codegen_float_intrinsic_call<'tcx>( let input_tys: Vec<_> = vec![AbiParam::new(clif_ty), lib_call_arg_param(fx.tcx, types::I32, true)]; let ret_val = fx.lib_call(name, input_tys, vec![AbiParam::new(clif_ty)], args)[0]; - let ret_val = if intrinsic == sym::powif16 { + if intrinsic == sym::powif16 { codegen_f16_f128::f32_to_f16(fx, ret_val) } else { ret_val - }; - CValue::by_val(ret_val, fx.layout_of(ty)) + } } sym::powf16 => { // FIXME(f16_f128): Rust `compiler-builtins` doesn't export `powf16` yet. @@ -491,15 +464,15 @@ fn codegen_float_intrinsic_call<'tcx>( vec![AbiParam::new(types::F32)], &[x, y], )[0]; - CValue::by_val(codegen_f16_f128::f32_to_f16(fx, ret_val), fx.layout_of(ty)) + codegen_f16_f128::f32_to_f16(fx, ret_val) } _ => { let input_tys: Vec<_> = args.iter().map(|_| AbiParam::new(clif_ty)).collect(); - let ret_val = fx.lib_call(name, input_tys, vec![AbiParam::new(clif_ty)], args)[0]; - CValue::by_val(ret_val, fx.layout_of(ty)) + fx.lib_call(name, input_tys, vec![AbiParam::new(clif_ty)], args)[0] } }; + let res = CValue::by_val(val, layout); ret.write_cvalue(fx, res); true From 477f9e4f77580dda393688465501c6d9dfc0788b Mon Sep 17 00:00:00 2001 From: N1ark Date: Mon, 16 Mar 2026 00:17:04 +0000 Subject: [PATCH 4/7] Genericize ceil, floor, trunc, round, round_ties_even --- .../src/intrinsics/mod.rs | 69 +++---- .../rustc_codegen_gcc/src/intrinsic/mod.rs | 137 ++++++++------ compiler/rustc_codegen_llvm/src/intrinsic.rs | 50 ++---- .../src/interpret/intrinsics.rs | 122 +------------ .../src/interpret/intrinsics/simd.rs | 8 +- .../rustc_hir_analysis/src/check/intrinsic.rs | 52 +----- compiler/rustc_span/src/symbol.rs | 25 +-- library/core/src/intrinsics/mod.rs | 169 +++--------------- library/core/src/num/f128.rs | 10 +- library/core/src/num/f16.rs | 10 +- library/core/src/num/f32.rs | 10 +- library/core/src/num/f64.rs | 10 +- .../core_arch/src/aarch64/neon/generated.rs | 10 +- tests/ui/intrinsics/reify-intrinsic.rs | 2 +- tests/ui/intrinsics/reify-intrinsic.stderr | 8 +- 15 files changed, 220 insertions(+), 472 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs index 2004de742a211..f057e1afffbb8 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs @@ -359,26 +359,6 @@ fn codegen_float_intrinsic_call<'tcx>( sym::copysignf32 => ("copysignf", 2, fx.tcx.types.f32, types::F32), sym::copysignf64 => ("copysign", 2, fx.tcx.types.f64, types::F64), sym::copysignf128 => ("copysignf128", 2, fx.tcx.types.f128, types::F128), - sym::floorf16 => ("floorf16", 1, fx.tcx.types.f16, types::F16), - sym::floorf32 => ("floorf", 1, fx.tcx.types.f32, types::F32), - sym::floorf64 => ("floor", 1, fx.tcx.types.f64, types::F64), - sym::floorf128 => ("floorf128", 1, fx.tcx.types.f128, types::F128), - sym::ceilf16 => ("ceilf16", 1, fx.tcx.types.f16, types::F16), - sym::ceilf32 => ("ceilf", 1, fx.tcx.types.f32, types::F32), - sym::ceilf64 => ("ceil", 1, fx.tcx.types.f64, types::F64), - sym::ceilf128 => ("ceilf128", 1, fx.tcx.types.f128, types::F128), - sym::truncf16 => ("truncf16", 1, fx.tcx.types.f16, types::F16), - sym::truncf32 => ("truncf", 1, fx.tcx.types.f32, types::F32), - sym::truncf64 => ("trunc", 1, fx.tcx.types.f64, types::F64), - sym::truncf128 => ("truncf128", 1, fx.tcx.types.f128, types::F128), - sym::round_ties_even_f16 => ("rintf16", 1, fx.tcx.types.f16, types::F16), - sym::round_ties_even_f32 => ("rintf", 1, fx.tcx.types.f32, types::F32), - sym::round_ties_even_f64 => ("rint", 1, fx.tcx.types.f64, types::F64), - sym::round_ties_even_f128 => ("rintf128", 1, fx.tcx.types.f128, types::F128), - sym::roundf16 => ("roundf16", 1, fx.tcx.types.f16, types::F16), - sym::roundf32 => ("roundf", 1, fx.tcx.types.f32, types::F32), - sym::roundf64 => ("round", 1, fx.tcx.types.f64, types::F64), - sym::roundf128 => ("roundf128", 1, fx.tcx.types.f128, types::F128), sym::sinf16 => ("sinf16", 1, fx.tcx.types.f16, types::F16), sym::sinf32 => ("sinf", 1, fx.tcx.types.f32, types::F32), sym::sinf64 => ("sin", 1, fx.tcx.types.f64, types::F64), @@ -429,10 +409,6 @@ fn codegen_float_intrinsic_call<'tcx>( sym::copysignf16 => codegen_f16_f128::copysign_f16(fx, args[0], args[1]), sym::copysignf128 => codegen_f16_f128::copysign_f128(fx, args[0], args[1]), sym::copysignf32 | sym::copysignf64 => fx.bcx.ins().fcopysign(args[0], args[1]), - sym::floorf32 | sym::floorf64 => fx.bcx.ins().floor(args[0]), - sym::ceilf32 | sym::ceilf64 => fx.bcx.ins().ceil(args[0]), - sym::truncf32 | sym::truncf64 => fx.bcx.ins().trunc(args[0]), - sym::round_ties_even_f32 | sym::round_ties_even_f64 => fx.bcx.ins().nearest(args[0]), sym::sqrtf32 | sym::sqrtf64 => fx.bcx.ins().sqrt(args[0]), // These intrinsics aren't supported natively by Cranelift. @@ -1143,20 +1119,53 @@ fn codegen_regular_intrinsic_call<'tcx>( ret.write_cvalue(fx, old); } - sym::fabs => { + // Float unop intrinsics + sym::fabs + | sym::floor + | sym::ceil + | sym::trunc + | sym::round_ties_even + | sym::round => { intrinsic_args!(fx, args => (arg); intrinsic); let layout = arg.layout(); let ty::Float(float_ty) = layout.ty.kind() else { - bug!("expected float type for fabs intrinsic: {:?}", layout.ty); + bug!( + "expected float type for float unop intrinsic {:?}: {:?}", + intrinsic, + layout.ty + ); }; let x = arg.load_scalar(fx); - let val = match float_ty { - FloatTy::F32 | FloatTy::F64 => fx.bcx.ins().fabs(x), + + use FloatTy::*; + let val = match (intrinsic, float_ty) { + (sym::fabs, F32 | F64) => Ok(fx.bcx.ins().fabs(x)), // FIXME(bytecodealliance/wasmtime#8312): Use `fabsf16` once Cranelift // backend lowerings are implemented. - FloatTy::F16 => codegen_f16_f128::abs_f16(fx, x), - FloatTy::F128 => codegen_f16_f128::abs_f128(fx, x), + (sym::fabs, F16) => Ok(codegen_f16_f128::abs_f16(fx, x)), + (sym::fabs, F128) => Ok(codegen_f16_f128::abs_f128(fx, x)), + (sym::floor, F32 | F64) => Ok(fx.bcx.ins().floor(x)), + (sym::floor, F16) => Err("floorf16"), + (sym::floor, F128) => Err("floorf128"), + (sym::ceil, F32 | F64) => Ok(fx.bcx.ins().ceil(x)), + (sym::ceil, F16) => Err("ceilf16"), + (sym::ceil, F128) => Err("ceilf128"), + (sym::trunc, F32 | F64) => Ok(fx.bcx.ins().trunc(x)), + (sym::trunc, F16) => Err("truncf16"), + (sym::trunc, F128) => Err("truncf128"), + (sym::round_ties_even, F32 | F64) => Ok(fx.bcx.ins().nearest(x)), + (sym::round_ties_even, F16) => Err("rintf16"), + (sym::round_ties_even, F128) => Err("rintf128"), + (sym::round, F16) => Err("roundf16"), + (sym::round, F32) => Err("roundf"), + (sym::round, F64) => Err("round"), + (sym::round, F128) => Err("roundf128"), + _ => unreachable!(), }; + let val = val.unwrap_or_else(|name| { + let ty = fx.clif_type(layout.ty).unwrap(); + fx.lib_call(name, vec![AbiParam::new(ty)], vec![AbiParam::new(ty)], &[x])[0] + }); let val = CValue::by_val(val, layout); ret.write_cvalue(fx, val); } diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs index f3a7ac3b4c0fa..3a4de89c9231d 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs +++ b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs @@ -108,17 +108,6 @@ fn get_simple_intrinsic<'gcc, 'tcx>( } sym::copysignf32 => "copysignf", sym::copysignf64 => "copysign", - sym::floorf32 => "floorf", - sym::floorf64 => "floor", - sym::ceilf32 => "ceilf", - sym::ceilf64 => "ceil", - sym::truncf32 => "truncf", - sym::truncf64 => "trunc", - // We match the LLVM backend and lower this to `rint`. - sym::round_ties_even_f32 => "rintf", - sym::round_ties_even_f64 => "rint", - sym::roundf32 => "roundf", - sym::roundf64 => "round", sym::abort => "abort", _ => return None, }; @@ -197,12 +186,6 @@ fn get_simple_function_f128<'gcc, 'tcx>( ) -> Function<'gcc> { let f128_type = cx.type_f128(); let func_name = match name { - sym::ceilf128 => "ceilf128", - sym::fabs => "fabsf128", - sym::floorf128 => "floorf128", - sym::truncf128 => "truncf128", - sym::roundf128 => "roundf128", - sym::round_ties_even_f128 => "roundevenf128", sym::sqrtf128 => "sqrtf128", _ => unreachable!(), }; @@ -223,10 +206,7 @@ fn f16_builtin<'gcc, 'tcx>( ) -> RValue<'gcc> { let f32_type = cx.type_f32(); let builtin_name = match name { - sym::ceilf16 => "__builtin_ceilf", sym::copysignf16 => "__builtin_copysignf", - sym::fabs => "fabsf", - sym::floorf16 => "__builtin_floorf", sym::fmaf16 => "fmaf", sym::powf16 => "__builtin_powf", sym::powif16 => { @@ -236,10 +216,7 @@ fn f16_builtin<'gcc, 'tcx>( let result = cx.context.new_call(None, func, &args); return cx.context.new_cast(None, result, cx.type_f16()); } - sym::roundf16 => "__builtin_roundf", - sym::round_ties_even_f16 => "__builtin_rintf", sym::sqrtf16 => "__builtin_sqrtf", - sym::truncf16 => "__builtin_truncf", _ => unreachable!(), }; @@ -284,24 +261,10 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc &args.iter().map(|arg| arg.immediate()).collect::>(), ) } - sym::ceilf16 - | sym::copysignf16 - | sym::floorf16 - | sym::fmaf16 - | sym::powf16 - | sym::powif16 - | sym::roundf16 - | sym::round_ties_even_f16 - | sym::sqrtf16 - | sym::truncf16 => f16_builtin(self, name, args), - sym::ceilf128 - | sym::floorf128 - | sym::truncf128 - | sym::roundf128 - | sym::round_ties_even_f128 - | sym::sqrtf128 - if self.cx.supports_f128_type => - { + sym::copysignf16 | sym::fmaf16 | sym::powf16 | sym::powif16 | sym::sqrtf16 => { + f16_builtin(self, name, args) + } + sym::sqrtf128 if self.cx.supports_f128_type => { let func = get_simple_function_f128(self, name); self.cx.context.new_call( self.location, @@ -485,23 +448,93 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc } } } - sym::fabs => 'fabs: { + // float unary intrinsics + sym::fabs + | sym::floor + | sym::ceil + | sym::trunc + | sym::round_ties_even + | sym::round => { + enum IntrinsicKind { + Builtin(&'static str), + Extern(&'static str), + BuiltinF16Cast(&'static str), + Fallback, + } + use IntrinsicKind::*; let ty = args[0].layout.ty; let ty::Float(float_ty) = *ty.kind() else { tcx.dcx().emit_err(InvalidMonomorphization::BasicFloatType { span, name, ty }); return Ok(()); }; - let func = match float_ty { - ty::FloatTy::F16 => break 'fabs f16_builtin(self, name, args), - ty::FloatTy::F32 => self.context.get_builtin_function("fabsf"), - ty::FloatTy::F64 => self.context.get_builtin_function("fabs"), - ty::FloatTy::F128 => get_simple_function_f128(self, name), + + use ty::FloatTy::*; + let func = match (name, float_ty) { + (_, F128) if !self.cx.supports_f128_type => Fallback, + (sym::fabs, F16) => BuiltinF16Cast("fabsf"), + (sym::fabs, F32) => Builtin("fabsf"), + (sym::fabs, F64) => Builtin("fabs"), + (sym::fabs, F128) => Extern("fabsf128"), + (sym::floor, F16) => BuiltinF16Cast("__builtin_floorf"), + (sym::floor, F32) => Builtin("floorf"), + (sym::floor, F64) => Builtin("floor"), + (sym::floor, F128) => Extern("floorf128"), + (sym::ceil, F16) => BuiltinF16Cast("__builtin_ceilf"), + (sym::ceil, F32) => Builtin("ceilf"), + (sym::ceil, F64) => Builtin("ceil"), + (sym::ceil, F128) => Extern("ceilf128"), + (sym::trunc, F16) => BuiltinF16Cast("__builtin_truncf"), + (sym::trunc, F32) => Builtin("truncf"), + (sym::trunc, F64) => Builtin("trunc"), + (sym::trunc, F128) => Extern("truncf128"), + // We match the LLVM backend and lower this to `rint`. + (sym::round_ties_even, F16) => BuiltinF16Cast("__builtin_rintf"), + (sym::round_ties_even, F32) => Builtin("rintf"), + (sym::round_ties_even, F64) => Builtin("rint"), + (sym::round_ties_even, F128) => Extern("roundevenf128"), + (sym::round, F16) => BuiltinF16Cast("__builtin_roundf"), + (sym::round, F32) => Builtin("roundf"), + (sym::round, F64) => Builtin("round"), + (sym::round, F128) => Extern("roundf128"), + _ => Fallback, }; - self.cx.context.new_call( - self.location, - func, - &args.iter().map(|arg| arg.immediate()).collect::>(), - ) + match func { + Builtin(name) => self.cx.context.new_call( + self.location, + self.context.get_builtin_function(name), + &args.iter().map(|arg| arg.immediate()).collect::>(), + ), + Extern(name) => { + let ty = self.cx.type_float_from_ty(float_ty); + let func = self.cx.context.new_function( + None, + FunctionType::Extern, + ty, + &[self.cx.context.new_parameter(None, ty, "a")], + name, + false, + ); + self.cx.context.new_call( + self.location, + func, + &args.iter().map(|arg| arg.immediate()).collect::>(), + ) + } + BuiltinF16Cast(name) => { + let func = self.cx.context.get_builtin_function(name); + let args: Vec<_> = args + .iter() + .map(|arg| { + self.cx.context.new_cast(None, arg.immediate(), self.cx.type_f32()) + }) + .collect(); + let result = self.cx.context.new_call(None, func, &args); + self.cx.context.new_cast(None, result, self.cx.type_f16()) + } + Fallback => { + return Err(Instance::new_raw(instance.def_id(), instance.args)); + } + } } sym::raw_eq => { diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index d04892e28759f..fd8c56380c2ec 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -126,35 +126,6 @@ fn call_simple_intrinsic<'ll, 'tcx>( sym::copysignf64 => ("llvm.copysign", &[bx.type_f64()]), sym::copysignf128 => ("llvm.copysign", &[bx.type_f128()]), - sym::floorf16 => ("llvm.floor", &[bx.type_f16()]), - sym::floorf32 => ("llvm.floor", &[bx.type_f32()]), - sym::floorf64 => ("llvm.floor", &[bx.type_f64()]), - sym::floorf128 => ("llvm.floor", &[bx.type_f128()]), - - sym::ceilf16 => ("llvm.ceil", &[bx.type_f16()]), - sym::ceilf32 => ("llvm.ceil", &[bx.type_f32()]), - sym::ceilf64 => ("llvm.ceil", &[bx.type_f64()]), - sym::ceilf128 => ("llvm.ceil", &[bx.type_f128()]), - - sym::truncf16 => ("llvm.trunc", &[bx.type_f16()]), - sym::truncf32 => ("llvm.trunc", &[bx.type_f32()]), - sym::truncf64 => ("llvm.trunc", &[bx.type_f64()]), - sym::truncf128 => ("llvm.trunc", &[bx.type_f128()]), - - // We could use any of `rint`, `nearbyint`, or `roundeven` - // for this -- they are all identical in semantics when - // assuming the default FP environment. - // `rint` is what we used for $forever. - sym::round_ties_even_f16 => ("llvm.rint", &[bx.type_f16()]), - sym::round_ties_even_f32 => ("llvm.rint", &[bx.type_f32()]), - sym::round_ties_even_f64 => ("llvm.rint", &[bx.type_f64()]), - sym::round_ties_even_f128 => ("llvm.rint", &[bx.type_f128()]), - - sym::roundf16 => ("llvm.round", &[bx.type_f16()]), - sym::roundf32 => ("llvm.round", &[bx.type_f32()]), - sym::roundf64 => ("llvm.round", &[bx.type_f64()]), - sym::roundf128 => ("llvm.round", &[bx.type_f128()]), - _ => return None, }; Some(bx.call_intrinsic( @@ -497,14 +468,31 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { } } - sym::fabs => { + sym::fabs + | sym::floor + | sym::ceil + | sym::trunc + | sym::round_ties_even + | sym::round => { let ty = args[0].layout.ty; let ty::Float(f) = ty.kind() else { tcx.dcx().emit_err(InvalidMonomorphization::BasicFloatType { span, name, ty }); return Ok(()); }; let llty = self.type_float_from_ty(*f); - let llvm_name = "llvm.fabs"; + let llvm_name = match name { + sym::fabs => "llvm.fabs", + sym::floor => "llvm.floor", + sym::ceil => "llvm.ceil", + sym::trunc => "llvm.trunc", + // We could use any of `rint`, `nearbyint`, or `roundeven` + // for this -- they are all identical in semantics when + // assuming the default FP environment. + // `rint` is what we used for $forever. + sym::round_ties_even => "llvm.rint", + sym::round => "llvm.round", + _ => bug!(), + }; self.call_intrinsic( llvm_name, &[llty], diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index 17311188879c1..e2539739d1e8a 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -575,7 +575,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { sym::copysignf64 => self.float_copysign_intrinsic::(args, dest)?, sym::copysignf128 => self.float_copysign_intrinsic::(args, dest)?, - sym::fabs => { + sym::fabs | sym::floor | sym::ceil | sym::trunc | sym::round_ties_even | sym::round => { let arg = self.read_immediate(&args[0])?; let ty::Float(float_ty) = arg.layout.ty.kind() else { span_bug!( @@ -593,102 +593,6 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { self.write_scalar(out_val, dest)?; } - sym::floorf16 => self.float_round_intrinsic::( - args, - dest, - rustc_apfloat::Round::TowardNegative, - )?, - sym::floorf32 => self.float_round_intrinsic::( - args, - dest, - rustc_apfloat::Round::TowardNegative, - )?, - sym::floorf64 => self.float_round_intrinsic::( - args, - dest, - rustc_apfloat::Round::TowardNegative, - )?, - sym::floorf128 => self.float_round_intrinsic::( - args, - dest, - rustc_apfloat::Round::TowardNegative, - )?, - - sym::ceilf16 => self.float_round_intrinsic::( - args, - dest, - rustc_apfloat::Round::TowardPositive, - )?, - sym::ceilf32 => self.float_round_intrinsic::( - args, - dest, - rustc_apfloat::Round::TowardPositive, - )?, - sym::ceilf64 => self.float_round_intrinsic::( - args, - dest, - rustc_apfloat::Round::TowardPositive, - )?, - sym::ceilf128 => self.float_round_intrinsic::( - args, - dest, - rustc_apfloat::Round::TowardPositive, - )?, - - sym::truncf16 => { - self.float_round_intrinsic::(args, dest, rustc_apfloat::Round::TowardZero)? - } - sym::truncf32 => { - self.float_round_intrinsic::(args, dest, rustc_apfloat::Round::TowardZero)? - } - sym::truncf64 => { - self.float_round_intrinsic::(args, dest, rustc_apfloat::Round::TowardZero)? - } - sym::truncf128 => { - self.float_round_intrinsic::(args, dest, rustc_apfloat::Round::TowardZero)? - } - - sym::roundf16 => self.float_round_intrinsic::( - args, - dest, - rustc_apfloat::Round::NearestTiesToAway, - )?, - sym::roundf32 => self.float_round_intrinsic::( - args, - dest, - rustc_apfloat::Round::NearestTiesToAway, - )?, - sym::roundf64 => self.float_round_intrinsic::( - args, - dest, - rustc_apfloat::Round::NearestTiesToAway, - )?, - sym::roundf128 => self.float_round_intrinsic::( - args, - dest, - rustc_apfloat::Round::NearestTiesToAway, - )?, - - sym::round_ties_even_f16 => self.float_round_intrinsic::( - args, - dest, - rustc_apfloat::Round::NearestTiesToEven, - )?, - sym::round_ties_even_f32 => self.float_round_intrinsic::( - args, - dest, - rustc_apfloat::Round::NearestTiesToEven, - )?, - sym::round_ties_even_f64 => self.float_round_intrinsic::( - args, - dest, - rustc_apfloat::Round::NearestTiesToEven, - )?, - sym::round_ties_even_f128 => self.float_round_intrinsic::( - args, - dest, - rustc_apfloat::Round::NearestTiesToEven, - )?, sym::fmaf16 => self.float_muladd_intrinsic::(args, dest, MulAddType::Fused)?, sym::fmaf32 => self.float_muladd_intrinsic::(args, dest, MulAddType::Fused)?, sym::fmaf64 => self.float_muladd_intrinsic::(args, dest, MulAddType::Fused)?, @@ -1045,6 +949,11 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { match name { // bitwise, no NaN adjustments sym::fabs => interp_ok(x.abs().into()), + sym::floor => self.float_round(x, rustc_apfloat::Round::TowardNegative), + sym::ceil => self.float_round(x, rustc_apfloat::Round::TowardPositive), + sym::trunc => self.float_round(x, rustc_apfloat::Round::TowardZero), + sym::round_ties_even => self.float_round(x, rustc_apfloat::Round::NearestTiesToEven), + sym::round => self.float_round(x, rustc_apfloat::Round::NearestTiesToAway), _ => bug!("not a unary float intrinsic: {}", name), } } @@ -1108,33 +1017,18 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { } fn float_round( - &mut self, - x: Scalar, + &self, + x: F, mode: rustc_apfloat::Round, ) -> InterpResult<'tcx, Scalar> where F: rustc_apfloat::Float + rustc_apfloat::FloatConvert + Into>, { - let x: F = x.to_float()?; let res = x.round_to_integral(mode).value; let res = self.adjust_nan(res, &[x]); interp_ok(res.into()) } - fn float_round_intrinsic( - &mut self, - args: &[OpTy<'tcx, M::Provenance>], - dest: &PlaceTy<'tcx, M::Provenance>, - mode: rustc_apfloat::Round, - ) -> InterpResult<'tcx, ()> - where - F: rustc_apfloat::Float + rustc_apfloat::FloatConvert + Into>, - { - let res = self.float_round::(self.read_scalar(&args[0])?, mode)?; - self.write_scalar(res, dest)?; - interp_ok(()) - } - fn float_muladd( &self, a: Scalar, diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics/simd.rs b/compiler/rustc_const_eval/src/interpret/intrinsics/simd.rs index c47c512025c08..280b881b1777e 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics/simd.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics/simd.rs @@ -145,10 +145,10 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { }; let op = op.to_scalar(); match float_ty { - FloatTy::F16 => self.float_round::(op, rounding)?, - FloatTy::F32 => self.float_round::(op, rounding)?, - FloatTy::F64 => self.float_round::(op, rounding)?, - FloatTy::F128 => self.float_round::(op, rounding)?, + FloatTy::F16 => self.float_round(op.to_f16()?, rounding)?, + FloatTy::F32 => self.float_round(op.to_f32()?, rounding)?, + FloatTy::F64 => self.float_round(op.to_f64()?, rounding)?, + FloatTy::F128 => self.float_round(op.to_f128()?, rounding)?, } } Op::Numeric(name) => { diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index e7cb6d2ba1645..17405d29e9a7e 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -82,10 +82,7 @@ fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -> hi | sym::caller_location | sym::carrying_mul_add | sym::carryless_mul - | sym::ceilf16 - | sym::ceilf32 - | sym::ceilf64 - | sym::ceilf128 + | sym::ceil | sym::cold_path | sym::const_eval_select | sym::contract_check_ensures @@ -115,10 +112,7 @@ fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -> hi | sym::fadd_algebraic | sym::fdiv_algebraic | sym::field_offset - | sym::floorf16 - | sym::floorf32 - | sym::floorf64 - | sym::floorf128 + | sym::floor | sym::fmaf16 | sym::fmaf32 | sym::fmaf64 @@ -182,14 +176,8 @@ fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -> hi | sym::ptr_metadata | sym::rotate_left | sym::rotate_right - | sym::round_ties_even_f16 - | sym::round_ties_even_f32 - | sym::round_ties_even_f64 - | sym::round_ties_even_f128 - | sym::roundf16 - | sym::roundf32 - | sym::roundf64 - | sym::roundf128 + | sym::round + | sym::round_ties_even | sym::rustc_peek | sym::saturating_add | sym::saturating_sub @@ -205,10 +193,7 @@ fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -> hi | sym::sqrtf128 | sym::sub_with_overflow | sym::three_way_compare - | sym::truncf16 - | sym::truncf32 - | sym::truncf64 - | sym::truncf128 + | sym::trunc | sym::type_id | sym::type_id_eq | sym::type_id_vtable @@ -491,30 +476,9 @@ pub(crate) fn check_intrinsic_type( sym::copysignf64 => (0, 0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64), sym::copysignf128 => (0, 0, vec![tcx.types.f128, tcx.types.f128], tcx.types.f128), - sym::floorf16 => (0, 0, vec![tcx.types.f16], tcx.types.f16), - sym::floorf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32), - sym::floorf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64), - sym::floorf128 => (0, 0, vec![tcx.types.f128], tcx.types.f128), - - sym::ceilf16 => (0, 0, vec![tcx.types.f16], tcx.types.f16), - sym::ceilf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32), - sym::ceilf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64), - sym::ceilf128 => (0, 0, vec![tcx.types.f128], tcx.types.f128), - - sym::truncf16 => (0, 0, vec![tcx.types.f16], tcx.types.f16), - sym::truncf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32), - sym::truncf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64), - sym::truncf128 => (0, 0, vec![tcx.types.f128], tcx.types.f128), - - sym::round_ties_even_f16 => (0, 0, vec![tcx.types.f16], tcx.types.f16), - sym::round_ties_even_f32 => (0, 0, vec![tcx.types.f32], tcx.types.f32), - sym::round_ties_even_f64 => (0, 0, vec![tcx.types.f64], tcx.types.f64), - sym::round_ties_even_f128 => (0, 0, vec![tcx.types.f128], tcx.types.f128), - - sym::roundf16 => (0, 0, vec![tcx.types.f16], tcx.types.f16), - sym::roundf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32), - sym::roundf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64), - sym::roundf128 => (0, 0, vec![tcx.types.f128], tcx.types.f128), + sym::floor | sym::ceil | sym::trunc | sym::round_ties_even | sym::round => { + (1, 0, vec![param(0)], param(0)) + } sym::volatile_load | sym::unaligned_volatile_load => { (1, 0, vec![Ty::new_imm_ptr(tcx, param(0))], param(0)) diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index eb95d3a0d9059..62510e392724f 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -561,10 +561,7 @@ symbols! { catch_unwind, cause, cdylib, - ceilf16, - ceilf32, - ceilf64, - ceilf128, + ceil, cfg, cfg_accessible, cfg_attr, @@ -941,10 +938,7 @@ symbols! { file, final_associated_functions, float_to_int_unchecked, - floorf16, - floorf32, - floorf64, - floorf128, + floor, fmaf16, fmaf32, fmaf64, @@ -1646,14 +1640,8 @@ symbols! { ropi_rwpi: "ropi-rwpi", rotate_left, rotate_right, - round_ties_even_f16, - round_ties_even_f32, - round_ties_even_f64, - round_ties_even_f128, - roundf16, - roundf32, - roundf64, - roundf128, + round, + round_ties_even, rtm_target_feature, runtime, rust, @@ -2032,10 +2020,7 @@ symbols! { transparent_unions, trivial_bounds, trivial_clone, - truncf16, - truncf32, - truncf64, - truncf128, + trunc, try_blocks, try_blocks_heterogeneous, try_capture, diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index a5c7cf76622d8..6826125722391 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -1395,177 +1395,52 @@ pub const fn fmuladdf64(a: f64, b: f64, c: f64) -> f64; #[rustc_nounwind] pub const fn fmuladdf128(a: f128, b: f128, c: f128) -> f128; -/// Returns the largest integer less than or equal to an `f16`. +/// Returns the largest integer less than or equal to a floating point value. /// -/// The stabilized version of this intrinsic is -/// [`f16::floor`](../../std/primitive.f16.html#method.floor) -#[rustc_intrinsic_const_stable_indirect] -#[rustc_intrinsic] -#[rustc_nounwind] -pub const fn floorf16(x: f16) -> f16; -/// Returns the largest integer less than or equal to an `f32`. -/// -/// The stabilized version of this intrinsic is -/// [`f32::floor`](../../std/primitive.f32.html#method.floor) -#[rustc_intrinsic_const_stable_indirect] -#[rustc_intrinsic] -#[rustc_nounwind] -pub const fn floorf32(x: f32) -> f32; -/// Returns the largest integer less than or equal to an `f64`. -/// -/// The stabilized version of this intrinsic is -/// [`f64::floor`](../../std/primitive.f64.html#method.floor) -#[rustc_intrinsic_const_stable_indirect] -#[rustc_intrinsic] -#[rustc_nounwind] -pub const fn floorf64(x: f64) -> f64; -/// Returns the largest integer less than or equal to an `f128`. -/// -/// The stabilized version of this intrinsic is -/// [`f128::floor`](../../std/primitive.f128.html#method.floor) -#[rustc_intrinsic_const_stable_indirect] -#[rustc_intrinsic] -#[rustc_nounwind] -pub const fn floorf128(x: f128) -> f128; - -/// Returns the smallest integer greater than or equal to an `f16`. -/// -/// The stabilized version of this intrinsic is -/// [`f16::ceil`](../../std/primitive.f16.html#method.ceil) -#[rustc_intrinsic_const_stable_indirect] -#[rustc_intrinsic] -#[rustc_nounwind] -pub const fn ceilf16(x: f16) -> f16; -/// Returns the smallest integer greater than or equal to an `f32`. -/// -/// The stabilized version of this intrinsic is -/// [`f32::ceil`](../../std/primitive.f32.html#method.ceil) -#[rustc_intrinsic_const_stable_indirect] -#[rustc_intrinsic] -#[rustc_nounwind] -pub const fn ceilf32(x: f32) -> f32; -/// Returns the smallest integer greater than or equal to an `f64`. -/// -/// The stabilized version of this intrinsic is -/// [`f64::ceil`](../../std/primitive.f64.html#method.ceil) -#[rustc_intrinsic_const_stable_indirect] -#[rustc_intrinsic] -#[rustc_nounwind] -pub const fn ceilf64(x: f64) -> f64; -/// Returns the smallest integer greater than or equal to an `f128`. -/// -/// The stabilized version of this intrinsic is -/// [`f128::ceil`](../../std/primitive.f128.html#method.ceil) -#[rustc_intrinsic_const_stable_indirect] -#[rustc_intrinsic] -#[rustc_nounwind] -pub const fn ceilf128(x: f128) -> f128; - -/// Returns the integer part of an `f16`. -/// -/// The stabilized version of this intrinsic is -/// [`f16::trunc`](../../std/primitive.f16.html#method.trunc) -#[rustc_intrinsic_const_stable_indirect] -#[rustc_intrinsic] -#[rustc_nounwind] -pub const fn truncf16(x: f16) -> f16; -/// Returns the integer part of an `f32`. -/// -/// The stabilized version of this intrinsic is -/// [`f32::trunc`](../../std/primitive.f32.html#method.trunc) -#[rustc_intrinsic_const_stable_indirect] -#[rustc_intrinsic] -#[rustc_nounwind] -pub const fn truncf32(x: f32) -> f32; -/// Returns the integer part of an `f64`. -/// -/// The stabilized version of this intrinsic is -/// [`f64::trunc`](../../std/primitive.f64.html#method.trunc) -#[rustc_intrinsic_const_stable_indirect] -#[rustc_intrinsic] -#[rustc_nounwind] -pub const fn truncf64(x: f64) -> f64; -/// Returns the integer part of an `f128`. -/// -/// The stabilized version of this intrinsic is -/// [`f128::trunc`](../../std/primitive.f128.html#method.trunc) -#[rustc_intrinsic_const_stable_indirect] -#[rustc_intrinsic] -#[rustc_nounwind] -pub const fn truncf128(x: f128) -> f128; - -/// Returns the nearest integer to an `f16`. Rounds half-way cases to the number with an even -/// least significant digit. -/// -/// The stabilized version of this intrinsic is -/// [`f16::round_ties_even`](../../std/primitive.f16.html#method.round_ties_even) +/// The stabilized versions of this intrinsic are available on the float +/// primitives via the `floor` method. For example, [`f32::floor`]. #[rustc_intrinsic_const_stable_indirect] #[rustc_intrinsic] #[rustc_nounwind] -pub const fn round_ties_even_f16(x: f16) -> f16; +pub const fn floor(x: T) -> T; -/// Returns the nearest integer to an `f32`. Rounds half-way cases to the number with an even -/// least significant digit. +/// Returns the smallest integer greater than or equal to a floating point value. /// -/// The stabilized version of this intrinsic is -/// [`f32::round_ties_even`](../../std/primitive.f32.html#method.round_ties_even) +/// The stabilized versions of this intrinsic are available on the float +/// primitives via the `ceil` method. For example, [`f32::ceil`]. #[rustc_intrinsic_const_stable_indirect] #[rustc_intrinsic] #[rustc_nounwind] -pub const fn round_ties_even_f32(x: f32) -> f32; +pub const fn ceil(x: T) -> T; -/// Returns the nearest integer to an `f64`. Rounds half-way cases to the number with an even -/// least significant digit. +/// Returns the integer part of a floating point value. /// -/// The stabilized version of this intrinsic is -/// [`f64::round_ties_even`](../../std/primitive.f64.html#method.round_ties_even) +/// The stabilized versions of this intrinsic are available on the float +/// primitives via the `trunc` method. For example, [`f32::trunc`]. #[rustc_intrinsic_const_stable_indirect] #[rustc_intrinsic] #[rustc_nounwind] -pub const fn round_ties_even_f64(x: f64) -> f64; +pub const fn trunc(x: T) -> T; -/// Returns the nearest integer to an `f128`. Rounds half-way cases to the number with an even -/// least significant digit. +/// Returns the nearest integer to a floating point value. Rounds half-way cases +/// to the number with an even least significant digit. /// -/// The stabilized version of this intrinsic is -/// [`f128::round_ties_even`](../../std/primitive.f128.html#method.round_ties_even) +/// The stabilized versions of this intrinsic are available on the float +/// primitives via the `round_ties_even` method. For example, [`f32::round_ties_even`]. #[rustc_intrinsic_const_stable_indirect] #[rustc_intrinsic] #[rustc_nounwind] -pub const fn round_ties_even_f128(x: f128) -> f128; +pub const fn round_ties_even(x: T) -> T; -/// Returns the nearest integer to an `f16`. Rounds half-way cases away from zero. -/// -/// The stabilized version of this intrinsic is -/// [`f16::round`](../../std/primitive.f16.html#method.round) -#[rustc_intrinsic_const_stable_indirect] -#[rustc_intrinsic] -#[rustc_nounwind] -pub const fn roundf16(x: f16) -> f16; -/// Returns the nearest integer to an `f32`. Rounds half-way cases away from zero. -/// -/// The stabilized version of this intrinsic is -/// [`f32::round`](../../std/primitive.f32.html#method.round) -#[rustc_intrinsic_const_stable_indirect] -#[rustc_intrinsic] -#[rustc_nounwind] -pub const fn roundf32(x: f32) -> f32; -/// Returns the nearest integer to an `f64`. Rounds half-way cases away from zero. +/// Returns the nearest integer to a floating point value. +/// Rounds half-way cases away from zero. /// -/// The stabilized version of this intrinsic is -/// [`f64::round`](../../std/primitive.f64.html#method.round) -#[rustc_intrinsic_const_stable_indirect] -#[rustc_intrinsic] -#[rustc_nounwind] -pub const fn roundf64(x: f64) -> f64; -/// Returns the nearest integer to an `f128`. Rounds half-way cases away from zero. -/// -/// The stabilized version of this intrinsic is -/// [`f128::round`](../../std/primitive.f128.html#method.round) +/// The stabilized versions of this intrinsic are available on the float +/// primitives via the `round` method. For example, [`f32::round`]. #[rustc_intrinsic_const_stable_indirect] #[rustc_intrinsic] #[rustc_nounwind] -pub const fn roundf128(x: f128) -> f128; +pub const fn round(x: T) -> T; /// Float addition that allows optimizations based on algebraic rules. /// Requires that inputs and output of the operation are finite, causing UB otherwise. diff --git a/library/core/src/num/f128.rs b/library/core/src/num/f128.rs index d833653fdba65..4a02593555667 100644 --- a/library/core/src/num/f128.rs +++ b/library/core/src/num/f128.rs @@ -1569,7 +1569,7 @@ impl f128 { #[rustc_const_unstable(feature = "f128", issue = "116909")] #[must_use = "method returns a new number and does not mutate the original value"] pub const fn floor(self) -> f128 { - intrinsics::floorf128(self) + intrinsics::floor(self) } /// Returns the smallest integer greater than or equal to `self`. @@ -1597,7 +1597,7 @@ impl f128 { #[rustc_const_unstable(feature = "f128", issue = "116909")] #[must_use = "method returns a new number and does not mutate the original value"] pub const fn ceil(self) -> f128 { - intrinsics::ceilf128(self) + intrinsics::ceil(self) } /// Returns the nearest integer to `self`. If a value is half-way between two @@ -1631,7 +1631,7 @@ impl f128 { #[rustc_const_unstable(feature = "f128", issue = "116909")] #[must_use = "method returns a new number and does not mutate the original value"] pub const fn round(self) -> f128 { - intrinsics::roundf128(self) + intrinsics::round(self) } /// Returns the nearest integer to a number. Rounds half-way cases to the number @@ -1663,7 +1663,7 @@ impl f128 { #[rustc_const_unstable(feature = "f128", issue = "116909")] #[must_use = "method returns a new number and does not mutate the original value"] pub const fn round_ties_even(self) -> f128 { - intrinsics::round_ties_even_f128(self) + intrinsics::round_ties_even(self) } /// Returns the integer part of `self`. @@ -1694,7 +1694,7 @@ impl f128 { #[rustc_const_unstable(feature = "f128", issue = "116909")] #[must_use = "method returns a new number and does not mutate the original value"] pub const fn trunc(self) -> f128 { - intrinsics::truncf128(self) + intrinsics::trunc(self) } /// Returns the fractional part of `self`. diff --git a/library/core/src/num/f16.rs b/library/core/src/num/f16.rs index b0664abcdc739..71a6115901bf7 100644 --- a/library/core/src/num/f16.rs +++ b/library/core/src/num/f16.rs @@ -1553,7 +1553,7 @@ impl f16 { #[rustc_const_unstable(feature = "f16", issue = "116909")] #[must_use = "method returns a new number and does not mutate the original value"] pub const fn floor(self) -> f16 { - intrinsics::floorf16(self) + intrinsics::floor(self) } /// Returns the smallest integer greater than or equal to `self`. @@ -1581,7 +1581,7 @@ impl f16 { #[rustc_const_unstable(feature = "f16", issue = "116909")] #[must_use = "method returns a new number and does not mutate the original value"] pub const fn ceil(self) -> f16 { - intrinsics::ceilf16(self) + intrinsics::ceil(self) } /// Returns the nearest integer to `self`. If a value is half-way between two @@ -1615,7 +1615,7 @@ impl f16 { #[rustc_const_unstable(feature = "f16", issue = "116909")] #[must_use = "method returns a new number and does not mutate the original value"] pub const fn round(self) -> f16 { - intrinsics::roundf16(self) + intrinsics::round(self) } /// Returns the nearest integer to a number. Rounds half-way cases to the number @@ -1647,7 +1647,7 @@ impl f16 { #[rustc_const_unstable(feature = "f16", issue = "116909")] #[must_use = "method returns a new number and does not mutate the original value"] pub const fn round_ties_even(self) -> f16 { - intrinsics::round_ties_even_f16(self) + intrinsics::round_ties_even(self) } /// Returns the integer part of `self`. @@ -1678,7 +1678,7 @@ impl f16 { #[rustc_const_unstable(feature = "f16", issue = "116909")] #[must_use = "method returns a new number and does not mutate the original value"] pub const fn trunc(self) -> f16 { - intrinsics::truncf16(self) + intrinsics::trunc(self) } /// Returns the fractional part of `self`. diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs index b85bd2b271588..81cada2dadf6f 100644 --- a/library/core/src/num/f32.rs +++ b/library/core/src/num/f32.rs @@ -1720,7 +1720,7 @@ pub mod math { #[unstable(feature = "core_float_math", issue = "137578")] #[must_use = "method returns a new number and does not mutate the original value"] pub const fn floor(x: f32) -> f32 { - intrinsics::floorf32(x) + intrinsics::floor(x) } /// Experimental version of `ceil` in `core`. See [`f32::ceil`] for details. @@ -1748,7 +1748,7 @@ pub mod math { #[must_use = "method returns a new number and does not mutate the original value"] #[unstable(feature = "core_float_math", issue = "137578")] pub const fn ceil(x: f32) -> f32 { - intrinsics::ceilf32(x) + intrinsics::ceil(x) } /// Experimental version of `round` in `core`. See [`f32::round`] for details. @@ -1781,7 +1781,7 @@ pub mod math { #[unstable(feature = "core_float_math", issue = "137578")] #[must_use = "method returns a new number and does not mutate the original value"] pub const fn round(x: f32) -> f32 { - intrinsics::roundf32(x) + intrinsics::round(x) } /// Experimental version of `round_ties_even` in `core`. See [`f32::round_ties_even`] for @@ -1813,7 +1813,7 @@ pub mod math { #[unstable(feature = "core_float_math", issue = "137578")] #[must_use = "method returns a new number and does not mutate the original value"] pub const fn round_ties_even(x: f32) -> f32 { - intrinsics::round_ties_even_f32(x) + intrinsics::round_ties_even(x) } /// Experimental version of `trunc` in `core`. See [`f32::trunc`] for details. @@ -1843,7 +1843,7 @@ pub mod math { #[must_use = "method returns a new number and does not mutate the original value"] #[unstable(feature = "core_float_math", issue = "137578")] pub const fn trunc(x: f32) -> f32 { - intrinsics::truncf32(x) + intrinsics::trunc(x) } /// Experimental version of `fract` in `core`. See [`f32::fract`] for details. diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs index 3e7c1e792ace6..41e38d9c61424 100644 --- a/library/core/src/num/f64.rs +++ b/library/core/src/num/f64.rs @@ -1718,7 +1718,7 @@ pub mod math { #[unstable(feature = "core_float_math", issue = "137578")] #[must_use = "method returns a new number and does not mutate the original value"] pub const fn floor(x: f64) -> f64 { - intrinsics::floorf64(x) + intrinsics::floor(x) } /// Experimental version of `ceil` in `core`. See [`f64::ceil`] for details. @@ -1746,7 +1746,7 @@ pub mod math { #[unstable(feature = "core_float_math", issue = "137578")] #[must_use = "method returns a new number and does not mutate the original value"] pub const fn ceil(x: f64) -> f64 { - intrinsics::ceilf64(x) + intrinsics::ceil(x) } /// Experimental version of `round` in `core`. See [`f64::round`] for details. @@ -1779,7 +1779,7 @@ pub mod math { #[unstable(feature = "core_float_math", issue = "137578")] #[must_use = "method returns a new number and does not mutate the original value"] pub const fn round(x: f64) -> f64 { - intrinsics::roundf64(x) + intrinsics::round(x) } /// Experimental version of `round_ties_even` in `core`. See [`f64::round_ties_even`] for @@ -1811,7 +1811,7 @@ pub mod math { #[unstable(feature = "core_float_math", issue = "137578")] #[must_use = "method returns a new number and does not mutate the original value"] pub const fn round_ties_even(x: f64) -> f64 { - intrinsics::round_ties_even_f64(x) + intrinsics::round_ties_even(x) } /// Experimental version of `trunc` in `core`. See [`f64::trunc`] for details. @@ -1841,7 +1841,7 @@ pub mod math { #[unstable(feature = "core_float_math", issue = "137578")] #[must_use = "method returns a new number and does not mutate the original value"] pub const fn trunc(x: f64) -> f64 { - intrinsics::truncf64(x) + intrinsics::trunc(x) } /// Experimental version of `fract` in `core`. See [`f64::fract`] for details. diff --git a/library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs b/library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs index 490f04020ee43..d104cd7595a8b 100644 --- a/library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs +++ b/library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs @@ -21951,7 +21951,7 @@ pub fn vrndaq_f64(a: float64x2_t) -> float64x2_t { #[cfg(not(target_arch = "arm64ec"))] #[cfg_attr(test, assert_instr(frinta))] pub fn vrndah_f16(a: f16) -> f16 { - roundf16(a) + round(a) } #[doc = "Floating-point round to integral, to nearest with ties to away"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndh_f16)"] @@ -21961,7 +21961,7 @@ pub fn vrndah_f16(a: f16) -> f16 { #[cfg(not(target_arch = "arm64ec"))] #[cfg_attr(test, assert_instr(frintz))] pub fn vrndh_f16(a: f16) -> f16 { - truncf16(a) + trunc(a) } #[doc = "Floating-point round to integral, using current rounding mode"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndi_f16)"] @@ -22142,7 +22142,7 @@ pub fn vrndmq_f64(a: float64x2_t) -> float64x2_t { #[cfg(not(target_arch = "arm64ec"))] #[cfg_attr(test, assert_instr(frintm))] pub fn vrndmh_f16(a: f16) -> f16 { - floorf16(a) + floor(a) } #[doc = "Floating-point round to integral, to nearest with ties to even"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndn_f64)"] @@ -22273,7 +22273,7 @@ pub fn vrndpq_f64(a: float64x2_t) -> float64x2_t { #[cfg(not(target_arch = "arm64ec"))] #[cfg_attr(test, assert_instr(frintp))] pub fn vrndph_f16(a: f16) -> f16 { - ceilf16(a) + ceil(a) } #[doc = "Floating-point round to integral exact, using current rounding mode"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrndx_f16)"] @@ -22339,7 +22339,7 @@ pub fn vrndxq_f64(a: float64x2_t) -> float64x2_t { #[cfg(not(target_arch = "arm64ec"))] #[cfg_attr(test, assert_instr(frintx))] pub fn vrndxh_f16(a: f16) -> f16 { - round_ties_even_f16(a) + round_ties_even(a) } #[doc = "Signed rounding shift left"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrshld_s64)"] diff --git a/tests/ui/intrinsics/reify-intrinsic.rs b/tests/ui/intrinsics/reify-intrinsic.rs index 5b2324235c1a9..792d39b7accd3 100644 --- a/tests/ui/intrinsics/reify-intrinsic.rs +++ b/tests/ui/intrinsics/reify-intrinsic.rs @@ -14,7 +14,7 @@ fn b() { fn c() { let _: [unsafe fn(f32) -> f32; 2] = [ - std::intrinsics::floorf32, //~ ERROR cannot coerce + std::intrinsics::floor, //~ ERROR cannot coerce std::intrinsics::log2f32, ]; } diff --git a/tests/ui/intrinsics/reify-intrinsic.stderr b/tests/ui/intrinsics/reify-intrinsic.stderr index 1307a85c8b6ca..a3904b6280c3f 100644 --- a/tests/ui/intrinsics/reify-intrinsic.stderr +++ b/tests/ui/intrinsics/reify-intrinsic.stderr @@ -18,11 +18,11 @@ LL | let _ = std::mem::transmute as unsafe fn(isize) -> usize; error[E0308]: cannot coerce intrinsics to function pointers --> $DIR/reify-intrinsic.rs:17:9 | -LL | std::intrinsics::floorf32, - | ^^^^^^^^^^^^^^^^^^^^^^^^^ cannot coerce intrinsics to function pointers +LL | std::intrinsics::floor, + | ^^^^^^^^^^^^^^^^^^^^^^ cannot coerce intrinsics to function pointers | - = note: expected fn pointer `unsafe fn(_) -> _` - found fn item `fn(_) -> _ {floorf32}` + = note: expected fn pointer `unsafe fn(f32) -> f32` + found fn item `fn(_) -> _ {std::intrinsics::floor::<_>}` error: aborting due to 3 previous errors From 52805b26fb05014e1b1c22d324b2132dd9ef05c6 Mon Sep 17 00:00:00 2001 From: N1ark Date: Mon, 16 Mar 2026 00:19:23 +0000 Subject: [PATCH 5/7] Genericize sqrt --- .../src/intrinsics/mod.rs | 9 ++--- .../rustc_codegen_gcc/src/intrinsic/mod.rs | 37 +++---------------- compiler/rustc_codegen_llvm/src/intrinsic.rs | 7 +--- .../rustc_hir_analysis/src/check/intrinsic.rs | 10 +---- compiler/rustc_span/src/symbol.rs | 5 +-- library/core/src/intrinsics/mod.rs | 29 ++------------- library/core/src/num/f128.rs | 2 +- library/core/src/num/f16.rs | 2 +- library/core/src/num/f32.rs | 2 +- library/core/src/num/f64.rs | 2 +- .../core_arch/src/aarch64/neon/generated.rs | 2 +- .../stdarch/crates/core_arch/src/x86/sse.rs | 4 +- .../stdarch/crates/core_arch/src/x86/sse2.rs | 4 +- 13 files changed, 28 insertions(+), 87 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs index f057e1afffbb8..487d17a838eb5 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs @@ -322,10 +322,6 @@ fn codegen_float_intrinsic_call<'tcx>( sym::exp2f32 => ("exp2f", 1, fx.tcx.types.f32, types::F32), sym::exp2f64 => ("exp2", 1, fx.tcx.types.f64, types::F64), sym::exp2f128 => ("exp2f128", 1, fx.tcx.types.f128, types::F128), - sym::sqrtf16 => ("sqrtf16", 1, fx.tcx.types.f16, types::F16), - sym::sqrtf32 => ("sqrtf", 1, fx.tcx.types.f32, types::F32), - sym::sqrtf64 => ("sqrt", 1, fx.tcx.types.f64, types::F64), - sym::sqrtf128 => ("sqrtf128", 1, fx.tcx.types.f128, types::F128), sym::powif16 => ("__powisf2", 2, fx.tcx.types.f16, types::F16), // compiler-builtins sym::powif32 => ("__powisf2", 2, fx.tcx.types.f32, types::F32), // compiler-builtins sym::powif64 => ("__powidf2", 2, fx.tcx.types.f64, types::F64), // compiler-builtins @@ -409,7 +405,6 @@ fn codegen_float_intrinsic_call<'tcx>( sym::copysignf16 => codegen_f16_f128::copysign_f16(fx, args[0], args[1]), sym::copysignf128 => codegen_f16_f128::copysign_f128(fx, args[0], args[1]), sym::copysignf32 | sym::copysignf64 => fx.bcx.ins().fcopysign(args[0], args[1]), - sym::sqrtf32 | sym::sqrtf64 => fx.bcx.ins().sqrt(args[0]), // These intrinsics aren't supported natively by Cranelift. // Lower them to a libcall. @@ -1121,6 +1116,7 @@ fn codegen_regular_intrinsic_call<'tcx>( // Float unop intrinsics sym::fabs + | sym::sqrt | sym::floor | sym::ceil | sym::trunc @@ -1144,6 +1140,9 @@ fn codegen_regular_intrinsic_call<'tcx>( // backend lowerings are implemented. (sym::fabs, F16) => Ok(codegen_f16_f128::abs_f16(fx, x)), (sym::fabs, F128) => Ok(codegen_f16_f128::abs_f128(fx, x)), + (sym::sqrt, F32 | F64) => Ok(fx.bcx.ins().sqrt(x)), + (sym::sqrt, F16) => Err("sqrtf16"), + (sym::sqrt, F128) => Err("sqrtf128"), (sym::floor, F32 | F64) => Ok(fx.bcx.ins().floor(x)), (sym::floor, F16) => Err("floorf16"), (sym::floor, F128) => Err("floorf128"), diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs index 3a4de89c9231d..46e942718dfb2 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs +++ b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs @@ -45,8 +45,6 @@ fn get_simple_intrinsic<'gcc, 'tcx>( name: Symbol, ) -> Option> { let gcc_name = match name { - sym::sqrtf32 => "sqrtf", - sym::sqrtf64 => "sqrt", sym::powif32 => "__builtin_powif", sym::powif64 => "__builtin_powi", sym::sinf32 => "sinf", @@ -180,25 +178,6 @@ fn get_simple_function<'gcc, 'tcx>( )) } -fn get_simple_function_f128<'gcc, 'tcx>( - cx: &CodegenCx<'gcc, 'tcx>, - name: Symbol, -) -> Function<'gcc> { - let f128_type = cx.type_f128(); - let func_name = match name { - sym::sqrtf128 => "sqrtf128", - _ => unreachable!(), - }; - cx.context.new_function( - None, - FunctionType::Extern, - f128_type, - &[cx.context.new_parameter(None, f128_type, "a")], - func_name, - false, - ) -} - fn f16_builtin<'gcc, 'tcx>( cx: &CodegenCx<'gcc, 'tcx>, name: Symbol, @@ -216,7 +195,6 @@ fn f16_builtin<'gcc, 'tcx>( let result = cx.context.new_call(None, func, &args); return cx.context.new_cast(None, result, cx.type_f16()); } - sym::sqrtf16 => "__builtin_sqrtf", _ => unreachable!(), }; @@ -261,17 +239,9 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc &args.iter().map(|arg| arg.immediate()).collect::>(), ) } - sym::copysignf16 | sym::fmaf16 | sym::powf16 | sym::powif16 | sym::sqrtf16 => { + sym::copysignf16 | sym::fmaf16 | sym::powf16 | sym::powif16 => { f16_builtin(self, name, args) } - sym::sqrtf128 if self.cx.supports_f128_type => { - let func = get_simple_function_f128(self, name); - self.cx.context.new_call( - self.location, - func, - &args.iter().map(|arg| arg.immediate()).collect::>(), - ) - } sym::copysignf128 if self.cx.supports_f128_type => { let f128_type = self.cx.type_f128(); let func = self.cx.context.new_function( @@ -450,6 +420,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc } // float unary intrinsics sym::fabs + | sym::sqrt | sym::floor | sym::ceil | sym::trunc @@ -475,6 +446,10 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc (sym::fabs, F32) => Builtin("fabsf"), (sym::fabs, F64) => Builtin("fabs"), (sym::fabs, F128) => Extern("fabsf128"), + (sym::sqrt, F16) => BuiltinF16Cast("__builtin_sqrtf"), + (sym::sqrt, F32) => Builtin("sqrtf"), + (sym::sqrt, F64) => Builtin("sqrt"), + (sym::sqrt, F128) => Extern("sqrtf128"), (sym::floor, F16) => BuiltinF16Cast("__builtin_floorf"), (sym::floor, F32) => Builtin("floorf"), (sym::floor, F64) => Builtin("floor"), diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index fd8c56380c2ec..62997ed39a997 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -47,11 +47,6 @@ fn call_simple_intrinsic<'ll, 'tcx>( args: &[OperandRef<'tcx, &'ll Value>], ) -> Option<&'ll Value> { let (base_name, type_params): (&'static str, &[&'ll Type]) = match name { - sym::sqrtf16 => ("llvm.sqrt", &[bx.type_f16()]), - sym::sqrtf32 => ("llvm.sqrt", &[bx.type_f32()]), - sym::sqrtf64 => ("llvm.sqrt", &[bx.type_f64()]), - sym::sqrtf128 => ("llvm.sqrt", &[bx.type_f128()]), - sym::powif16 => ("llvm.powi", &[bx.type_f16(), bx.type_i32()]), sym::powif32 => ("llvm.powi", &[bx.type_f32(), bx.type_i32()]), sym::powif64 => ("llvm.powi", &[bx.type_f64(), bx.type_i32()]), @@ -469,6 +464,7 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { } sym::fabs + | sym::sqrt | sym::floor | sym::ceil | sym::trunc @@ -482,6 +478,7 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { let llty = self.type_float_from_ty(*f); let llvm_name = match name { sym::fabs => "llvm.fabs", + sym::sqrt => "llvm.sqrt", sym::floor => "llvm.floor", sym::ceil => "llvm.ceil", sym::trunc => "llvm.trunc", diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index 17405d29e9a7e..33ca13012add2 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -187,10 +187,7 @@ fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -> hi | sym::sinf64 | sym::sinf128 | sym::size_of - | sym::sqrtf16 - | sym::sqrtf32 - | sym::sqrtf64 - | sym::sqrtf128 + | sym::sqrt | sym::sub_with_overflow | sym::three_way_compare | sym::trunc @@ -381,10 +378,7 @@ pub(crate) fn check_intrinsic_type( tcx.types.unit, ), - sym::sqrtf16 => (0, 0, vec![tcx.types.f16], tcx.types.f16), - sym::sqrtf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32), - sym::sqrtf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64), - sym::sqrtf128 => (0, 0, vec![tcx.types.f128], tcx.types.f128), + sym::sqrt => (1, 0, vec![param(0)], param(0)), sym::powif16 => (0, 0, vec![tcx.types.f16, tcx.types.i32], tcx.types.f16), sym::powif32 => (0, 0, vec![tcx.types.f32, tcx.types.i32], tcx.types.f32), diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 62510e392724f..a34a883f6dd55 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1909,10 +1909,7 @@ symbols! { speed, spirv, spotlight, - sqrtf16, - sqrtf32, - sqrtf64, - sqrtf128, + sqrt, sreg, sreg_low16, sse, diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index 6826125722391..9552590646d7a 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -1019,34 +1019,13 @@ pub unsafe fn unaligned_volatile_load(src: *const T) -> T; #[rustc_diagnostic_item = "intrinsics_unaligned_volatile_store"] pub unsafe fn unaligned_volatile_store(dst: *mut T, val: T); -/// Returns the square root of an `f16` +/// Returns the square root of a floating point value. /// -/// The stabilized version of this intrinsic is -/// [`f16::sqrt`](../../std/primitive.f16.html#method.sqrt) -#[rustc_intrinsic] -#[rustc_nounwind] -pub fn sqrtf16(x: f16) -> f16; -/// Returns the square root of an `f32` -/// -/// The stabilized version of this intrinsic is -/// [`f32::sqrt`](../../std/primitive.f32.html#method.sqrt) -#[rustc_intrinsic] -#[rustc_nounwind] -pub fn sqrtf32(x: f32) -> f32; -/// Returns the square root of an `f64` -/// -/// The stabilized version of this intrinsic is -/// [`f64::sqrt`](../../std/primitive.f64.html#method.sqrt) -#[rustc_intrinsic] -#[rustc_nounwind] -pub fn sqrtf64(x: f64) -> f64; -/// Returns the square root of an `f128` -/// -/// The stabilized version of this intrinsic is -/// [`f128::sqrt`](../../std/primitive.f128.html#method.sqrt) +/// The stabilized versions of this intrinsic are available on the float +/// primitives via the `sqrt` method. For example, [`f32::sqrt`]. #[rustc_intrinsic] #[rustc_nounwind] -pub fn sqrtf128(x: f128) -> f128; +pub fn sqrt(x: T) -> T; /// Raises an `f16` to an integer power. /// diff --git a/library/core/src/num/f128.rs b/library/core/src/num/f128.rs index 4a02593555667..71239713b28e5 100644 --- a/library/core/src/num/f128.rs +++ b/library/core/src/num/f128.rs @@ -1927,6 +1927,6 @@ impl f128 { #[unstable(feature = "f128", issue = "116909")] #[must_use = "method returns a new number and does not mutate the original value"] pub fn sqrt(self) -> f128 { - intrinsics::sqrtf128(self) + intrinsics::sqrt(self) } } diff --git a/library/core/src/num/f16.rs b/library/core/src/num/f16.rs index 71a6115901bf7..23e931e5c12ae 100644 --- a/library/core/src/num/f16.rs +++ b/library/core/src/num/f16.rs @@ -1911,7 +1911,7 @@ impl f16 { #[unstable(feature = "f16", issue = "116909")] #[must_use = "method returns a new number and does not mutate the original value"] pub fn sqrt(self) -> f16 { - intrinsics::sqrtf16(self) + intrinsics::sqrt(self) } /// Returns the cube root of a number. diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs index 81cada2dadf6f..711cf477f3590 100644 --- a/library/core/src/num/f32.rs +++ b/library/core/src/num/f32.rs @@ -2039,7 +2039,7 @@ pub mod math { #[unstable(feature = "core_float_math", issue = "137578")] #[must_use = "method returns a new number and does not mutate the original value"] pub fn sqrt(x: f32) -> f32 { - intrinsics::sqrtf32(x) + intrinsics::sqrt(x) } /// Experimental version of `abs_sub` in `core`. See [`f32::abs_sub`] for details. diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs index 41e38d9c61424..2b724fe7a27a5 100644 --- a/library/core/src/num/f64.rs +++ b/library/core/src/num/f64.rs @@ -2037,7 +2037,7 @@ pub mod math { #[unstable(feature = "core_float_math", issue = "137578")] #[must_use = "method returns a new number and does not mutate the original value"] pub fn sqrt(x: f64) -> f64 { - intrinsics::sqrtf64(x) + intrinsics::sqrt(x) } /// Experimental version of `abs_sub` in `core`. See [`f64::abs_sub`] for details. diff --git a/library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs b/library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs index d104cd7595a8b..839c9e3d7a295 100644 --- a/library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs +++ b/library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs @@ -23851,7 +23851,7 @@ pub fn vsqrtq_f64(a: float64x2_t) -> float64x2_t { #[cfg(not(target_arch = "arm64ec"))] #[cfg_attr(test, assert_instr(fsqrt))] pub fn vsqrth_f16(a: f16) -> f16 { - sqrtf16(a) + sqrt(a) } #[doc = "Shift Right and Insert (immediate)"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vsri_n_s8)"] diff --git a/library/stdarch/crates/core_arch/src/x86/sse.rs b/library/stdarch/crates/core_arch/src/x86/sse.rs index 3f7781cc7dc4c..8d945371dddc3 100644 --- a/library/stdarch/crates/core_arch/src/x86/sse.rs +++ b/library/stdarch/crates/core_arch/src/x86/sse.rs @@ -3,7 +3,7 @@ use crate::{ core_arch::{simd::*, x86::*}, intrinsics::simd::*, - intrinsics::sqrtf32, + intrinsics::sqrt, mem, ptr, }; @@ -123,7 +123,7 @@ pub const fn _mm_div_ps(a: __m128, b: __m128) -> __m128 { #[cfg_attr(test, assert_instr(sqrtss))] #[stable(feature = "simd_x86", since = "1.27.0")] pub fn _mm_sqrt_ss(a: __m128) -> __m128 { - unsafe { simd_insert!(a, 0, sqrtf32(_mm_cvtss_f32(a))) } + unsafe { simd_insert!(a, 0, sqrt(_mm_cvtss_f32(a))) } } /// Returns the square root of packed single-precision (32-bit) floating-point diff --git a/library/stdarch/crates/core_arch/src/x86/sse2.rs b/library/stdarch/crates/core_arch/src/x86/sse2.rs index 1f97f3c69d0e3..56d22a5314103 100644 --- a/library/stdarch/crates/core_arch/src/x86/sse2.rs +++ b/library/stdarch/crates/core_arch/src/x86/sse2.rs @@ -6,7 +6,7 @@ use stdarch_test::assert_instr; use crate::{ core_arch::{simd::*, x86::*}, intrinsics::simd::*, - intrinsics::sqrtf64, + intrinsics::sqrt, mem, ptr, }; @@ -1962,7 +1962,7 @@ pub const fn _mm_mul_pd(a: __m128d, b: __m128d) -> __m128d { #[cfg_attr(test, assert_instr(sqrtsd))] #[stable(feature = "simd_x86", since = "1.27.0")] pub fn _mm_sqrt_sd(a: __m128d, b: __m128d) -> __m128d { - unsafe { simd_insert!(a, 0, sqrtf64(_mm_cvtsd_f64(b))) } + unsafe { simd_insert!(a, 0, sqrt(_mm_cvtsd_f64(b))) } } /// Returns a new vector with the square root of each of the values in `a`. From 81b7dda43f1955e58bcb4381075fef1560ab355c Mon Sep 17 00:00:00 2001 From: N1ark Date: Mon, 16 Mar 2026 00:22:13 +0000 Subject: [PATCH 6/7] Genericize sin and cos --- .../src/intrinsics/mod.rs | 18 +++--- .../rustc_codegen_gcc/src/intrinsic/mod.rs | 10 ++-- compiler/rustc_codegen_llvm/src/intrinsic.rs | 14 ++--- .../rustc_hir_analysis/src/check/intrinsic.rs | 20 +------ compiler/rustc_span/src/symbol.rs | 10 +--- library/core/src/intrinsics/mod.rs | 58 +++---------------- library/std/src/num/f128.rs | 4 +- library/std/src/num/f16.rs | 4 +- library/std/src/num/f32.rs | 4 +- library/std/src/num/f64.rs | 4 +- 10 files changed, 41 insertions(+), 105 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs index 487d17a838eb5..733e664a02cca 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs @@ -355,14 +355,6 @@ fn codegen_float_intrinsic_call<'tcx>( sym::copysignf32 => ("copysignf", 2, fx.tcx.types.f32, types::F32), sym::copysignf64 => ("copysign", 2, fx.tcx.types.f64, types::F64), sym::copysignf128 => ("copysignf128", 2, fx.tcx.types.f128, types::F128), - sym::sinf16 => ("sinf16", 1, fx.tcx.types.f16, types::F16), - sym::sinf32 => ("sinf", 1, fx.tcx.types.f32, types::F32), - sym::sinf64 => ("sin", 1, fx.tcx.types.f64, types::F64), - sym::sinf128 => ("sinf128", 1, fx.tcx.types.f128, types::F128), - sym::cosf16 => ("cosf16", 1, fx.tcx.types.f16, types::F16), - sym::cosf32 => ("cosf", 1, fx.tcx.types.f32, types::F32), - sym::cosf64 => ("cos", 1, fx.tcx.types.f64, types::F64), - sym::cosf128 => ("cosf128", 1, fx.tcx.types.f128, types::F128), _ => return false, }; @@ -1117,6 +1109,8 @@ fn codegen_regular_intrinsic_call<'tcx>( // Float unop intrinsics sym::fabs | sym::sqrt + | sym::sin + | sym::cos | sym::floor | sym::ceil | sym::trunc @@ -1143,6 +1137,14 @@ fn codegen_regular_intrinsic_call<'tcx>( (sym::sqrt, F32 | F64) => Ok(fx.bcx.ins().sqrt(x)), (sym::sqrt, F16) => Err("sqrtf16"), (sym::sqrt, F128) => Err("sqrtf128"), + (sym::sin, F16) => Err("sinf16"), + (sym::sin, F32) => Err("sinf"), + (sym::sin, F64) => Err("sin"), + (sym::sin, F128) => Err("sinf128"), + (sym::cos, F16) => Err("cosf16"), + (sym::cos, F32) => Err("cosf"), + (sym::cos, F64) => Err("cos"), + (sym::cos, F128) => Err("cosf128"), (sym::floor, F32 | F64) => Ok(fx.bcx.ins().floor(x)), (sym::floor, F16) => Err("floorf16"), (sym::floor, F128) => Err("floorf128"), diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs index 46e942718dfb2..43a9cd0b8efc8 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs +++ b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs @@ -47,10 +47,6 @@ fn get_simple_intrinsic<'gcc, 'tcx>( let gcc_name = match name { sym::powif32 => "__builtin_powif", sym::powif64 => "__builtin_powi", - sym::sinf32 => "sinf", - sym::sinf64 => "sin", - sym::cosf32 => "cosf", - sym::cosf64 => "cos", sym::powf32 => "powf", sym::powf64 => "pow", sym::expf32 => "expf", @@ -421,6 +417,8 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc // float unary intrinsics sym::fabs | sym::sqrt + | sym::sin + | sym::cos | sym::floor | sym::ceil | sym::trunc @@ -450,6 +448,10 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc (sym::sqrt, F32) => Builtin("sqrtf"), (sym::sqrt, F64) => Builtin("sqrt"), (sym::sqrt, F128) => Extern("sqrtf128"), + (sym::sin, F32) => Builtin("sinf"), + (sym::sin, F64) => Builtin("sin"), + (sym::cos, F32) => Builtin("cosf"), + (sym::cos, F64) => Builtin("cos"), (sym::floor, F16) => BuiltinF16Cast("__builtin_floorf"), (sym::floor, F32) => Builtin("floorf"), (sym::floor, F64) => Builtin("floor"), diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 62997ed39a997..da9331a96753f 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -52,16 +52,6 @@ fn call_simple_intrinsic<'ll, 'tcx>( sym::powif64 => ("llvm.powi", &[bx.type_f64(), bx.type_i32()]), sym::powif128 => ("llvm.powi", &[bx.type_f128(), bx.type_i32()]), - sym::sinf16 => ("llvm.sin", &[bx.type_f16()]), - sym::sinf32 => ("llvm.sin", &[bx.type_f32()]), - sym::sinf64 => ("llvm.sin", &[bx.type_f64()]), - sym::sinf128 => ("llvm.sin", &[bx.type_f128()]), - - sym::cosf16 => ("llvm.cos", &[bx.type_f16()]), - sym::cosf32 => ("llvm.cos", &[bx.type_f32()]), - sym::cosf64 => ("llvm.cos", &[bx.type_f64()]), - sym::cosf128 => ("llvm.cos", &[bx.type_f128()]), - sym::powf16 => ("llvm.pow", &[bx.type_f16()]), sym::powf32 => ("llvm.pow", &[bx.type_f32()]), sym::powf64 => ("llvm.pow", &[bx.type_f64()]), @@ -465,6 +455,8 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { sym::fabs | sym::sqrt + | sym::sin + | sym::cos | sym::floor | sym::ceil | sym::trunc @@ -479,6 +471,8 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { let llvm_name = match name { sym::fabs => "llvm.fabs", sym::sqrt => "llvm.sqrt", + sym::sin => "llvm.sin", + sym::cos => "llvm.cos", sym::floor => "llvm.floor", sym::ceil => "llvm.ceil", sym::trunc => "llvm.trunc", diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index 33ca13012add2..3806e602c56d4 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -92,10 +92,7 @@ fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -> hi | sym::copysignf32 | sym::copysignf64 | sym::copysignf128 - | sym::cosf16 - | sym::cosf32 - | sym::cosf64 - | sym::cosf128 + | sym::cos | sym::ctlz | sym::ctpop | sym::cttz @@ -182,10 +179,7 @@ fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -> hi | sym::saturating_add | sym::saturating_sub | sym::select_unpredictable - | sym::sinf16 - | sym::sinf32 - | sym::sinf64 - | sym::sinf128 + | sym::sin | sym::size_of | sym::sqrt | sym::sub_with_overflow @@ -385,15 +379,7 @@ pub(crate) fn check_intrinsic_type( sym::powif64 => (0, 0, vec![tcx.types.f64, tcx.types.i32], tcx.types.f64), sym::powif128 => (0, 0, vec![tcx.types.f128, tcx.types.i32], tcx.types.f128), - sym::sinf16 => (0, 0, vec![tcx.types.f16], tcx.types.f16), - sym::sinf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32), - sym::sinf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64), - sym::sinf128 => (0, 0, vec![tcx.types.f128], tcx.types.f128), - - sym::cosf16 => (0, 0, vec![tcx.types.f16], tcx.types.f16), - sym::cosf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32), - sym::cosf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64), - sym::cosf128 => (0, 0, vec![tcx.types.f128], tcx.types.f128), + sym::sin | sym::cos => (1, 0, vec![param(0)], param(0)), sym::powf16 => (0, 0, vec![tcx.types.f16, tcx.types.f16], tcx.types.f16), sym::powf32 => (0, 0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32), diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index a34a883f6dd55..37bd84ce328cd 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -712,10 +712,7 @@ symbols! { coroutine_state, coroutine_yield, coroutines, - cosf16, - cosf32, - cosf64, - cosf128, + cos, count, coverage, coverage_attribute, @@ -1883,11 +1880,8 @@ symbols! { simd_trunc, simd_with_exposed_provenance, simd_xor, + sin, since, - sinf16, - sinf32, - sinf64, - sinf128, size, size_of, size_of_val, diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index 9552590646d7a..6c520f25f9ee8 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -1056,63 +1056,21 @@ pub fn powif64(a: f64, x: i32) -> f64; #[rustc_nounwind] pub fn powif128(a: f128, x: i32) -> f128; -/// Returns the sine of an `f16`. +/// Returns the sine of a floating point value. /// -/// The stabilized version of this intrinsic is -/// [`f16::sin`](../../std/primitive.f16.html#method.sin) -#[rustc_intrinsic] -#[rustc_nounwind] -pub fn sinf16(x: f16) -> f16; -/// Returns the sine of an `f32`. -/// -/// The stabilized version of this intrinsic is -/// [`f32::sin`](../../std/primitive.f32.html#method.sin) -#[rustc_intrinsic] -#[rustc_nounwind] -pub fn sinf32(x: f32) -> f32; -/// Returns the sine of an `f64`. -/// -/// The stabilized version of this intrinsic is -/// [`f64::sin`](../../std/primitive.f64.html#method.sin) -#[rustc_intrinsic] -#[rustc_nounwind] -pub fn sinf64(x: f64) -> f64; -/// Returns the sine of an `f128`. -/// -/// The stabilized version of this intrinsic is -/// [`f128::sin`](../../std/primitive.f128.html#method.sin) +/// The stabilized versions of this intrinsic are available on the float +/// primitives via the `sin` method. For example, [`f32::sin`]. #[rustc_intrinsic] #[rustc_nounwind] -pub fn sinf128(x: f128) -> f128; +pub fn sin(x: T) -> T; -/// Returns the cosine of an `f16`. +/// Returns the cosine of a floating point value. /// -/// The stabilized version of this intrinsic is -/// [`f16::cos`](../../std/primitive.f16.html#method.cos) -#[rustc_intrinsic] -#[rustc_nounwind] -pub fn cosf16(x: f16) -> f16; -/// Returns the cosine of an `f32`. -/// -/// The stabilized version of this intrinsic is -/// [`f32::cos`](../../std/primitive.f32.html#method.cos) -#[rustc_intrinsic] -#[rustc_nounwind] -pub fn cosf32(x: f32) -> f32; -/// Returns the cosine of an `f64`. -/// -/// The stabilized version of this intrinsic is -/// [`f64::cos`](../../std/primitive.f64.html#method.cos) -#[rustc_intrinsic] -#[rustc_nounwind] -pub fn cosf64(x: f64) -> f64; -/// Returns the cosine of an `f128`. -/// -/// The stabilized version of this intrinsic is -/// [`f128::cos`](../../std/primitive.f128.html#method.cos) +/// The stabilized versions of this intrinsic are available on the float +/// primitives via the `cos` method. For example, [`f32::cos`]. #[rustc_intrinsic] #[rustc_nounwind] -pub fn cosf128(x: f128) -> f128; +pub fn cos(x: T) -> T; /// Raises an `f16` to an `f16` power. /// diff --git a/library/std/src/num/f128.rs b/library/std/src/num/f128.rs index 2c8898a6aa86a..756789128f70a 100644 --- a/library/std/src/num/f128.rs +++ b/library/std/src/num/f128.rs @@ -392,7 +392,7 @@ impl f128 { #[unstable(feature = "f128", issue = "116909")] #[must_use = "method returns a new number and does not mutate the original value"] pub fn sin(self) -> f128 { - intrinsics::sinf128(self) + intrinsics::sin(self) } /// Computes the cosine of a number (in radians). @@ -421,7 +421,7 @@ impl f128 { #[unstable(feature = "f128", issue = "116909")] #[must_use = "method returns a new number and does not mutate the original value"] pub fn cos(self) -> f128 { - intrinsics::cosf128(self) + intrinsics::cos(self) } /// Computes the tangent of a number (in radians). diff --git a/library/std/src/num/f16.rs b/library/std/src/num/f16.rs index 7ca266c8a5f60..d3ab2eaee0d1a 100644 --- a/library/std/src/num/f16.rs +++ b/library/std/src/num/f16.rs @@ -357,7 +357,7 @@ impl f16 { #[unstable(feature = "f16", issue = "116909")] #[must_use = "method returns a new number and does not mutate the original value"] pub fn sin(self) -> f16 { - intrinsics::sinf16(self) + intrinsics::sin(self) } /// Computes the cosine of a number (in radians). @@ -386,7 +386,7 @@ impl f16 { #[unstable(feature = "f16", issue = "116909")] #[must_use = "method returns a new number and does not mutate the original value"] pub fn cos(self) -> f16 { - intrinsics::cosf16(self) + intrinsics::cos(self) } /// Computes the tangent of a number (in radians). diff --git a/library/std/src/num/f32.rs b/library/std/src/num/f32.rs index 77e6824784605..c103572c925a4 100644 --- a/library/std/src/num/f32.rs +++ b/library/std/src/num/f32.rs @@ -697,7 +697,7 @@ impl f32 { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn sin(self) -> f32 { - intrinsics::sinf32(self) + intrinsics::sin(self) } /// Computes the cosine of a number (in radians). @@ -721,7 +721,7 @@ impl f32 { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn cos(self) -> f32 { - intrinsics::cosf32(self) + intrinsics::cos(self) } /// Computes the tangent of a number (in radians). diff --git a/library/std/src/num/f64.rs b/library/std/src/num/f64.rs index e0b9948a924db..496411111c026 100644 --- a/library/std/src/num/f64.rs +++ b/library/std/src/num/f64.rs @@ -697,7 +697,7 @@ impl f64 { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn sin(self) -> f64 { - intrinsics::sinf64(self) + intrinsics::sin(self) } /// Computes the cosine of a number (in radians). @@ -721,7 +721,7 @@ impl f64 { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn cos(self) -> f64 { - intrinsics::cosf64(self) + intrinsics::cos(self) } /// Computes the tangent of a number (in radians). From 1edf65b5664d75409450ca09c66a70c1bd666f3b Mon Sep 17 00:00:00 2001 From: N1ark Date: Mon, 16 Mar 2026 00:25:26 +0000 Subject: [PATCH 7/7] Genericize exp, exp2, log, log2, log10 --- .../src/intrinsics/mod.rs | 45 +++--- .../rustc_codegen_gcc/src/intrinsic/mod.rs | 25 +-- compiler/rustc_codegen_llvm/src/intrinsic.rs | 35 ++--- .../rustc_hir_analysis/src/check/intrinsic.rs | 52 +------ compiler/rustc_span/src/symbol.rs | 25 +-- library/core/src/intrinsics/mod.rs | 145 +++--------------- library/std/src/num/f128.rs | 10 +- library/std/src/num/f16.rs | 10 +- library/std/src/num/f32.rs | 10 +- library/std/src/num/f64.rs | 10 +- tests/ui/resolve/bad-env-capture.stderr | 17 +- tests/ui/resolve/bad-env-capture2.stderr | 17 +- tests/ui/resolve/bad-env-capture3.stderr | 17 +- tests/ui/resolve/bad-expr-path.stderr | 17 +- tests/ui/resolve/bad-expr-path2.stderr | 17 +- 15 files changed, 158 insertions(+), 294 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs index 733e664a02cca..3206b004ad355 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs @@ -314,14 +314,6 @@ fn codegen_float_intrinsic_call<'tcx>( ret: CPlace<'tcx>, ) -> bool { let (name, arg_count, ty, clif_ty) = match intrinsic { - sym::expf16 => ("expf16", 1, fx.tcx.types.f16, types::F16), - sym::expf32 => ("expf", 1, fx.tcx.types.f32, types::F32), - sym::expf64 => ("exp", 1, fx.tcx.types.f64, types::F64), - sym::expf128 => ("expf128", 1, fx.tcx.types.f128, types::F128), - sym::exp2f16 => ("exp2f16", 1, fx.tcx.types.f16, types::F16), - sym::exp2f32 => ("exp2f", 1, fx.tcx.types.f32, types::F32), - sym::exp2f64 => ("exp2", 1, fx.tcx.types.f64, types::F64), - sym::exp2f128 => ("exp2f128", 1, fx.tcx.types.f128, types::F128), sym::powif16 => ("__powisf2", 2, fx.tcx.types.f16, types::F16), // compiler-builtins sym::powif32 => ("__powisf2", 2, fx.tcx.types.f32, types::F32), // compiler-builtins sym::powif64 => ("__powidf2", 2, fx.tcx.types.f64, types::F64), // compiler-builtins @@ -330,18 +322,6 @@ fn codegen_float_intrinsic_call<'tcx>( sym::powf32 => ("powf", 2, fx.tcx.types.f32, types::F32), sym::powf64 => ("pow", 2, fx.tcx.types.f64, types::F64), sym::powf128 => ("powf128", 2, fx.tcx.types.f128, types::F128), - sym::logf16 => ("logf16", 1, fx.tcx.types.f16, types::F16), - sym::logf32 => ("logf", 1, fx.tcx.types.f32, types::F32), - sym::logf64 => ("log", 1, fx.tcx.types.f64, types::F64), - sym::logf128 => ("logf128", 1, fx.tcx.types.f128, types::F128), - sym::log2f16 => ("log2f16", 1, fx.tcx.types.f16, types::F16), - sym::log2f32 => ("log2f", 1, fx.tcx.types.f32, types::F32), - sym::log2f64 => ("log2", 1, fx.tcx.types.f64, types::F64), - sym::log2f128 => ("log2f128", 1, fx.tcx.types.f128, types::F128), - sym::log10f16 => ("log10f16", 1, fx.tcx.types.f16, types::F16), - sym::log10f32 => ("log10f", 1, fx.tcx.types.f32, types::F32), - sym::log10f64 => ("log10", 1, fx.tcx.types.f64, types::F64), - sym::log10f128 => ("log10f128", 1, fx.tcx.types.f128, types::F128), sym::fmaf16 => ("fmaf16", 3, fx.tcx.types.f16, types::F16), sym::fmaf32 => ("fmaf", 3, fx.tcx.types.f32, types::F32), sym::fmaf64 => ("fma", 3, fx.tcx.types.f64, types::F64), @@ -1111,6 +1091,11 @@ fn codegen_regular_intrinsic_call<'tcx>( | sym::sqrt | sym::sin | sym::cos + | sym::exp + | sym::exp2 + | sym::log + | sym::log2 + | sym::log10 | sym::floor | sym::ceil | sym::trunc @@ -1145,6 +1130,26 @@ fn codegen_regular_intrinsic_call<'tcx>( (sym::cos, F32) => Err("cosf"), (sym::cos, F64) => Err("cos"), (sym::cos, F128) => Err("cosf128"), + (sym::exp, F16) => Err("expf16"), + (sym::exp, F32) => Err("expf"), + (sym::exp, F64) => Err("exp"), + (sym::exp, F128) => Err("expf128"), + (sym::exp2, F16) => Err("exp2f16"), + (sym::exp2, F32) => Err("exp2f"), + (sym::exp2, F64) => Err("exp2"), + (sym::exp2, F128) => Err("exp2f128"), + (sym::log, F16) => Err("logf16"), + (sym::log, F32) => Err("logf"), + (sym::log, F64) => Err("log"), + (sym::log, F128) => Err("logf128"), + (sym::log2, F16) => Err("log2f16"), + (sym::log2, F32) => Err("log2f"), + (sym::log2, F64) => Err("log2"), + (sym::log2, F128) => Err("log2f128"), + (sym::log10, F16) => Err("log10f16"), + (sym::log10, F32) => Err("log10f"), + (sym::log10, F64) => Err("log10"), + (sym::log10, F128) => Err("log10f128"), (sym::floor, F32 | F64) => Ok(fx.bcx.ins().floor(x)), (sym::floor, F16) => Err("floorf16"), (sym::floor, F128) => Err("floorf128"), diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs index 43a9cd0b8efc8..f5278e89b0b26 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs +++ b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs @@ -49,16 +49,6 @@ fn get_simple_intrinsic<'gcc, 'tcx>( sym::powif64 => "__builtin_powi", sym::powf32 => "powf", sym::powf64 => "pow", - sym::expf32 => "expf", - sym::expf64 => "exp", - sym::exp2f32 => "exp2f", - sym::exp2f64 => "exp2", - sym::logf32 => "logf", - sym::logf64 => "log", - sym::log10f32 => "log10f", - sym::log10f64 => "log10", - sym::log2f32 => "log2f", - sym::log2f64 => "log2", sym::fmaf32 => "fmaf", sym::fmaf64 => "fma", // FIXME: calling `fma` from libc without FMA target feature uses expensive software emulation @@ -419,6 +409,11 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc | sym::sqrt | sym::sin | sym::cos + | sym::exp + | sym::exp2 + | sym::log + | sym::log2 + | sym::log10 | sym::floor | sym::ceil | sym::trunc @@ -452,6 +447,16 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc (sym::sin, F64) => Builtin("sin"), (sym::cos, F32) => Builtin("cosf"), (sym::cos, F64) => Builtin("cos"), + (sym::exp, F32) => Builtin("expf"), + (sym::exp, F64) => Builtin("exp"), + (sym::exp2, F32) => Builtin("exp2f"), + (sym::exp2, F64) => Builtin("exp2"), + (sym::log, F32) => Builtin("logf"), + (sym::log, F64) => Builtin("log"), + (sym::log2, F32) => Builtin("log2f"), + (sym::log2, F64) => Builtin("log2"), + (sym::log10, F32) => Builtin("log10f"), + (sym::log10, F64) => Builtin("log10"), (sym::floor, F16) => BuiltinF16Cast("__builtin_floorf"), (sym::floor, F32) => Builtin("floorf"), (sym::floor, F64) => Builtin("floor"), diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index da9331a96753f..8b8a3105a454e 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -57,31 +57,6 @@ fn call_simple_intrinsic<'ll, 'tcx>( sym::powf64 => ("llvm.pow", &[bx.type_f64()]), sym::powf128 => ("llvm.pow", &[bx.type_f128()]), - sym::expf16 => ("llvm.exp", &[bx.type_f16()]), - sym::expf32 => ("llvm.exp", &[bx.type_f32()]), - sym::expf64 => ("llvm.exp", &[bx.type_f64()]), - sym::expf128 => ("llvm.exp", &[bx.type_f128()]), - - sym::exp2f16 => ("llvm.exp2", &[bx.type_f16()]), - sym::exp2f32 => ("llvm.exp2", &[bx.type_f32()]), - sym::exp2f64 => ("llvm.exp2", &[bx.type_f64()]), - sym::exp2f128 => ("llvm.exp2", &[bx.type_f128()]), - - sym::logf16 => ("llvm.log", &[bx.type_f16()]), - sym::logf32 => ("llvm.log", &[bx.type_f32()]), - sym::logf64 => ("llvm.log", &[bx.type_f64()]), - sym::logf128 => ("llvm.log", &[bx.type_f128()]), - - sym::log10f16 => ("llvm.log10", &[bx.type_f16()]), - sym::log10f32 => ("llvm.log10", &[bx.type_f32()]), - sym::log10f64 => ("llvm.log10", &[bx.type_f64()]), - sym::log10f128 => ("llvm.log10", &[bx.type_f128()]), - - sym::log2f16 => ("llvm.log2", &[bx.type_f16()]), - sym::log2f32 => ("llvm.log2", &[bx.type_f32()]), - sym::log2f64 => ("llvm.log2", &[bx.type_f64()]), - sym::log2f128 => ("llvm.log2", &[bx.type_f128()]), - sym::fmaf16 => ("llvm.fma", &[bx.type_f16()]), sym::fmaf32 => ("llvm.fma", &[bx.type_f32()]), sym::fmaf64 => ("llvm.fma", &[bx.type_f64()]), @@ -457,6 +432,11 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { | sym::sqrt | sym::sin | sym::cos + | sym::exp + | sym::exp2 + | sym::log + | sym::log2 + | sym::log10 | sym::floor | sym::ceil | sym::trunc @@ -473,6 +453,11 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { sym::sqrt => "llvm.sqrt", sym::sin => "llvm.sin", sym::cos => "llvm.cos", + sym::exp => "llvm.exp", + sym::exp2 => "llvm.exp2", + sym::log => "llvm.log", + sym::log2 => "llvm.log2", + sym::log10 => "llvm.log10", sym::floor => "llvm.floor", sym::ceil => "llvm.ceil", sym::trunc => "llvm.trunc", diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index 3806e602c56d4..ea1ffb35ea6ff 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -97,14 +97,8 @@ fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -> hi | sym::ctpop | sym::cttz | sym::discriminant_value - | sym::exp2f16 - | sym::exp2f32 - | sym::exp2f64 - | sym::exp2f128 - | sym::expf16 - | sym::expf32 - | sym::expf64 - | sym::expf128 + | sym::exp + | sym::exp2 | sym::fabs | sym::fadd_algebraic | sym::fdiv_algebraic @@ -123,18 +117,9 @@ fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -> hi | sym::frem_algebraic | sym::fsub_algebraic | sym::is_val_statically_known - | sym::log2f16 - | sym::log2f32 - | sym::log2f64 - | sym::log2f128 - | sym::log10f16 - | sym::log10f32 - | sym::log10f64 - | sym::log10f128 - | sym::logf16 - | sym::logf32 - | sym::logf64 - | sym::logf128 + | sym::log + | sym::log2 + | sym::log10 | sym::maximum_number_nsz_f16 | sym::maximum_number_nsz_f32 | sym::maximum_number_nsz_f64 @@ -386,30 +371,9 @@ pub(crate) fn check_intrinsic_type( sym::powf64 => (0, 0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64), sym::powf128 => (0, 0, vec![tcx.types.f128, tcx.types.f128], tcx.types.f128), - sym::expf16 => (0, 0, vec![tcx.types.f16], tcx.types.f16), - sym::expf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32), - sym::expf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64), - sym::expf128 => (0, 0, vec![tcx.types.f128], tcx.types.f128), - - sym::exp2f16 => (0, 0, vec![tcx.types.f16], tcx.types.f16), - sym::exp2f32 => (0, 0, vec![tcx.types.f32], tcx.types.f32), - sym::exp2f64 => (0, 0, vec![tcx.types.f64], tcx.types.f64), - sym::exp2f128 => (0, 0, vec![tcx.types.f128], tcx.types.f128), - - sym::logf16 => (0, 0, vec![tcx.types.f16], tcx.types.f16), - sym::logf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32), - sym::logf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64), - sym::logf128 => (0, 0, vec![tcx.types.f128], tcx.types.f128), - - sym::log10f16 => (0, 0, vec![tcx.types.f16], tcx.types.f16), - sym::log10f32 => (0, 0, vec![tcx.types.f32], tcx.types.f32), - sym::log10f64 => (0, 0, vec![tcx.types.f64], tcx.types.f64), - sym::log10f128 => (0, 0, vec![tcx.types.f128], tcx.types.f128), - - sym::log2f16 => (0, 0, vec![tcx.types.f16], tcx.types.f16), - sym::log2f32 => (0, 0, vec![tcx.types.f32], tcx.types.f32), - sym::log2f64 => (0, 0, vec![tcx.types.f64], tcx.types.f64), - sym::log2f128 => (0, 0, vec![tcx.types.f128], tcx.types.f128), + sym::exp | sym::exp2 | sym::log | sym::log10 | sym::log2 => { + (1, 0, vec![param(0)], param(0)) + } sym::fmaf16 => (0, 0, vec![tcx.types.f16, tcx.types.f16, tcx.types.f16], tcx.types.f16), sym::fmaf32 => (0, 0, vec![tcx.types.f32, tcx.types.f32, tcx.types.f32], tcx.types.f32), diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 37bd84ce328cd..5727ce7315e55 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -867,16 +867,10 @@ symbols! { exhaustive_integer_patterns, exhaustive_patterns, existential_type, - exp2f16, - exp2f32, - exp2f64, - exp2f128, + exp, + exp2, expect, expected, - expf16, - expf32, - expf64, - expf128, explicit_extern_abis, explicit_generic_args_with_impl_trait, explicit_tail_calls, @@ -1151,19 +1145,10 @@ symbols! { loaded_from_disk, local, local_inner_macros, - log2f16, - log2f32, - log2f64, - log2f128, - log10f16, - log10f32, - log10f64, - log10f128, + log, + log2, + log10, log_syntax, - logf16, - logf32, - logf64, - logf128, loongarch32, loongarch64, loongarch_target_feature, diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index 6c520f25f9ee8..a233e3687dffc 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -1101,150 +1101,45 @@ pub fn powf64(a: f64, x: f64) -> f64; #[rustc_nounwind] pub fn powf128(a: f128, x: f128) -> f128; -/// Returns the exponential of an `f16`. +/// Returns the exponential of a floating point value. /// -/// The stabilized version of this intrinsic is -/// [`f16::exp`](../../std/primitive.f16.html#method.exp) -#[rustc_intrinsic] -#[rustc_nounwind] -pub fn expf16(x: f16) -> f16; -/// Returns the exponential of an `f32`. -/// -/// The stabilized version of this intrinsic is -/// [`f32::exp`](../../std/primitive.f32.html#method.exp) -#[rustc_intrinsic] -#[rustc_nounwind] -pub fn expf32(x: f32) -> f32; -/// Returns the exponential of an `f64`. -/// -/// The stabilized version of this intrinsic is -/// [`f64::exp`](../../std/primitive.f64.html#method.exp) -#[rustc_intrinsic] -#[rustc_nounwind] -pub fn expf64(x: f64) -> f64; -/// Returns the exponential of an `f128`. -/// -/// The stabilized version of this intrinsic is -/// [`f128::exp`](../../std/primitive.f128.html#method.exp) +/// The stabilized versions of this intrinsic are available on the float +/// primitives via the `exp` method. For example, [`f32::exp`]. #[rustc_intrinsic] #[rustc_nounwind] -pub fn expf128(x: f128) -> f128; +pub fn exp(x: T) -> T; -/// Returns 2 raised to the power of an `f16`. -/// -/// The stabilized version of this intrinsic is -/// [`f16::exp2`](../../std/primitive.f16.html#method.exp2) -#[rustc_intrinsic] -#[rustc_nounwind] -pub fn exp2f16(x: f16) -> f16; -/// Returns 2 raised to the power of an `f32`. +/// Returns 2 raised to the power of a floating point value. /// -/// The stabilized version of this intrinsic is -/// [`f32::exp2`](../../std/primitive.f32.html#method.exp2) -#[rustc_intrinsic] -#[rustc_nounwind] -pub fn exp2f32(x: f32) -> f32; -/// Returns 2 raised to the power of an `f64`. -/// -/// The stabilized version of this intrinsic is -/// [`f64::exp2`](../../std/primitive.f64.html#method.exp2) -#[rustc_intrinsic] -#[rustc_nounwind] -pub fn exp2f64(x: f64) -> f64; -/// Returns 2 raised to the power of an `f128`. -/// -/// The stabilized version of this intrinsic is -/// [`f128::exp2`](../../std/primitive.f128.html#method.exp2) +/// The stabilized versions of this intrinsic are available on the float +/// primitives via the `exp2` method. For example, [`f32::exp2`]. #[rustc_intrinsic] #[rustc_nounwind] -pub fn exp2f128(x: f128) -> f128; +pub fn exp2(x: T) -> T; -/// Returns the natural logarithm of an `f16`. -/// -/// The stabilized version of this intrinsic is -/// [`f16::ln`](../../std/primitive.f16.html#method.ln) -#[rustc_intrinsic] -#[rustc_nounwind] -pub fn logf16(x: f16) -> f16; -/// Returns the natural logarithm of an `f32`. -/// -/// The stabilized version of this intrinsic is -/// [`f32::ln`](../../std/primitive.f32.html#method.ln) -#[rustc_intrinsic] -#[rustc_nounwind] -pub fn logf32(x: f32) -> f32; -/// Returns the natural logarithm of an `f64`. -/// -/// The stabilized version of this intrinsic is -/// [`f64::ln`](../../std/primitive.f64.html#method.ln) -#[rustc_intrinsic] -#[rustc_nounwind] -pub fn logf64(x: f64) -> f64; -/// Returns the natural logarithm of an `f128`. +/// Returns the natural logarithm of a floating point value. /// -/// The stabilized version of this intrinsic is -/// [`f128::ln`](../../std/primitive.f128.html#method.ln) +/// The stabilized versions of this intrinsic are available on the float +/// primitives via the `ln` method. For example, [`f32::ln`]. #[rustc_intrinsic] #[rustc_nounwind] -pub fn logf128(x: f128) -> f128; +pub fn log(x: T) -> T; -/// Returns the base 10 logarithm of an `f16`. -/// -/// The stabilized version of this intrinsic is -/// [`f16::log10`](../../std/primitive.f16.html#method.log10) -#[rustc_intrinsic] -#[rustc_nounwind] -pub fn log10f16(x: f16) -> f16; -/// Returns the base 10 logarithm of an `f32`. +/// Returns the base 10 logarithm of a floating point value. /// -/// The stabilized version of this intrinsic is -/// [`f32::log10`](../../std/primitive.f32.html#method.log10) -#[rustc_intrinsic] -#[rustc_nounwind] -pub fn log10f32(x: f32) -> f32; -/// Returns the base 10 logarithm of an `f64`. -/// -/// The stabilized version of this intrinsic is -/// [`f64::log10`](../../std/primitive.f64.html#method.log10) -#[rustc_intrinsic] -#[rustc_nounwind] -pub fn log10f64(x: f64) -> f64; -/// Returns the base 10 logarithm of an `f128`. -/// -/// The stabilized version of this intrinsic is -/// [`f128::log10`](../../std/primitive.f128.html#method.log10) +/// The stabilized versions of this intrinsic are available on the float +/// primitives via the `log10` method. For example, [`f32::log10`]. #[rustc_intrinsic] #[rustc_nounwind] -pub fn log10f128(x: f128) -> f128; +pub fn log10(x: T) -> T; -/// Returns the base 2 logarithm of an `f16`. +/// Returns the base 2 logarithm of a floating point value. /// -/// The stabilized version of this intrinsic is -/// [`f16::log2`](../../std/primitive.f16.html#method.log2) -#[rustc_intrinsic] -#[rustc_nounwind] -pub fn log2f16(x: f16) -> f16; -/// Returns the base 2 logarithm of an `f32`. -/// -/// The stabilized version of this intrinsic is -/// [`f32::log2`](../../std/primitive.f32.html#method.log2) -#[rustc_intrinsic] -#[rustc_nounwind] -pub fn log2f32(x: f32) -> f32; -/// Returns the base 2 logarithm of an `f64`. -/// -/// The stabilized version of this intrinsic is -/// [`f64::log2`](../../std/primitive.f64.html#method.log2) -#[rustc_intrinsic] -#[rustc_nounwind] -pub fn log2f64(x: f64) -> f64; -/// Returns the base 2 logarithm of an `f128`. -/// -/// The stabilized version of this intrinsic is -/// [`f128::log2`](../../std/primitive.f128.html#method.log2) +/// The stabilized versions of this intrinsic are available on the float +/// primitives via the `log2` method. For example, [`f32::log2`]. #[rustc_intrinsic] #[rustc_nounwind] -pub fn log2f128(x: f128) -> f128; +pub fn log2(x: T) -> T; /// Returns `a * b + c` for `f16` values. /// diff --git a/library/std/src/num/f128.rs b/library/std/src/num/f128.rs index 756789128f70a..1895d2e0aff20 100644 --- a/library/std/src/num/f128.rs +++ b/library/std/src/num/f128.rs @@ -83,7 +83,7 @@ impl f128 { #[unstable(feature = "f128", issue = "116909")] #[must_use = "method returns a new number and does not mutate the original value"] pub fn exp(self) -> f128 { - intrinsics::expf128(self) + intrinsics::exp(self) } /// Returns `2^(self)`. @@ -113,7 +113,7 @@ impl f128 { #[unstable(feature = "f128", issue = "116909")] #[must_use = "method returns a new number and does not mutate the original value"] pub fn exp2(self) -> f128 { - intrinsics::exp2f128(self) + intrinsics::exp2(self) } /// Returns the natural logarithm of the number. @@ -158,7 +158,7 @@ impl f128 { #[unstable(feature = "f128", issue = "116909")] #[must_use = "method returns a new number and does not mutate the original value"] pub fn ln(self) -> f128 { - intrinsics::logf128(self) + intrinsics::log(self) } /// Returns the logarithm of the number with respect to an arbitrary base. @@ -248,7 +248,7 @@ impl f128 { #[unstable(feature = "f128", issue = "116909")] #[must_use = "method returns a new number and does not mutate the original value"] pub fn log2(self) -> f128 { - intrinsics::log2f128(self) + intrinsics::log2(self) } /// Returns the base 10 logarithm of the number. @@ -291,7 +291,7 @@ impl f128 { #[unstable(feature = "f128", issue = "116909")] #[must_use = "method returns a new number and does not mutate the original value"] pub fn log10(self) -> f128 { - intrinsics::log10f128(self) + intrinsics::log10(self) } /// Returns the cube root of a number. diff --git a/library/std/src/num/f16.rs b/library/std/src/num/f16.rs index d3ab2eaee0d1a..81284e82acb69 100644 --- a/library/std/src/num/f16.rs +++ b/library/std/src/num/f16.rs @@ -83,7 +83,7 @@ impl f16 { #[unstable(feature = "f16", issue = "116909")] #[must_use = "method returns a new number and does not mutate the original value"] pub fn exp(self) -> f16 { - intrinsics::expf16(self) + intrinsics::exp(self) } /// Returns `2^(self)`. @@ -113,7 +113,7 @@ impl f16 { #[unstable(feature = "f16", issue = "116909")] #[must_use = "method returns a new number and does not mutate the original value"] pub fn exp2(self) -> f16 { - intrinsics::exp2f16(self) + intrinsics::exp2(self) } /// Returns the natural logarithm of the number. @@ -158,7 +158,7 @@ impl f16 { #[unstable(feature = "f16", issue = "116909")] #[must_use = "method returns a new number and does not mutate the original value"] pub fn ln(self) -> f16 { - intrinsics::logf16(self) + intrinsics::log(self) } /// Returns the logarithm of the number with respect to an arbitrary base. @@ -248,7 +248,7 @@ impl f16 { #[unstable(feature = "f16", issue = "116909")] #[must_use = "method returns a new number and does not mutate the original value"] pub fn log2(self) -> f16 { - intrinsics::log2f16(self) + intrinsics::log2(self) } /// Returns the base 10 logarithm of the number. @@ -291,7 +291,7 @@ impl f16 { #[unstable(feature = "f16", issue = "116909")] #[must_use = "method returns a new number and does not mutate the original value"] pub fn log10(self) -> f16 { - intrinsics::log10f16(self) + intrinsics::log10(self) } /// Compute the distance between the origin and a point (`x`, `y`) on the diff --git a/library/std/src/num/f32.rs b/library/std/src/num/f32.rs index c103572c925a4..82def2b5befa0 100644 --- a/library/std/src/num/f32.rs +++ b/library/std/src/num/f32.rs @@ -409,7 +409,7 @@ impl f32 { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn exp(self) -> f32 { - intrinsics::expf32(self) + intrinsics::exp(self) } /// Returns `2^(self)`. @@ -434,7 +434,7 @@ impl f32 { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn exp2(self) -> f32 { - intrinsics::exp2f32(self) + intrinsics::exp2(self) } /// Returns the natural logarithm of the number. @@ -469,7 +469,7 @@ impl f32 { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn ln(self) -> f32 { - intrinsics::logf32(self) + intrinsics::log(self) } /// Returns the logarithm of the number with respect to an arbitrary base. @@ -539,7 +539,7 @@ impl f32 { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn log2(self) -> f32 { - intrinsics::log2f32(self) + intrinsics::log2(self) } /// Returns the base 10 logarithm of the number. @@ -572,7 +572,7 @@ impl f32 { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn log10(self) -> f32 { - intrinsics::log10f32(self) + intrinsics::log10(self) } /// The positive difference of two numbers. diff --git a/library/std/src/num/f64.rs b/library/std/src/num/f64.rs index 496411111c026..1e4c94b906e89 100644 --- a/library/std/src/num/f64.rs +++ b/library/std/src/num/f64.rs @@ -409,7 +409,7 @@ impl f64 { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn exp(self) -> f64 { - intrinsics::expf64(self) + intrinsics::exp(self) } /// Returns `2^(self)`. @@ -434,7 +434,7 @@ impl f64 { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn exp2(self) -> f64 { - intrinsics::exp2f64(self) + intrinsics::exp2(self) } /// Returns the natural logarithm of the number. @@ -469,7 +469,7 @@ impl f64 { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn ln(self) -> f64 { - intrinsics::logf64(self) + intrinsics::log(self) } /// Returns the logarithm of the number with respect to an arbitrary base. @@ -539,7 +539,7 @@ impl f64 { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn log2(self) -> f64 { - intrinsics::log2f64(self) + intrinsics::log2(self) } /// Returns the base 10 logarithm of the number. @@ -572,7 +572,7 @@ impl f64 { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn log10(self) -> f64 { - intrinsics::log10f64(self) + intrinsics::log10(self) } /// The positive difference of two numbers. diff --git a/tests/ui/resolve/bad-env-capture.stderr b/tests/ui/resolve/bad-env-capture.stderr index a3a15ca245b2a..a8456ca33d46c 100644 --- a/tests/ui/resolve/bad-env-capture.stderr +++ b/tests/ui/resolve/bad-env-capture.stderr @@ -6,17 +6,22 @@ LL | fn bar() { log(debug, x); } | = help: use the `|| { ... }` closure form instead -error[E0425]: cannot find value `debug` in this scope - --> $DIR/bad-env-capture.rs:3:20 - | -LL | fn bar() { log(debug, x); } - | ^^^^^ not found in this scope - error[E0425]: cannot find function `log` in this scope --> $DIR/bad-env-capture.rs:3:16 | LL | fn bar() { log(debug, x); } | ^^^ not found in this scope + | +help: consider importing this function + | +LL + use std::intrinsics::log; + | + +error[E0425]: cannot find value `debug` in this scope + --> $DIR/bad-env-capture.rs:3:20 + | +LL | fn bar() { log(debug, x); } + | ^^^^^ not found in this scope error: aborting due to 3 previous errors diff --git a/tests/ui/resolve/bad-env-capture2.stderr b/tests/ui/resolve/bad-env-capture2.stderr index 403fe2d32b980..4e8ebb621b671 100644 --- a/tests/ui/resolve/bad-env-capture2.stderr +++ b/tests/ui/resolve/bad-env-capture2.stderr @@ -6,17 +6,22 @@ LL | fn bar() { log(debug, x); } | = help: use the `|| { ... }` closure form instead -error[E0425]: cannot find value `debug` in this scope - --> $DIR/bad-env-capture2.rs:2:20 - | -LL | fn bar() { log(debug, x); } - | ^^^^^ not found in this scope - error[E0425]: cannot find function `log` in this scope --> $DIR/bad-env-capture2.rs:2:16 | LL | fn bar() { log(debug, x); } | ^^^ not found in this scope + | +help: consider importing this function + | +LL + use std::intrinsics::log; + | + +error[E0425]: cannot find value `debug` in this scope + --> $DIR/bad-env-capture2.rs:2:20 + | +LL | fn bar() { log(debug, x); } + | ^^^^^ not found in this scope error: aborting due to 3 previous errors diff --git a/tests/ui/resolve/bad-env-capture3.stderr b/tests/ui/resolve/bad-env-capture3.stderr index 962eb72ee68bf..65c39ace65d96 100644 --- a/tests/ui/resolve/bad-env-capture3.stderr +++ b/tests/ui/resolve/bad-env-capture3.stderr @@ -6,17 +6,22 @@ LL | fn bar() { log(debug, x); } | = help: use the `|| { ... }` closure form instead -error[E0425]: cannot find value `debug` in this scope - --> $DIR/bad-env-capture3.rs:3:24 - | -LL | fn bar() { log(debug, x); } - | ^^^^^ not found in this scope - error[E0425]: cannot find function `log` in this scope --> $DIR/bad-env-capture3.rs:3:20 | LL | fn bar() { log(debug, x); } | ^^^ not found in this scope + | +help: consider importing this function + | +LL + use std::intrinsics::log; + | + +error[E0425]: cannot find value `debug` in this scope + --> $DIR/bad-env-capture3.rs:3:24 + | +LL | fn bar() { log(debug, x); } + | ^^^^^ not found in this scope error: aborting due to 3 previous errors diff --git a/tests/ui/resolve/bad-expr-path.stderr b/tests/ui/resolve/bad-expr-path.stderr index 0392c1fa23993..be2e3a1e90350 100644 --- a/tests/ui/resolve/bad-expr-path.stderr +++ b/tests/ui/resolve/bad-expr-path.stderr @@ -1,3 +1,14 @@ +error[E0425]: cannot find function `log` in this scope + --> $DIR/bad-expr-path.rs:4:5 + | +LL | log(debug, m1::arguments); + | ^^^ not found in this scope + | +help: consider importing this function + | +LL + use std::intrinsics::log; + | + error[E0425]: cannot find value `debug` in this scope --> $DIR/bad-expr-path.rs:4:9 | @@ -19,12 +30,6 @@ LL | fn main(arguments: Vec) { = note: expected signature `fn()` found signature `fn(Vec)` -error[E0425]: cannot find function `log` in this scope - --> $DIR/bad-expr-path.rs:4:5 - | -LL | log(debug, m1::arguments); - | ^^^ not found in this scope - error: aborting due to 4 previous errors Some errors have detailed explanations: E0425, E0580. diff --git a/tests/ui/resolve/bad-expr-path2.stderr b/tests/ui/resolve/bad-expr-path2.stderr index 9238b1f7023e5..0be0b54fb820d 100644 --- a/tests/ui/resolve/bad-expr-path2.stderr +++ b/tests/ui/resolve/bad-expr-path2.stderr @@ -1,3 +1,14 @@ +error[E0425]: cannot find function `log` in this scope + --> $DIR/bad-expr-path2.rs:6:5 + | +LL | log(debug, m1::arguments); + | ^^^ not found in this scope + | +help: consider importing this function + | +LL + use std::intrinsics::log; + | + error[E0425]: cannot find value `debug` in this scope --> $DIR/bad-expr-path2.rs:6:9 | @@ -19,12 +30,6 @@ LL | fn main(arguments: Vec) { = note: expected signature `fn()` found signature `fn(Vec)` -error[E0425]: cannot find function `log` in this scope - --> $DIR/bad-expr-path2.rs:6:5 - | -LL | log(debug, m1::arguments); - | ^^^ not found in this scope - error: aborting due to 4 previous errors Some errors have detailed explanations: E0423, E0425, E0580.