Skip to content

Commit

Permalink
Merge pull request #17 from zedar/add_support_for_float16_float128
Browse files Browse the repository at this point in the history
Add support for Float16, Float32, Float64 and Float128
  • Loading branch information
antoyo authored Jun 25, 2024
2 parents a63b83e + 9274c63 commit 70d3655
Show file tree
Hide file tree
Showing 8 changed files with 136 additions and 12 deletions.
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
}

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
}

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() {
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

0 comments on commit 70d3655

Please sign in to comment.