Skip to content

Commit dff7178

Browse files
topperctstellar
authored andcommitted
[RISCV] Use 'riscv-isa' module flag to set ELF flags and attributes. (#85155)
Walk all the ISA strings and set the subtarget bits for any extension we find in any string. This allows LTO output to have a ELF attributes from the union of all of the files used to compile it.
1 parent 3512b12 commit dff7178

File tree

3 files changed

+58
-4
lines changed

3 files changed

+58
-4
lines changed

llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp

+28-4
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ class RISCVAsmPrinter : public AsmPrinter {
100100
bool emitDirectiveOptionArch();
101101

102102
private:
103-
void emitAttributes();
103+
void emitAttributes(const MCSubtargetInfo &SubtargetInfo);
104104

105105
void emitNTLHint(const MachineInstr *MI);
106106

@@ -385,8 +385,32 @@ void RISCVAsmPrinter::emitStartOfAsmFile(Module &M) {
385385
if (const MDString *ModuleTargetABI =
386386
dyn_cast_or_null<MDString>(M.getModuleFlag("target-abi")))
387387
RTS.setTargetABI(RISCVABI::getTargetABI(ModuleTargetABI->getString()));
388+
389+
MCSubtargetInfo SubtargetInfo = *TM.getMCSubtargetInfo();
390+
391+
// Use module flag to update feature bits.
392+
if (auto *MD = dyn_cast_or_null<MDNode>(M.getModuleFlag("riscv-isa"))) {
393+
for (auto &ISA : MD->operands()) {
394+
if (auto *ISAString = dyn_cast_or_null<MDString>(ISA)) {
395+
auto ParseResult = llvm::RISCVISAInfo::parseArchString(
396+
ISAString->getString(), /*EnableExperimentalExtension=*/true,
397+
/*ExperimentalExtensionVersionCheck=*/true);
398+
if (!errorToBool(ParseResult.takeError())) {
399+
auto &ISAInfo = *ParseResult;
400+
for (const auto &Feature : RISCVFeatureKV) {
401+
if (ISAInfo->hasExtension(Feature.Key) &&
402+
!SubtargetInfo.hasFeature(Feature.Value))
403+
SubtargetInfo.ToggleFeature(Feature.Key);
404+
}
405+
}
406+
}
407+
}
408+
409+
RTS.setFlagsFromFeatures(SubtargetInfo);
410+
}
411+
388412
if (TM.getTargetTriple().isOSBinFormatELF())
389-
emitAttributes();
413+
emitAttributes(SubtargetInfo);
390414
}
391415

392416
void RISCVAsmPrinter::emitEndOfAsmFile(Module &M) {
@@ -398,13 +422,13 @@ void RISCVAsmPrinter::emitEndOfAsmFile(Module &M) {
398422
EmitHwasanMemaccessSymbols(M);
399423
}
400424

401-
void RISCVAsmPrinter::emitAttributes() {
425+
void RISCVAsmPrinter::emitAttributes(const MCSubtargetInfo &SubtargetInfo) {
402426
RISCVTargetStreamer &RTS =
403427
static_cast<RISCVTargetStreamer &>(*OutStreamer->getTargetStreamer());
404428
// Use MCSubtargetInfo from TargetMachine. Individual functions may have
405429
// attributes that differ from other functions in the module and we have no
406430
// way to know which function is correct.
407-
RTS.emitTargetAttributes(*TM.getMCSubtargetInfo(), /*EmitStackAlign*/ true);
431+
RTS.emitTargetAttributes(SubtargetInfo, /*EmitStackAlign*/ true);
408432
}
409433

410434
void RISCVAsmPrinter::emitFunctionEntryLabel() {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
; RUN: llc -mtriple=riscv32 %s -o - | FileCheck %s --check-prefix=RV32
2+
; RUN: llc -mtriple=riscv64 %s -o - | FileCheck %s --check-prefix=RV64
3+
4+
; Test generation of ELF attribute from module metadata
5+
6+
; RV32: .attribute 5, "rv32i2p1_m2p0_zba1p0"
7+
; RV64: .attribute 5, "rv64i2p1_m2p0_zba1p0"
8+
9+
define i32 @addi(i32 %a) {
10+
%1 = add i32 %a, 1
11+
ret i32 %1
12+
}
13+
14+
!llvm.module.flags = !{!0}
15+
16+
!0 = !{i32 6, !"riscv-isa", !1}
17+
!1 = !{!"rv64i2p1_m2p0", !"rv64i2p1_zba1p0"}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
; RUN: llc -mtriple=riscv32 -filetype=obj < %s | llvm-readelf -h - | FileCheck -check-prefixes=FLAGS %s
2+
3+
; FLAGS: Flags: 0x11, RVC, TSO
4+
5+
define i32 @addi(i32 %a) {
6+
%1 = add i32 %a, 1
7+
ret i32 %1
8+
}
9+
10+
!llvm.module.flags = !{!0}
11+
12+
!0 = !{i32 6, !"riscv-isa", !1}
13+
!1 = !{!"rv64i2p1_c2p0_ztso0p1"}

0 commit comments

Comments
 (0)