Rollup merge of #124797 - beetrees:primitive-float, r=davidtwco

Refactor float `Primitive`s to a separate `Float` type

Now there are 4 of them, it makes sense to refactor `F16`, `F32`, `F64` and `F128` out of `Primitive` and into a separate `Float` type (like integers already are). This allows patterns like `F16 | F32 | F64 | F128` to be simplified into `Float(_)`, and is consistent with `ty::FloatTy`.

As a side effect, this PR also makes the `Ty::primitive_size` method work with `f16` and `f128`.

Tracking issue: #116909

`@rustbot` label +F-f16_and_f128
This commit is contained in:
Matthias Krüger 2024-05-10 16:10:46 +02:00 committed by GitHub
commit 1ae0d90b72
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
23 changed files with 156 additions and 96 deletions

View File

@ -926,6 +926,41 @@ pub fn from_size(size: Size) -> Result<Self, String> {
} }
} }
/// Floating-point types.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
#[cfg_attr(feature = "nightly", derive(HashStable_Generic))]
pub enum Float {
F16,
F32,
F64,
F128,
}
impl Float {
pub fn size(self) -> Size {
use Float::*;
match self {
F16 => Size::from_bits(16),
F32 => Size::from_bits(32),
F64 => Size::from_bits(64),
F128 => Size::from_bits(128),
}
}
pub fn align<C: HasDataLayout>(self, cx: &C) -> AbiAndPrefAlign {
use Float::*;
let dl = cx.data_layout();
match self {
F16 => dl.f16_align,
F32 => dl.f32_align,
F64 => dl.f64_align,
F128 => dl.f128_align,
}
}
}
/// Fundamental unit of memory access and layout. /// Fundamental unit of memory access and layout.
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
#[cfg_attr(feature = "nightly", derive(HashStable_Generic))] #[cfg_attr(feature = "nightly", derive(HashStable_Generic))]
@ -938,10 +973,7 @@ pub enum Primitive {
/// a negative integer passed by zero-extension will appear positive in /// a negative integer passed by zero-extension will appear positive in
/// the callee, and most operations on it will produce the wrong values. /// the callee, and most operations on it will produce the wrong values.
Int(Integer, bool), Int(Integer, bool),
F16, Float(Float),
F32,
F64,
F128,
Pointer(AddressSpace), Pointer(AddressSpace),
} }
@ -952,10 +984,7 @@ pub fn size<C: HasDataLayout>(self, cx: &C) -> Size {
match self { match self {
Int(i, _) => i.size(), Int(i, _) => i.size(),
F16 => Size::from_bits(16), Float(f) => f.size(),
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 // FIXME(erikdesjardins): ignoring address space is technically wrong, pointers in
// different address spaces can have different sizes // different address spaces can have different sizes
// (but TargetDataLayout doesn't currently parse that part of the DL string) // (but TargetDataLayout doesn't currently parse that part of the DL string)
@ -969,10 +998,7 @@ pub fn align<C: HasDataLayout>(self, cx: &C) -> AbiAndPrefAlign {
match self { match self {
Int(i, _) => i.align(dl), Int(i, _) => i.align(dl),
F16 => dl.f16_align, Float(f) => f.align(dl),
F32 => dl.f32_align,
F64 => dl.f64_align,
F128 => dl.f128_align,
// FIXME(erikdesjardins): ignoring address space is technically wrong, pointers in // FIXME(erikdesjardins): ignoring address space is technically wrong, pointers in
// different address spaces can have different alignments // different address spaces can have different alignments
// (but TargetDataLayout doesn't currently parse that part of the DL string) // (but TargetDataLayout doesn't currently parse that part of the DL string)

View File

@ -7,7 +7,7 @@
use rustc_middle::ty::TypeFoldable; use rustc_middle::ty::TypeFoldable;
use rustc_span::source_map::Spanned; use rustc_span::source_map::Spanned;
use rustc_target::abi::call::FnAbi; use rustc_target::abi::call::FnAbi;
use rustc_target::abi::{Integer, Primitive}; use rustc_target::abi::{Float, Integer, Primitive};
use rustc_target::spec::{HasTargetSpec, Target}; use rustc_target::spec::{HasTargetSpec, Target};
use crate::constant::ConstantCx; use crate::constant::ConstantCx;
@ -32,10 +32,12 @@ pub(crate) fn scalar_to_clif_type(tcx: TyCtxt<'_>, scalar: Scalar) -> Type {
Integer::I64 => types::I64, Integer::I64 => types::I64,
Integer::I128 => types::I128, Integer::I128 => types::I128,
}, },
Primitive::F16 => unimplemented!("f16_f128"), Primitive::Float(float) => match float {
Primitive::F32 => types::F32, Float::F16 => unimplemented!("f16_f128"),
Primitive::F64 => types::F64, Float::F32 => types::F32,
Primitive::F128 => unimplemented!("f16_f128"), Float::F64 => types::F64,
Float::F128 => unimplemented!("f16_f128"),
},
// FIXME(erikdesjardins): handle non-default addrspace ptr sizes // FIXME(erikdesjardins): handle non-default addrspace ptr sizes
Primitive::Pointer(_) => pointer_ty(tcx), Primitive::Pointer(_) => pointer_ty(tcx),
} }

View File

@ -8,8 +8,8 @@
use rustc_middle::ty::{self, Ty, TypeVisitableExt}; use rustc_middle::ty::{self, Ty, TypeVisitableExt};
use rustc_target::abi::call::{CastTarget, FnAbi, Reg}; use rustc_target::abi::call::{CastTarget, FnAbi, Reg};
use rustc_target::abi::{ use rustc_target::abi::{
self, Abi, Align, FieldsShape, Int, Integer, PointeeInfo, Pointer, Size, TyAbiInterface, self, Abi, Align, FieldsShape, Float, Int, Integer, PointeeInfo, Pointer, Size, TyAbiInterface,
Variants, F128, F16, F32, F64, Variants,
}; };
use crate::abi::{FnAbiGcc, FnAbiGccExt, GccType}; use crate::abi::{FnAbiGcc, FnAbiGccExt, GccType};
@ -283,10 +283,7 @@ fn scalar_gcc_type_at<'gcc>(
match scalar.primitive() { match scalar.primitive() {
Int(i, true) => cx.type_from_integer(i), Int(i, true) => cx.type_from_integer(i),
Int(i, false) => cx.type_from_unsigned_integer(i), Int(i, false) => cx.type_from_unsigned_integer(i),
F16 => cx.type_f16(), Float(f) => cx.type_from_float(f),
F32 => cx.type_f32(),
F64 => cx.type_f64(),
F128 => cx.type_f128(),
Pointer(address_space) => { Pointer(address_space) => {
// If we know the alignment, pick something better than i8. // If we know the alignment, pick something better than i8.
let pointee = if let Some(pointee) = self.pointee_info_at(cx, offset) { let pointee = if let Some(pointee) = self.pointee_info_at(cx, offset) {

View File

@ -904,8 +904,8 @@ fn llvm_asm_scalar_type<'ll>(cx: &CodegenCx<'ll, '_>, scalar: Scalar) -> &'ll Ty
Primitive::Int(Integer::I16, _) => cx.type_i16(), Primitive::Int(Integer::I16, _) => cx.type_i16(),
Primitive::Int(Integer::I32, _) => cx.type_i32(), Primitive::Int(Integer::I32, _) => cx.type_i32(),
Primitive::Int(Integer::I64, _) => cx.type_i64(), Primitive::Int(Integer::I64, _) => cx.type_i64(),
Primitive::F32 => cx.type_f32(), Primitive::Float(Float::F32) => cx.type_f32(),
Primitive::F64 => cx.type_f64(), Primitive::Float(Float::F64) => cx.type_f64(),
// FIXME(erikdesjardins): handle non-default addrspace ptr sizes // FIXME(erikdesjardins): handle non-default addrspace ptr sizes
Primitive::Pointer(_) => cx.type_from_integer(dl.ptr_sized_integer()), Primitive::Pointer(_) => cx.type_from_integer(dl.ptr_sized_integer()),
_ => unreachable!(), _ => unreachable!(),
@ -950,7 +950,7 @@ fn llvm_fixup_input<'ll, 'tcx>(
bx.shuffle_vector(value, bx.const_undef(vec_ty), bx.const_vector(&indices)) bx.shuffle_vector(value, bx.const_undef(vec_ty), bx.const_vector(&indices))
} }
(InlineAsmRegClass::X86(X86InlineAsmRegClass::reg_abcd), Abi::Scalar(s)) (InlineAsmRegClass::X86(X86InlineAsmRegClass::reg_abcd), Abi::Scalar(s))
if s.primitive() == Primitive::F64 => if s.primitive() == Primitive::Float(Float::F64) =>
{ {
bx.bitcast(value, bx.cx.type_i64()) bx.bitcast(value, bx.cx.type_i64())
} }
@ -986,8 +986,8 @@ fn llvm_fixup_input<'ll, 'tcx>(
match s.primitive() { match s.primitive() {
// MIPS only supports register-length arithmetics. // MIPS only supports register-length arithmetics.
Primitive::Int(Integer::I8 | Integer::I16, _) => bx.zext(value, bx.cx.type_i32()), Primitive::Int(Integer::I8 | Integer::I16, _) => bx.zext(value, bx.cx.type_i32()),
Primitive::F32 => bx.bitcast(value, bx.cx.type_i32()), Primitive::Float(Float::F32) => bx.bitcast(value, bx.cx.type_i32()),
Primitive::F64 => bx.bitcast(value, bx.cx.type_i64()), Primitive::Float(Float::F64) => bx.bitcast(value, bx.cx.type_i64()),
_ => value, _ => value,
} }
} }
@ -1027,7 +1027,7 @@ fn llvm_fixup_output<'ll, 'tcx>(
bx.shuffle_vector(value, bx.const_undef(vec_ty), bx.const_vector(&indices)) bx.shuffle_vector(value, bx.const_undef(vec_ty), bx.const_vector(&indices))
} }
(InlineAsmRegClass::X86(X86InlineAsmRegClass::reg_abcd), Abi::Scalar(s)) (InlineAsmRegClass::X86(X86InlineAsmRegClass::reg_abcd), Abi::Scalar(s))
if s.primitive() == Primitive::F64 => if s.primitive() == Primitive::Float(Float::F64) =>
{ {
bx.bitcast(value, bx.cx.type_f64()) bx.bitcast(value, bx.cx.type_f64())
} }
@ -1064,8 +1064,8 @@ fn llvm_fixup_output<'ll, 'tcx>(
// MIPS only supports register-length arithmetics. // MIPS only supports register-length arithmetics.
Primitive::Int(Integer::I8, _) => bx.trunc(value, bx.cx.type_i8()), Primitive::Int(Integer::I8, _) => bx.trunc(value, bx.cx.type_i8()),
Primitive::Int(Integer::I16, _) => bx.trunc(value, bx.cx.type_i16()), Primitive::Int(Integer::I16, _) => bx.trunc(value, bx.cx.type_i16()),
Primitive::F32 => bx.bitcast(value, bx.cx.type_f32()), Primitive::Float(Float::F32) => bx.bitcast(value, bx.cx.type_f32()),
Primitive::F64 => bx.bitcast(value, bx.cx.type_f64()), Primitive::Float(Float::F64) => bx.bitcast(value, bx.cx.type_f64()),
_ => value, _ => value,
} }
} }
@ -1100,7 +1100,7 @@ fn llvm_fixup_output_type<'ll, 'tcx>(
cx.type_vector(elem_ty, count * 2) cx.type_vector(elem_ty, count * 2)
} }
(InlineAsmRegClass::X86(X86InlineAsmRegClass::reg_abcd), Abi::Scalar(s)) (InlineAsmRegClass::X86(X86InlineAsmRegClass::reg_abcd), Abi::Scalar(s))
if s.primitive() == Primitive::F64 => if s.primitive() == Primitive::Float(Float::F64) =>
{ {
cx.type_i64() cx.type_i64()
} }
@ -1136,8 +1136,8 @@ fn llvm_fixup_output_type<'ll, 'tcx>(
match s.primitive() { match s.primitive() {
// MIPS only supports register-length arithmetics. // MIPS only supports register-length arithmetics.
Primitive::Int(Integer::I8 | Integer::I16, _) => cx.type_i32(), Primitive::Int(Integer::I8 | Integer::I16, _) => cx.type_i32(),
Primitive::F32 => cx.type_i32(), Primitive::Float(Float::F32) => cx.type_i32(),
Primitive::F64 => cx.type_i64(), Primitive::Float(Float::F64) => cx.type_i64(),
_ => layout.llvm_type(cx), _ => layout.llvm_type(cx),
} }
} }

View File

@ -576,7 +576,7 @@ fn scalar_load_metadata<'a, 'll, 'tcx>(
} }
} }
} }
abi::F16 | abi::F32 | abi::F64 | abi::F128 => {} abi::Float(_) => {}
} }
} }

View File

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

View File

@ -18,7 +18,7 @@
use rustc_middle::ty::{self, GenericArgsRef, Ty}; use rustc_middle::ty::{self, GenericArgsRef, Ty};
use rustc_middle::{bug, span_bug}; use rustc_middle::{bug, span_bug};
use rustc_span::{sym, Span, Symbol}; use rustc_span::{sym, Span, Symbol};
use rustc_target::abi::{self, Align, HasDataLayout, Primitive, Size}; use rustc_target::abi::{self, Align, Float, HasDataLayout, Primitive, Size};
use rustc_target::spec::{HasTargetSpec, PanicStrategy}; use rustc_target::spec::{HasTargetSpec, PanicStrategy};
use std::cmp::Ordering; use std::cmp::Ordering;
@ -231,13 +231,17 @@ fn codegen_intrinsic_call(
emit_va_arg(self, args[0], ret_ty) emit_va_arg(self, args[0], ret_ty)
} }
} }
Primitive::F16 => bug!("the va_arg intrinsic does not work with `f16`"), Primitive::Float(Float::F16) => {
Primitive::F64 | Primitive::Pointer(_) => { bug!("the va_arg intrinsic does not work with `f16`")
}
Primitive::Float(Float::F64) | Primitive::Pointer(_) => {
emit_va_arg(self, args[0], ret_ty) emit_va_arg(self, args[0], ret_ty)
} }
// `va_arg` should never be used with the return type f32. // `va_arg` should never be used with the return type f32.
Primitive::F32 => bug!("the va_arg intrinsic does not work with `f32`"), Primitive::Float(Float::F32) => {
Primitive::F128 => { bug!("the va_arg intrinsic does not work with `f32`")
}
Primitive::Float(Float::F128) => {
bug!("the va_arg intrinsic does not work with `f128`") bug!("the va_arg intrinsic does not work with `f128`")
} }
} }

View File

@ -6,7 +6,7 @@
use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths}; use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths};
use rustc_middle::ty::{self, Ty, TypeVisitableExt}; use rustc_middle::ty::{self, Ty, TypeVisitableExt};
use rustc_target::abi::{Abi, Align, FieldsShape}; use rustc_target::abi::{Abi, Align, FieldsShape};
use rustc_target::abi::{Int, Pointer, F128, F16, F32, F64}; use rustc_target::abi::{Float, Int, Pointer};
use rustc_target::abi::{Scalar, Size, Variants}; use rustc_target::abi::{Scalar, Size, Variants};
use std::fmt::Write; use std::fmt::Write;
@ -272,10 +272,7 @@ fn immediate_llvm_type<'a>(&self, cx: &CodegenCx<'a, 'tcx>) -> &'a Type {
fn scalar_llvm_type_at<'a>(&self, cx: &CodegenCx<'a, 'tcx>, scalar: Scalar) -> &'a Type { fn scalar_llvm_type_at<'a>(&self, cx: &CodegenCx<'a, 'tcx>, scalar: Scalar) -> &'a Type {
match scalar.primitive() { match scalar.primitive() {
Int(i, _) => cx.type_from_integer(i), Int(i, _) => cx.type_from_integer(i),
F16 => cx.type_f16(), Float(f) => cx.type_from_float(f),
F32 => cx.type_f32(),
F64 => cx.type_f64(),
F128 => cx.type_f128(),
Pointer(address_space) => cx.type_ptr_ext(address_space), Pointer(address_space) => cx.type_ptr_ext(address_space),
} }
} }

View File

@ -306,17 +306,15 @@ fn transmute_immediate(
self.assume_scalar_range(bx, imm, from_scalar, from_backend_ty); self.assume_scalar_range(bx, imm, from_scalar, from_backend_ty);
imm = match (from_scalar.primitive(), to_scalar.primitive()) { imm = match (from_scalar.primitive(), to_scalar.primitive()) {
(Int(..) | F16 | F32 | F64 | F128, Int(..) | F16 | F32 | F64 | F128) => { (Int(..) | Float(_), Int(..) | Float(_)) => bx.bitcast(imm, to_backend_ty),
bx.bitcast(imm, to_backend_ty)
}
(Pointer(..), Pointer(..)) => bx.pointercast(imm, to_backend_ty), (Pointer(..), Pointer(..)) => bx.pointercast(imm, to_backend_ty),
(Int(..), Pointer(..)) => bx.ptradd(bx.const_null(bx.type_ptr()), imm), (Int(..), Pointer(..)) => bx.ptradd(bx.const_null(bx.type_ptr()), imm),
(Pointer(..), Int(..)) => bx.ptrtoint(imm, to_backend_ty), (Pointer(..), Int(..)) => bx.ptrtoint(imm, to_backend_ty),
(F16 | F32 | F64 | F128, Pointer(..)) => { (Float(_), Pointer(..)) => {
let int_imm = bx.bitcast(imm, bx.cx().type_isize()); let int_imm = bx.bitcast(imm, bx.cx().type_isize());
bx.ptradd(bx.const_null(bx.type_ptr()), int_imm) bx.ptradd(bx.const_null(bx.type_ptr()), int_imm)
} }
(Pointer(..), F16 | F32 | F64 | F128) => { (Pointer(..), Float(_)) => {
let int_imm = bx.ptrtoint(imm, bx.cx().type_isize()); let int_imm = bx.ptrtoint(imm, bx.cx().type_isize());
bx.bitcast(int_imm, to_backend_ty) bx.bitcast(int_imm, to_backend_ty)
} }

View File

@ -7,7 +7,7 @@
use rustc_middle::ty::layout::TyAndLayout; use rustc_middle::ty::layout::TyAndLayout;
use rustc_middle::ty::{self, Ty}; use rustc_middle::ty::{self, Ty};
use rustc_target::abi::call::{ArgAbi, CastTarget, FnAbi, Reg}; use rustc_target::abi::call::{ArgAbi, CastTarget, FnAbi, Reg};
use rustc_target::abi::{AddressSpace, Integer}; use rustc_target::abi::{AddressSpace, Float, Integer};
// This depends on `Backend` and not `BackendTypes`, because consumers will probably want to use // This depends on `Backend` and not `BackendTypes`, because consumers will probably want to use
// `LayoutOf` or `HasTyCtxt`. This way, they don't have to add a constraint on it themselves. // `LayoutOf` or `HasTyCtxt`. This way, they don't have to add a constraint on it themselves.
@ -65,6 +65,16 @@ fn type_from_integer(&self, i: Integer) -> Self::Type {
} }
} }
fn type_from_float(&self, f: Float) -> Self::Type {
use Float::*;
match f {
F16 => self.type_f16(),
F32 => self.type_f32(),
F64 => self.type_f64(),
F128 => self.type_f128(),
}
}
fn type_needs_drop(&self, ty: Ty<'tcx>) -> bool { fn type_needs_drop(&self, ty: Ty<'tcx>) -> bool {
ty.needs_drop(self.tcx(), ty::ParamEnv::reveal_all()) ty.needs_drop(self.tcx(), ty::ParamEnv::reveal_all())
} }

View File

@ -114,16 +114,35 @@ fn repr_discr<'tcx>(
} }
} }
#[extension(pub trait FloatExt)]
impl Float {
#[inline]
fn to_ty<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
match *self {
F16 => tcx.types.f16,
F32 => tcx.types.f32,
F64 => tcx.types.f64,
F128 => tcx.types.f128,
}
}
fn from_float_ty(fty: ty::FloatTy) -> Self {
match fty {
ty::FloatTy::F16 => F16,
ty::FloatTy::F32 => F32,
ty::FloatTy::F64 => F64,
ty::FloatTy::F128 => F128,
}
}
}
#[extension(pub trait PrimitiveExt)] #[extension(pub trait PrimitiveExt)]
impl Primitive { impl Primitive {
#[inline] #[inline]
fn to_ty<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> { fn to_ty<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
match *self { match *self {
Int(i, signed) => i.to_ty(tcx, signed), Int(i, signed) => i.to_ty(tcx, signed),
F16 => tcx.types.f16, Float(f) => f.to_ty(tcx),
F32 => tcx.types.f32,
F64 => tcx.types.f64,
F128 => tcx.types.f128,
// FIXME(erikdesjardins): handle non-default addrspace ptr sizes // FIXME(erikdesjardins): handle non-default addrspace ptr sizes
Pointer(_) => Ty::new_mut_ptr(tcx, tcx.types.unit), Pointer(_) => Ty::new_mut_ptr(tcx, tcx.types.unit),
} }
@ -140,7 +159,7 @@ fn to_int_ty<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
let signed = false; let signed = false;
tcx.data_layout().ptr_sized_integer().to_ty(tcx, signed) tcx.data_layout().ptr_sized_integer().to_ty(tcx, signed)
} }
F16 | F32 | F64 | F128 => bug!("floats do not have an int type"), Float(_) => bug!("floats do not have an int type"),
} }
} }
} }

View File

@ -2,7 +2,7 @@
use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags; use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use crate::query::{IntoQueryParam, Providers}; use crate::query::{IntoQueryParam, Providers};
use crate::ty::layout::IntegerExt; use crate::ty::layout::{FloatExt, IntegerExt};
use crate::ty::{ use crate::ty::{
self, FallibleTypeFolder, ToPredicate, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, self, FallibleTypeFolder, ToPredicate, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable,
TypeVisitableExt, TypeVisitableExt,
@ -20,7 +20,7 @@
use rustc_macros::{extension, HashStable, TyDecodable, TyEncodable}; use rustc_macros::{extension, HashStable, TyDecodable, TyEncodable};
use rustc_session::Limit; use rustc_session::Limit;
use rustc_span::sym; use rustc_span::sym;
use rustc_target::abi::{Integer, IntegerType, Primitive, Size}; use rustc_target::abi::{Float, Integer, IntegerType, Size};
use rustc_target::spec::abi::Abi; use rustc_target::spec::abi::Abi;
use smallvec::{smallvec, SmallVec}; use smallvec::{smallvec, SmallVec};
use std::{fmt, iter}; use std::{fmt, iter};
@ -1145,8 +1145,7 @@ pub fn primitive_size(self, tcx: TyCtxt<'tcx>) -> Size {
ty::Char => Size::from_bytes(4), ty::Char => Size::from_bytes(4),
ty::Int(ity) => Integer::from_int_ty(&tcx, ity).size(), ty::Int(ity) => Integer::from_int_ty(&tcx, ity).size(),
ty::Uint(uty) => Integer::from_uint_ty(&tcx, uty).size(), ty::Uint(uty) => Integer::from_uint_ty(&tcx, uty).size(),
ty::Float(ty::FloatTy::F32) => Primitive::F32.size(&tcx), ty::Float(fty) => Float::from_float_ty(fty).size(),
ty::Float(ty::FloatTy::F64) => Primitive::F64.size(&tcx),
_ => bug!("non primitive type"), _ => bug!("non primitive type"),
} }
} }

View File

@ -256,10 +256,9 @@ fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
rustc_abi::Primitive::Int(length, signed) => { rustc_abi::Primitive::Int(length, signed) => {
Primitive::Int { length: length.stable(tables), signed: *signed } Primitive::Int { length: length.stable(tables), signed: *signed }
} }
rustc_abi::Primitive::F16 => Primitive::Float { length: FloatLength::F16 }, rustc_abi::Primitive::Float(length) => {
rustc_abi::Primitive::F32 => Primitive::Float { length: FloatLength::F32 }, Primitive::Float { length: length.stable(tables) }
rustc_abi::Primitive::F64 => Primitive::Float { length: FloatLength::F64 }, }
rustc_abi::Primitive::F128 => Primitive::Float { length: FloatLength::F128 },
rustc_abi::Primitive::Pointer(space) => Primitive::Pointer(space.stable(tables)), rustc_abi::Primitive::Pointer(space) => Primitive::Pointer(space.stable(tables)),
} }
} }
@ -287,6 +286,19 @@ fn stable(&self, _tables: &mut Tables<'_>) -> Self::T {
} }
} }
impl<'tcx> Stable<'tcx> for rustc_abi::Float {
type T = FloatLength;
fn stable(&self, _tables: &mut Tables<'_>) -> Self::T {
match self {
rustc_abi::Float::F16 => FloatLength::F16,
rustc_abi::Float::F32 => FloatLength::F32,
rustc_abi::Float::F64 => FloatLength::F64,
rustc_abi::Float::F128 => FloatLength::F128,
}
}
}
impl<'tcx> Stable<'tcx> for rustc_abi::WrappingRange { impl<'tcx> Stable<'tcx> for rustc_abi::WrappingRange {
type T = WrappingRange; type T = WrappingRange;

View File

@ -59,7 +59,7 @@ fn should_use_fp_conv_helper<'a, Ty, C>(
_ => return Err(CannotUseFpConv), _ => return Err(CannotUseFpConv),
} }
} }
abi::F16 | abi::F32 | abi::F64 | abi::F128 => { abi::Float(_) => {
if arg_layout.size.bits() > flen { if arg_layout.size.bits() > flen {
return Err(CannotUseFpConv); return Err(CannotUseFpConv);
} }

View File

@ -26,8 +26,8 @@ fn float_reg<'a, Ty, C>(cx: &C, ret: &ArgAbi<'a, Ty>, i: usize) -> Option<Reg>
{ {
match ret.layout.field(cx, i).abi { match ret.layout.field(cx, i).abi {
abi::Abi::Scalar(scalar) => match scalar.primitive() { abi::Abi::Scalar(scalar) => match scalar.primitive() {
abi::F32 => Some(Reg::f32()), abi::Float(abi::F32) => Some(Reg::f32()),
abi::F64 => Some(Reg::f64()), abi::Float(abi::F64) => Some(Reg::f64()),
_ => None, _ => None,
}, },
_ => None, _ => None,
@ -110,7 +110,7 @@ fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>)
// We only care about aligned doubles // We only care about aligned doubles
if let abi::Abi::Scalar(scalar) = field.abi { if let abi::Abi::Scalar(scalar) = field.abi {
if let abi::F64 = scalar.primitive() { if scalar.primitive() == abi::Float(abi::F64) {
if offset.is_aligned(dl.f64_align.abi) { if offset.is_aligned(dl.f64_align.abi) {
// Insert enough integers to cover [last_offset, offset) // Insert enough integers to cover [last_offset, offset)
assert!(last_offset.is_aligned(dl.f64_align.abi)); assert!(last_offset.is_aligned(dl.f64_align.abi));

View File

@ -443,7 +443,7 @@ pub fn homogeneous_aggregate<C>(&self, cx: &C) -> Result<HomogeneousAggregate, H
Abi::Scalar(scalar) => { Abi::Scalar(scalar) => {
let kind = match scalar.primitive() { let kind = match scalar.primitive() {
abi::Int(..) | abi::Pointer(_) => RegKind::Integer, abi::Int(..) | abi::Pointer(_) => RegKind::Integer,
abi::F16 | abi::F32 | abi::F64 | abi::F128 => RegKind::Float, abi::Float(_) => RegKind::Float,
}; };
Ok(HomogeneousAggregate::Homogeneous(Reg { kind, size: self.size })) Ok(HomogeneousAggregate::Homogeneous(Reg { kind, size: self.size }))
} }

View File

@ -65,7 +65,7 @@ fn should_use_fp_conv_helper<'a, Ty, C>(
_ => return Err(CannotUseFpConv), _ => return Err(CannotUseFpConv),
} }
} }
abi::F16 | abi::F32 | abi::F64 | abi::F128 => { abi::Float(_) => {
if arg_layout.size.bits() > flen { if arg_layout.size.bits() > flen {
return Err(CannotUseFpConv); return Err(CannotUseFpConv);
} }

View File

@ -20,7 +20,7 @@ fn arg_scalar<C>(cx: &C, scalar: &Scalar, offset: Size, mut data: Sdata) -> Sdat
{ {
let dl = cx.data_layout(); let dl = cx.data_layout();
if !matches!(scalar.primitive(), abi::F32 | abi::F64) { if !matches!(scalar.primitive(), abi::Float(abi::F32 | abi::F64)) {
return data; return data;
} }
@ -56,7 +56,7 @@ fn arg_scalar<C>(cx: &C, scalar: &Scalar, offset: Size, mut data: Sdata) -> Sdat
return data; return data;
} }
if scalar.primitive() == abi::F32 { if scalar.primitive() == abi::Float(abi::F32) {
data.arg_attribute = ArgAttribute::InReg; data.arg_attribute = ArgAttribute::InReg;
data.prefix[data.prefix_index] = Some(Reg::f32()); data.prefix[data.prefix_index] = Some(Reg::f32());
data.last_offset = offset + Reg::f32().size; data.last_offset = offset + Reg::f32().size;
@ -80,14 +80,14 @@ fn arg_scalar_pair<C>(
{ {
data = arg_scalar(cx, scalar1, offset, data); data = arg_scalar(cx, scalar1, offset, data);
match (scalar1.primitive(), scalar2.primitive()) { match (scalar1.primitive(), scalar2.primitive()) {
(abi::F32, _) => offset += Reg::f32().size, (abi::Float(abi::F32), _) => offset += Reg::f32().size,
(_, abi::F64) => offset += Reg::f64().size, (_, abi::Float(abi::F64)) => offset += Reg::f64().size,
(abi::Int(i, _signed), _) => offset += i.size(), (abi::Int(i, _signed), _) => offset += i.size(),
(abi::Pointer(_), _) => offset += Reg::i64().size, (abi::Pointer(_), _) => offset += Reg::i64().size,
_ => {} _ => {}
} }
if (offset.bytes() % 4) != 0 && matches!(scalar2.primitive(), abi::F32 | abi::F64) { if (offset.bytes() % 4) != 0 && matches!(scalar2.primitive(), abi::Float(abi::F32 | abi::F64)) {
offset += Size::from_bytes(4 - (offset.bytes() % 4)); offset += Size::from_bytes(4 - (offset.bytes() % 4));
} }
data = arg_scalar(cx, scalar2, offset, data); data = arg_scalar(cx, scalar2, offset, data);

View File

@ -51,7 +51,7 @@ fn classify<'a, Ty, C>(
Abi::Scalar(scalar) => match scalar.primitive() { Abi::Scalar(scalar) => match scalar.primitive() {
abi::Int(..) | abi::Pointer(_) => Class::Int, abi::Int(..) | abi::Pointer(_) => Class::Int,
abi::F16 | abi::F32 | abi::F64 | abi::F128 => Class::Sse, abi::Float(_) => Class::Sse,
}, },
Abi::Vector { .. } => Class::Sse, Abi::Vector { .. } => Class::Sse,

View File

@ -1,4 +1,5 @@
use rustc_data_structures::intern::Interned; use rustc_data_structures::intern::Interned;
pub use Float::*;
pub use Integer::*; pub use Integer::*;
pub use Primitive::*; pub use Primitive::*;
@ -11,7 +12,8 @@
pub mod call; pub mod call;
pub use rustc_abi::*; // Explicitly import `Float` to avoid ambiguity with `Primitive::Float`.
pub use rustc_abi::{Float, *};
impl ToJson for Endian { impl ToJson for Endian {
fn to_json(&self) -> Json { fn to_json(&self) -> Json {
@ -207,7 +209,7 @@ pub fn is_single_fp_element<C>(self, cx: &C) -> bool
C: HasDataLayout, C: HasDataLayout,
{ {
match self.abi { match self.abi {
Abi::Scalar(scalar) => matches!(scalar.primitive(), F32 | F64), Abi::Scalar(scalar) => matches!(scalar.primitive(), Float(F32 | F64)),
Abi::Aggregate { .. } => { Abi::Aggregate { .. } => {
if self.fields.count() == 1 && self.fields.offset(0).bytes() == 0 { if self.fields.count() == 1 && self.fields.offset(0).bytes() == 0 {
self.field(cx, 0).is_single_fp_element(cx) self.field(cx, 0).is_single_fp_element(cx)

View File

@ -5,7 +5,7 @@
use rustc_middle::mir::{CoroutineLayout, CoroutineSavedLocal}; use rustc_middle::mir::{CoroutineLayout, CoroutineSavedLocal};
use rustc_middle::query::Providers; use rustc_middle::query::Providers;
use rustc_middle::ty::layout::{ use rustc_middle::ty::layout::{
IntegerExt, LayoutCx, LayoutError, LayoutOf, TyAndLayout, MAX_SIMD_LANES, FloatExt, IntegerExt, LayoutCx, LayoutError, LayoutOf, TyAndLayout, MAX_SIMD_LANES,
}; };
use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::print::with_no_trimmed_paths;
use rustc_middle::ty::{ use rustc_middle::ty::{
@ -180,12 +180,7 @@ fn layout_of_uncached<'tcx>(
)), )),
ty::Int(ity) => scalar(Int(Integer::from_int_ty(dl, ity), true)), ty::Int(ity) => scalar(Int(Integer::from_int_ty(dl, ity), true)),
ty::Uint(ity) => scalar(Int(Integer::from_uint_ty(dl, ity), false)), ty::Uint(ity) => scalar(Int(Integer::from_uint_ty(dl, ity), false)),
ty::Float(fty) => scalar(match fty { ty::Float(fty) => scalar(Float(Float::from_float_ty(fty))),
ty::FloatTy::F16 => F16,
ty::FloatTy::F32 => F32,
ty::FloatTy::F64 => F64,
ty::FloatTy::F128 => F128,
}),
ty::FnPtr(_) => { ty::FnPtr(_) => {
let mut ptr = scalar_unit(Pointer(dl.instruction_address_space)); let mut ptr = scalar_unit(Pointer(dl.instruction_address_space));
ptr.valid_range_mut().start = 1; ptr.valid_range_mut().start = 1;

View File

@ -6,8 +6,8 @@
use chalk_ir::{AdtId, FloatTy, IntTy, TyKind, UintTy}; use chalk_ir::{AdtId, FloatTy, IntTy, TyKind, UintTy};
use hir_def::{ use hir_def::{
layout::{ layout::{
Abi, FieldsShape, Integer, LayoutCalculator, LayoutS, Primitive, ReprOptions, Scalar, Size, Abi, FieldsShape, Float, Integer, LayoutCalculator, LayoutS, Primitive, ReprOptions,
StructKind, TargetDataLayout, WrappingRange, Scalar, Size, StructKind, TargetDataLayout, WrappingRange,
}, },
LocalFieldId, StructId, LocalFieldId, StructId,
}; };
@ -264,10 +264,10 @@ pub fn layout_of_ty_query(
), ),
chalk_ir::Scalar::Float(f) => scalar( chalk_ir::Scalar::Float(f) => scalar(
dl, dl,
match f { Primitive::Float(match f {
FloatTy::F32 => Primitive::F32, FloatTy::F32 => Float::F32,
FloatTy::F64 => Primitive::F64, FloatTy::F64 => Float::F64,
}, }),
), ),
}, },
TyKind::Tuple(len, tys) => { TyKind::Tuple(len, tys) => {

View File

@ -576,7 +576,9 @@ error: ABIs are not compatible
}, },
abi: Scalar( abi: Scalar(
Initialized { Initialized {
value: F32, value: Float(
F32,
),
valid_range: $FULL, valid_range: $FULL,
}, },
), ),