llvm-project/bolt/test/RISCV/cie-gnu.test
Job Noorman 6795bfce4d
[BOLT][RISCV] Handle CIE's produced by GNU as (#69578)
On RISC-V, GNU as produces the following initial instruction in CIE's:

```
DW_CFA_def_cfa_register: r2
```

While I believe it is technically illegal to use this instruction
without first using a `DW_CFA_def_cfa` (since the offset is undefined),
both `readelf` and `llvm-dwarfdump` accept this and implicitly set the
offset to 0.

In BOLT, however, this triggers an assert (in `CFISnapshot::advanceTo`)
as it (correctly) believes the offset is not set. This patch fixes this
by setting the offset to 0 whenever executing `DW_CFA_def_cfa_register`
while the offset is undefined.

Note that this is probably the simplest workaround but it has a
downside: while emitting CFI start, we check if the initial instructions
are contained within `MCAsmInfo::getInitialFrameState` and omit them if
they are. This will not be true for GNU CIE's (since they differ from
LLVM's) which causes an unnecessary `DW_CFA_def_cfa_register` to be
emitted.

While technically correct, it would probably be better to replace the
GNU CIE with the one used by LLVM to avoid this situation. This would
solve the problem this patch solves while also preventing unnecessary
CFI instructions. However, this is a bit trickier to implement correctly
so I propose to keep this for a later time.

Note on testing: the test creates a simple function with three basic
blocks and forces the CFI state of the last one to be different from the
others using an arbitrary CFI instruction. Then,
`--reorder-blocks=reverse` is used to force `CFISnapshot::advanceTo` to
be called. This causes an assert on the current main branch.
2023-10-20 15:49:17 +00:00

18 lines
773 B
Plaintext

# Test that BOLT can handle CIE's produced by GNU as. On RISC-V, GNU as produces
# the following initial instruction:
# DW_CFA_def_cfa_register: r2
# While I believe it is technically incorrect to use this instruction without
# first using a DW_CFA_def_cfa (since the offset is unspecified), both readelf
# and llvm-dwarfdump accept this and implicitly set the offset to 0.
# In BOLT, this used to trigger an assert, however, since it (correctly)
# believed the offset was not set. This test checks we can handle this
# situation.
RUN: yaml2obj -o %t %p/Inputs/cie-gnu.yaml
RUN: llvm-bolt -o %t.bolt %t --reorder-blocks=reverse
RUN: llvm-dwarfdump --debug-frame %t.bolt | FileCheck %s
CHECK: 0x400000: CFA=X2
CHECK: 0x400004: CFA=X2: X5=undefined
CHECK: 0x400006: CFA=X2