Skip to content

Commit

Permalink
[RISCV] Use 'riscv-isa' module flag to set ELF flags and attributes. (#…
Browse files Browse the repository at this point in the history
…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.
  • Loading branch information
topperc authored and tstellar committed May 14, 2024
1 parent 3512b12 commit dff7178
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 4 deletions.
32 changes: 28 additions & 4 deletions llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ class RISCVAsmPrinter : public AsmPrinter {
bool emitDirectiveOptionArch();

private:
void emitAttributes();
void emitAttributes(const MCSubtargetInfo &SubtargetInfo);

void emitNTLHint(const MachineInstr *MI);

Expand Down Expand Up @@ -385,8 +385,32 @@ void RISCVAsmPrinter::emitStartOfAsmFile(Module &M) {
if (const MDString *ModuleTargetABI =
dyn_cast_or_null<MDString>(M.getModuleFlag("target-abi")))
RTS.setTargetABI(RISCVABI::getTargetABI(ModuleTargetABI->getString()));

MCSubtargetInfo SubtargetInfo = *TM.getMCSubtargetInfo();

// Use module flag to update feature bits.
if (auto *MD = dyn_cast_or_null<MDNode>(M.getModuleFlag("riscv-isa"))) {
for (auto &ISA : MD->operands()) {
if (auto *ISAString = dyn_cast_or_null<MDString>(ISA)) {
auto ParseResult = llvm::RISCVISAInfo::parseArchString(
ISAString->getString(), /*EnableExperimentalExtension=*/true,
/*ExperimentalExtensionVersionCheck=*/true);
if (!errorToBool(ParseResult.takeError())) {
auto &ISAInfo = *ParseResult;
for (const auto &Feature : RISCVFeatureKV) {
if (ISAInfo->hasExtension(Feature.Key) &&
!SubtargetInfo.hasFeature(Feature.Value))
SubtargetInfo.ToggleFeature(Feature.Key);
}
}
}
}

RTS.setFlagsFromFeatures(SubtargetInfo);
}

if (TM.getTargetTriple().isOSBinFormatELF())
emitAttributes();
emitAttributes(SubtargetInfo);
}

void RISCVAsmPrinter::emitEndOfAsmFile(Module &M) {
Expand All @@ -398,13 +422,13 @@ void RISCVAsmPrinter::emitEndOfAsmFile(Module &M) {
EmitHwasanMemaccessSymbols(M);
}

void RISCVAsmPrinter::emitAttributes() {
void RISCVAsmPrinter::emitAttributes(const MCSubtargetInfo &SubtargetInfo) {
RISCVTargetStreamer &RTS =
static_cast<RISCVTargetStreamer &>(*OutStreamer->getTargetStreamer());
// 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.
RTS.emitTargetAttributes(*TM.getMCSubtargetInfo(), /*EmitStackAlign*/ true);
RTS.emitTargetAttributes(SubtargetInfo, /*EmitStackAlign*/ true);
}

void RISCVAsmPrinter::emitFunctionEntryLabel() {
Expand Down
17 changes: 17 additions & 0 deletions llvm/test/CodeGen/RISCV/attributes-module-flag.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
; RUN: llc -mtriple=riscv32 %s -o - | FileCheck %s --check-prefix=RV32
; RUN: llc -mtriple=riscv64 %s -o - | FileCheck %s --check-prefix=RV64

; Test generation of ELF attribute from module metadata

; RV32: .attribute 5, "rv32i2p1_m2p0_zba1p0"
; RV64: .attribute 5, "rv64i2p1_m2p0_zba1p0"

define i32 @addi(i32 %a) {
%1 = add i32 %a, 1
ret i32 %1
}

!llvm.module.flags = !{!0}

!0 = !{i32 6, !"riscv-isa", !1}
!1 = !{!"rv64i2p1_m2p0", !"rv64i2p1_zba1p0"}
13 changes: 13 additions & 0 deletions llvm/test/CodeGen/RISCV/module-elf-flags.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
; RUN: llc -mtriple=riscv32 -filetype=obj < %s | llvm-readelf -h - | FileCheck -check-prefixes=FLAGS %s

; FLAGS: Flags: 0x11, RVC, TSO

define i32 @addi(i32 %a) {
%1 = add i32 %a, 1
ret i32 %1
}

!llvm.module.flags = !{!0}

!0 = !{i32 6, !"riscv-isa", !1}
!1 = !{!"rv64i2p1_c2p0_ztso0p1"}

0 comments on commit dff7178

Please sign in to comment.