From 42528421379f2b4e6afabdbc10c8432f2962a3e8 Mon Sep 17 00:00:00 2001 From: beetrees Date: Wed, 26 Jun 2024 18:18:32 +0100 Subject: [PATCH] Add Natvis visualiser and debuginfo tests for `f16` --- .../src/debuginfo/metadata.rs | 43 +++++++++++++- src/etc/natvis/intrinsic.natvis | 26 +++++++++ .../debuginfo/basic-types-globals-metadata.rs | 7 ++- tests/debuginfo/basic-types-globals.rs | 11 +++- tests/debuginfo/basic-types-metadata.rs | 4 ++ tests/debuginfo/basic-types-mut-globals.rs | 44 ++++++++------ tests/debuginfo/basic-types.rs | 14 +++-- tests/debuginfo/borrowed-basic.rs | 15 ++++- tests/debuginfo/borrowed-unique-basic.rs | 15 ++++- tests/debuginfo/f16-natvis.rs | 58 +++++++++++++++++++ tests/debuginfo/reference-debuginfo.rs | 17 +++++- 11 files changed, 218 insertions(+), 36 deletions(-) create mode 100644 tests/debuginfo/f16-natvis.rs diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index 8de4e0effad28..64f173308c09e 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -705,10 +705,12 @@ impl MsvcBasicName for ty::UintTy { impl MsvcBasicName for ty::FloatTy { fn msvc_basic_name(self) -> &'static str { - // FIXME: f16 and f128 have no MSVC representation. We could improve the debuginfo. - // See: + // FIXME(f16_f128): `f16` and `f128` have no MSVC representation. We could improve the + // debuginfo. See: match self { - ty::FloatTy::F16 => "half", + ty::FloatTy::F16 => { + bug!("`f16` should have been handled in `build_basic_type_di_node`") + } ty::FloatTy::F32 => "float", ty::FloatTy::F64 => "double", ty::FloatTy::F128 => "fp128", @@ -716,6 +718,38 @@ impl MsvcBasicName for ty::FloatTy { } } +fn build_cpp_f16_di_node<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>) -> DINodeCreationResult<'ll> { + // MSVC has no native support for `f16`. Instead, emit `struct f16 { bits: u16 }` to allow the + // `f16`'s value to be displayed using a Natvis visualiser in `intrinsic.natvis`. + let float_ty = cx.tcx.types.f16; + let bits_ty = cx.tcx.types.u16; + type_map::build_type_with_children( + cx, + type_map::stub( + cx, + Stub::Struct, + UniqueTypeId::for_ty(cx.tcx, float_ty), + "f16", + cx.size_and_align_of(float_ty), + NO_SCOPE_METADATA, + DIFlags::FlagZero, + ), + // Fields: + |cx, float_di_node| { + smallvec![build_field_di_node( + cx, + float_di_node, + "bits", + cx.size_and_align_of(bits_ty), + Size::ZERO, + DIFlags::FlagZero, + type_di_node(cx, bits_ty), + )] + }, + NO_GENERICS, + ) +} + fn build_basic_type_di_node<'ll, 'tcx>( cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>, @@ -739,6 +773,9 @@ fn build_basic_type_di_node<'ll, 'tcx>( ty::Char => ("char", DW_ATE_UTF), ty::Int(int_ty) if cpp_like_debuginfo => (int_ty.msvc_basic_name(), DW_ATE_signed), ty::Uint(uint_ty) if cpp_like_debuginfo => (uint_ty.msvc_basic_name(), DW_ATE_unsigned), + ty::Float(ty::FloatTy::F16) if cpp_like_debuginfo => { + return build_cpp_f16_di_node(cx); + } ty::Float(float_ty) if cpp_like_debuginfo => (float_ty.msvc_basic_name(), DW_ATE_float), ty::Int(int_ty) => (int_ty.name_str(), DW_ATE_signed), ty::Uint(uint_ty) => (uint_ty.name_str(), DW_ATE_unsigned), diff --git a/src/etc/natvis/intrinsic.natvis b/src/etc/natvis/intrinsic.natvis index 8c16a562e349e..49e0ce319efac 100644 --- a/src/etc/natvis/intrinsic.natvis +++ b/src/etc/natvis/intrinsic.natvis @@ -33,6 +33,32 @@ + + + + + + + + + + + + + + + + + + + inf + -inf + NaN + + {(float) (sign() * raw_significand() / 16384.0)} + + {(float) (sign() * (raw_significand() + 1.0) * two_pow_exponent())} + () diff --git a/tests/debuginfo/basic-types-globals-metadata.rs b/tests/debuginfo/basic-types-globals-metadata.rs index 124be655c3523..d346b405555bc 100644 --- a/tests/debuginfo/basic-types-globals-metadata.rs +++ b/tests/debuginfo/basic-types-globals-metadata.rs @@ -39,6 +39,9 @@ // gdbg-command:whatis 'basic_types_globals_metadata::U64' // gdbr-command:whatis basic_types_globals_metadata::U64 // gdb-check:type = u64 +// gdbg-command:whatis 'basic_types_globals_metadata::F16' +// gdbr-command:whatis basic_types_globals_metadata::F16 +// gdb-check:type = f16 // gdbg-command:whatis 'basic_types_globals_metadata::F32' // gdbr-command:whatis basic_types_globals_metadata::F32 // gdb-check:type = f32 @@ -51,6 +54,7 @@ #![allow(dead_code)] #![feature(omit_gdb_pretty_printer_section)] #![omit_gdb_pretty_printer_section] +#![feature(f16)] // N.B. These are `mut` only so they don't constant fold away. static mut B: bool = false; @@ -65,13 +69,14 @@ static mut U8: u8 = 100; static mut U16: u16 = 16; static mut U32: u32 = 32; static mut U64: u64 = 64; +static mut F16: f16 = 1.5; static mut F32: f32 = 2.5; static mut F64: f64 = 3.5; fn main() { _zzz(); // #break - let a = unsafe { (B, I, C, I8, I16, I32, I64, U, U8, U16, U32, U64, F32, F64) }; + let a = unsafe { (B, I, C, I8, I16, I32, I64, U, U8, U16, U32, U64, F16, F32, F64) }; } fn _zzz() {()} diff --git a/tests/debuginfo/basic-types-globals.rs b/tests/debuginfo/basic-types-globals.rs index 319e86ad46015..0425d14fa5a34 100644 --- a/tests/debuginfo/basic-types-globals.rs +++ b/tests/debuginfo/basic-types-globals.rs @@ -49,17 +49,21 @@ // gdbg-command:print 'basic_types_globals::U64' // gdbr-command:print U64 // gdb-check:$12 = 64 +// gdbg-command:print 'basic_types_globals::F16' +// gdbr-command:print F16 +// gdb-check:$13 = 1.5 // gdbg-command:print 'basic_types_globals::F32' // gdbr-command:print F32 -// gdb-check:$13 = 2.5 +// gdb-check:$14 = 2.5 // gdbg-command:print 'basic_types_globals::F64' // gdbr-command:print F64 -// gdb-check:$14 = 3.5 +// gdb-check:$15 = 3.5 // gdb-command:continue #![allow(unused_variables)] #![feature(omit_gdb_pretty_printer_section)] #![omit_gdb_pretty_printer_section] +#![feature(f16)] // N.B. These are `mut` only so they don't constant fold away. static mut B: bool = false; @@ -74,13 +78,14 @@ static mut U8: u8 = 100; static mut U16: u16 = 16; static mut U32: u32 = 32; static mut U64: u64 = 64; +static mut F16: f16 = 1.5; static mut F32: f32 = 2.5; static mut F64: f64 = 3.5; fn main() { _zzz(); // #break - let a = unsafe { (B, I, C, I8, I16, I32, I64, U, U8, U16, U32, U64, F32, F64) }; + let a = unsafe { (B, I, C, I8, I16, I32, I64, U, U8, U16, U32, U64, F16, F32, F64) }; } fn _zzz() {()} diff --git a/tests/debuginfo/basic-types-metadata.rs b/tests/debuginfo/basic-types-metadata.rs index 8a25c0c452413..5f953c81a138d 100644 --- a/tests/debuginfo/basic-types-metadata.rs +++ b/tests/debuginfo/basic-types-metadata.rs @@ -29,6 +29,8 @@ // gdb-check:type = u32 // gdb-command:whatis u64 // gdb-check:type = u64 +// gdb-command:whatis f16 +// gdb-check:type = f16 // gdb-command:whatis f32 // gdb-check:type = f32 // gdb-command:whatis f64 @@ -66,6 +68,7 @@ #![allow(unused_variables)] #![feature(omit_gdb_pretty_printer_section)] #![omit_gdb_pretty_printer_section] +#![feature(f16)] fn main() { let unit: () = (); @@ -81,6 +84,7 @@ fn main() { let u16: u16 = 16; let u32: u32 = 32; let u64: u64 = 64; + let f16: f16 = 1.5; let f32: f32 = 2.5; let f64: f64 = 3.5; let fnptr : fn() = _zzz; diff --git a/tests/debuginfo/basic-types-mut-globals.rs b/tests/debuginfo/basic-types-mut-globals.rs index c3e5f2534d314..c676fd737714d 100644 --- a/tests/debuginfo/basic-types-mut-globals.rs +++ b/tests/debuginfo/basic-types-mut-globals.rs @@ -5,7 +5,6 @@ // its numerical value. //@ min-lldb-version: 310 -//@ ignore-gdb // Test temporarily ignored due to debuginfo tests being disabled, see PR 47155 //@ compile-flags:-g @@ -49,62 +48,69 @@ // gdbg-command:print 'basic_types_mut_globals::U64' // gdbr-command:print U64 // gdb-check:$12 = 64 +// gdbg-command:print 'basic_types_mut_globals::F16' +// gdbr-command:print F16 +// gdb-check:$13 = 1.5 // gdbg-command:print 'basic_types_mut_globals::F32' // gdbr-command:print F32 -// gdb-check:$13 = 2.5 +// gdb-check:$14 = 2.5 // gdbg-command:print 'basic_types_mut_globals::F64' // gdbr-command:print F64 -// gdb-check:$14 = 3.5 +// gdb-check:$15 = 3.5 // gdb-command:continue // Check new values // gdbg-command:print 'basic_types_mut_globals'::B // gdbr-command:print B -// gdb-check:$15 = true +// gdb-check:$16 = true // gdbg-command:print 'basic_types_mut_globals'::I // gdbr-command:print I -// gdb-check:$16 = 2 +// gdb-check:$17 = 2 // gdbg-command:print/d 'basic_types_mut_globals'::C // gdbr-command:print C -// gdbg-check:$17 = 102 -// gdbr-check:$17 = 102 'f' +// gdbg-check:$18 = 102 +// gdbr-check:$18 = 102 'f' // gdbg-command:print/d 'basic_types_mut_globals'::I8 // gdbr-command:print/d I8 -// gdb-check:$18 = 78 +// gdb-check:$19 = 78 // gdbg-command:print 'basic_types_mut_globals'::I16 // gdbr-command:print I16 -// gdb-check:$19 = -26 +// gdb-check:$20 = -26 // gdbg-command:print 'basic_types_mut_globals'::I32 // gdbr-command:print I32 -// gdb-check:$20 = -12 +// gdb-check:$21 = -12 // gdbg-command:print 'basic_types_mut_globals'::I64 // gdbr-command:print I64 -// gdb-check:$21 = -54 +// gdb-check:$22 = -54 // gdbg-command:print 'basic_types_mut_globals'::U // gdbr-command:print U -// gdb-check:$22 = 5 +// gdb-check:$23 = 5 // gdbg-command:print/d 'basic_types_mut_globals'::U8 // gdbr-command:print/d U8 -// gdb-check:$23 = 20 +// gdb-check:$24 = 20 // gdbg-command:print 'basic_types_mut_globals'::U16 // gdbr-command:print U16 -// gdb-check:$24 = 32 +// gdb-check:$25 = 32 // gdbg-command:print 'basic_types_mut_globals'::U32 // gdbr-command:print U32 -// gdb-check:$25 = 16 +// gdb-check:$26 = 16 // gdbg-command:print 'basic_types_mut_globals'::U64 // gdbr-command:print U64 -// gdb-check:$26 = 128 +// gdb-check:$27 = 128 +// gdbg-command:print 'basic_types_mut_globals'::F16 +// gdbr-command:print F16 +// gdb-check:$28 = 2.25 // gdbg-command:print 'basic_types_mut_globals'::F32 // gdbr-command:print F32 -// gdb-check:$27 = 5.75 +// gdb-check:$29 = 5.75 // gdbg-command:print 'basic_types_mut_globals'::F64 // gdbr-command:print F64 -// gdb-check:$28 = 9.25 +// gdb-check:$30 = 9.25 #![allow(unused_variables)] #![feature(omit_gdb_pretty_printer_section)] #![omit_gdb_pretty_printer_section] +#![feature(f16)] static mut B: bool = false; static mut I: isize = -1; @@ -118,6 +124,7 @@ static mut U8: u8 = 100; static mut U16: u16 = 16; static mut U32: u32 = 32; static mut U64: u64 = 64; +static mut F16: f16 = 1.5; static mut F32: f32 = 2.5; static mut F64: f64 = 3.5; @@ -137,6 +144,7 @@ fn main() { U16 = 32; U32 = 16; U64 = 128; + F16 = 2.25; F32 = 5.75; F64 = 9.25; } diff --git a/tests/debuginfo/basic-types.rs b/tests/debuginfo/basic-types.rs index 13d85d326ee3d..10ffd74d3e909 100644 --- a/tests/debuginfo/basic-types.rs +++ b/tests/debuginfo/basic-types.rs @@ -39,13 +39,15 @@ // gdb-check:$11 = 32 // gdb-command:print u64 // gdb-check:$12 = 64 +// gdb-command:print f16 +// gdb-check:$13 = 1.5 // gdb-command:print f32 -// gdb-check:$13 = 2.5 +// gdb-check:$14 = 2.5 // gdb-command:print f64 -// gdb-check:$14 = 3.5 +// gdb-check:$15 = 3.5 // gdb-command:print s -// gdbg-check:$15 = {data_ptr = [...] "Hello, World!", length = 13} -// gdbr-check:$15 = "Hello, World!" +// gdbg-check:$16 = {data_ptr = [...] "Hello, World!", length = 13} +// gdbr-check:$16 = "Hello, World!" // === LLDB TESTS ================================================================================== @@ -122,6 +124,8 @@ // cdb-check:u32 : 0x20 [Type: unsigned int] // cdb-command:dx u64 // cdb-check:u64 : 0x40 [Type: unsigned __int64] +// cdb-command:dx f16 +// cdb-check:f16 : 1.500000 [Type: f16] // cdb-command:dx f32 // cdb-check:f32 : 2.500000 [Type: float] // cdb-command:dx f64 @@ -134,6 +138,7 @@ #![allow(unused_variables)] #![feature(omit_gdb_pretty_printer_section)] #![omit_gdb_pretty_printer_section] +#![feature(f16)] fn main() { let b: bool = false; @@ -148,6 +153,7 @@ fn main() { let u16: u16 = 16; let u32: u32 = 32; let u64: u64 = 64; + let f16: f16 = 1.5; let f32: f32 = 2.5; let f64: f64 = 3.5; let s: &str = "Hello, World!"; diff --git a/tests/debuginfo/borrowed-basic.rs b/tests/debuginfo/borrowed-basic.rs index e48e3dd055e43..e3cf74dab1e75 100644 --- a/tests/debuginfo/borrowed-basic.rs +++ b/tests/debuginfo/borrowed-basic.rs @@ -42,11 +42,14 @@ // gdb-command:print *u64_ref // gdb-check:$12 = 64 +// gdb-command:print *f16_ref +// gdb-check:$13 = 1.5 + // gdb-command:print *f32_ref -// gdb-check:$13 = 2.5 +// gdb-check:$14 = 2.5 // gdb-command:print *f64_ref -// gdb-check:$14 = 3.5 +// gdb-check:$15 = 3.5 // === LLDB TESTS ================================================================================== @@ -100,6 +103,10 @@ // lldbg-check:[...] 64 // lldbr-check:(u64) *u64_ref = 64 +// lldb-command:v *f16_ref +// lldbg-check:[...] 1.5 +// lldbr-check:(f16) *f16_ref = 1.5 + // lldb-command:v *f32_ref // lldbg-check:[...] 2.5 // lldbr-check:(f32) *f32_ref = 2.5 @@ -111,6 +118,7 @@ #![allow(unused_variables)] #![feature(omit_gdb_pretty_printer_section)] #![omit_gdb_pretty_printer_section] +#![feature(f16)] fn main() { let bool_val: bool = true; @@ -149,6 +157,9 @@ fn main() { let u64_val: u64 = 64; let u64_ref: &u64 = &u64_val; + let f16_val: f16 = 1.5; + let f16_ref: &f16 = &f16_val; + let f32_val: f32 = 2.5; let f32_ref: &f32 = &f32_val; diff --git a/tests/debuginfo/borrowed-unique-basic.rs b/tests/debuginfo/borrowed-unique-basic.rs index d6948a12851a5..e952ec8cebb52 100644 --- a/tests/debuginfo/borrowed-unique-basic.rs +++ b/tests/debuginfo/borrowed-unique-basic.rs @@ -42,11 +42,14 @@ // gdb-command:print *u64_ref // gdb-check:$12 = 64 +// gdb-command:print *f16_ref +// gdb-check:$13 = 1.5 + // gdb-command:print *f32_ref -// gdb-check:$13 = 2.5 +// gdb-check:$14 = 2.5 // gdb-command:print *f64_ref -// gdb-check:$14 = 3.5 +// gdb-check:$15 = 3.5 // === LLDB TESTS ================================================================================== @@ -103,6 +106,10 @@ // lldbg-check:[...] 64 // lldbr-check:(u64) *u64_ref = 64 +// lldb-command:v *f16_ref +// lldbg-check:[...] 1.5 +// lldbr-check:(f16) *f16_ref = 1.5 + // lldb-command:v *f32_ref // lldbg-check:[...] 2.5 // lldbr-check:(f32) *f32_ref = 2.5 @@ -114,6 +121,7 @@ #![allow(unused_variables)] #![feature(omit_gdb_pretty_printer_section)] #![omit_gdb_pretty_printer_section] +#![feature(f16)] fn main() { let bool_box: Box = Box::new(true); @@ -152,6 +160,9 @@ fn main() { let u64_box: Box = Box::new(64); let u64_ref: &u64 = &*u64_box; + let f16_box: Box = Box::new(1.5); + let f16_ref: &f16 = &*f16_box; + let f32_box: Box = Box::new(2.5); let f32_ref: &f32 = &*f32_box; diff --git a/tests/debuginfo/f16-natvis.rs b/tests/debuginfo/f16-natvis.rs new file mode 100644 index 0000000000000..deb857c6703f7 --- /dev/null +++ b/tests/debuginfo/f16-natvis.rs @@ -0,0 +1,58 @@ +//@ compile-flags: -g +//@ only-msvc + +// This tests the `f16` Natvis visualiser. +// cdb-command:g +// cdb-command:dx v0_0 +// cdb-check:v0_0 : 0.000000 [Type: f16] +// cdb-command:dx neg_0_0 +// cdb-check:neg_0_0 : -0.000000 [Type: f16] +// cdb-command:dx v1_0 +// cdb-check:v1_0 : 1.000000 [Type: f16] +// cdb-command:dx v1_5 +// cdb-check:v1_5 : 1.500000 [Type: f16] +// cdb-command:dx v72_3 +// cdb-check:v72_3 : 72.312500 [Type: f16] +// cdb-command:dx neg_0_126 +// cdb-check:neg_0_126 : -0.125997 [Type: f16] +// cdb-command:dx v0_00003 +// cdb-check:v0_00003 : 0.000030 [Type: f16] +// cdb-command:dx neg_0_00004 +// cdb-check:neg_0_00004 : -0.000040 [Type: f16] +// cdb-command:dx max +// cdb-check:max : 65504.000000 [Type: f16] +// cdb-command:dx min +// cdb-check:min : -65504.000000 [Type: f16] +// cdb-command:dx inf +// cdb-check:inf : inf [Type: f16] +// cdb-command:dx neg_inf +// cdb-check:neg_inf : -inf [Type: f16] +// cdb-command:dx nan +// cdb-check:nan : nan [Type: f16] +// cdb-command:dx other_nan +// cdb-check:other_nan : nan [Type: f16] + +#![feature(f16)] + +fn main() { + let v0_0 = 0.0_f16; + let neg_0_0 = -0.0_f16; + let v1_0 = 1.0_f16; + let v1_5 = 1.5_f16; + let v72_3 = 72.3_f16; + let neg_0_126 = -0.126_f16; + let v0_00003 = 0.00003_f16; + let neg_0_00004 = -0.00004_f16; + let max = f16::MAX; + let min = f16::MIN; + let inf = f16::INFINITY; + let neg_inf = f16::NEG_INFINITY; + let nan = f16::NAN; + let other_nan = f16::from_bits(0xfc02); + + _zzz(); // #break +} + +fn _zzz() { + () +} diff --git a/tests/debuginfo/reference-debuginfo.rs b/tests/debuginfo/reference-debuginfo.rs index 339839f07cca9..e2fb964ace521 100644 --- a/tests/debuginfo/reference-debuginfo.rs +++ b/tests/debuginfo/reference-debuginfo.rs @@ -46,14 +46,17 @@ // gdb-command:print *u64_ref // gdb-check:$12 = 64 +// gdb-command:print *f16_ref +// gdb-check:$13 = 1.5 + // gdb-command:print *f32_ref -// gdb-check:$13 = 2.5 +// gdb-check:$14 = 2.5 // gdb-command:print *f64_ref -// gdb-check:$14 = 3.5 +// gdb-check:$15 = 3.5 // gdb-command:print *f64_double_ref -// gdb-check:$15 = 3.5 +// gdb-check:$16 = 3.5 // === LLDB TESTS ================================================================================== @@ -107,6 +110,10 @@ // lldbg-check:[...] 64 // lldbr-check:(u64) *u64_ref = 64 +// lldb-command:v *f16_ref +// lldbg-check:[...] 1.5 +// lldbr-check:(f16) *f16_ref = 1.5 + // lldb-command:v *f32_ref // lldbg-check:[...] 2.5 // lldbr-check:(f32) *f32_ref = 2.5 @@ -122,6 +129,7 @@ #![allow(unused_variables)] #![feature(omit_gdb_pretty_printer_section)] #![omit_gdb_pretty_printer_section] +#![feature(f16)] fn main() { let bool_val: bool = true; @@ -160,6 +168,9 @@ fn main() { let u64_val: u64 = 64; let u64_ref: &u64 = &u64_val; + let f16_val: f16 = 1.5; + let f16_ref: &f16 = &f16_val; + let f32_val: f32 = 2.5; let f32_ref: &f32 = &f32_val;