llvm / llvm/llvm-project

[XRay] Debug instructions count toward xray-instruction-threshold

Open
#219,376 0 comments 0 reactions 0 assignees View on GitHub
llvm:codegen xray
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

Debug information changes the generated code when selective XRay
instrumentation is enabled. LLVM counts debug-only `MachineInstr`s toward
`xray-instruction-threshold`, so the same function can be instrumented with
`-g` but not with `-g0`.

This is a code-generation quality bug rather than a miscompile. It reproduces
on x86-64 with LLVM 24.0.0git at llvm-project revision
`2e3d50b4111f324fb615c3c18d02189caa1ef62d`.

Reproducer

```c
__attribute__((noinline)) int xray_frontier(int x) {
return x + 1;
}
```

Compile the same source twice:

```sh
clang -O2 -fxray-instrument -fxray-instruction-threshold=4 \
-g0 -c reduced.c -o g0.o
clang -O2 -fxray-instrument -fxray-instruction-threshold=4 \
-g -c reduced.c -o debug.o

llvm-readobj --sections g0.o | grep -E 'xray_(instr_map|fn_idx)'
llvm-readobj --sections debug.o | grep -E 'xray_(instr_map|fn_idx)'
```

The first query has no output. The second reports both sections:

```text
Name: xray_instr_map
Name: xray_fn_idx
```

The `-g0` object contains only the ordinary `lea` and `ret` instructions for
`xray_frontier`. The `-g` object also contains an XRay entry sled.

## Causal evidence

The Machine IR can be dumped with:

```sh
clang -O2 -fxray-instrument -fxray-instruction-threshold=4 -g0 \
-mllvm -print-before=xray-instrumentation \
-mllvm -filter-print-funcs=xray_frontier -c reduced.c -o /dev/null

clang -O2 -fxray-instrument -fxray-instruction-threshold=4 -g \
-mllvm -print-before=xray-instrumentation \
-mllvm -filter-print-funcs=xray_frontier -c reduced.c -o /dev/null
```

Immediately before `xray-instrumentation`, the `-g0` function has three
MachineInstrs:

```text
KILL
LEA64_32r
RET64
```

The `-g` function has the same three ordinary instructions and one additional
debug instruction:

```text
DBG_VALUE
KILL
LEA64_32r
RET64
```

`XRayInstrumentation.cpp` currently computes the threshold count with:

```cpp
uint64_t MICount = 0;
for (const auto &MBB : MF)
MICount += MBB.size();
```

The raw counts are therefore three and four. At threshold four, the `-g0`
function is below the threshold, while the debug build is not.

## Expected behavior

Debug information should not affect the XRay instrumentation decision. The
threshold should count non-debug machine instructions. This report is limited
to `MachineInstr::isDebugInstr()` records; changing the treatment of pseudo
probes or other non-debug meta instructions is outside its scope.

Contributor guide

Open the contributing guide

Research direction

Start in XRayInstrumentation.cpp at the MICount calculation and compare its handling with MachineInstr::isDebugInstr(). Re-run the supplied clang reproducer and Machine IR dumps with -g0 and -g; done means debug instructions no longer change whether the function crosses xray-instruction-threshold.

Written by the indexing model from the issue text.

Assessment

Tech stack
c, cpp
Domain
compilers
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
72/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.