[llvm] 6eeb3b4 - [RISC-V][MC] Update ELF streamer ArchString in setFlagsFromFeatures() (#225140)
via llvm-commits
llvm-commits at lists.llvm.org
Sat Sep 26 19:02:18 PDT 2026
Author: Alexander Richardson
Date: 2026-09-26T19:02:12-07:00
New Revision: 6eeb3b4ebdae20cd5f1e0fe5e74df3b418b654e2
URL: https://github.com/llvm/llvm-project/commit/6eeb3b4ebdae20cd5f1e0fe5e74df3b418b654e2
DIFF: https://github.com/llvm/llvm-project/commit/6eeb3b4ebdae20cd5f1e0fe5e74df3b418b654e2.diff
LOG: [RISC-V][MC] Update ELF streamer ArchString in setFlagsFromFeatures() (#225140)
During LTO, the TargetMachine subtarget is initialized with the linker's
default CPU (e.g. `generic-rv64`, `rv64i2p1`), while
RISCVAsmPrinter::emitStartOfAsmFile() reconstructs the module's actual ISA from
the `riscv-isa` module flag and calls RISCVTargetStreamer::setFlagsFromFeatures()
and RISCVTargetStreamer::emitTargetAttributes(). Because
RISCVTargetELFStreamer previously only initialized InitialArchString and
ArchString in its constructor rather than in setFlagsFromFeatures(), direct
object emission bypassed the update and tagged `.text` with `$xrv64i2p1`
instead of the module's full architecture string.
Move the InitialArchString and ArchString initialization into
RISCVTargetELFStreamer::setFlagsFromFeatures() and also call setArchString()
alongside emitTextAttribute(RISCVAttrs::ARCH, ...) in
RISCVTargetStreamer::emitTargetAttributes().
This commit was created with the help of AI tools
Pull-Request: https://github.com/llvm/llvm-project/pull/225140
Added:
Modified:
cross-project-tests/riscv/lto-inline-asm-abi.c
llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp
llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.h
llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp
llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.h
Removed:
################################################################################
diff --git a/cross-project-tests/riscv/lto-inline-asm-abi.c b/cross-project-tests/riscv/lto-inline-asm-abi.c
index 883244f1854f7..897413428500f 100644
--- a/cross-project-tests/riscv/lto-inline-asm-abi.c
+++ b/cross-project-tests/riscv/lto-inline-asm-abi.c
@@ -35,33 +35,30 @@
// FLAGS-NEXT: EF_RISCV_RVC (0x1)
// FLAGS-NEXT: ]
//
-/// TODO: RISCVTargetELFStreamer::emitTextAttribute does not update the
-/// streamer's ArchString when emitting the module's RISCVAttrs::ARCH attribute
-/// ("rv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_v1p0_...").
// DISASM-LABEL: Disassembly of section .text:
// DISASM-EMPTY:
-// DISASM-NEXT: [[#%x,]] <$xrv64i2p1>:
+// DISASM-NEXT: [[#%x,]] <$xrv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_v1p0_zicsr2p0_zifencei2p0_zmmul1p0_zaamo1p0_zalrsc1p0_zca1p0_zcd1p0_zve32f1p0_zve32x1p0_zve64d1p0_zve64f1p0_zve64x1p0_zvl128b1p0_zvl32b1p0_zvl64b1p0>:
// DISASM-NEXT: [[#%x,]]: nop
// DISASM-EMPTY:
-// DISASM-NEXT: [[#%x,]] <$xrv64i2p1>:
+// DISASM-NEXT: [[#%x,]] <$xrv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_v1p0_zicsr2p0_zifencei2p0_zmmul1p0_zaamo1p0_zalrsc1p0_zca1p0_zcd1p0_zve32f1p0_zve32x1p0_zve64d1p0_zve64f1p0_zve64x1p0_zvl128b1p0_zvl32b1p0_zvl64b1p0>:
// DISASM-NEXT: [[#%x,]] <symver_fn>:
// DISASM-NEXT: [[#%x,]]: ret
// DISASM-EMPTY:
-// DISASM-NEXT: [[#%x,]] <$xrv64i2p1>:
+// DISASM-NEXT: [[#%x,]] <$xrv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_v1p0_zicsr2p0_zifencei2p0_zmmul1p0_zaamo1p0_zalrsc1p0_zca1p0_zcd1p0_zve32f1p0_zve32x1p0_zve64d1p0_zve64f1p0_zve64x1p0_zvl128b1p0_zvl32b1p0_zvl64b1p0>:
// DISASM-NEXT: [[#%x,]] <fn>:
// DISASM-NEXT: [[#%x,]]: nop
// DISASM-NEXT: [[#%x,]]: ret
// DISASM-EMPTY:
-// DISASM-NEXT: [[#%x,]] <$xrv64i2p1>:
+// DISASM-NEXT: [[#%x,]] <$xrv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_v1p0_zicsr2p0_zifencei2p0_zmmul1p0_zaamo1p0_zalrsc1p0_zca1p0_zcd1p0_zve32f1p0_zve32x1p0_zve64d1p0_zve64f1p0_zve64x1p0_zvl128b1p0_zvl32b1p0_zvl64b1p0>:
// DISASM-NEXT: [[#%x,]] <caller>:
// DISASM-NEXT: [[#%x,]]: nop
// DISASM-NEXT: [[#%x,]]: ret
// DISASM-NOT: {{.}}
//
-// SYMS: [[#%x,]] l .text 0000000000000000 $xrv64i2p1{{$}}
-// SYMS: [[#%x,]] l .text 0000000000000000 $xrv64i2p1{{$}}
-// SYMS: [[#%x,]] l .text 0000000000000000 $xrv64i2p1{{$}}
-// SYMS: [[#%x,]] l .text 0000000000000000 $xrv64i2p1{{$}}
+// SYMS: [[#%x,]] l .text 0000000000000000 $xrv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_v1p0_zicsr2p0_zifencei2p0_zmmul1p0_zaamo1p0_zalrsc1p0_zca1p0_zcd1p0_zve32f1p0_zve32x1p0_zve64d1p0_zve64f1p0_zve64x1p0_zvl128b1p0_zvl32b1p0_zvl64b1p0{{$}}
+// SYMS: [[#%x,]] l .text 0000000000000000 $xrv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_v1p0_zicsr2p0_zifencei2p0_zmmul1p0_zaamo1p0_zalrsc1p0_zca1p0_zcd1p0_zve32f1p0_zve32x1p0_zve64d1p0_zve64f1p0_zve64x1p0_zvl128b1p0_zvl32b1p0_zvl64b1p0{{$}}
+// SYMS: [[#%x,]] l .text 0000000000000000 $xrv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_v1p0_zicsr2p0_zifencei2p0_zmmul1p0_zaamo1p0_zalrsc1p0_zca1p0_zcd1p0_zve32f1p0_zve32x1p0_zve64d1p0_zve64f1p0_zve64x1p0_zvl128b1p0_zvl32b1p0_zvl64b1p0{{$}}
+// SYMS: [[#%x,]] l .text 0000000000000000 $xrv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_v1p0_zicsr2p0_zifencei2p0_zmmul1p0_zaamo1p0_zalrsc1p0_zca1p0_zcd1p0_zve32f1p0_zve32x1p0_zve64d1p0_zve64f1p0_zve64x1p0_zvl128b1p0_zvl32b1p0_zvl64b1p0{{$}}
// SYMS: [[#%x,]] g F .text 0000000000000004 fn{{$}}
// SYMS: [[#%x,]] g F .text 0000000000000002 symver_fn{{$}}
// SYMS: [[#%x,]] g F .text 0000000000000004 caller{{$}}
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp
index 10702a836de33..11093a700ac27 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp
@@ -28,18 +28,6 @@ RISCVTargetELFStreamer::RISCVTargetELFStreamer(MCStreamer &S,
const MCSubtargetInfo &STI)
: RISCVTargetStreamer(S), CurrentVendor("riscv") {
setFlagsFromFeatures(STI);
-
- // Compute the initial ISA string. This serves two purposes:
- // 1. Deduplication: subsequent .option arch/rvc/norvc directives compare
- // against ArchString to avoid propagating redundant ISA updates.
- // 2. Initial symbol: seed the streamer's active ISA so a "$x<ArchString>"
- // mapping symbol is emitted before the first instruction, recording
- // the full ISA in the object even when no .option directive is present.
- if (auto ParseResult = RISCVFeatures::parseFeatureBits(STI)) {
- InitialArchString = (*ParseResult)->toString();
- ArchString = InitialArchString;
- getStreamer().setMappingSymbolArch(ArchString);
- }
}
RISCVELFStreamer::RISCVELFStreamer(MCContext &C,
@@ -52,6 +40,23 @@ RISCVELFStreamer &RISCVTargetELFStreamer::getStreamer() {
return static_cast<RISCVELFStreamer &>(Streamer);
}
+void RISCVTargetELFStreamer::setFlagsFromFeatures(const MCSubtargetInfo &STI) {
+ RISCVTargetStreamer::setFlagsFromFeatures(STI);
+
+ // Compute the initial ISA string. This serves two purposes:
+ // 1. Deduplication: subsequent .option arch/rvc/norvc directives compare
+ // against ArchString to avoid propagating redundant ISA updates.
+ // 2. Initial symbol: seed the streamer's active ISA so a "$x<ArchString>"
+ // mapping symbol is emitted before the first instruction, recording
+ // the full ISA in the object even when no .option directive is present.
+ if (auto ParseResult = RISCVFeatures::parseFeatureBits(STI)) {
+ InitialArchString = (*ParseResult)->toString();
+ setArchString(InitialArchString);
+ } else {
+ consumeError(ParseResult.takeError());
+ }
+}
+
void RISCVTargetELFStreamer::setArchString(StringRef Arch) {
if (Arch == ArchString)
return;
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.h
index ac738307922d7..e86144ac20c9b 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.h
@@ -56,8 +56,8 @@ class RISCVTargetELFStreamer : public RISCVTargetStreamer {
private:
StringRef CurrentVendor;
- // Initial ISA string derived from the subtarget features in the constructor.
- // Used to re-establish state on reset().
+ // Initial ISA string derived from the subtarget features in
+ // setFlagsFromFeatures(). Used to re-establish state on reset().
std::string InitialArchString;
// Current ISA string, kept in sync with each .option arch/rvc/norvc/pop
@@ -81,6 +81,7 @@ class RISCVTargetELFStreamer : public RISCVTargetStreamer {
RISCVELFStreamer &getStreamer();
RISCVTargetELFStreamer(MCStreamer &S, const MCSubtargetInfo &STI);
+ void setFlagsFromFeatures(const MCSubtargetInfo &STI) override;
// Update ArchString and propagate the change to the streamer so the next
// instruction-run emits an ISA-specific mapping symbol. A no-op when
// Arch == ArchString (deduplication).
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp
index d6523cb42c879..f5f62bc5200f1 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp
@@ -86,7 +86,9 @@ void RISCVTargetStreamer::emitTargetAttributes(const MCSubtargetInfo &STI,
report_fatal_error(ParseResult.takeError());
} else {
auto &ISAInfo = *ParseResult;
- emitTextAttribute(RISCVAttrs::ARCH, ISAInfo->toString());
+ std::string Arch = ISAInfo->toString();
+ emitTextAttribute(RISCVAttrs::ARCH, Arch);
+ setArchString(Arch);
}
if (RiscvAbiAttr && STI.hasFeature(RISCV::FeatureStdExtA)) {
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.h
index cd59089fae4c7..c7b4f752d7264 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.h
@@ -64,7 +64,7 @@ class RISCVTargetStreamer : public MCTargetStreamer {
void setTargetABI(RISCVABI::ABI ABI);
RISCVABI::ABI getTargetABI() const { return TargetABI; }
bool hasTargetABI() const { return TargetABI != RISCVABI::ABI_Unknown; }
- void setFlagsFromFeatures(const MCSubtargetInfo &STI);
+ virtual void setFlagsFromFeatures(const MCSubtargetInfo &STI);
bool hasRVC() const { return HasRVC; }
bool hasTSO() const { return HasTSO; }
};
More information about the llvm-commits
mailing list