Skip to content

Commit 2205317

Browse files
authored
Merge pull request #863 from N1ark/tidy-float-intrinsics
Tidy handling of intrinsics for `f128`
2 parents 66d6f7b + 41f5085 commit 2205317

1 file changed

Lines changed: 68 additions & 97 deletions

File tree

src/intrinsic/mod.rs

Lines changed: 68 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -95,80 +95,10 @@ fn get_simple_intrinsic<'gcc, 'tcx>(
9595
Some(cx.context.get_builtin_function(gcc_name))
9696
}
9797

98-
// TODO(antoyo): We can probably remove these and use the fallback intrinsic implementation.
99-
fn get_simple_function<'gcc, 'tcx>(
100-
cx: &CodegenCx<'gcc, 'tcx>,
101-
name: Symbol,
102-
) -> Option<Function<'gcc>> {
103-
let (return_type, parameters, func_name) = match name {
104-
sym::minimumf32 => {
105-
let parameters = [
106-
cx.context.new_parameter(None, cx.float_type, "a"),
107-
cx.context.new_parameter(None, cx.float_type, "b"),
108-
];
109-
(cx.float_type, parameters, "fminimumf")
110-
}
111-
sym::minimumf64 => {
112-
let parameters = [
113-
cx.context.new_parameter(None, cx.double_type, "a"),
114-
cx.context.new_parameter(None, cx.double_type, "b"),
115-
];
116-
(cx.double_type, parameters, "fminimum")
117-
}
118-
sym::minimumf128 => {
119-
let f128_type = cx.type_f128();
120-
// GCC doesn't have the intrinsic we want so we use the compiler-builtins one
121-
// https://docs.rs/compiler_builtins/latest/compiler_builtins/math/full_availability/fn.fminimumf128.html
122-
let parameters = [
123-
cx.context.new_parameter(None, f128_type, "a"),
124-
cx.context.new_parameter(None, f128_type, "b"),
125-
];
126-
(f128_type, parameters, "fminimumf128")
127-
}
128-
sym::maximumf32 => {
129-
let parameters = [
130-
cx.context.new_parameter(None, cx.float_type, "a"),
131-
cx.context.new_parameter(None, cx.float_type, "b"),
132-
];
133-
(cx.float_type, parameters, "fmaximumf")
134-
}
135-
sym::maximumf64 => {
136-
let parameters = [
137-
cx.context.new_parameter(None, cx.double_type, "a"),
138-
cx.context.new_parameter(None, cx.double_type, "b"),
139-
];
140-
(cx.double_type, parameters, "fmaximum")
141-
}
142-
sym::maximumf128 => {
143-
let f128_type = cx.type_f128();
144-
// GCC doesn't have the intrinsic we want so we use the compiler-builtins one
145-
// https://docs.rs/compiler_builtins/latest/compiler_builtins/math/full_availability/fn.fmaximumf128.html
146-
let parameters = [
147-
cx.context.new_parameter(None, f128_type, "a"),
148-
cx.context.new_parameter(None, f128_type, "b"),
149-
];
150-
(f128_type, parameters, "fmaximumf128")
151-
}
152-
_ => return None,
153-
};
154-
Some(cx.context.new_function(
155-
None,
156-
FunctionType::Extern,
157-
return_type,
158-
&parameters,
159-
func_name,
160-
false,
161-
))
162-
}
163-
16498
fn get_simple_function_f128<'gcc, 'tcx>(
16599
cx: &CodegenCx<'gcc, 'tcx>,
166100
name: Symbol,
167-
) -> Option<Function<'gcc>> {
168-
if !cx.supports_f128_type {
169-
return None;
170-
}
171-
101+
) -> Function<'gcc> {
172102
let f128_type = cx.type_f128();
173103
let func_name = match name {
174104
sym::ceilf128 => "ceilf128",
@@ -178,34 +108,35 @@ fn get_simple_function_f128<'gcc, 'tcx>(
178108
sym::roundf128 => "roundf128",
179109
sym::round_ties_even_f128 => "roundevenf128",
180110
sym::sqrtf128 => "sqrtf128",
181-
_ => return None,
111+
_ => unreachable!(),
182112
};
183-
Some(cx.context.new_function(
113+
cx.context.new_function(
184114
None,
185115
FunctionType::Extern,
186116
f128_type,
187117
&[cx.context.new_parameter(None, f128_type, "a")],
188118
func_name,
189119
false,
190-
))
120+
)
191121
}
192122

193123
fn get_simple_function_f128_2args<'gcc, 'tcx>(
194124
cx: &CodegenCx<'gcc, 'tcx>,
195125
name: Symbol,
196-
) -> Option<Function<'gcc>> {
197-
if !cx.supports_f128_type {
198-
return None;
199-
}
200-
126+
) -> Function<'gcc> {
201127
let f128_type = cx.type_f128();
202128
let func_name = match name {
129+
// GCC doesn't have the intrinsic we want so we use the compiler-builtins one
130+
// https://docs.rs/compiler_builtins/latest/compiler_builtins/math/full_availability/fn.fmaximumf128.html
131+
// https://docs.rs/compiler_builtins/latest/compiler_builtins/math/full_availability/fn.fminimumf128.html
132+
sym::maximumf128 => "fmaximumf128",
133+
sym::minimumf128 => "fminimumf128",
203134
sym::maxnumf128 => "fmaxf128",
204135
sym::minnumf128 => "fminf128",
205136
sym::copysignf128 => "copysignf128",
206-
_ => return None,
137+
_ => unreachable!(),
207138
};
208-
Some(cx.context.new_function(
139+
cx.context.new_function(
209140
None,
210141
FunctionType::Extern,
211142
f128_type,
@@ -215,7 +146,7 @@ fn get_simple_function_f128_2args<'gcc, 'tcx>(
215146
],
216147
func_name,
217148
false,
218-
))
149+
)
219150
}
220151

221152
fn f16_builtin<'gcc, 'tcx>(
@@ -233,13 +164,6 @@ fn f16_builtin<'gcc, 'tcx>(
233164
sym::maxnumf16 => "__builtin_fmaxf",
234165
sym::minnumf16 => "__builtin_fminf",
235166
sym::powf16 => "__builtin_powf",
236-
sym::powif16 => {
237-
let func = cx.context.get_builtin_function("__builtin_powif");
238-
let arg0 = cx.context.new_cast(None, args[0].immediate(), f32_type);
239-
let args = [arg0, args[1].immediate()];
240-
let result = cx.context.new_call(None, func, &args);
241-
return cx.context.new_cast(None, result, cx.type_f16());
242-
}
243167
sym::roundf16 => "__builtin_roundf",
244168
sym::round_ties_even_f16 => "__builtin_rintf",
245169
sym::sqrtf16 => "__builtin_sqrtf",
@@ -269,11 +193,6 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
269193
let fn_args = instance.args;
270194

271195
let simple = get_simple_intrinsic(self, name);
272-
// TODO(antoyo): Only call get_simple_function_f128 and get_simple_function_f128_2args when
273-
// it is the symbols for the supported f128 builtins.
274-
let simple_func = get_simple_function(self, name)
275-
.or_else(|| get_simple_function_f128(self, name))
276-
.or_else(|| get_simple_function_f128_2args(self, name));
277196

278197
let value = match name {
279198
_ if simple.is_some() => {
@@ -284,8 +203,26 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
284203
&args.iter().map(|arg| arg.immediate()).collect::<Vec<_>>(),
285204
)
286205
}
287-
_ if simple_func.is_some() => {
288-
let func = simple_func.expect("simple function");
206+
// TODO(antoyo): We can probably remove these and use the fallback intrinsic implementation.
207+
sym::minimumf32 | sym::minimumf64 | sym::maximumf32 | sym::maximumf64 => {
208+
let (ty, func_name) = match name {
209+
sym::minimumf32 => (self.cx.float_type, "fminimumf"),
210+
sym::maximumf32 => (self.cx.float_type, "fmaximumf"),
211+
sym::minimumf64 => (self.cx.double_type, "fminimum"),
212+
sym::maximumf64 => (self.cx.double_type, "fmaximum"),
213+
_ => unreachable!(),
214+
};
215+
let func = self.cx.context.new_function(
216+
None,
217+
FunctionType::Extern,
218+
ty,
219+
&[
220+
self.cx.context.new_parameter(None, ty, "a"),
221+
self.cx.context.new_parameter(None, ty, "b"),
222+
],
223+
func_name,
224+
false,
225+
);
289226
self.cx.context.new_call(
290227
self.location,
291228
func,
@@ -300,11 +237,38 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
300237
| sym::maxnumf16
301238
| sym::minnumf16
302239
| sym::powf16
303-
| sym::powif16
304240
| sym::roundf16
305241
| sym::round_ties_even_f16
306242
| sym::sqrtf16
307243
| sym::truncf16 => f16_builtin(self, name, args),
244+
sym::ceilf128
245+
| sym::fabsf128
246+
| sym::floorf128
247+
| sym::truncf128
248+
| sym::roundf128
249+
| sym::round_ties_even_f128
250+
| sym::sqrtf128
251+
if self.cx.supports_f128_type =>
252+
{
253+
self.cx.context.new_call(
254+
self.location,
255+
get_simple_function_f128(self, name),
256+
&args.iter().map(|arg| arg.immediate()).collect::<Vec<_>>(),
257+
)
258+
}
259+
sym::maximumf128
260+
| sym::minimumf128
261+
| sym::maxnumf128
262+
| sym::minnumf128
263+
| sym::copysignf128
264+
if self.cx.supports_f128_type =>
265+
{
266+
self.cx.context.new_call(
267+
self.location,
268+
get_simple_function_f128_2args(self, name),
269+
&args.iter().map(|arg| arg.immediate()).collect::<Vec<_>>(),
270+
)
271+
}
308272
sym::fmaf128 => {
309273
let f128_type = self.cx.type_f128();
310274
let func = self.cx.context.new_function(
@@ -325,6 +289,13 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
325289
&args.iter().map(|arg| arg.immediate()).collect::<Vec<_>>(),
326290
)
327291
}
292+
sym::powif16 => {
293+
let func = self.cx.context.get_builtin_function("__builtin_powif");
294+
let arg0 = self.cx.context.new_cast(None, args[0].immediate(), self.cx.type_f32());
295+
let args = [arg0, args[1].immediate()];
296+
let result = self.cx.context.new_call(None, func, &args);
297+
self.cx.context.new_cast(None, result, self.cx.type_f16())
298+
}
328299
sym::powif128 => {
329300
let f128_type = self.cx.type_f128();
330301
let func = self.cx.context.new_function(

0 commit comments

Comments
 (0)