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 stubs in IR and ABI for f16 and f128 #121728

Merged
merged 5 commits into from
Mar 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading