Skip to content

Commit

Permalink
Add f16 and f128 to rustc_type_ir::FloatTy and `rustc_abi::Prim…
Browse files Browse the repository at this point in the history
…itive`

Make changes necessary to support these types in the compiler.
  • Loading branch information
tgross35 committed Feb 28, 2024
1 parent ef32456 commit e3f63d9
Show file tree
Hide file tree
Showing 31 changed files with 107 additions and 14 deletions.
12 changes: 12 additions & 0 deletions compiler/rustc_abi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,8 +171,10 @@ pub struct TargetDataLayout {
pub i32_align: AbiAndPrefAlign,
pub i64_align: AbiAndPrefAlign,
pub i128_align: AbiAndPrefAlign,
pub f16_align: AbiAndPrefAlign,
pub f32_align: AbiAndPrefAlign,
pub f64_align: AbiAndPrefAlign,
pub f128_align: AbiAndPrefAlign,
pub pointer_size: Size,
pub pointer_align: AbiAndPrefAlign,
pub aggregate_align: AbiAndPrefAlign,
Expand Down Expand Up @@ -200,8 +202,10 @@ impl Default for TargetDataLayout {
i32_align: AbiAndPrefAlign::new(align(32)),
i64_align: AbiAndPrefAlign { abi: align(32), pref: align(64) },
i128_align: AbiAndPrefAlign { abi: align(32), pref: align(64) },
f16_align: AbiAndPrefAlign::new(align(16)),
f32_align: AbiAndPrefAlign::new(align(32)),
f64_align: AbiAndPrefAlign::new(align(64)),
f128_align: AbiAndPrefAlign::new(align(128)),
pointer_size: Size::from_bits(64),
pointer_align: AbiAndPrefAlign::new(align(64)),
aggregate_align: AbiAndPrefAlign { abi: align(0), pref: align(64) },
Expand Down Expand Up @@ -281,8 +285,10 @@ impl TargetDataLayout {
dl.instruction_address_space = parse_address_space(&p[1..], "P")?
}
["a", ref a @ ..] => dl.aggregate_align = parse_align(a, "a")?,
["f16", ref a @ ..] => dl.f16_align = parse_align(a, "f16")?,
["f32", ref a @ ..] => dl.f32_align = parse_align(a, "f32")?,
["f64", ref a @ ..] => dl.f64_align = parse_align(a, "f64")?,
["f128", ref a @ ..] => dl.f128_align = parse_align(a, "f128")?,
// FIXME(erikdesjardins): we should be parsing nonzero address spaces
// this will require replacing TargetDataLayout::{pointer_size,pointer_align}
// with e.g. `fn pointer_size_in(AddressSpace)`
Expand Down Expand Up @@ -919,8 +925,10 @@ pub enum Primitive {
/// a negative integer passed by zero-extension will appear positive in
/// the callee, and most operations on it will produce the wrong values.
Int(Integer, bool),
F16,
F32,
F64,
F128,
Pointer(AddressSpace),
}

Expand All @@ -931,8 +939,10 @@ impl Primitive {

match self {
Int(i, _) => i.size(),
F16 => Size::from_bits(16),
F32 => Size::from_bits(32),
F64 => Size::from_bits(64),
F128 => Size::from_bits(128),
// FIXME(erikdesjardins): ignoring address space is technically wrong, pointers in
// different address spaces can have different sizes
// (but TargetDataLayout doesn't currently parse that part of the DL string)
Expand All @@ -946,8 +956,10 @@ impl Primitive {

match self {
Int(i, _) => i.align(dl),
F16 => dl.f16_align,
F32 => dl.f32_align,
F64 => dl.f64_align,
F128 => dl.f128_align,
// FIXME(erikdesjardins): ignoring address space is technically wrong, pointers in
// different address spaces can have different alignments
// (but TargetDataLayout doesn't currently parse that part of the DL string)
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_codegen_cranelift/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,10 @@ pub(crate) fn scalar_to_clif_type(tcx: TyCtxt<'_>, scalar: Scalar) -> Type {
Integer::I64 => types::I64,
Integer::I128 => types::I128,
},
Primitive::F16 => unimplemented!("f16_f128"),
Primitive::F32 => types::F32,
Primitive::F64 => types::F64,
Primitive::F128 => unimplemented!("f16_f128"),
// FIXME(erikdesjardins): handle non-default addrspace ptr sizes
Primitive::Pointer(_) => pointer_ty(tcx),
}
Expand All @@ -61,8 +63,10 @@ fn clif_type_from_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option<types::Typ
},
ty::Char => types::I32,
ty::Float(size) => match size {
FloatTy::F16 => unimplemented!("f16_f128"),
FloatTy::F32 => types::F32,
FloatTy::F64 => types::F64,
FloatTy::F128 => unimplemented!("f16_f128"),
},
ty::FnPtr(_) => pointer_ty(tcx),
ty::RawPtr(TypeAndMut { ty: pointee_ty, mutbl: _ }) | ty::Ref(_, pointee_ty, _) => {
Expand Down
10 changes: 10 additions & 0 deletions compiler/rustc_codegen_gcc/src/type_.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,10 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {

pub fn type_float_from_ty(&self, t: ty::FloatTy) -> Type<'gcc> {
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(),
}
}
}
Expand Down Expand Up @@ -118,13 +120,21 @@ impl<'gcc, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
self.isize_type
}

fn type_f16(&self) -> Type<'gcc> {
unimplemented!("f16_f128")
}

fn type_f32(&self) -> Type<'gcc> {
self.float_type
}

fn type_f64(&self) -> Type<'gcc> {
self.double_type
}

fn type_f128(&self) -> Type<'gcc> {
unimplemented!("f16_f128")
}

fn type_func(&self, params: &[Type<'gcc>], return_type: Type<'gcc>) -> Type<'gcc> {
self.context.new_function_pointer_type(None, return_type, params, false)
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_codegen_gcc/src/type_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use rustc_middle::bug;
use rustc_middle::ty::{self, Ty, TypeVisitableExt};
use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
use rustc_middle::ty::print::with_no_trimmed_paths;
use rustc_target::abi::{self, Abi, Align, F32, F64, FieldsShape, Int, Integer, Pointer, PointeeInfo, Size, TyAbiInterface, Variants};
use rustc_target::abi::{self, Abi, Align, F16, F128, F32, F64, FieldsShape, Int, Integer, Pointer, PointeeInfo, Size, TyAbiInterface, Variants};
use rustc_target::abi::call::{CastTarget, FnAbi, Reg};

use crate::abi::{FnAbiGcc, FnAbiGccExt, GccType};
Expand Down Expand Up @@ -257,8 +257,10 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> {
match scalar.primitive() {
Int(i, true) => cx.type_from_integer(i),
Int(i, false) => cx.type_from_unsigned_integer(i),
F16 => cx.type_f16(),
F32 => cx.type_f32(),
F64 => cx.type_f64(),
F128 => cx.type_f128(),
Pointer(address_space) => {
// If we know the alignment, pick something better than i8.
let pointee =
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_llvm/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 => {}
}
}

Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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",
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_codegen_llvm/src/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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"),
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_codegen_llvm/src/llvm/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>(
Expand Down
15 changes: 13 additions & 2 deletions compiler/rustc_codegen_llvm/src/type_.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
}
}

Expand Down Expand Up @@ -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) }
}
Expand All @@ -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) }
}
Expand Down Expand Up @@ -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:?}"),
}
}

Expand All @@ -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:?}"),
}
}

Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_codegen_llvm/src/type_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};

Expand Down Expand Up @@ -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),
}
}
Expand Down
8 changes: 5 additions & 3 deletions compiler/rustc_codegen_ssa/src/mir/rvalue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -303,15 +303,17 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
self.assume_scalar_range(bx, imm, from_scalar, from_backend_ty);

imm = match (from_scalar.primitive(), to_scalar.primitive()) {
(Int(..) | F32 | F64, Int(..) | F32 | F64) => bx.bitcast(imm, to_backend_ty),
(Int(..) | F16 | F32 | F64 | F128, Int(..) | F16 | F32 | F64 | F128) => {
bx.bitcast(imm, to_backend_ty)
}
(Pointer(..), Pointer(..)) => bx.pointercast(imm, to_backend_ty),
(Int(..), Pointer(..)) => bx.inttoptr(imm, to_backend_ty),
(Pointer(..), Int(..)) => bx.ptrtoint(imm, to_backend_ty),
(F32 | F64, Pointer(..)) => {
(F16 | F32 | F64 | F128, Pointer(..)) => {
let int_imm = bx.bitcast(imm, bx.cx().type_isize());
bx.inttoptr(int_imm, to_backend_ty)
}
(Pointer(..), F32 | F64) => {
(Pointer(..), F16 | F32 | F64 | F128) => {
let int_imm = bx.ptrtoint(imm, bx.cx().type_isize());
bx.bitcast(int_imm, to_backend_ty)
}
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_codegen_ssa/src/traits/type_.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@ pub trait BaseTypeMethods<'tcx>: Backend<'tcx> {
fn type_i128(&self) -> Self::Type;
fn type_isize(&self) -> Self::Type;

fn type_f16(&self) -> Self::Type;
fn type_f32(&self) -> Self::Type;
fn type_f64(&self) -> Self::Type;
fn type_f128(&self) -> Self::Type;

fn type_array(&self, ty: Self::Type, len: u64) -> Self::Type;
fn type_func(&self, args: &[Self::Type], ret: Self::Type) -> Self::Type;
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_const_eval/src/interpret/operator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -389,12 +389,14 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
let left = left.to_scalar();
let right = right.to_scalar();
Ok(match fty {
FloatTy::F16 => unimplemented!("f16_f128"),
FloatTy::F32 => {
self.binary_float_op(bin_op, layout, left.to_f32()?, right.to_f32()?)
}
FloatTy::F64 => {
self.binary_float_op(bin_op, layout, left.to_f64()?, right.to_f64()?)
}
FloatTy::F128 => unimplemented!("f16_f128"),
})
}
_ if left.layout.ty.is_integral() => {
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_lint/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -561,8 +561,10 @@ fn lint_literal<'tcx>(
ty::Float(t) => {
let is_infinite = match lit.node {
ast::LitKind::Float(v, _) => match t {
ty::FloatTy::F16 => unimplemented!("f16_f128"),
ty::FloatTy::F32 => v.as_str().parse().map(f32::is_infinite),
ty::FloatTy::F64 => v.as_str().parse().map(f64::is_infinite),
ty::FloatTy::F128 => unimplemented!("f16_f128"),
},
_ => bug!(),
};
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_middle/src/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -337,8 +337,10 @@ pub struct CommonTypes<'tcx> {
pub u32: Ty<'tcx>,
pub u64: Ty<'tcx>,
pub u128: Ty<'tcx>,
pub f16: Ty<'tcx>,
pub f32: Ty<'tcx>,
pub f64: Ty<'tcx>,
pub f128: Ty<'tcx>,
pub str_: Ty<'tcx>,
pub never: Ty<'tcx>,
pub self_param: Ty<'tcx>,
Expand Down Expand Up @@ -418,8 +420,10 @@ impl<'tcx> CommonTypes<'tcx> {
u32: mk(Uint(ty::UintTy::U32)),
u64: mk(Uint(ty::UintTy::U64)),
u128: mk(Uint(ty::UintTy::U128)),
f16: mk(Float(ty::FloatTy::F16)),
f32: mk(Float(ty::FloatTy::F32)),
f64: mk(Float(ty::FloatTy::F64)),
f128: mk(Float(ty::FloatTy::F128)),
str_: mk(Str),
self_param: mk(ty::Param(ty::ParamTy { index: 0, name: kw::SelfUpper })),

Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_middle/src/ty/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,10 @@ impl Primitive {
fn to_ty<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
match *self {
Int(i, signed) => i.to_ty(tcx, signed),
F16 => tcx.types.f16,
F32 => tcx.types.f32,
F64 => tcx.types.f64,
F128 => tcx.types.f128,
// FIXME(erikdesjardins): handle non-default addrspace ptr sizes
Pointer(_) => Ty::new_mut_ptr(tcx, Ty::new_unit(tcx)),
}
Expand All @@ -135,7 +137,7 @@ impl Primitive {
let signed = false;
tcx.data_layout().ptr_sized_integer().to_ty(tcx, signed)
}
F32 | F64 => bug!("floats do not have an int type"),
F16 | F32 | F64 | F128 => bug!("floats do not have an int type"),
}
}
}
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_middle/src/ty/sty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1580,8 +1580,10 @@ impl<'tcx> Ty<'tcx> {
pub fn new_float(tcx: TyCtxt<'tcx>, f: ty::FloatTy) -> Ty<'tcx> {
use ty::FloatTy::*;
match f {
F16 => tcx.types.f16,
F32 => tcx.types.f32,
F64 => tcx.types.f64,
F128 => tcx.types.f128,
}
}

Expand Down Expand Up @@ -2539,8 +2541,10 @@ impl<'tcx> Ty<'tcx> {
ty::Bool => Some(sym::bool),
ty::Char => Some(sym::char),
ty::Float(f) => match f {
ty::FloatTy::F16 => Some(sym::f16),
ty::FloatTy::F32 => Some(sym::f32),
ty::FloatTy::F64 => Some(sym::f64),
ty::FloatTy::F128 => Some(sym::f128),
},
ty::Int(f) => match f {
ty::IntTy::Isize => Some(sym::isize),
Expand Down
Loading

0 comments on commit e3f63d9

Please sign in to comment.