Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for Float16, Float32, Float64 and Float128 #17

Merged
merged 12 commits into from
Jun 25, 2024
8 changes: 4 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion build_system/build_sysroot/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ resolver = "2"

[dependencies]
core = { path = "./sysroot_src/library/core" }
compiler_builtins = "0.1"
# TODO: after the sync, revert to using version 0.1.
# compiler_builtins = "0.1"
compiler_builtins = "=0.1.109"
alloc = { path = "./sysroot_src/library/alloc" }
std = { path = "./sysroot_src/library/std", features = ["panic_unwind", "backtrace"] }
test = { path = "./sysroot_src/library/test" }
Expand Down
2 changes: 1 addition & 1 deletion libgccjit.version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
b6f163f52
d61ce945badf4c9d8237a13ca135e3c46ad13be3
21 changes: 19 additions & 2 deletions src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::collections::HashSet;
use std::env;
use std::time::Instant;

use gccjit::{FunctionType, GlobalKind};
use gccjit::{CType, FunctionType, GlobalKind};
use rustc_codegen_ssa::base::maybe_create_entry_wrapper;
use rustc_codegen_ssa::mono_item::MonoItemExt;
use rustc_codegen_ssa::traits::DebugInfoMethods;
Expand Down Expand Up @@ -181,7 +181,24 @@ pub fn compile_codegen_unit(
context.set_allow_unreachable_blocks(true);

{
let cx = CodegenCx::new(&context, cgu, tcx, target_info.supports_128bit_int());
// TODO: to make it less error-prone (calling get_target_info() will add the flag
// -fsyntax-only), forbid the compilation when get_target_info() is called on a
// context.
let f16_type_supported = target_info.supports_target_dependent_type(CType::Float16);
let f32_type_supported = target_info.supports_target_dependent_type(CType::Float32);
let f64_type_supported = target_info.supports_target_dependent_type(CType::Float64);
let f128_type_supported = target_info.supports_target_dependent_type(CType::Float128);
// TODO: improve this to avoid passing that many arguments.
let cx = CodegenCx::new(
&context,
cgu,
tcx,
target_info.supports_128bit_int(),
f16_type_supported,
f32_type_supported,
f64_type_supported,
f128_type_supported,
);

let mono_items = cgu.items_in_deterministic_order(tcx);
for &(mono_item, data) in &mono_items {
Expand Down
18 changes: 18 additions & 0 deletions src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -748,6 +748,24 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
// FIXME(antoyo): this seems to produce the wrong result.
return self.context.new_call(self.location, fmodf, &[a, b]);
}

#[cfg(feature = "master")]
match self.cx.type_kind(a_type) {
TypeKind::Half | TypeKind::Float => {
let fmodf = self.context.get_builtin_function("fmodf");
return self.context.new_call(self.location, fmodf, &[a, b]);
}
TypeKind::Double => {
let fmod = self.context.get_builtin_function("fmod");
return self.context.new_call(self.location, fmod, &[a, b]);
}
TypeKind::FP128 => {
let fmodl = self.context.get_builtin_function("fmodl");
return self.context.new_call(self.location, fmodl, &[a, b]);
}
_ => (),
}

if let Some(vector_type) = a_type_unqualified.dyncast_vector() {
assert_eq!(a_type_unqualified, b.get_type().unqualified());

Expand Down
13 changes: 13 additions & 0 deletions src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ pub struct CodegenCx<'gcc, 'tcx> {
pub sizet_type: Type<'gcc>,

pub supports_128bit_integers: bool,
pub supports_f16_type: bool,
pub supports_f32_type: bool,
pub supports_f64_type: bool,
pub supports_f128_type: bool,

pub float_type: Type<'gcc>,
pub double_type: Type<'gcc>,
Expand Down Expand Up @@ -125,11 +129,16 @@ pub struct CodegenCx<'gcc, 'tcx> {
}

impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
#[allow(clippy::too_many_arguments)]
pub fn new(
context: &'gcc Context<'gcc>,
codegen_unit: &'tcx CodegenUnit<'tcx>,
tcx: TyCtxt<'tcx>,
supports_128bit_integers: bool,
supports_f16_type: bool,
supports_f32_type: bool,
supports_f64_type: bool,
supports_f128_type: bool,
) -> Self {
let check_overflow = tcx.sess.overflow_checks();

Expand Down Expand Up @@ -305,6 +314,10 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
sizet_type,

supports_128bit_integers,
supports_f16_type,
supports_f32_type,
supports_f64_type,
supports_f128_type,

float_type,
double_type,
Expand Down
12 changes: 10 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,6 @@ use std::sync::Arc;
use std::sync::Mutex;

use errors::LTONotSupported;
#[cfg(not(feature = "master"))]
use gccjit::CType;
use gccjit::{Context, OptimizationLevel};
#[cfg(feature = "master")]
Expand Down Expand Up @@ -147,6 +146,10 @@ impl TargetInfo {
fn supports_128bit_int(&self) -> bool {
self.supports_128bit_integers.load(Ordering::SeqCst)
}

fn supports_target_dependent_type(&self, _typ: CType) -> bool {
false
}
}

#[derive(Clone)]
Expand All @@ -168,6 +171,10 @@ impl LockedTargetInfo {
fn supports_128bit_int(&self) -> bool {
self.info.lock().expect("lock").supports_128bit_int()
}

fn supports_target_dependent_type(&self, typ: CType) -> bool {
self.info.lock().expect("lock").supports_target_dependent_type(typ)
}
}

#[derive(Clone)]
Expand Down Expand Up @@ -438,7 +445,8 @@ impl WriteBackendMethods for GccCodegenBackend {
pub fn __rustc_codegen_backend() -> Box<dyn CodegenBackend> {
#[cfg(feature = "master")]
let info = {
// Check whether the target supports 128-bit integers.
// Check whether the target supports 128-bit integers, and sized floating point types (like
// Float16).
let context = Context::default();
Arc::new(Mutex::new(IntoDynSyncSend(context.get_target_info())))
};
Expand Down
70 changes: 68 additions & 2 deletions src/type_.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
#[cfg(feature = "master")]
use std::convert::TryInto;

#[cfg(feature = "master")]
use gccjit::CType;
use gccjit::{RValue, Struct, Type};
use rustc_codegen_ssa::common::TypeKind;
use rustc_codegen_ssa::traits::{BaseTypeMethods, DerivedTypeMethods, TypeMembershipMethods};
Expand Down Expand Up @@ -121,19 +126,35 @@ impl<'gcc, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
}

fn type_f16(&self) -> Type<'gcc> {
unimplemented!("f16_f128")
#[cfg(feature = "master")]
if self.supports_f16_type {
return self.context.new_c_type(CType::Float16);
}
bug!("unsupported float width 16")
}

fn type_f32(&self) -> Type<'gcc> {
#[cfg(feature = "master")]
if self.supports_f32_type {
return self.context.new_c_type(CType::Float32);
}
self.float_type
}

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't forget to implement type_f64 as well.

fn type_f64(&self) -> Type<'gcc> {
#[cfg(feature = "master")]
if self.supports_f64_type {
return self.context.new_c_type(CType::Float64);
}
self.double_type
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Depending on what you decide to do above, you could return Float32/Float64 in those functions if you decide to add the support for checking if those types are supported.

Of course, we would keep returing Float and Double on platforms where those types are not supported.

}

fn type_f128(&self) -> Type<'gcc> {
unimplemented!("f16_f128")
#[cfg(feature = "master")]
if self.supports_f128_type {
return self.context.new_c_type(CType::Float128);
}
bug!("unsupported float width 128")
}

fn type_func(&self, params: &[Type<'gcc>], return_type: Type<'gcc>) -> Type<'gcc> {
Expand Down Expand Up @@ -161,6 +182,41 @@ impl<'gcc, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
typ
}

#[cfg(feature = "master")]
fn type_kind(&self, typ: Type<'gcc>) -> TypeKind {
if self.is_int_type_or_bool(typ) {
TypeKind::Integer
} else if typ.get_pointee().is_some() {
TypeKind::Pointer
} else if typ.is_vector() {
TypeKind::Vector
} else if typ.dyncast_array().is_some() {
TypeKind::Array
} else if typ.is_struct().is_some() {
TypeKind::Struct
} else if typ.dyncast_function_ptr_type().is_some() {
TypeKind::Function
} else if typ.is_compatible_with(self.float_type) {
TypeKind::Float
} else if typ.is_compatible_with(self.double_type) {
TypeKind::Double
} else if typ.is_floating_point() {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You'll need to do this:

Suggested change
} else if typ.is_floating_point() {
}
#[cfg(feature="master")]
else if typ.is_floating_point() {

Copy link
Owner

@antoyo antoyo Jun 21, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This syntax isn't supported.
Unless you can put this above the if, I guess you can revert to 2 different implementations:

#[cfg(feature="master")]
if typ.is_floating_point() {
    match typ.get_size() {
                 2 => return TypeKind::Half,
                 4 => return TypeKind::Float,
                 8 => return TypeKind::Double,
                 16 => return TypeKind::FP128,
                 _ => return TypeKind::Void,
    }
}

match typ.get_size() {
2 => TypeKind::Half,
4 => TypeKind::Float,
8 => TypeKind::Double,
16 => TypeKind::FP128,
size => unreachable!("Floating-point type of size {}", size),
}
} else if typ == self.type_void() {
TypeKind::Void
} else {
// TODO(antoyo): support other types.
unimplemented!();
}
}

#[cfg(not(feature = "master"))]
fn type_kind(&self, typ: Type<'gcc>) -> TypeKind {
if self.is_int_type_or_bool(typ) {
TypeKind::Integer
Expand Down Expand Up @@ -210,6 +266,16 @@ impl<'gcc, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
unimplemented!();
}

#[cfg(feature = "master")]
fn float_width(&self, typ: Type<'gcc>) -> usize {
if typ.is_floating_point() {
(typ.get_size() * u8::BITS).try_into().unwrap()
} else {
panic!("Cannot get width of float type {:?}", typ);
}
}

#[cfg(not(feature = "master"))]
fn float_width(&self, typ: Type<'gcc>) -> usize {
let f32 = self.context.new_type::<f32>();
let f64 = self.context.new_type::<f64>();
Expand Down
Loading