Skip to content

Commit 7a04335

Browse files
committed
fixup! codegen: Generate dbg_value for the ref statement
`&_1` is only valid if the pass mode is indirect.
1 parent 0a0b3c1 commit 7a04335

File tree

2 files changed

+23
-11
lines changed

2 files changed

+23
-11
lines changed

compiler/rustc_codegen_ssa/src/mir/statement.rs

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
use rustc_middle::mir::{self, NonDivergingIntrinsic, StmtDebugInfo};
1+
use rustc_middle::mir::{self, NonDivergingIntrinsic, RETURN_PLACE, StmtDebugInfo};
22
use rustc_middle::{bug, span_bug};
3+
use rustc_target::callconv::PassMode;
34
use tracing::instrument;
45

56
use super::{FunctionCx, LocalRef};
67
use crate::common::TypeKind;
7-
use crate::mir::operand::OperandValue;
88
use crate::mir::place::PlaceRef;
99
use crate::traits::*;
1010

@@ -113,21 +113,27 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
113113
LocalRef::Place(place_ref) | LocalRef::UnsizedPlace(place_ref) => {
114114
Some(place_ref)
115115
}
116-
LocalRef::Operand(operand_ref) => match operand_ref.val {
117-
OperandValue::Immediate(v) => {
118-
Some(PlaceRef::new_sized(v, operand_ref.layout))
119-
}
120-
OperandValue::Ref(_)
121-
| OperandValue::Pair(_, _)
122-
| OperandValue::ZeroSized => None,
123-
},
116+
LocalRef::Operand(operand_ref) => {
117+
let pointer = operand_ref.val.pointer_parts().0;
118+
Some(PlaceRef::new_sized(pointer, operand_ref.layout))
119+
}
124120
LocalRef::PendingOperand => None,
125121
}
126122
.filter(|place_ref| {
123+
// For the reference of an argument (e.x. `&_1`), it's only valid if the pass mode is indirect, and its reference is
124+
// llval.
125+
let local_ref_pass_mode = place.as_local().and_then(|local| {
126+
if local == RETURN_PLACE {
127+
None
128+
} else {
129+
self.fn_abi.args.get(local.as_usize() - 1).map(|arg| &arg.mode)
130+
}
131+
});
132+
matches!(local_ref_pass_mode, Some(&PassMode::Indirect {..}) | None) &&
127133
// Drop unsupported projections.
128134
// FIXME: Add a test case.
129135
place.projection.iter().all(|p| p.can_use_in_debuginfo()) &&
130-
// Only pointers can calculate addresses.
136+
// Only pointers can be calculated addresses.
131137
bx.type_kind(bx.val_ty(place_ref.val.llval)) == TypeKind::Pointer
132138
});
133139
if let Some(local_ref) = local_ref {

tests/codegen-llvm/debuginfo-dse.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,11 @@ fn r#ref(ref_foo: &Foo) -> i32 {
2121
// CHECK-LABEL: define {{.*}} i32 @ref
2222
// CHECK-SAME: (ptr {{.*}} [[ARG_ref_foo:%.*]])
2323
// OPTIMIZED: #dbg_value(ptr [[ARG_ref_foo]], [[VAR_ref_foo:![0-9]+]], !DIExpression()
24+
// CHECK: #dbg_value(ptr poison, [[VAR_invalid_ref_of_ref_foo:![0-9]+]], !DIExpression()
2425
// CHECK: #dbg_value(ptr [[ARG_ref_foo]], [[VAR_ref_v0:![0-9]+]], !DIExpression()
2526
// CHECK: #dbg_value(ptr [[ARG_ref_foo]], [[VAR_ref_v1:![0-9]+]], !DIExpression(DW_OP_plus_uconst, 8, DW_OP_stack_value)
2627
// CHECK: #dbg_value(ptr [[ARG_ref_foo]], [[VAR_ref_v2:![0-9]+]], !DIExpression(DW_OP_plus_uconst, 16, DW_OP_stack_value)
28+
let invalid_ref_of_ref_foo = &ref_foo;
2729
let ref_v0 = &ref_foo.0;
2830
let ref_v1 = &ref_foo.1;
2931
let ref_v2 = &ref_foo.2;
@@ -49,9 +51,11 @@ pub fn dead_first(dead_first_foo: &Foo) -> &i32 {
4951
fn ptr(ptr_foo: Foo) -> i32 {
5052
// CHECK-LABEL: define {{.*}} i32 @ptr
5153
// CHECK-SAME: (ptr {{.*}} [[ARG_ptr_foo:%.*]])
54+
// CHECK: #dbg_value(ptr [[ARG_ptr_foo]], [[ref_ptr_foo:![0-9]+]], !DIExpression()
5255
// CHECK: #dbg_value(ptr [[ARG_ptr_foo]], [[VAR_ptr_v0:![0-9]+]], !DIExpression()
5356
// CHECK: #dbg_value(ptr [[ARG_ptr_foo]], [[VAR_ptr_v1:![0-9]+]], !DIExpression(DW_OP_plus_uconst, 8, DW_OP_stack_value)
5457
// CHECK: #dbg_value(ptr [[ARG_ptr_foo]], [[VAR_ptr_v2:![0-9]+]], !DIExpression(DW_OP_plus_uconst, 16, DW_OP_stack_value)
58+
let ref_ptr_foo = &ptr_foo;
5559
let ptr_v0 = &ptr_foo.0;
5660
let ptr_v1 = &ptr_foo.1;
5761
let ptr_v2 = &ptr_foo.2;
@@ -99,10 +103,12 @@ pub fn tuple(foo: (i32, &Foo)) -> i32 {
99103
foo.1.0
100104
}
101105

106+
// CHECK-DAG: [[VAR_invalid_ref_of_ref_foo]] = !DILocalVariable(name: "invalid_ref_of_ref_foo"
102107
// OPTIMIZED-DAG: [[VAR_ref_foo]] = !DILocalVariable(name: "ref_foo"
103108
// CHECK-DAG: [[VAR_ref_v0]] = !DILocalVariable(name: "ref_v0"
104109
// CHECK-DAG: [[VAR_ref_v1]] = !DILocalVariable(name: "ref_v1"
105110
// CHECK-DAG: [[VAR_ref_v2]] = !DILocalVariable(name: "ref_v2"
111+
// CHECK-DAG: [[ref_ptr_foo]] = !DILocalVariable(name: "ref_ptr_foo"
106112
// CHECK-DAG: [[VAR_ptr_v0]] = !DILocalVariable(name: "ptr_v0"
107113
// CHECK-DAG: [[VAR_ptr_v1]] = !DILocalVariable(name: "ptr_v1"
108114
// CHECK-DAG: [[VAR_ptr_v2]] = !DILocalVariable(name: "ptr_v2"

0 commit comments

Comments
 (0)