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

Refactor float Primitives to a separate Float type #124797

Merged
merged 1 commit into from
May 10, 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
50 changes: 38 additions & 12 deletions compiler/rustc_abi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -926,6 +926,41 @@ impl Integer {
}
}

/// 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.
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
#[cfg_attr(feature = "nightly", derive(HashStable_Generic))]
Expand All @@ -938,10 +973,7 @@ 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,
Float(Float),
Pointer(AddressSpace),
}

Expand All @@ -952,10 +984,7 @@ 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),
Float(f) => f.size(),
// 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 @@ -969,10 +998,7 @@ 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,
Float(f) => f.align(dl),
// 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
12 changes: 7 additions & 5 deletions compiler/rustc_codegen_cranelift/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use rustc_middle::ty::layout::{
use rustc_middle::ty::TypeFoldable;
use rustc_span::source_map::Spanned;
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 crate::constant::ConstantCx;
Expand All @@ -32,10 +32,12 @@ 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"),
Primitive::Float(float) => match float {
Float::F16 => unimplemented!("f16_f128"),
Float::F32 => types::F32,
Float::F64 => types::F64,
Float::F128 => unimplemented!("f16_f128"),
},
// FIXME(erikdesjardins): handle non-default addrspace ptr sizes
Primitive::Pointer(_) => pointer_ty(tcx),
}
Expand Down
9 changes: 3 additions & 6 deletions compiler/rustc_codegen_gcc/src/type_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ use rustc_middle::ty::print::with_no_trimmed_paths;
use rustc_middle::ty::{self, Ty, TypeVisitableExt};
use rustc_target::abi::call::{CastTarget, FnAbi, Reg};
use rustc_target::abi::{
self, Abi, Align, FieldsShape, Int, Integer, PointeeInfo, Pointer, Size, TyAbiInterface,
Variants, F128, F16, F32, F64,
self, Abi, Align, FieldsShape, Float, Int, Integer, PointeeInfo, Pointer, Size, TyAbiInterface,
Variants,
};

use crate::abi::{FnAbiGcc, FnAbiGccExt, GccType};
Expand Down Expand Up @@ -283,10 +283,7 @@ 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(),
Float(f) => cx.type_from_float(f),
Pointer(address_space) => {
// If we know the alignment, pick something better than i8.
let pointee = if let Some(pointee) = self.pointee_info_at(cx, offset) {
Expand Down
22 changes: 11 additions & 11 deletions compiler/rustc_codegen_llvm/src/asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::I32, _) => cx.type_i32(),
Primitive::Int(Integer::I64, _) => cx.type_i64(),
Primitive::F32 => cx.type_f32(),
Primitive::F64 => cx.type_f64(),
Primitive::Float(Float::F32) => cx.type_f32(),
Primitive::Float(Float::F64) => cx.type_f64(),
// FIXME(erikdesjardins): handle non-default addrspace ptr sizes
Primitive::Pointer(_) => cx.type_from_integer(dl.ptr_sized_integer()),
_ => unreachable!(),
Expand Down Expand Up @@ -950,7 +950,7 @@ fn llvm_fixup_input<'ll, 'tcx>(
bx.shuffle_vector(value, bx.const_undef(vec_ty), bx.const_vector(&indices))
}
(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())
}
Expand Down Expand Up @@ -986,8 +986,8 @@ fn llvm_fixup_input<'ll, 'tcx>(
match s.primitive() {
// MIPS only supports register-length arithmetics.
Primitive::Int(Integer::I8 | Integer::I16, _) => bx.zext(value, bx.cx.type_i32()),
Primitive::F32 => bx.bitcast(value, bx.cx.type_i32()),
Primitive::F64 => bx.bitcast(value, bx.cx.type_i64()),
Primitive::Float(Float::F32) => bx.bitcast(value, bx.cx.type_i32()),
Primitive::Float(Float::F64) => bx.bitcast(value, bx.cx.type_i64()),
_ => value,
}
}
Expand Down Expand Up @@ -1027,7 +1027,7 @@ fn llvm_fixup_output<'ll, 'tcx>(
bx.shuffle_vector(value, bx.const_undef(vec_ty), bx.const_vector(&indices))
}
(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())
}
Expand Down Expand Up @@ -1064,8 +1064,8 @@ fn llvm_fixup_output<'ll, 'tcx>(
// MIPS only supports register-length arithmetics.
Primitive::Int(Integer::I8, _) => bx.trunc(value, bx.cx.type_i8()),
Primitive::Int(Integer::I16, _) => bx.trunc(value, bx.cx.type_i16()),
Primitive::F32 => bx.bitcast(value, bx.cx.type_f32()),
Primitive::F64 => bx.bitcast(value, bx.cx.type_f64()),
Primitive::Float(Float::F32) => bx.bitcast(value, bx.cx.type_f32()),
Primitive::Float(Float::F64) => bx.bitcast(value, bx.cx.type_f64()),
_ => value,
}
}
Expand Down Expand Up @@ -1100,7 +1100,7 @@ fn llvm_fixup_output_type<'ll, 'tcx>(
cx.type_vector(elem_ty, count * 2)
}
(InlineAsmRegClass::X86(X86InlineAsmRegClass::reg_abcd), Abi::Scalar(s))
if s.primitive() == Primitive::F64 =>
if s.primitive() == Primitive::Float(Float::F64) =>
{
cx.type_i64()
}
Expand Down Expand Up @@ -1136,8 +1136,8 @@ fn llvm_fixup_output_type<'ll, 'tcx>(
match s.primitive() {
// MIPS only supports register-length arithmetics.
Primitive::Int(Integer::I8 | Integer::I16, _) => cx.type_i32(),
Primitive::F32 => cx.type_i32(),
Primitive::F64 => cx.type_i64(),
Primitive::Float(Float::F32) => cx.type_i32(),
Primitive::Float(Float::F64) => cx.type_i64(),
_ => layout.llvm_type(cx),
}
}
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 @@ -576,7 +576,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
}
}
}
abi::F16 | abi::F32 | abi::F64 | abi::F128 => {}
abi::Float(_) => {}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,10 +122,7 @@ 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,
Primitive::Float(f) => Integer::from_size(f.size()).unwrap(),
// 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
14 changes: 9 additions & 5 deletions compiler/rustc_codegen_llvm/src/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, LayoutOf};
use rustc_middle::ty::{self, GenericArgsRef, Ty};
use rustc_middle::{bug, span_bug};
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 std::cmp::Ordering;
Expand Down Expand Up @@ -231,13 +231,17 @@ 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(_) => {
Primitive::Float(Float::F16) => {
bug!("the va_arg intrinsic does not work with `f16`")
}
Primitive::Float(Float::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 => {
Primitive::Float(Float::F32) => {
bug!("the va_arg intrinsic does not work with `f32`")
}
Primitive::Float(Float::F128) => {
bug!("the va_arg intrinsic does not work with `f128`")
}
}
Expand Down
7 changes: 2 additions & 5 deletions compiler/rustc_codegen_llvm/src/type_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths};
use rustc_middle::ty::{self, Ty, TypeVisitableExt};
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 std::fmt::Write;
Expand Down Expand Up @@ -272,10 +272,7 @@ 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(),
Float(f) => cx.type_from_float(f),
Pointer(address_space) => cx.type_ptr_ext(address_space),
}
}
Expand Down
8 changes: 3 additions & 5 deletions compiler/rustc_codegen_ssa/src/mir/rvalue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -306,17 +306,15 @@ 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(..) | F16 | F32 | F64 | F128, Int(..) | F16 | F32 | F64 | F128) => {
bx.bitcast(imm, to_backend_ty)
}
(Int(..) | Float(_), Int(..) | Float(_)) => bx.bitcast(imm, to_backend_ty),
(Pointer(..), Pointer(..)) => bx.pointercast(imm, to_backend_ty),
(Int(..), Pointer(..)) => bx.ptradd(bx.const_null(bx.type_ptr()), imm),
(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());
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());
bx.bitcast(int_imm, to_backend_ty)
}
Expand Down
12 changes: 11 additions & 1 deletion compiler/rustc_codegen_ssa/src/traits/type_.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use rustc_middle::bug;
use rustc_middle::ty::layout::TyAndLayout;
use rustc_middle::ty::{self, Ty};
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
// `LayoutOf` or `HasTyCtxt`. This way, they don't have to add a constraint on it themselves.
Expand Down Expand Up @@ -65,6 +65,16 @@ pub trait DerivedTypeMethods<'tcx>: BaseTypeMethods<'tcx> + MiscMethods<'tcx> {
}
}

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 {
ty.needs_drop(self.tcx(), ty::ParamEnv::reveal_all())
}
Expand Down
27 changes: 23 additions & 4 deletions compiler/rustc_middle/src/ty/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,16 +114,35 @@ impl Integer {
}
}

#[extension(pub trait PrimitiveExt)]
impl Primitive {
#[extension(pub trait FloatExt)]
impl Float {
#[inline]
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,
}
}

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)]
impl Primitive {
#[inline]
fn to_ty<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
match *self {
Int(i, signed) => i.to_ty(tcx, signed),
Float(f) => f.to_ty(tcx),
// FIXME(erikdesjardins): handle non-default addrspace ptr sizes
Pointer(_) => Ty::new_mut_ptr(tcx, tcx.types.unit),
}
Expand All @@ -140,7 +159,7 @@ impl Primitive {
let signed = false;
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"),
}
}
}
Expand Down
7 changes: 3 additions & 4 deletions compiler/rustc_middle/src/ty/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use crate::query::{IntoQueryParam, Providers};
use crate::ty::layout::IntegerExt;
use crate::ty::layout::{FloatExt, IntegerExt};
use crate::ty::{
self, FallibleTypeFolder, ToPredicate, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable,
TypeVisitableExt,
Expand All @@ -20,7 +20,7 @@ use rustc_index::bit_set::GrowableBitSet;
use rustc_macros::{extension, HashStable, TyDecodable, TyEncodable};
use rustc_session::Limit;
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 smallvec::{smallvec, SmallVec};
use std::{fmt, iter};
Expand Down Expand Up @@ -1145,8 +1145,7 @@ impl<'tcx> Ty<'tcx> {
ty::Char => Size::from_bytes(4),
ty::Int(ity) => Integer::from_int_ty(&tcx, ity).size(),
ty::Uint(uty) => Integer::from_uint_ty(&tcx, uty).size(),
ty::Float(ty::FloatTy::F32) => Primitive::F32.size(&tcx),
ty::Float(ty::FloatTy::F64) => Primitive::F64.size(&tcx),
ty::Float(fty) => Float::from_float_ty(fty).size(),
_ => bug!("non primitive type"),
}
}
Expand Down
Loading
Loading