Skip to content

Commit

Permalink
Auto merge of #127001 - beetrees:f16-debuginfo, r=michaelwoerister
Browse files Browse the repository at this point in the history
Add Natvis visualiser and debuginfo tests for `f16`

To render `f16`s in debuggers on MSVC targets, this PR changes the compiler to output `f16`s as `struct f16 { bits: u16 }`, and includes a Natvis visualiser that manually converts the `f16`'s bits to a `float` which is can then be displayed by debuggers. `gdb`, `lldb` and `cdb` tests are also included for `f16` .

`f16`/`f128` MSVC debug info issue: #121837
Tracking issue: #116909
  • Loading branch information
bors committed Jul 9, 2024
2 parents d4a6200 + 4252842 commit 585ffed
Show file tree
Hide file tree
Showing 11 changed files with 218 additions and 36 deletions.
43 changes: 40 additions & 3 deletions compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -705,17 +705,51 @@ 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: <https://github.com/rust-lang/rust/pull/114607/files#r1454683264>
// FIXME(f16_f128): `f16` and `f128` have no MSVC representation. We could improve the
// debuginfo. See: <https://github.com/rust-lang/rust/issues/121837>
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",
}
}
}

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>,
Expand All @@ -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),
Expand Down
26 changes: 26 additions & 0 deletions src/etc/natvis/intrinsic.natvis
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,32 @@
</ArrayItems>
</Expand>
</Type>
<Type Name="f16">
<Intrinsic Name="sign_mask" Expression="(unsigned __int16) 0x8000" />
<Intrinsic Name="exponent_mask" Expression="(unsigned __int16) 0x7c00" />
<Intrinsic Name="significand_mask" Expression="(unsigned __int16) 0x03ff" />
<Intrinsic Name="sign_bit" Expression="(unsigned __int16) (bits &amp; sign_mask())" />
<Intrinsic Name="exponent_bits" Expression="(unsigned __int16) (bits &amp; exponent_mask())" />
<Intrinsic Name="significand_bits" Expression="(unsigned __int16) (bits &amp; significand_mask())" />

<Intrinsic Name="if_set" Expression="(bits &amp; mask) != 0 ? value : 1.0">
<Parameter Name="mask" Type="unsigned __int16" />
<Parameter Name="value" Type="float" />
</Intrinsic>
<!-- Calculates 2**exp without needing a pow function. Each float in if_set() is the square of the previous float. 32768 == 2.pow(bias), bias == 15 -->
<Intrinsic Name="two_pow_exponent" Expression="if_set(0x0400, 2.0) * if_set(0x0800, 4.0) * if_set(0x1000, 16.0) * if_set(0x2000, 256.0) * if_set(0x4000, 65536.0) / 32768.0" />
<!-- Calculates 0.significand, without any implicit bit. 1024 == 2.pow(explicit significand width), explicit significand width == 10 -->
<Intrinsic Name="raw_significand" Expression="((float) significand_bits()) / 1024.0" />
<Intrinsic Name="sign" Expression="sign_bit() == 0 ? 1.0 : -1.0" />

<DisplayString Condition="bits == 0x7c00">inf</DisplayString>
<DisplayString Condition="bits == 0xfc00">-inf</DisplayString>
<DisplayString Condition="exponent_bits() == exponent_mask()">NaN</DisplayString>
<!-- Subnormal or zero (16384 == 2.pow(bias - 1), bias - 1 == 14) -->
<DisplayString Condition="exponent_bits() == 0">{(float) (sign() * raw_significand() / 16384.0)}</DisplayString>
<!-- Normal -->
<DisplayString>{(float) (sign() * (raw_significand() + 1.0) * two_pow_exponent())}</DisplayString>
</Type>
<Type Name="tuple$&lt;&gt;">
<DisplayString>()</DisplayString>
</Type>
Expand Down
7 changes: 6 additions & 1 deletion tests/debuginfo/basic-types-globals-metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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;
Expand All @@ -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() {()}
11 changes: 8 additions & 3 deletions tests/debuginfo/basic-types-globals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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() {()}
4 changes: 4 additions & 0 deletions tests/debuginfo/basic-types-metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -66,6 +68,7 @@
#![allow(unused_variables)]
#![feature(omit_gdb_pretty_printer_section)]
#![omit_gdb_pretty_printer_section]
#![feature(f16)]

fn main() {
let unit: () = ();
Expand All @@ -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;
Expand Down
44 changes: 26 additions & 18 deletions tests/debuginfo/basic-types-mut-globals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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;
Expand All @@ -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;

Expand All @@ -137,6 +144,7 @@ fn main() {
U16 = 32;
U32 = 16;
U64 = 128;
F16 = 2.25;
F32 = 5.75;
F64 = 9.25;
}
Expand Down
14 changes: 10 additions & 4 deletions tests/debuginfo/basic-types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 ==================================================================================

Expand Down Expand Up @@ -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
Expand All @@ -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;
Expand All @@ -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!";
Expand Down
15 changes: 13 additions & 2 deletions tests/debuginfo/borrowed-basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 ==================================================================================
Expand Down Expand Up @@ -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
Expand All @@ -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;
Expand Down Expand Up @@ -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;

Expand Down
Loading

0 comments on commit 585ffed

Please sign in to comment.