Skip to content

Commit 6cbf092

Browse files
committed
Auto merge of rust-lang#121728 - tgross35:f16-f128-step1-ty-updates, r=compiler-errors
Add stubs in IR and ABI for `f16` and `f128` This is the very first step toward the changes in rust-lang#114607 and the [`f16` and `f128` RFC](https://rust-lang.github.io/rfcs/3453-f16-and-f128.html). It adds the types to `rustc_type_ir::FloatTy` and `rustc_abi::Primitive`, and just propagates those out as `unimplemented!` stubs where necessary. These types do not parse yet so there is no feature gate, and it should be okay to use `unimplemented!`. The next steps will probably be AST support with parsing and the feature gate. r? `@compiler-errors` cc `@Nilstrieb` suggested breaking the PR up in rust-lang#120645 (comment)
2 parents 6f435eb + 406790e commit 6cbf092

File tree

37 files changed

+233
-14
lines changed

37 files changed

+233
-14
lines changed

compiler/rustc_abi/src/lib.rs

+12
Original file line numberDiff line numberDiff line change
@@ -171,8 +171,10 @@ pub struct TargetDataLayout {
171171
pub i32_align: AbiAndPrefAlign,
172172
pub i64_align: AbiAndPrefAlign,
173173
pub i128_align: AbiAndPrefAlign,
174+
pub f16_align: AbiAndPrefAlign,
174175
pub f32_align: AbiAndPrefAlign,
175176
pub f64_align: AbiAndPrefAlign,
177+
pub f128_align: AbiAndPrefAlign,
176178
pub pointer_size: Size,
177179
pub pointer_align: AbiAndPrefAlign,
178180
pub aggregate_align: AbiAndPrefAlign,
@@ -200,8 +202,10 @@ impl Default for TargetDataLayout {
200202
i32_align: AbiAndPrefAlign::new(align(32)),
201203
i64_align: AbiAndPrefAlign { abi: align(32), pref: align(64) },
202204
i128_align: AbiAndPrefAlign { abi: align(32), pref: align(64) },
205+
f16_align: AbiAndPrefAlign::new(align(16)),
203206
f32_align: AbiAndPrefAlign::new(align(32)),
204207
f64_align: AbiAndPrefAlign::new(align(64)),
208+
f128_align: AbiAndPrefAlign::new(align(128)),
205209
pointer_size: Size::from_bits(64),
206210
pointer_align: AbiAndPrefAlign::new(align(64)),
207211
aggregate_align: AbiAndPrefAlign { abi: align(0), pref: align(64) },
@@ -281,8 +285,10 @@ impl TargetDataLayout {
281285
dl.instruction_address_space = parse_address_space(&p[1..], "P")?
282286
}
283287
["a", ref a @ ..] => dl.aggregate_align = parse_align(a, "a")?,
288+
["f16", ref a @ ..] => dl.f16_align = parse_align(a, "f16")?,
284289
["f32", ref a @ ..] => dl.f32_align = parse_align(a, "f32")?,
285290
["f64", ref a @ ..] => dl.f64_align = parse_align(a, "f64")?,
291+
["f128", ref a @ ..] => dl.f128_align = parse_align(a, "f128")?,
286292
// FIXME(erikdesjardins): we should be parsing nonzero address spaces
287293
// this will require replacing TargetDataLayout::{pointer_size,pointer_align}
288294
// with e.g. `fn pointer_size_in(AddressSpace)`
@@ -919,8 +925,10 @@ pub enum Primitive {
919925
/// a negative integer passed by zero-extension will appear positive in
920926
/// the callee, and most operations on it will produce the wrong values.
921927
Int(Integer, bool),
928+
F16,
922929
F32,
923930
F64,
931+
F128,
924932
Pointer(AddressSpace),
925933
}
926934

@@ -931,8 +939,10 @@ impl Primitive {
931939

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

947957
match self {
948958
Int(i, _) => i.align(dl),
959+
F16 => dl.f16_align,
949960
F32 => dl.f32_align,
950961
F64 => dl.f64_align,
962+
F128 => dl.f128_align,
951963
// FIXME(erikdesjardins): ignoring address space is technically wrong, pointers in
952964
// different address spaces can have different alignments
953965
// (but TargetDataLayout doesn't currently parse that part of the DL string)

compiler/rustc_codegen_cranelift/src/common.rs

+4
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,10 @@ pub(crate) fn scalar_to_clif_type(tcx: TyCtxt<'_>, scalar: Scalar) -> Type {
3333
Integer::I64 => types::I64,
3434
Integer::I128 => types::I128,
3535
},
36+
Primitive::F16 => unimplemented!("f16_f128"),
3637
Primitive::F32 => types::F32,
3738
Primitive::F64 => types::F64,
39+
Primitive::F128 => unimplemented!("f16_f128"),
3840
// FIXME(erikdesjardins): handle non-default addrspace ptr sizes
3941
Primitive::Pointer(_) => pointer_ty(tcx),
4042
}
@@ -61,8 +63,10 @@ fn clif_type_from_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option<types::Typ
6163
},
6264
ty::Char => types::I32,
6365
ty::Float(size) => match size {
66+
FloatTy::F16 => unimplemented!("f16_f128"),
6467
FloatTy::F32 => types::F32,
6568
FloatTy::F64 => types::F64,
69+
FloatTy::F128 => unimplemented!("f16_f128"),
6670
},
6771
ty::FnPtr(_) => pointer_ty(tcx),
6872
ty::RawPtr(TypeAndMut { ty: pointee_ty, mutbl: _ }) | ty::Ref(_, pointee_ty, _) => {

compiler/rustc_codegen_gcc/src/type_.rs

+10
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,10 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
8383

8484
pub fn type_float_from_ty(&self, t: ty::FloatTy) -> Type<'gcc> {
8585
match t {
86+
ty::FloatTy::F16 => self.type_f16(),
8687
ty::FloatTy::F32 => self.type_f32(),
8788
ty::FloatTy::F64 => self.type_f64(),
89+
ty::FloatTy::F128 => self.type_f128(),
8890
}
8991
}
9092
}
@@ -118,13 +120,21 @@ impl<'gcc, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
118120
self.isize_type
119121
}
120122

123+
fn type_f16(&self) -> Type<'gcc> {
124+
unimplemented!("f16_f128")
125+
}
126+
121127
fn type_f32(&self) -> Type<'gcc> {
122128
self.float_type
123129
}
124130

125131
fn type_f64(&self) -> Type<'gcc> {
126132
self.double_type
127133
}
134+
135+
fn type_f128(&self) -> Type<'gcc> {
136+
unimplemented!("f16_f128")
137+
}
128138

129139
fn type_func(&self, params: &[Type<'gcc>], return_type: Type<'gcc>) -> Type<'gcc> {
130140
self.context.new_function_pointer_type(None, return_type, params, false)

compiler/rustc_codegen_gcc/src/type_of.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use rustc_middle::bug;
66
use rustc_middle::ty::{self, Ty, TypeVisitableExt};
77
use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
88
use rustc_middle::ty::print::with_no_trimmed_paths;
9-
use rustc_target::abi::{self, Abi, Align, F32, F64, FieldsShape, Int, Integer, Pointer, PointeeInfo, Size, TyAbiInterface, Variants};
9+
use rustc_target::abi::{self, Abi, Align, F16, F128, F32, F64, FieldsShape, Int, Integer, Pointer, PointeeInfo, Size, TyAbiInterface, Variants};
1010
use rustc_target::abi::call::{CastTarget, FnAbi, Reg};
1111

1212
use crate::abi::{FnAbiGcc, FnAbiGccExt, GccType};
@@ -257,8 +257,10 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> {
257257
match scalar.primitive() {
258258
Int(i, true) => cx.type_from_integer(i),
259259
Int(i, false) => cx.type_from_unsigned_integer(i),
260+
F16 => cx.type_f16(),
260261
F32 => cx.type_f32(),
261262
F64 => cx.type_f64(),
263+
F128 => cx.type_f128(),
262264
Pointer(address_space) => {
263265
// If we know the alignment, pick something better than i8.
264266
let pointee =

compiler/rustc_codegen_llvm/src/builder.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -568,7 +568,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
568568
}
569569
}
570570
}
571-
abi::F32 | abi::F64 => {}
571+
abi::F16 | abi::F32 | abi::F64 | abi::F128 => {}
572572
}
573573
}
574574

compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs

+4
Original file line numberDiff line numberDiff line change
@@ -695,9 +695,13 @@ impl MsvcBasicName for ty::UintTy {
695695

696696
impl MsvcBasicName for ty::FloatTy {
697697
fn msvc_basic_name(self) -> &'static str {
698+
// FIXME: f16 and f128 have no MSVE representation. We could improve the debuginfo.
699+
// See: <https://github.com/rust-lang/rust/pull/114607/files#r1454683264>
698700
match self {
701+
ty::FloatTy::F16 => "half",
699702
ty::FloatTy::F32 => "float",
700703
ty::FloatTy::F64 => "double",
704+
ty::FloatTy::F128 => "fp128",
701705
}
702706
}
703707
}

compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs

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

compiler/rustc_codegen_llvm/src/intrinsic.rs

+4
Original file line numberDiff line numberDiff line change
@@ -163,11 +163,15 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> {
163163
emit_va_arg(self, args[0], ret_ty)
164164
}
165165
}
166+
Primitive::F16 => bug!("the va_arg intrinsic does not work with `f16`"),
166167
Primitive::F64 | Primitive::Pointer(_) => {
167168
emit_va_arg(self, args[0], ret_ty)
168169
}
169170
// `va_arg` should never be used with the return type f32.
170171
Primitive::F32 => bug!("the va_arg intrinsic does not work with `f32`"),
172+
Primitive::F128 => {
173+
bug!("the va_arg intrinsic does not work with `f128`")
174+
}
171175
}
172176
}
173177
_ => bug!("the va_arg intrinsic does not work with non-scalar types"),

compiler/rustc_codegen_llvm/src/llvm/ffi.rs

+2
Original file line numberDiff line numberDiff line change
@@ -858,8 +858,10 @@ extern "C" {
858858
pub fn LLVMGetIntTypeWidth(IntegerTy: &Type) -> c_uint;
859859

860860
// Operations on real types
861+
pub fn LLVMHalfTypeInContext(C: &Context) -> &Type;
861862
pub fn LLVMFloatTypeInContext(C: &Context) -> &Type;
862863
pub fn LLVMDoubleTypeInContext(C: &Context) -> &Type;
864+
pub fn LLVMFP128TypeInContext(C: &Context) -> &Type;
863865

864866
// Operations on function types
865867
pub fn LLVMFunctionType<'a>(

compiler/rustc_codegen_llvm/src/type_.rs

+13-2
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,10 @@ impl<'ll> CodegenCx<'ll, '_> {
107107

108108
pub(crate) fn type_float_from_ty(&self, t: ty::FloatTy) -> &'ll Type {
109109
match t {
110+
ty::FloatTy::F16 => self.type_f16(),
110111
ty::FloatTy::F32 => self.type_f32(),
111112
ty::FloatTy::F64 => self.type_f64(),
113+
ty::FloatTy::F128 => self.type_f128(),
112114
}
113115
}
114116

@@ -156,6 +158,10 @@ impl<'ll, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> {
156158
self.isize_ty
157159
}
158160

161+
fn type_f16(&self) -> &'ll Type {
162+
unsafe { llvm::LLVMHalfTypeInContext(self.llcx) }
163+
}
164+
159165
fn type_f32(&self) -> &'ll Type {
160166
unsafe { llvm::LLVMFloatTypeInContext(self.llcx) }
161167
}
@@ -164,6 +170,10 @@ impl<'ll, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> {
164170
unsafe { llvm::LLVMDoubleTypeInContext(self.llcx) }
165171
}
166172

173+
fn type_f128(&self) -> &'ll Type {
174+
unsafe { llvm::LLVMFP128TypeInContext(self.llcx) }
175+
}
176+
167177
fn type_func(&self, args: &[&'ll Type], ret: &'ll Type) -> &'ll Type {
168178
unsafe { llvm::LLVMFunctionType(ret, args.as_ptr(), args.len() as c_uint, False) }
169179
}
@@ -195,7 +205,7 @@ impl<'ll, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> {
195205
match self.type_kind(ty) {
196206
TypeKind::Array | TypeKind::Vector => unsafe { llvm::LLVMGetElementType(ty) },
197207
TypeKind::Pointer => bug!("element_type is not supported for opaque pointers"),
198-
other => bug!("element_type called on unsupported type {:?}", other),
208+
other => bug!("element_type called on unsupported type {other:?}"),
199209
}
200210
}
201211

@@ -205,11 +215,12 @@ impl<'ll, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> {
205215

206216
fn float_width(&self, ty: &'ll Type) -> usize {
207217
match self.type_kind(ty) {
218+
TypeKind::Half => 16,
208219
TypeKind::Float => 32,
209220
TypeKind::Double => 64,
210221
TypeKind::X86_FP80 => 80,
211222
TypeKind::FP128 | TypeKind::PPC_FP128 => 128,
212-
_ => bug!("llvm_float_width called on a non-float type"),
223+
other => bug!("llvm_float_width called on a non-float type {other:?}"),
213224
}
214225
}
215226

compiler/rustc_codegen_llvm/src/type_of.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths};
88
use rustc_middle::ty::{self, Ty, TypeVisitableExt};
99
use rustc_target::abi::HasDataLayout;
1010
use rustc_target::abi::{Abi, Align, FieldsShape};
11-
use rustc_target::abi::{Int, Pointer, F32, F64};
11+
use rustc_target::abi::{Int, Pointer, F128, F16, F32, F64};
1212
use rustc_target::abi::{Scalar, Size, Variants};
1313
use smallvec::{smallvec, SmallVec};
1414

@@ -291,8 +291,10 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyAndLayout<'tcx> {
291291
fn scalar_llvm_type_at<'a>(&self, cx: &CodegenCx<'a, 'tcx>, scalar: Scalar) -> &'a Type {
292292
match scalar.primitive() {
293293
Int(i, _) => cx.type_from_integer(i),
294+
F16 => cx.type_f16(),
294295
F32 => cx.type_f32(),
295296
F64 => cx.type_f64(),
297+
F128 => cx.type_f128(),
296298
Pointer(address_space) => cx.type_ptr_ext(address_space),
297299
}
298300
}

compiler/rustc_codegen_ssa/src/mir/rvalue.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -303,15 +303,17 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
303303
self.assume_scalar_range(bx, imm, from_scalar, from_backend_ty);
304304

305305
imm = match (from_scalar.primitive(), to_scalar.primitive()) {
306-
(Int(..) | F32 | F64, Int(..) | F32 | F64) => bx.bitcast(imm, to_backend_ty),
306+
(Int(..) | F16 | F32 | F64 | F128, Int(..) | F16 | F32 | F64 | F128) => {
307+
bx.bitcast(imm, to_backend_ty)
308+
}
307309
(Pointer(..), Pointer(..)) => bx.pointercast(imm, to_backend_ty),
308310
(Int(..), Pointer(..)) => bx.inttoptr(imm, to_backend_ty),
309311
(Pointer(..), Int(..)) => bx.ptrtoint(imm, to_backend_ty),
310-
(F32 | F64, Pointer(..)) => {
312+
(F16 | F32 | F64 | F128, Pointer(..)) => {
311313
let int_imm = bx.bitcast(imm, bx.cx().type_isize());
312314
bx.inttoptr(int_imm, to_backend_ty)
313315
}
314-
(Pointer(..), F32 | F64) => {
316+
(Pointer(..), F16 | F32 | F64 | F128) => {
315317
let int_imm = bx.ptrtoint(imm, bx.cx().type_isize());
316318
bx.bitcast(int_imm, to_backend_ty)
317319
}

compiler/rustc_codegen_ssa/src/traits/type_.rs

+2
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,10 @@ pub trait BaseTypeMethods<'tcx>: Backend<'tcx> {
1919
fn type_i128(&self) -> Self::Type;
2020
fn type_isize(&self) -> Self::Type;
2121

22+
fn type_f16(&self) -> Self::Type;
2223
fn type_f32(&self) -> Self::Type;
2324
fn type_f64(&self) -> Self::Type;
25+
fn type_f128(&self) -> Self::Type;
2426

2527
fn type_array(&self, ty: Self::Type, len: u64) -> Self::Type;
2628
fn type_func(&self, args: &[Self::Type], ret: Self::Type) -> Self::Type;

compiler/rustc_const_eval/src/interpret/operator.rs

+2
Original file line numberDiff line numberDiff line change
@@ -389,12 +389,14 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
389389
let left = left.to_scalar();
390390
let right = right.to_scalar();
391391
Ok(match fty {
392+
FloatTy::F16 => unimplemented!("f16_f128"),
392393
FloatTy::F32 => {
393394
self.binary_float_op(bin_op, layout, left.to_f32()?, right.to_f32()?)
394395
}
395396
FloatTy::F64 => {
396397
self.binary_float_op(bin_op, layout, left.to_f64()?, right.to_f64()?)
397398
}
399+
FloatTy::F128 => unimplemented!("f16_f128"),
398400
})
399401
}
400402
_ if left.layout.ty.is_integral() => {

compiler/rustc_lint/src/types.rs

+2
Original file line numberDiff line numberDiff line change
@@ -561,8 +561,10 @@ fn lint_literal<'tcx>(
561561
ty::Float(t) => {
562562
let is_infinite = match lit.node {
563563
ast::LitKind::Float(v, _) => match t {
564+
ty::FloatTy::F16 => unimplemented!("f16_f128"),
564565
ty::FloatTy::F32 => v.as_str().parse().map(f32::is_infinite),
565566
ty::FloatTy::F64 => v.as_str().parse().map(f64::is_infinite),
567+
ty::FloatTy::F128 => unimplemented!("f16_f128"),
566568
},
567569
_ => bug!(),
568570
};

compiler/rustc_middle/src/ty/context.rs

+4
Original file line numberDiff line numberDiff line change
@@ -335,8 +335,10 @@ pub struct CommonTypes<'tcx> {
335335
pub u32: Ty<'tcx>,
336336
pub u64: Ty<'tcx>,
337337
pub u128: Ty<'tcx>,
338+
pub f16: Ty<'tcx>,
338339
pub f32: Ty<'tcx>,
339340
pub f64: Ty<'tcx>,
341+
pub f128: Ty<'tcx>,
340342
pub str_: Ty<'tcx>,
341343
pub never: Ty<'tcx>,
342344
pub self_param: Ty<'tcx>,
@@ -416,8 +418,10 @@ impl<'tcx> CommonTypes<'tcx> {
416418
u32: mk(Uint(ty::UintTy::U32)),
417419
u64: mk(Uint(ty::UintTy::U64)),
418420
u128: mk(Uint(ty::UintTy::U128)),
421+
f16: mk(Float(ty::FloatTy::F16)),
419422
f32: mk(Float(ty::FloatTy::F32)),
420423
f64: mk(Float(ty::FloatTy::F64)),
424+
f128: mk(Float(ty::FloatTy::F128)),
421425
str_: mk(Str),
422426
self_param: mk(ty::Param(ty::ParamTy { index: 0, name: kw::SelfUpper })),
423427

compiler/rustc_middle/src/ty/layout.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,10 @@ impl Primitive {
116116
fn to_ty<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
117117
match *self {
118118
Int(i, signed) => i.to_ty(tcx, signed),
119+
F16 => tcx.types.f16,
119120
F32 => tcx.types.f32,
120121
F64 => tcx.types.f64,
122+
F128 => tcx.types.f128,
121123
// FIXME(erikdesjardins): handle non-default addrspace ptr sizes
122124
Pointer(_) => Ty::new_mut_ptr(tcx, Ty::new_unit(tcx)),
123125
}
@@ -134,7 +136,7 @@ impl Primitive {
134136
let signed = false;
135137
tcx.data_layout().ptr_sized_integer().to_ty(tcx, signed)
136138
}
137-
F32 | F64 => bug!("floats do not have an int type"),
139+
F16 | F32 | F64 | F128 => bug!("floats do not have an int type"),
138140
}
139141
}
140142
}

compiler/rustc_middle/src/ty/sty.rs

+4
Original file line numberDiff line numberDiff line change
@@ -1580,8 +1580,10 @@ impl<'tcx> Ty<'tcx> {
15801580
pub fn new_float(tcx: TyCtxt<'tcx>, f: ty::FloatTy) -> Ty<'tcx> {
15811581
use ty::FloatTy::*;
15821582
match f {
1583+
F16 => tcx.types.f16,
15831584
F32 => tcx.types.f32,
15841585
F64 => tcx.types.f64,
1586+
F128 => tcx.types.f128,
15851587
}
15861588
}
15871589

@@ -2539,8 +2541,10 @@ impl<'tcx> Ty<'tcx> {
25392541
ty::Bool => Some(sym::bool),
25402542
ty::Char => Some(sym::char),
25412543
ty::Float(f) => match f {
2544+
ty::FloatTy::F16 => Some(sym::f16),
25422545
ty::FloatTy::F32 => Some(sym::f32),
25432546
ty::FloatTy::F64 => Some(sym::f64),
2547+
ty::FloatTy::F128 => Some(sym::f128),
25442548
},
25452549
ty::Int(f) => match f {
25462550
ty::IntTy::Isize => Some(sym::isize),

0 commit comments

Comments
 (0)