Skip to content

Commit dd6d5e2

Browse files
committed
Fix f128 intrinsics
1 parent dca28e5 commit dd6d5e2

File tree

4 files changed

+116
-18
lines changed

4 files changed

+116
-18
lines changed

build_system/src/test.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -680,7 +680,7 @@ fn test_libcore(env: &Env, args: &TestArg) -> Result<(), String> {
680680
println!("[TEST] libcore");
681681
let path = get_sysroot_dir().join("sysroot_src/library/coretests");
682682
let _ = remove_dir_all(path.join("target"));
683-
run_cargo_command(&[&"test"], Some(&path), env, args)?;
683+
run_cargo_command(&[&"test", &"--release"], Some(&path), env, args)?;
684684
Ok(())
685685
}
686686

src/builder.rs

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ use std::convert::TryFrom;
44
use std::ops::Deref;
55

66
use gccjit::{
7-
BinaryOp, Block, ComparisonOp, Context, Function, LValue, Location, RValue, ToRValue, Type,
8-
UnaryOp,
7+
BinaryOp, Block, ComparisonOp, Context, Function, FunctionType, LValue, Location, RValue,
8+
ToRValue, Type, UnaryOp,
99
};
1010
use rustc_abi as abi;
1111
use rustc_abi::{Align, HasDataLayout, Size, TargetDataLayout, WrappingRange};
@@ -782,8 +782,19 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
782782
return self.context.new_call(self.location, fmod, &[a, b]);
783783
}
784784
TypeKind::FP128 => {
785-
let fmodl = self.context.get_builtin_function("fmodl");
786-
return self.context.new_call(self.location, fmodl, &[a, b]);
785+
let f128_type = self.type_f128();
786+
let fmodf128 = self.context.new_function(
787+
None,
788+
FunctionType::Extern,
789+
f128_type,
790+
&[
791+
self.context.new_parameter(None, f128_type, "a"),
792+
self.context.new_parameter(None, f128_type, "b"),
793+
],
794+
"fmodf128",
795+
false,
796+
);
797+
return self.context.new_call(self.location, fmodf128, &[a, b]);
787798
}
788799
_ => (),
789800
}

src/common.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -237,14 +237,15 @@ impl<'gcc, 'tcx> ConstCodegenMethods for CodegenCx<'gcc, 'tcx> {
237237

238238
// FIXME(antoyo): there's some issues with using the u128 code that follows, so hard-code
239239
// the paths for floating-point values.
240-
if ty == self.float_type {
240+
// TODO: Remove this code?
241+
/*if ty == self.float_type {
241242
return self
242243
.context
243244
.new_rvalue_from_double(ty, f32::from_bits(data as u32) as f64);
244245
}
245246
if ty == self.double_type {
246247
return self.context.new_rvalue_from_double(ty, f64::from_bits(data as u64));
247-
}
248+
}*/
248249

249250
let value = self.const_uint_big(self.type_ix(bitsize), data);
250251
let bytesize = layout.size(self).bytes();

src/intrinsic/mod.rs

Lines changed: 97 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,8 @@ fn get_simple_intrinsic<'gcc, 'tcx>(
4545
let gcc_name = match name {
4646
sym::sqrtf32 => "sqrtf",
4747
sym::sqrtf64 => "sqrt",
48-
sym::sqrtf128 => "sqrtl",
4948
sym::powif32 => "__builtin_powif",
5049
sym::powif64 => "__builtin_powi",
51-
sym::powif128 => "__builtin_powil",
5250
sym::sinf32 => "sinf",
5351
sym::sinf64 => "sin",
5452
sym::cosf32 => "cosf",
@@ -67,37 +65,29 @@ fn get_simple_intrinsic<'gcc, 'tcx>(
6765
sym::log2f64 => "log2",
6866
sym::fmaf32 => "fmaf",
6967
sym::fmaf64 => "fma",
70-
sym::fmaf128 => "fmal",
7168
// FIXME: calling `fma` from libc without FMA target feature uses expensive software emulation
7269
sym::fmuladdf32 => "fmaf", // TODO: use gcc intrinsic analogous to llvm.fmuladd.f32
7370
sym::fmuladdf64 => "fma", // TODO: use gcc intrinsic analogous to llvm.fmuladd.f64
7471
sym::fabsf32 => "fabsf",
7572
sym::fabsf64 => "fabs",
7673
sym::minnumf32 => "fminf",
7774
sym::minnumf64 => "fmin",
78-
sym::minnumf128 => "fminl",
7975
sym::maxnumf32 => "fmaxf",
8076
sym::maxnumf64 => "fmax",
81-
sym::maxnumf128 => "fmaxl",
8277
sym::copysignf32 => "copysignf",
8378
sym::copysignf64 => "copysign",
8479
sym::copysignf128 => "copysignl",
8580
sym::floorf32 => "floorf",
8681
sym::floorf64 => "floor",
87-
sym::floorf128 => "floorl",
8882
sym::ceilf32 => "ceilf",
8983
sym::ceilf64 => "ceil",
90-
sym::ceilf128 => "ceill",
9184
sym::truncf32 => "truncf",
9285
sym::truncf64 => "trunc",
93-
sym::truncf128 => "truncl",
9486
// We match the LLVM backend and lower this to `rint`.
9587
sym::round_ties_even_f32 => "rintf",
9688
sym::round_ties_even_f64 => "rint",
97-
sym::round_ties_even_f128 => "rintl",
9889
sym::roundf32 => "roundf",
9990
sym::roundf64 => "round",
100-
sym::roundf128 => "roundl",
10191
sym::abort => "abort",
10292
_ => return None,
10393
};
@@ -170,6 +160,61 @@ fn get_simple_function<'gcc, 'tcx>(
170160
))
171161
}
172162

163+
fn get_simple_function_f128<'gcc, 'tcx>(
164+
cx: &CodegenCx<'gcc, 'tcx>,
165+
name: Symbol,
166+
) -> Option<Function<'gcc>> {
167+
if !cx.supports_f128_type {
168+
return None;
169+
}
170+
171+
let f128_type = cx.type_f128();
172+
let func_name = match name {
173+
sym::ceilf128 => "ceilf128",
174+
sym::floorf128 => "floorf128",
175+
sym::truncf128 => "truncf128",
176+
sym::roundf128 => "roundf128",
177+
sym::round_ties_even_f128 => "roundevenf128",
178+
sym::sqrtf128 => "sqrtf128",
179+
_ => return None,
180+
};
181+
Some(cx.context.new_function(
182+
None,
183+
FunctionType::Extern,
184+
f128_type,
185+
&[cx.context.new_parameter(None, f128_type, "a")],
186+
func_name,
187+
false,
188+
))
189+
}
190+
191+
fn get_simple_function_f128_2args<'gcc, 'tcx>(
192+
cx: &CodegenCx<'gcc, 'tcx>,
193+
name: Symbol,
194+
) -> Option<Function<'gcc>> {
195+
if !cx.supports_f128_type {
196+
return None;
197+
}
198+
199+
let f128_type = cx.type_f128();
200+
let func_name = match name {
201+
sym::maxnumf128 => "fmaxf128",
202+
sym::minnumf128 => "fminf128",
203+
_ => return None,
204+
};
205+
Some(cx.context.new_function(
206+
None,
207+
FunctionType::Extern,
208+
f128_type,
209+
&[
210+
cx.context.new_parameter(None, f128_type, "a"),
211+
cx.context.new_parameter(None, f128_type, "b"),
212+
],
213+
func_name,
214+
false,
215+
))
216+
}
217+
173218
fn f16_builtin<'gcc, 'tcx>(
174219
cx: &CodegenCx<'gcc, 'tcx>,
175220
name: Symbol,
@@ -232,7 +277,9 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
232277
let result = PlaceRef::new_sized(llresult, fn_abi.ret.layout);
233278

234279
let simple = get_simple_intrinsic(self, name);
235-
let simple_func = get_simple_function(self, name);
280+
let simple_func = get_simple_function(self, name)
281+
.or_else(|| get_simple_function_f128(self, name))
282+
.or_else(|| get_simple_function_f128_2args(self, name));
236283

237284
// FIXME(tempdragon): Re-enable `clippy::suspicious_else_formatting` if the following issue is solved:
238285
// https://github.com/rust-lang/rust-clippy/issues/12497
@@ -266,6 +313,45 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
266313
| sym::round_ties_even_f16
267314
| sym::sqrtf16
268315
| sym::truncf16 => f16_builtin(self, name, args),
316+
sym::fmaf128 => {
317+
let f128_type = self.cx.type_f128();
318+
let func = self.cx.context.new_function(
319+
None,
320+
FunctionType::Extern,
321+
f128_type,
322+
&[
323+
self.cx.context.new_parameter(None, f128_type, "a"),
324+
self.cx.context.new_parameter(None, f128_type, "b"),
325+
self.cx.context.new_parameter(None, f128_type, "c"),
326+
],
327+
"fmaf128",
328+
false,
329+
);
330+
self.cx.context.new_call(
331+
self.location,
332+
func,
333+
&args.iter().map(|arg| arg.immediate()).collect::<Vec<_>>(),
334+
)
335+
}
336+
sym::powif128 => {
337+
let f128_type = self.cx.type_f128();
338+
let func = self.cx.context.new_function(
339+
None,
340+
FunctionType::Extern,
341+
f128_type,
342+
&[
343+
self.cx.context.new_parameter(None, f128_type, "a"),
344+
self.cx.context.new_parameter(None, self.int_type, "b"),
345+
],
346+
"__powitf2",
347+
false,
348+
);
349+
self.cx.context.new_call(
350+
self.location,
351+
func,
352+
&args.iter().map(|arg| arg.immediate()).collect::<Vec<_>>(),
353+
)
354+
}
269355
sym::is_val_statically_known => {
270356
let a = args[0].immediate();
271357
let builtin = self.context.get_builtin_function("__builtin_constant_p");

0 commit comments

Comments
 (0)