From 25a7f23f90746f1f4dee8390568bc98670c3e2c0 Mon Sep 17 00:00:00 2001 From: N1ark Date: Sat, 14 Mar 2026 13:16:38 +0000 Subject: [PATCH 1/5] Move `powif16` next to `powif128` --- src/intrinsic/mod.rs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/intrinsic/mod.rs b/src/intrinsic/mod.rs index ffcae6a1cdd..0b1ef083fd7 100644 --- a/src/intrinsic/mod.rs +++ b/src/intrinsic/mod.rs @@ -233,13 +233,6 @@ fn f16_builtin<'gcc, 'tcx>( sym::maxnumf16 => "__builtin_fmaxf", sym::minnumf16 => "__builtin_fminf", sym::powf16 => "__builtin_powf", - sym::powif16 => { - let func = cx.context.get_builtin_function("__builtin_powif"); - let arg0 = cx.context.new_cast(None, args[0].immediate(), f32_type); - let args = [arg0, args[1].immediate()]; - 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", @@ -300,7 +293,6 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc | sym::maxnumf16 | sym::minnumf16 | sym::powf16 - | sym::powif16 | sym::roundf16 | sym::round_ties_even_f16 | sym::sqrtf16 @@ -325,6 +317,13 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc &args.iter().map(|arg| arg.immediate()).collect::>(), ) } + sym::powif16 => { + let func = self.cx.context.get_builtin_function("__builtin_powif"); + let arg0 = self.cx.context.new_cast(None, args[0].immediate(), self.cx.type_f32()); + let args = [arg0, args[1].immediate()]; + let result = self.cx.context.new_call(None, func, &args); + self.cx.context.new_cast(None, result, self.cx.type_f16()) + } sym::powif128 => { let f128_type = self.cx.type_f128(); let func = self.cx.context.new_function( From 99aecacf24a031da2a5f2a3eaaee8f6947d09bef Mon Sep 17 00:00:00 2001 From: N1ark Date: Sat, 14 Mar 2026 13:17:57 +0000 Subject: [PATCH 2/5] handle minimumf128/maximumf128 in get_simple_function_f128_2args --- src/intrinsic/mod.rs | 25 +++++-------------------- 1 file changed, 5 insertions(+), 20 deletions(-) diff --git a/src/intrinsic/mod.rs b/src/intrinsic/mod.rs index 0b1ef083fd7..923d74eea8d 100644 --- a/src/intrinsic/mod.rs +++ b/src/intrinsic/mod.rs @@ -115,16 +115,6 @@ fn get_simple_function<'gcc, 'tcx>( ]; (cx.double_type, parameters, "fminimum") } - sym::minimumf128 => { - let f128_type = cx.type_f128(); - // GCC doesn't have the intrinsic we want so we use the compiler-builtins one - // https://docs.rs/compiler_builtins/latest/compiler_builtins/math/full_availability/fn.fminimumf128.html - let parameters = [ - cx.context.new_parameter(None, f128_type, "a"), - cx.context.new_parameter(None, f128_type, "b"), - ]; - (f128_type, parameters, "fminimumf128") - } sym::maximumf32 => { let parameters = [ cx.context.new_parameter(None, cx.float_type, "a"), @@ -139,16 +129,6 @@ fn get_simple_function<'gcc, 'tcx>( ]; (cx.double_type, parameters, "fmaximum") } - sym::maximumf128 => { - let f128_type = cx.type_f128(); - // GCC doesn't have the intrinsic we want so we use the compiler-builtins one - // https://docs.rs/compiler_builtins/latest/compiler_builtins/math/full_availability/fn.fmaximumf128.html - let parameters = [ - cx.context.new_parameter(None, f128_type, "a"), - cx.context.new_parameter(None, f128_type, "b"), - ]; - (f128_type, parameters, "fmaximumf128") - } _ => return None, }; Some(cx.context.new_function( @@ -200,6 +180,11 @@ fn get_simple_function_f128_2args<'gcc, 'tcx>( let f128_type = cx.type_f128(); let func_name = match name { + // GCC doesn't have the intrinsic we want so we use the compiler-builtins one + // https://docs.rs/compiler_builtins/latest/compiler_builtins/math/full_availability/fn.fmaximumf128.html + // https://docs.rs/compiler_builtins/latest/compiler_builtins/math/full_availability/fn.fminimumf128.html + sym::maximumf128 => "fmaximumf128", + sym::minimumf128 => "fminimumf128", sym::maxnumf128 => "fmaxf128", sym::minnumf128 => "fminf128", sym::copysignf128 => "copysignf128", From f67c935c39ab6134ae207c83111d7fcca0f157f3 Mon Sep 17 00:00:00 2001 From: N1ark Date: Sat, 14 Mar 2026 13:19:24 +0000 Subject: [PATCH 3/5] Simplify get_simple_function --- src/intrinsic/mod.rs | 38 +++++++------------------------------- 1 file changed, 7 insertions(+), 31 deletions(-) diff --git a/src/intrinsic/mod.rs b/src/intrinsic/mod.rs index 923d74eea8d..6311e20a2d6 100644 --- a/src/intrinsic/mod.rs +++ b/src/intrinsic/mod.rs @@ -100,42 +100,18 @@ fn get_simple_function<'gcc, 'tcx>( cx: &CodegenCx<'gcc, 'tcx>, name: Symbol, ) -> Option> { - let (return_type, parameters, func_name) = match name { - sym::minimumf32 => { - let parameters = [ - cx.context.new_parameter(None, cx.float_type, "a"), - cx.context.new_parameter(None, cx.float_type, "b"), - ]; - (cx.float_type, parameters, "fminimumf") - } - sym::minimumf64 => { - let parameters = [ - cx.context.new_parameter(None, cx.double_type, "a"), - cx.context.new_parameter(None, cx.double_type, "b"), - ]; - (cx.double_type, parameters, "fminimum") - } - sym::maximumf32 => { - let parameters = [ - cx.context.new_parameter(None, cx.float_type, "a"), - cx.context.new_parameter(None, cx.float_type, "b"), - ]; - (cx.float_type, parameters, "fmaximumf") - } - sym::maximumf64 => { - let parameters = [ - cx.context.new_parameter(None, cx.double_type, "a"), - cx.context.new_parameter(None, cx.double_type, "b"), - ]; - (cx.double_type, parameters, "fmaximum") - } + let (ty, func_name) = match name { + sym::minimumf32 => (cx.float_type, "fminimumf"), + sym::minimumf64 => (cx.double_type, "fminimum"), + sym::maximumf32 => (cx.float_type, "fmaximumf"), + sym::maximumf64 => (cx.double_type, "fmaximum"), _ => return None, }; Some(cx.context.new_function( None, FunctionType::Extern, - return_type, - ¶meters, + ty, + &[cx.context.new_parameter(None, ty, "a"), cx.context.new_parameter(None, ty, "b")], func_name, false, )) From 2acd77eb9ba4d5c33945e34a6589a43fac03cf1a Mon Sep 17 00:00:00 2001 From: N1ark Date: Sat, 14 Mar 2026 13:22:55 +0000 Subject: [PATCH 4/5] Fix TODO: only call f128 fns if is a f128 fn --- src/intrinsic/mod.rs | 58 ++++++++++++++++++++++++++++---------------- 1 file changed, 37 insertions(+), 21 deletions(-) diff --git a/src/intrinsic/mod.rs b/src/intrinsic/mod.rs index 6311e20a2d6..abb40257bee 100644 --- a/src/intrinsic/mod.rs +++ b/src/intrinsic/mod.rs @@ -120,11 +120,7 @@ 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", @@ -134,26 +130,22 @@ fn get_simple_function_f128<'gcc, 'tcx>( 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; - } - +) -> Function<'gcc> { let f128_type = cx.type_f128(); let func_name = match name { // GCC doesn't have the intrinsic we want so we use the compiler-builtins one @@ -164,9 +156,9 @@ fn get_simple_function_f128_2args<'gcc, 'tcx>( sym::maxnumf128 => "fmaxf128", sym::minnumf128 => "fminf128", sym::copysignf128 => "copysignf128", - _ => return None, + _ => unreachable!(), }; - Some(cx.context.new_function( + cx.context.new_function( None, FunctionType::Extern, f128_type, @@ -176,7 +168,7 @@ fn get_simple_function_f128_2args<'gcc, 'tcx>( ], func_name, false, - )) + ) } fn f16_builtin<'gcc, 'tcx>( @@ -223,11 +215,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc let fn_args = instance.args; let simple = get_simple_intrinsic(self, name); - // TODO(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() => { @@ -258,6 +246,34 @@ 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::fabsf128 + | sym::floorf128 + | sym::truncf128 + | sym::roundf128 + | sym::round_ties_even_f128 + | sym::sqrtf128 + if self.cx.supports_f128_type => + { + self.cx.context.new_call( + self.location, + get_simple_function_f128(self, name), + &args.iter().map(|arg| arg.immediate()).collect::>(), + ) + } + sym::maximumf128 + | sym::minimumf128 + | sym::maxnumf128 + | sym::minnumf128 + | sym::copysignf128 + if self.cx.supports_f128_type => + { + self.cx.context.new_call( + self.location, + get_simple_function_f128_2args(self, name), + &args.iter().map(|arg| arg.immediate()).collect::>(), + ) + } sym::fmaf128 => { let f128_type = self.cx.type_f128(); let func = self.cx.context.new_function( From 41f5085725bb9406ba9507dfe91bc52ee675b9bc Mon Sep 17 00:00:00 2001 From: N1ark Date: Sat, 14 Mar 2026 13:26:25 +0000 Subject: [PATCH 5/5] Inline `get_simple_function` --- src/intrinsic/mod.rs | 45 ++++++++++++++++++++------------------------ 1 file changed, 20 insertions(+), 25 deletions(-) diff --git a/src/intrinsic/mod.rs b/src/intrinsic/mod.rs index abb40257bee..22d0522f79a 100644 --- a/src/intrinsic/mod.rs +++ b/src/intrinsic/mod.rs @@ -95,28 +95,6 @@ fn get_simple_intrinsic<'gcc, 'tcx>( Some(cx.context.get_builtin_function(gcc_name)) } -// TODO(antoyo): We can probably remove these and use the fallback intrinsic implementation. -fn get_simple_function<'gcc, 'tcx>( - cx: &CodegenCx<'gcc, 'tcx>, - name: Symbol, -) -> Option> { - let (ty, func_name) = match name { - sym::minimumf32 => (cx.float_type, "fminimumf"), - sym::minimumf64 => (cx.double_type, "fminimum"), - sym::maximumf32 => (cx.float_type, "fmaximumf"), - sym::maximumf64 => (cx.double_type, "fmaximum"), - _ => return None, - }; - Some(cx.context.new_function( - None, - FunctionType::Extern, - ty, - &[cx.context.new_parameter(None, ty, "a"), cx.context.new_parameter(None, ty, "b")], - func_name, - false, - )) -} - fn get_simple_function_f128<'gcc, 'tcx>( cx: &CodegenCx<'gcc, 'tcx>, name: Symbol, @@ -215,7 +193,6 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc let fn_args = instance.args; let simple = get_simple_intrinsic(self, name); - let simple_func = get_simple_function(self, name); let value = match name { _ if simple.is_some() => { @@ -226,8 +203,26 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc &args.iter().map(|arg| arg.immediate()).collect::>(), ) } - _ if simple_func.is_some() => { - let func = simple_func.expect("simple function"); + // TODO(antoyo): We can probably remove these and use the fallback intrinsic implementation. + sym::minimumf32 | sym::minimumf64 | sym::maximumf32 | sym::maximumf64 => { + let (ty, func_name) = match name { + sym::minimumf32 => (self.cx.float_type, "fminimumf"), + sym::maximumf32 => (self.cx.float_type, "fmaximumf"), + sym::minimumf64 => (self.cx.double_type, "fminimum"), + sym::maximumf64 => (self.cx.double_type, "fmaximum"), + _ => unreachable!(), + }; + let func = self.cx.context.new_function( + None, + FunctionType::Extern, + ty, + &[ + self.cx.context.new_parameter(None, ty, "a"), + self.cx.context.new_parameter(None, ty, "b"), + ], + func_name, + false, + ); self.cx.context.new_call( self.location, func,