Missing ELF attributes for code generation options
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
When investigating what turned out to be a misconfigured build, the Fuchsia kernel developers discovered that the Rust compiler can generate object files without matching ELF attributes for key ABI affecting code generation options. In particular, on RISC-V vector instructions were not listed as part of the ELF attributes, when they normally would be. In this case the kernel devs were surprised to find V instructions at all (ultimately due to a misconfigured build, as +v shouldn't have been part of march), but when we were using llvm-objdump, we were surprised to find that the normal attributes that objdump would use to set the right extensions for disassembly were missing `vector support altogether.
When investigating further, I found that the general issue on RISCV is somewhat known: https://github.com/llvm/llvm-project/blob/5ed5468f3810cd3c424eec5e9288884f67594068/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp#L672-#L678
```cpp
// Use MCSubtargetInfo from TargetMachine. Individual functions may have
// attributes that differ from other functions in the module and we have no
// way to know which function is correct.
```
Originally we believed this was Rust and LTO specific, but I was able to trigger this behavior with Clang and without LTO, though some would argue that the following example is an abuse of function attributes.
```cpp
// REQUIRES: riscv-registered-target
// RUN: %clang -target riscv64-unknown-linux-gnu -march=rv64gc -c -O2 %s -o %t.o
// RUN: llvm-objdump -d %t.o | FileCheck %s --check-prefix=OBJDUMP
// RUN: llvm-objdump -d --mattr=+zbb %t.o | FileCheck %s --check-prefix=OBJDUMP-ZBB
// RUN: llvm-readelf -A %t.o | FileCheck %s --check-prefix=READELF
// RUN: %clang -target riscv64-unknown-linux-gnu -march=rv64gc_zbb -c -O2 %s -o %t_zbb.o
// RUN: llvm-objdump -d %t_zbb.o | FileCheck %s --check-prefix=OBJDUMP-ZBB-ATTR
// RUN: llvm-readelf -A %t_zbb.o | FileCheck %s --check-prefix=READELF-ZBB
#include
// OBJDUMP-LABEL: <_Z10normal_clzy>:
// OBJDUMP-NOT: clz
// OBJDUMP: ret
// OBJDUMP-ZBB-LABEL: <_Z10normal_clzy>:
// OBJDUMP-ZBB-NOT: clz
// OBJDUMP-ZBB: ret
// OBJDUMP-ZBB-ATTR-LABEL: <_Z10normal_clzy>:
// OBJDUMP-ZBB-ATTR-NEXT: {{[0-9a-f]+}}: 60051513 clz a0, a0
// OBJDUMP-ZBB-ATTR-NEXT: {{[0-9a-f]+}}: 8082 ret
uint64_t normal_clz(uint64_t a) {
return __builtin_clzll(a);
}
// OBJDUMP-LABEL: <_Z7zbb_clzy>:
// OBJDUMP-NEXT: {{[0-9a-f]+}}: 60051513
// OBJDUMP-NEXT: {{[0-9a-f]+}}: 8082 ret
// OBJDUMP-ZBB-LABEL: <_Z7zbb_clzy>:
// OBJDUMP-ZBB-NEXT: {{[0-9a-f]+}}: 60051513 clz a0, a0
// OBJDUMP-ZBB-NEXT: {{[0-9a-f]+}}: 8082 ret
// OBJDUMP-ZBB-ATTR-LABEL: <_Z7zbb_clzy>:
// OBJDUMP-ZBB-ATTR-NEXT: {{[0-9a-f]+}}: 60051513 clz a0, a0
// OBJDUMP-ZBB-ATTR-NEXT: {{[0-9a-f]+}}: 8082 ret
__attribute__((target("arch=+zbb")))
uint64_t zbb_clz(uint64_t a) {
return __builtin_clzll(a);
}
// READELF: TagName: arch
// READELF-NOT: zbb
// READELF-ZBB: TagName: arch
// READELF-ZBB-NEXT: Value: {{.*}}zbb
```
@topperc @preames While this manifests in our experience as a RISC-V specific issue, its not clear to me if this is a more fundamental consequence of the per function target features that disproportionately affect RISC-V compared to other architectures. This certainly feels like something we should be able to avoid, but I know a lot of the `-march` handling rules are a bit complicated. I haven't' started looking at how to solve the issue yet, but given the code comment linked above, this seems to be an area we've already encountered problems.
Contributor guide
Research direction
Start with the RISCVAsmPrinter.cpp logic linked in the issue, then run the supplied Clang, llvm-objdump, and llvm-readelf reproducer. Compare the baseline and zbb cases and add or update an LLVM regression test so ELF attributes reflect the code-generation extensions used by the object file.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp, rust
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100