From 204bfb6a8c1f9aaa9b5c04d72a47f7fd8772a4bb Mon Sep 17 00:00:00 2001 From: DonoughLiu Date: Sat, 10 Jun 2023 03:21:39 +0800 Subject: [PATCH 1/3] Support 128-bit enum variant in debuginfo codegen --- compiler/rustc_codegen_gcc/src/common.rs | 6 +++++- compiler/rustc_codegen_llvm/src/common.rs | 4 ++++ compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs | 2 +- .../src/debuginfo/metadata/enums/native.rs | 8 +------- compiler/rustc_codegen_ssa/src/traits/consts.rs | 1 + 5 files changed, 12 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_codegen_gcc/src/common.rs b/compiler/rustc_codegen_gcc/src/common.rs index bad87db4732..b62f4676f70 100644 --- a/compiler/rustc_codegen_gcc/src/common.rs +++ b/compiler/rustc_codegen_gcc/src/common.rs @@ -108,6 +108,10 @@ fn const_u64(&self, i: u64) -> RValue<'gcc> { self.const_uint(self.type_u64(), i) } + fn const_u128(&self, i: u128) -> RValue<'gcc> { + self.const_uint_big(self.type_u128(), i) + } + fn const_usize(&self, i: u64) -> RValue<'gcc> { let bit_size = self.data_layout().pointer_size.bits(); if bit_size < 64 { @@ -254,7 +258,7 @@ fn const_bitcast(&self, value: RValue<'gcc>, typ: Type<'gcc>) -> RValue<'gcc> { // SIMD builtins require a constant value. self.bitcast_if_needed(value, typ) } - + fn const_ptr_byte_offset(&self, base_addr: Self::Value, offset: abi::Size) -> Self::Value { self.context.new_array_access(None, base_addr, self.const_usize(offset.bytes())).get_address(None) } diff --git a/compiler/rustc_codegen_llvm/src/common.rs b/compiler/rustc_codegen_llvm/src/common.rs index a3910fef954..a2db59bd6c4 100644 --- a/compiler/rustc_codegen_llvm/src/common.rs +++ b/compiler/rustc_codegen_llvm/src/common.rs @@ -168,6 +168,10 @@ fn const_u64(&self, i: u64) -> &'ll Value { self.const_uint(self.type_i64(), i) } + fn const_u128(&self, i: u128) -> &'ll Value { + self.const_uint_big(self.type_i128(), i) + } + fn const_usize(&self, i: u64) -> &'ll Value { let bit_size = self.data_layout().pointer_size.bits(); if bit_size < 64 { diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index 166454d3ae7..bede63373b1 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -429,7 +429,7 @@ pub fn type_di_node<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) -> &'ll D return existing_di_node; } - debug!("type_di_node: {:?}", t); + debug!("type_di_node: {:?} kind: {:?}", t, t.kind()); let DINodeCreationResult { di_node, already_stored_in_typemap } = match *t.kind() { ty::Never | ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Float(_) => { diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs index 978141917c6..666b9762f5a 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs @@ -412,13 +412,7 @@ fn build_enum_variant_member_di_node<'ll, 'tcx>( enum_type_and_layout.size.bits(), enum_type_and_layout.align.abi.bits() as u32, Size::ZERO.bits(), - discr_value.opt_single_val().map(|value| { - // NOTE(eddyb) do *NOT* remove this assert, until - // we pass the full 128-bit value to LLVM, otherwise - // truncation will be silent and remain undetected. - assert_eq!(value as u64 as u128, value); - cx.const_u64(value as u64) - }), + discr_value.opt_single_val().map(|value| cx.const_u128(value)), DIFlags::FlagZero, variant_member_info.variant_struct_type_di_node, ) diff --git a/compiler/rustc_codegen_ssa/src/traits/consts.rs b/compiler/rustc_codegen_ssa/src/traits/consts.rs index dc2fc396480..d6e9bfce1a4 100644 --- a/compiler/rustc_codegen_ssa/src/traits/consts.rs +++ b/compiler/rustc_codegen_ssa/src/traits/consts.rs @@ -15,6 +15,7 @@ pub trait ConstMethods<'tcx>: BackendTypes { fn const_i32(&self, i: i32) -> Self::Value; fn const_u32(&self, i: u32) -> Self::Value; fn const_u64(&self, i: u64) -> Self::Value; + fn const_u128(&self, i: u128) -> Self::Value; fn const_usize(&self, i: u64) -> Self::Value; fn const_u8(&self, i: u8) -> Self::Value; fn const_real(&self, t: Self::Type, val: f64) -> Self::Value; From 859bac7af8705f610ae8aa5c7df17398a46c0cdf Mon Sep 17 00:00:00 2001 From: ldm0 Date: Sat, 10 Jun 2023 08:31:06 +0000 Subject: [PATCH 2/3] Fix codegen tests --- tests/codegen/enum-debug-niche-2.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/codegen/enum-debug-niche-2.rs b/tests/codegen/enum-debug-niche-2.rs index 9c72ad9d248..4b607d50574 100644 --- a/tests/codegen/enum-debug-niche-2.rs +++ b/tests/codegen/enum-debug-niche-2.rs @@ -7,8 +7,8 @@ // compile-flags: -g -C no-prepopulate-passes // CHECK: {{.*}}DICompositeType{{.*}}tag: DW_TAG_variant_part,{{.*}}size: 32,{{.*}} -// CHECK: {{.*}}DIDerivedType{{.*}}tag: DW_TAG_member,{{.*}}name: "Placeholder",{{.*}}extraData: i64 4294967295{{[,)].*}} -// CHECK: {{.*}}DIDerivedType{{.*}}tag: DW_TAG_member,{{.*}}name: "Error",{{.*}}extraData: i64 0{{[,)].*}} +// CHECK: {{.*}}DIDerivedType{{.*}}tag: DW_TAG_member,{{.*}}name: "Placeholder",{{.*}}extraData: i128 4294967295{{[,)].*}} +// CHECK: {{.*}}DIDerivedType{{.*}}tag: DW_TAG_member,{{.*}}name: "Error",{{.*}}extraData: i128 0{{[,)].*}} #![feature(never_type)] From ea19243d15de0d15bdeee6f82c27366477d7a043 Mon Sep 17 00:00:00 2001 From: ldm0 Date: Sat, 10 Jun 2023 16:58:51 +0000 Subject: [PATCH 3/3] Add test --- tests/codegen/enum-u128.rs | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 tests/codegen/enum-u128.rs diff --git a/tests/codegen/enum-u128.rs b/tests/codegen/enum-u128.rs new file mode 100644 index 00000000000..f50d360ac9f --- /dev/null +++ b/tests/codegen/enum-u128.rs @@ -0,0 +1,27 @@ +// This tests that debug info for "c-like" 128bit enums is properly emitted. +// This is ignored for the fallback mode on MSVC due to problems with PDB. + +// +// ignore-msvc + +// compile-flags: -g -C no-prepopulate-passes + +// CHECK-LABEL: @main +// CHECK: {{.*}}DICompositeType{{.*}}tag: DW_TAG_enumeration_type,{{.*}}name: "Foo",{{.*}}flags: DIFlagEnumClass,{{.*}} +// CHECK: {{.*}}DIEnumerator{{.*}}name: "Lo",{{.*}}value: 0,{{.*}} +// CHECK: {{.*}}DIEnumerator{{.*}}name: "Hi",{{.*}}value: 18446744073709551616,{{.*}} +// CHECK: {{.*}}DIEnumerator{{.*}}name: "Bar",{{.*}}value: 18446745000000000123,{{.*}} + +#![allow(incomplete_features)] +#![feature(repr128)] + +#[repr(u128)] +pub enum Foo { + Lo, + Hi = 1 << 64, + Bar = 18_446_745_000_000_000_123, +} + +pub fn main() { + let foo = Foo::Bar; +}