Add f16 and f128 to rustc_type_ir::FloatTy and rustc_abi::Primitive

Make changes necessary to support these types in the compiler.
This commit is contained in:
Trevor Gross 2024-02-28 03:44:23 -05:00
parent ef324565d0
commit e3f63d9375
31 changed files with 107 additions and 14 deletions

View file

@ -568,7 +568,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
}
}
}
abi::F32 | abi::F64 => {}
abi::F16 | abi::F32 | abi::F64 | abi::F128 => {}
}
}

View file

@ -695,9 +695,13 @@ impl MsvcBasicName for ty::UintTy {
impl MsvcBasicName for ty::FloatTy {
fn msvc_basic_name(self) -> &'static str {
// FIXME: f16 and f128 have no MSVE representation. We could improve the debuginfo.
// See: <https://github.com/rust-lang/rust/pull/114607/files#r1454683264>
match self {
ty::FloatTy::F16 => "half",
ty::FloatTy::F32 => "float",
ty::FloatTy::F64 => "double",
ty::FloatTy::F128 => "fp128",
}
}
}

View file

@ -122,8 +122,10 @@ fn tag_base_type<'ll, 'tcx>(
// Niche tags are always normalized to unsized integers of the correct size.
match tag.primitive() {
Primitive::Int(t, _) => t,
Primitive::F16 => Integer::I16,
Primitive::F32 => Integer::I32,
Primitive::F64 => Integer::I64,
Primitive::F128 => Integer::I128,
// FIXME(erikdesjardins): handle non-default addrspace ptr sizes
Primitive::Pointer(_) => {
// If the niche is the NULL value of a reference, then `discr_enum_ty` will be

View file

@ -163,11 +163,15 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> {
emit_va_arg(self, args[0], ret_ty)
}
}
Primitive::F16 => bug!("the va_arg intrinsic does not work with `f16`"),
Primitive::F64 | Primitive::Pointer(_) => {
emit_va_arg(self, args[0], ret_ty)
}
// `va_arg` should never be used with the return type f32.
Primitive::F32 => bug!("the va_arg intrinsic does not work with `f32`"),
Primitive::F128 => {
bug!("the va_arg intrinsic does not work with `f128`")
}
}
}
_ => bug!("the va_arg intrinsic does not work with non-scalar types"),

View file

@ -858,8 +858,10 @@ extern "C" {
pub fn LLVMGetIntTypeWidth(IntegerTy: &Type) -> c_uint;
// Operations on real types
pub fn LLVMHalfTypeInContext(C: &Context) -> &Type;
pub fn LLVMFloatTypeInContext(C: &Context) -> &Type;
pub fn LLVMDoubleTypeInContext(C: &Context) -> &Type;
pub fn LLVMFP128TypeInContext(C: &Context) -> &Type;
// Operations on function types
pub fn LLVMFunctionType<'a>(

View file

@ -107,8 +107,10 @@ impl<'ll> CodegenCx<'ll, '_> {
pub(crate) fn type_float_from_ty(&self, t: ty::FloatTy) -> &'ll Type {
match t {
ty::FloatTy::F16 => self.type_f16(),
ty::FloatTy::F32 => self.type_f32(),
ty::FloatTy::F64 => self.type_f64(),
ty::FloatTy::F128 => self.type_f128(),
}
}
@ -156,6 +158,10 @@ impl<'ll, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> {
self.isize_ty
}
fn type_f16(&self) -> &'ll Type {
unsafe { llvm::LLVMHalfTypeInContext(self.llcx) }
}
fn type_f32(&self) -> &'ll Type {
unsafe { llvm::LLVMFloatTypeInContext(self.llcx) }
}
@ -164,6 +170,10 @@ impl<'ll, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> {
unsafe { llvm::LLVMDoubleTypeInContext(self.llcx) }
}
fn type_f128(&self) -> &'ll Type {
unsafe { llvm::LLVMFP128TypeInContext(self.llcx) }
}
fn type_func(&self, args: &[&'ll Type], ret: &'ll Type) -> &'ll Type {
unsafe { llvm::LLVMFunctionType(ret, args.as_ptr(), args.len() as c_uint, False) }
}
@ -195,7 +205,7 @@ impl<'ll, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> {
match self.type_kind(ty) {
TypeKind::Array | TypeKind::Vector => unsafe { llvm::LLVMGetElementType(ty) },
TypeKind::Pointer => bug!("element_type is not supported for opaque pointers"),
other => bug!("element_type called on unsupported type {:?}", other),
other => bug!("element_type called on unsupported type {other:?}"),
}
}
@ -205,11 +215,12 @@ impl<'ll, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> {
fn float_width(&self, ty: &'ll Type) -> usize {
match self.type_kind(ty) {
TypeKind::Half => 16,
TypeKind::Float => 32,
TypeKind::Double => 64,
TypeKind::X86_FP80 => 80,
TypeKind::FP128 | TypeKind::PPC_FP128 => 128,
_ => bug!("llvm_float_width called on a non-float type"),
other => bug!("llvm_float_width called on a non-float type {other:?}"),
}
}

View file

@ -8,7 +8,7 @@ use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths};
use rustc_middle::ty::{self, Ty, TypeVisitableExt};
use rustc_target::abi::HasDataLayout;
use rustc_target::abi::{Abi, Align, FieldsShape};
use rustc_target::abi::{Int, Pointer, F32, F64};
use rustc_target::abi::{Int, Pointer, F128, F16, F32, F64};
use rustc_target::abi::{Scalar, Size, Variants};
use smallvec::{smallvec, SmallVec};
@ -291,8 +291,10 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyAndLayout<'tcx> {
fn scalar_llvm_type_at<'a>(&self, cx: &CodegenCx<'a, 'tcx>, scalar: Scalar) -> &'a Type {
match scalar.primitive() {
Int(i, _) => cx.type_from_integer(i),
F16 => cx.type_f16(),
F32 => cx.type_f32(),
F64 => cx.type_f64(),
F128 => cx.type_f128(),
Pointer(address_space) => cx.type_ptr_ext(address_space),
}
}